限流,支持客户端ID修改、删除.
This commit is contained in:
@@ -11,6 +11,8 @@ import java.util.List;
|
|||||||
@Data
|
@Data
|
||||||
public class AlterClientQuotaDTO {
|
public class AlterClientQuotaDTO {
|
||||||
|
|
||||||
|
private String type;
|
||||||
|
|
||||||
private List<String> types;
|
private List<String> types;
|
||||||
|
|
||||||
private List<String> names;
|
private List<String> names;
|
||||||
@@ -20,4 +22,6 @@ public class AlterClientQuotaDTO {
|
|||||||
private String producerRate;
|
private String producerRate;
|
||||||
|
|
||||||
private String requestPercentage;
|
private String requestPercentage;
|
||||||
|
|
||||||
|
private List<String> deleteConfigs;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ public class ClientQuotaEntityVO {
|
|||||||
double _1kb = 1024;
|
double _1kb = 1024;
|
||||||
double _1mb = 1024 * _1kb;
|
double _1mb = 1024 * _1kb;
|
||||||
if (value < _1kb) {
|
if (value < _1kb) {
|
||||||
return value + "Byte";
|
return value + " Byte";
|
||||||
}
|
}
|
||||||
if (value < _1mb) {
|
if (value < _1mb) {
|
||||||
return String.format("%.1f KB", (value / _1kb));
|
return String.format("%.1f KB", (value / _1kb));
|
||||||
|
|||||||
@@ -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.beans.dto.QueryClientQuotaDTO;
|
||||||
import com.xuxd.kafka.console.service.ClientQuotaService;
|
import com.xuxd.kafka.console.service.ClientQuotaService;
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author: xuxd
|
* @author: xuxd
|
||||||
@@ -38,4 +35,14 @@ public class ClientQuotaController {
|
|||||||
}
|
}
|
||||||
return clientQuotaService.alterClientQuotaConfigs(request);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,4 +13,6 @@ public interface ClientQuotaService {
|
|||||||
ResponseData getClientQuotaConfigs(List<String> types, List<String> names);
|
ResponseData getClientQuotaConfigs(List<String> types, List<String> names);
|
||||||
|
|
||||||
ResponseData alterClientQuotaConfigs(AlterClientQuotaDTO request);
|
ResponseData alterClientQuotaConfigs(AlterClientQuotaDTO request);
|
||||||
|
|
||||||
|
ResponseData deleteClientQuotaConfigs(AlterClientQuotaDTO request);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,9 @@ import com.xuxd.kafka.console.beans.vo.ClientQuotaEntityVO;
|
|||||||
import com.xuxd.kafka.console.service.ClientQuotaService;
|
import com.xuxd.kafka.console.service.ClientQuotaService;
|
||||||
import kafka.console.ClientQuotaConsole;
|
import kafka.console.ClientQuotaConsole;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.kafka.common.config.internals.QuotaConfigs;
|
||||||
import org.apache.kafka.common.quota.ClientQuotaEntity;
|
import org.apache.kafka.common.quota.ClientQuotaEntity;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@@ -24,10 +26,22 @@ public class ClientQuotaServiceImpl implements ClientQuotaService {
|
|||||||
|
|
||||||
private final Map<String, String> typeDict = new HashMap<>();
|
private final Map<String, String> typeDict = new HashMap<>();
|
||||||
|
|
||||||
|
private final Map<String, String> 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(USER, ClientQuotaEntity.USER);
|
||||||
typeDict.put("client-id", ClientQuotaEntity.CLIENT_ID);
|
typeDict.put(CLIENT_ID, ClientQuotaEntity.CLIENT_ID);
|
||||||
typeDict.put("ip", ClientQuotaEntity.IP);
|
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) {
|
public ClientQuotaServiceImpl(ClientQuotaConsole clientQuotaConsole) {
|
||||||
@@ -65,9 +79,84 @@ public class ClientQuotaServiceImpl implements ClientQuotaService {
|
|||||||
@Override
|
@Override
|
||||||
public ResponseData alterClientQuotaConfigs(AlterClientQuotaDTO request) {
|
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<String> types = new ArrayList<>();
|
||||||
|
List<String> names = new ArrayList<>();
|
||||||
|
parseTypesAndNames(request, types, names, request.getType());
|
||||||
|
Map<String, String> 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<String> 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<String> types = new ArrayList<>();
|
||||||
|
List<String> names = new ArrayList<>();
|
||||||
|
parseTypesAndNames(request, types, names, request.getType());
|
||||||
|
List<String> 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<String> types, List<String> 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<String> types, List<String> 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("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -303,4 +303,8 @@ export const KafkaClientQuotaApi = {
|
|||||||
url: "/client/quota",
|
url: "/client/quota",
|
||||||
method: "post",
|
method: "post",
|
||||||
},
|
},
|
||||||
|
deleteClientQuotaConfigs: {
|
||||||
|
url: "/client/quota",
|
||||||
|
method: "delete",
|
||||||
|
},
|
||||||
};
|
};
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
<script src="../../store/index.js"></script>
|
||||||
<template>
|
<template>
|
||||||
<a-modal
|
<a-modal
|
||||||
title="新增配置"
|
title="新增配置"
|
||||||
@@ -17,28 +18,28 @@
|
|||||||
:wrapper-col="{ span: 12 }"
|
:wrapper-col="{ span: 12 }"
|
||||||
@submit="handleSubmit"
|
@submit="handleSubmit"
|
||||||
>
|
>
|
||||||
<a-form-item label="用户">
|
<a-form-item label="用户" v-show="showUser">
|
||||||
<a-input
|
<a-input
|
||||||
v-decorator="[
|
v-decorator="[
|
||||||
'user',
|
'user',
|
||||||
]"
|
]"
|
||||||
placeholder="输入用户主体标识,比如:用户名!"
|
placeholder="输入用户主体标识,比如:用户名,未指定表示用户默认设置"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="客户端ID">
|
<a-form-item label="客户端ID" v-show="showClientId">
|
||||||
<a-input
|
<a-input
|
||||||
v-decorator="[
|
v-decorator="[
|
||||||
'client-id',
|
'client',
|
||||||
]"
|
]"
|
||||||
placeholder="输入用户客户端ID!"
|
placeholder="输入用户客户端ID,未指定表示默认客户端设置"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="IP">
|
<a-form-item label="IP" v-show="showIP">
|
||||||
<a-input
|
<a-input
|
||||||
v-decorator="[
|
v-decorator="[
|
||||||
'ip',
|
'ip',
|
||||||
]"
|
]"
|
||||||
placeholder="输入客户端IP!"
|
placeholder="输入客户端IP"
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="生产速率">
|
<a-form-item label="生产速率">
|
||||||
@@ -89,17 +90,29 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import request from "@/utils/request";
|
import request from "@/utils/request";
|
||||||
import {KafkaTopicApi} from "@/utils/api";
|
import {KafkaClientQuotaApi} from "@/utils/api";
|
||||||
import notification from "ant-design-vue/es/notification";
|
import notification from "ant-design-vue/es/notification";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "AddQuotaConfig",
|
name: "AddQuotaConfig",
|
||||||
props: {
|
props: {
|
||||||
topic: {
|
visible: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
type: {
|
||||||
type: String,
|
type: String,
|
||||||
default: "",
|
default: "",
|
||||||
},
|
},
|
||||||
visible: {
|
showClientId: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
showUser: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
showIP: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
@@ -120,29 +133,47 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
handleSubmit(e) {
|
handleSubmit() {
|
||||||
e.preventDefault();
|
|
||||||
this.form.validateFields((err, values) => {
|
this.form.validateFields((err, values) => {
|
||||||
if (!err) {
|
if (!err) {
|
||||||
if (values.configs) {
|
const params = Object.assign({type: this.type}, values);
|
||||||
const config = {};
|
const unitMap = {MB: 1024 * 1024, KB: 1024, Byte: 1};
|
||||||
values.configs.split("\n").forEach((e) => {
|
if (values.consumerRate) {
|
||||||
const c = e.split("=");
|
params.consumerRate = params.consumerRate * unitMap[this.consumerRateUnit];
|
||||||
if (c.length > 1) {
|
}
|
||||||
let k = c[0].trim(),
|
if (values.producerRate) {
|
||||||
v = c[1].trim();
|
params.producerRate = params.producerRate * unitMap[this.producerRateUnit];
|
||||||
if (k && v) {
|
}
|
||||||
config[k] = v;
|
params.types = [];
|
||||||
|
if (this.showUser) {
|
||||||
|
params.types.push("user");
|
||||||
|
if (params.user) {
|
||||||
|
params.names = [params.user.trim()];
|
||||||
|
} else {
|
||||||
|
params.names = [""];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
if (this.showClientId) {
|
||||||
values.configs = config;
|
params.types.push("client-id");
|
||||||
|
if (params.client) {
|
||||||
|
params.names = [params.client.trim()];
|
||||||
|
} else {
|
||||||
|
params.names = [""];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.showIP) {
|
||||||
|
params.types.push("ip");
|
||||||
|
if (params.ip) {
|
||||||
|
params.names = [params.ip.trim()];
|
||||||
|
} else {
|
||||||
|
params.names = [""];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
request({
|
request({
|
||||||
url: KafkaTopicApi.creatTopic.url,
|
url: KafkaClientQuotaApi.alterClientQuotaConfigs.url,
|
||||||
method: KafkaTopicApi.creatTopic.method,
|
method: KafkaClientQuotaApi.alterClientQuotaConfigs.method,
|
||||||
data: values,
|
data: params,
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
if (res.code == 0) {
|
if (res.code == 0) {
|
||||||
@@ -161,6 +192,12 @@ export default {
|
|||||||
handleCancel() {
|
handleCancel() {
|
||||||
this.data = [];
|
this.data = [];
|
||||||
this.$emit("closeAddQuotaDialog", {refresh: false});
|
this.$emit("closeAddQuotaDialog", {refresh: false});
|
||||||
|
this.producerRateUnit = "MB";
|
||||||
|
this.consumerRateUnit = "MB";
|
||||||
|
},
|
||||||
|
create() {
|
||||||
|
this.producerRateUnit = "MB";
|
||||||
|
this.consumerRateUnit = "MB";
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -31,8 +31,8 @@
|
|||||||
>新增配置
|
>新增配置
|
||||||
</a-button>
|
</a-button>
|
||||||
</div>
|
</div>
|
||||||
<QuotaList :columns="columns" :data="data"></QuotaList>
|
<QuotaList type="client-id" :columns="columns" :data="data" @refreshQuotaList="refresh"></QuotaList>
|
||||||
<AddQuotaConfig :visible="showAddQuotaDialog" @closeAddQuotaDialog="closeAddQuotaDialog"></AddQuotaConfig>
|
<AddQuotaConfig type="client-id" :visible="showAddQuotaDialog" :showClientId="true" @closeAddQuotaDialog="closeAddQuotaDialog"></AddQuotaConfig>
|
||||||
</a-spin>
|
</a-spin>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -116,9 +116,15 @@ export default {
|
|||||||
openAddQuotaDialog() {
|
openAddQuotaDialog() {
|
||||||
this.showAddQuotaDialog = true;
|
this.showAddQuotaDialog = true;
|
||||||
},
|
},
|
||||||
closeAddQuotaDialog() {
|
closeAddQuotaDialog(p) {
|
||||||
|
if (p.refresh) {
|
||||||
|
this.handleSearch();
|
||||||
|
}
|
||||||
this.showAddQuotaDialog = false;
|
this.showAddQuotaDialog = false;
|
||||||
},
|
},
|
||||||
|
refresh() {
|
||||||
|
this.handleSearch();
|
||||||
|
},
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.handleSearch();
|
this.handleSearch();
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
|
<a-spin :spinning="loading">
|
||||||
<a-table
|
<a-table
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:data-source="data"
|
:data-source="data"
|
||||||
@@ -12,17 +13,44 @@
|
|||||||
@change="handleChange"
|
@change="handleChange"
|
||||||
>
|
>
|
||||||
<div slot="client" slot-scope="text">
|
<div slot="client" slot-scope="text">
|
||||||
<span v-if="text" >{{text}}</span><span v-else style="color: red">默认配置</span>
|
<span v-if="text">{{ text }}</span><span v-else style="color: red">默认配置</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div slot="operation" slot-scope="record">
|
||||||
|
<a-popconfirm
|
||||||
|
:title="'删除当前配置?'"
|
||||||
|
ok-text="确认"
|
||||||
|
cancel-text="取消"
|
||||||
|
@confirm="deleteConfig(record)"
|
||||||
|
>
|
||||||
|
<a-button size="small" href="javascript:;" class="operation-btn"
|
||||||
|
>删除
|
||||||
|
</a-button>
|
||||||
|
</a-popconfirm>
|
||||||
|
<a-button
|
||||||
|
size="small"
|
||||||
|
href="javascript:;"
|
||||||
|
class="operation-btn"
|
||||||
|
@click="openUpdateDialog(record)"
|
||||||
|
>修改
|
||||||
|
</a-button>
|
||||||
</div>
|
</div>
|
||||||
</a-table>
|
</a-table>
|
||||||
|
<UpdateQuotaConfig :type="type" :record="selectRow" :visible="showUpdateDialog"
|
||||||
|
@closeUpdateQuotaDialog="closeUpdateQuotaDialog"></UpdateQuotaConfig>
|
||||||
|
</a-spin>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import {KafkaClientQuotaApi} from "@/utils/api";
|
||||||
|
import request from "@/utils/request";
|
||||||
|
import notification from "ant-design-vue/lib/notification";
|
||||||
|
import UpdateQuotaConfig from "@/views/quota/UpdateQuotaConfig.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "QuotaList",
|
name: "QuotaList",
|
||||||
components: {},
|
components: {UpdateQuotaConfig},
|
||||||
props: {
|
props: {
|
||||||
columns: {
|
columns: {
|
||||||
type: Array,
|
type: Array,
|
||||||
@@ -30,12 +58,18 @@ export default {
|
|||||||
data: {
|
data: {
|
||||||
type: Array,
|
type: Array,
|
||||||
},
|
},
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: "",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
showDetailDialog: false,
|
|
||||||
record: {},
|
record: {},
|
||||||
sortedInfo: null,
|
sortedInfo: null,
|
||||||
|
loading: false,
|
||||||
|
selectRow: {},
|
||||||
|
showUpdateDialog: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -49,8 +83,74 @@ export default {
|
|||||||
handleChange() {
|
handleChange() {
|
||||||
this.sortedInfo = arguments[2];
|
this.sortedInfo = arguments[2];
|
||||||
},
|
},
|
||||||
|
deleteConfig(record) {
|
||||||
|
this.loading = true;
|
||||||
|
const params = {type: this.type};
|
||||||
|
params.types = [];
|
||||||
|
if (this.type == "user") {
|
||||||
|
params.types.push("user");
|
||||||
|
if (record.user) {
|
||||||
|
params.names = [record.user.trim()];
|
||||||
|
} else {
|
||||||
|
params.names = [""];
|
||||||
|
}
|
||||||
|
} else if (this.type == "client-id") {
|
||||||
|
params.types.push("client-id");
|
||||||
|
if (record.client) {
|
||||||
|
params.names = [record.client.trim()];
|
||||||
|
} else {
|
||||||
|
params.names = [""];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.type == "ip") {
|
||||||
|
params.types.push("ip");
|
||||||
|
if (record.ip) {
|
||||||
|
params.names = [record.ip.trim()];
|
||||||
|
} else {
|
||||||
|
params.names = [""];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
request({
|
||||||
|
url: KafkaClientQuotaApi.deleteClientQuotaConfigs.url,
|
||||||
|
method: KafkaClientQuotaApi.deleteClientQuotaConfigs.method,
|
||||||
|
data: params,
|
||||||
|
}).then((res) => {
|
||||||
|
this.loading = false;
|
||||||
|
if (res.code == 0) {
|
||||||
|
this.$message.success(res.msg);
|
||||||
|
this.$emit("refreshQuotaList");
|
||||||
|
} else {
|
||||||
|
notification.error({
|
||||||
|
message: "error",
|
||||||
|
description: res.msg,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
openUpdateDialog(record) {
|
||||||
|
this.selectRow = record;
|
||||||
|
this.showUpdateDialog = true;
|
||||||
|
},
|
||||||
|
closeUpdateQuotaDialog(event) {
|
||||||
|
this.selectRow = {};
|
||||||
|
this.showUpdateDialog = false;
|
||||||
|
if (event.refresh) {
|
||||||
|
this.$emit("refreshQuotaList");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.columns.push({
|
||||||
|
title: "操作",
|
||||||
|
key: "operation",
|
||||||
|
scopedSlots: {customRender: "operation"},
|
||||||
|
});
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped>
|
||||||
|
.operation-btn {
|
||||||
|
margin-right: 3%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
238
ui/src/views/quota/UpdateQuotaConfig.vue
Normal file
238
ui/src/views/quota/UpdateQuotaConfig.vue
Normal file
@@ -0,0 +1,238 @@
|
|||||||
|
<script src="../../store/index.js"></script>
|
||||||
|
<template>
|
||||||
|
<a-modal
|
||||||
|
title="修改配置"
|
||||||
|
:visible="show"
|
||||||
|
:width="800"
|
||||||
|
:mask="false"
|
||||||
|
:destroyOnClose="true"
|
||||||
|
:footer="null"
|
||||||
|
:maskClosable="false"
|
||||||
|
@cancel="handleCancel"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<a-spin :spinning="loading">
|
||||||
|
<a-form
|
||||||
|
:form="form"
|
||||||
|
:label-col="{ span: 5 }"
|
||||||
|
:wrapper-col="{ span: 12 }"
|
||||||
|
@submit="handleSubmit"
|
||||||
|
>
|
||||||
|
<a-form-item label="用户" v-show="showUser">
|
||||||
|
<a-input
|
||||||
|
:disabled="true"
|
||||||
|
v-decorator="[
|
||||||
|
'user', { initialValue: record.user }
|
||||||
|
]"
|
||||||
|
placeholder="输入用户主体标识,比如:用户名,未指定表示用户默认设置"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="客户端ID" v-show="showClientId">
|
||||||
|
<a-input
|
||||||
|
:disabled="true"
|
||||||
|
v-decorator="[
|
||||||
|
'client', { initialValue: record.client }
|
||||||
|
]"
|
||||||
|
placeholder="输入用户客户端ID,未指定表示默认客户端设置"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="IP" v-show="showIP">
|
||||||
|
<a-input
|
||||||
|
:disabled="true"
|
||||||
|
v-decorator="[
|
||||||
|
'ip', { initialValue: record.ip }
|
||||||
|
]"
|
||||||
|
placeholder="输入客户端IP"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="生产速率">
|
||||||
|
<a-input-number
|
||||||
|
:min="1"
|
||||||
|
:max="102400000"
|
||||||
|
v-decorator="[
|
||||||
|
'producerRate', { initialValue: record.producerRate }
|
||||||
|
]"
|
||||||
|
/>
|
||||||
|
<a-select default-value="MB" v-model="producerRateUnit" style="width: 100px">
|
||||||
|
<a-select-option value="MB"> MB/s</a-select-option>
|
||||||
|
<a-select-option value="KB"> KB/s</a-select-option>
|
||||||
|
<a-select-option value="Byte"> Byte/s</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="消费速率">
|
||||||
|
<a-input-number
|
||||||
|
:min="1"
|
||||||
|
:max="102400000"
|
||||||
|
v-decorator="[
|
||||||
|
'consumerRate', { initialValue: record.consumerRate }
|
||||||
|
]"
|
||||||
|
/>
|
||||||
|
<a-select default-value="MB" v-model="consumerRateUnit" style="width: 100px">
|
||||||
|
<a-select-option value="MB"> MB/s</a-select-option>
|
||||||
|
<a-select-option value="KB"> KB/s</a-select-option>
|
||||||
|
<a-select-option value="Byte"> Byte/s</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="吞吐量">
|
||||||
|
<a-input-number
|
||||||
|
:min="1"
|
||||||
|
:max="102400000"
|
||||||
|
v-decorator="[
|
||||||
|
'requestPercentage', { initialValue: record.requestPercentage }
|
||||||
|
]"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item :wrapper-col="{ span: 12, offset: 5 }">
|
||||||
|
<a-button type="primary" html-type="submit"> 提交</a-button>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</a-spin>
|
||||||
|
</div>
|
||||||
|
</a-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import request from "@/utils/request";
|
||||||
|
import {KafkaClientQuotaApi} from "@/utils/api";
|
||||||
|
import notification from "ant-design-vue/es/notification";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "UpdateQuotaConfig",
|
||||||
|
props: {
|
||||||
|
visible: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: "",
|
||||||
|
},
|
||||||
|
record: {
|
||||||
|
type: Object,
|
||||||
|
default: function () {
|
||||||
|
return {}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
show: this.visible,
|
||||||
|
data: [],
|
||||||
|
loading: false,
|
||||||
|
form: this.$form.createForm(this, {name: "coordinated"}),
|
||||||
|
producerRateUnit: "MB",
|
||||||
|
consumerRateUnit: "MB",
|
||||||
|
showUser: false,
|
||||||
|
showIP: false,
|
||||||
|
showClientId: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
visible(v) {
|
||||||
|
this.show = v;
|
||||||
|
if (this.show) {
|
||||||
|
this.init();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleSubmit() {
|
||||||
|
this.form.validateFields((err, values) => {
|
||||||
|
if (!err) {
|
||||||
|
const params = {type: this.type, deleteConfigs: []};
|
||||||
|
const unitMap = {MB: 1024 * 1024, KB: 1024, Byte: 1};
|
||||||
|
if (values.consumerRate) {
|
||||||
|
const num = typeof (values.consumerRate) == "string" && values.consumerRate.indexOf(" ") > 0 ? values.consumerRate.split(" ")[0] : values.consumerRate;
|
||||||
|
params.consumerRate = num * unitMap[this.consumerRateUnit];
|
||||||
|
} else {
|
||||||
|
params.deleteConfigs.push("consumerRate");
|
||||||
|
}
|
||||||
|
if (values.producerRate) {
|
||||||
|
const num = typeof (values.producerRate) && values.producerRate.indexOf(" ") > 0 ? values.producerRate.split(" ")[0] : values.producerRate;
|
||||||
|
params.producerRate = num * unitMap[this.producerRateUnit];
|
||||||
|
} else {
|
||||||
|
params.deleteConfigs.push("producerRate");
|
||||||
|
}
|
||||||
|
if (values.requestPercentage) {
|
||||||
|
params.requestPercentage = values.requestPercentage;
|
||||||
|
} else {
|
||||||
|
params.deleteConfigs.push("requestPercentage");
|
||||||
|
}
|
||||||
|
params.types = [];
|
||||||
|
if (this.showUser) {
|
||||||
|
params.types.push("user");
|
||||||
|
if (values.user) {
|
||||||
|
params.names = [values.user.trim()];
|
||||||
|
} else {
|
||||||
|
params.names = [""];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.showClientId) {
|
||||||
|
params.types.push("client-id");
|
||||||
|
if (values.client) {
|
||||||
|
params.names = [values.client.trim()];
|
||||||
|
} else {
|
||||||
|
params.names = [""];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.showIP) {
|
||||||
|
params.types.push("ip");
|
||||||
|
if (values.ip) {
|
||||||
|
params.names = [values.ip.trim()];
|
||||||
|
} else {
|
||||||
|
params.names = [""];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(params)
|
||||||
|
this.loading = true;
|
||||||
|
request({
|
||||||
|
url: KafkaClientQuotaApi.alterClientQuotaConfigs.url,
|
||||||
|
method: KafkaClientQuotaApi.alterClientQuotaConfigs.method,
|
||||||
|
data: params,
|
||||||
|
}).then((res) => {
|
||||||
|
this.loading = false;
|
||||||
|
if (res.code == 0) {
|
||||||
|
this.$message.success(res.msg);
|
||||||
|
this.$emit("closeUpdateQuotaDialog", {refresh: true});
|
||||||
|
} else {
|
||||||
|
notification.error({
|
||||||
|
message: "error",
|
||||||
|
description: res.msg,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handleCancel() {
|
||||||
|
this.data = [];
|
||||||
|
this.$emit("closeUpdateQuotaDialog", {refresh: false});
|
||||||
|
},
|
||||||
|
init() {
|
||||||
|
this.producerRateUnit = "MB";
|
||||||
|
if (this.record.producerRate) {
|
||||||
|
this.producerRateUnit = this.record.producerRate.split(" ")[1];
|
||||||
|
}
|
||||||
|
this.consumerRateUnit = "MB";
|
||||||
|
if (this.record.consumerRate) {
|
||||||
|
this.consumerRateUnit = this.record.consumerRate.split(" ")[1];
|
||||||
|
}
|
||||||
|
if (this.type == "user") {
|
||||||
|
this.showUser = true;
|
||||||
|
} else if (this.type == "client-id") {
|
||||||
|
this.showClientId = true;
|
||||||
|
} else if (this.type == "ip") {
|
||||||
|
this.showIP = true;
|
||||||
|
} else if (this.type == "user&client-id") {
|
||||||
|
this.showUser = true;
|
||||||
|
this.showClientId = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped></style>
|
||||||
Reference in New Issue
Block a user