diff --git a/README.md b/README.md index 49e8614..b854e5a 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,23 @@ # kafka可视化管理平台 -目前支持acl:SASL认证机制及受权管理操作 -实现:spring boot + scala + vue + kafka +## 功能支持 +* 基于SASL_SCRAM认证授权管理 +* Topic管理 +* 消费组管理 +* 运维 +## 技术栈 +* spring boot +* java、scala +* kafka +* h2 +* vue ## kafka版本 -* kafka 2.8.0 +* 当前使用的kafka 2.8.0 # 打包、部署 ## 打包 环境要求 * maven 3+ * jdk 8 +* git ``` git clone https://github.com/xxd763795151/kafka-console-ui.git cd kafka-console-ui diff --git a/src/main/java/com/xuxd/kafka/console/config/KafkaConfig.java b/src/main/java/com/xuxd/kafka/console/config/KafkaConfig.java index 8add192..147048a 100644 --- a/src/main/java/com/xuxd/kafka/console/config/KafkaConfig.java +++ b/src/main/java/com/xuxd/kafka/console/config/KafkaConfig.java @@ -31,6 +31,8 @@ public class KafkaConfig { private String zookeeperAddr; + private boolean enableAcl; + public String getBootstrapServer() { return bootstrapServer; } @@ -102,4 +104,12 @@ public class KafkaConfig { public void setZookeeperAddr(String zookeeperAddr) { this.zookeeperAddr = zookeeperAddr; } + + public boolean isEnableAcl() { + return enableAcl; + } + + public void setEnableAcl(boolean enableAcl) { + this.enableAcl = enableAcl; + } } diff --git a/src/main/java/com/xuxd/kafka/console/controller/ConfigController.java b/src/main/java/com/xuxd/kafka/console/controller/ConfigController.java new file mode 100644 index 0000000..8f5b6e9 --- /dev/null +++ b/src/main/java/com/xuxd/kafka/console/controller/ConfigController.java @@ -0,0 +1,33 @@ +package com.xuxd.kafka.console.controller; + +import com.xuxd.kafka.console.beans.ResponseData; +import com.xuxd.kafka.console.config.KafkaConfig; +import com.xuxd.kafka.console.utils.ConvertUtil; +import java.util.Map; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * kafka-console-ui. + * + * @author xuxd + * @date 2021-09-08 16:08:22 + **/ +@RestController +@RequestMapping("/config") +public class ConfigController { + + private final KafkaConfig config; + private final Map configMap; + + public ConfigController(KafkaConfig config) { + this.config = config; + this.configMap = ConvertUtil.toMap(config); + } + + @GetMapping + public Object getConfig() { + return ResponseData.create().data(configMap).success(); + } +} diff --git a/src/main/java/com/xuxd/kafka/console/service/impl/AclServiceImpl.java b/src/main/java/com/xuxd/kafka/console/service/impl/AclServiceImpl.java index 299b5da..f8c1ea2 100644 --- a/src/main/java/com/xuxd/kafka/console/service/impl/AclServiceImpl.java +++ b/src/main/java/com/xuxd/kafka/console/service/impl/AclServiceImpl.java @@ -208,7 +208,7 @@ public class AclServiceImpl implements AclService, SmartInitializingSingleton { } @Override public void afterSingletonsInstantiated() { - if (kafkaConfig.isAdminCreate()) { + if (kafkaConfig.isEnableAcl() && kafkaConfig.isAdminCreate()) { log.info("Start create admin user, username: {}, password: {}", kafkaConfig.getAdminUsername(), kafkaConfig.getAdminPassword()); boolean done = configConsole.addOrUpdateUserWithZK(kafkaConfig.getAdminUsername(), kafkaConfig.getAdminPassword()); if (!done) { diff --git a/src/main/java/com/xuxd/kafka/console/utils/ConvertUtil.java b/src/main/java/com/xuxd/kafka/console/utils/ConvertUtil.java new file mode 100644 index 0000000..68ef690 --- /dev/null +++ b/src/main/java/com/xuxd/kafka/console/utils/ConvertUtil.java @@ -0,0 +1,40 @@ +package com.xuxd.kafka.console.utils; + +import com.google.common.base.Preconditions; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import lombok.extern.slf4j.Slf4j; +import org.springframework.util.ClassUtils; + +/** + * kafka-console-ui. + * + * @author xuxd + * @date 2021-09-08 16:21:43 + **/ +@Slf4j +public class ConvertUtil { + + public static Map toMap(Object src) { + Preconditions.checkNotNull(src); + Map res = new HashMap<>(); + for (Class clz = src.getClass(); clz != Object.class; clz = clz.getSuperclass()) { + if (ClassUtils.isCglibProxyClass(clz)) { + continue; + } + Arrays.stream(clz.getDeclaredFields()).forEach(f -> { + + try { + boolean accessible = f.isAccessible(); + f.setAccessible(true); + res.put(f.getName(), f.get(src)); + f.setAccessible(accessible); + } catch (IllegalAccessException ignore) { + log.error("filed: " + f.getName(), ignore); + } + }); + } + return res; + } +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 71395e1..1f6c13f 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -9,6 +9,8 @@ kafka: # kafka broker地址,多个以逗号分隔 bootstrap-server: 'localhost:9092' request-timeout-ms: 60000 + # 服务端是否启用acl,如果不启用,下面的几项都忽略即可 + enable-acl: true security-protocol: SASL_PLAINTEXT sasl-mechanism: SCRAM-SHA-256 # 超级管理员用户名,在broker上已经配置为超级管理员 diff --git a/src/main/scala/kafka/console/KafkaConsole.scala b/src/main/scala/kafka/console/KafkaConsole.scala index 9ad1949..f554697 100644 --- a/src/main/scala/kafka/console/KafkaConsole.scala +++ b/src/main/scala/kafka/console/KafkaConsole.scala @@ -41,9 +41,11 @@ class KafkaConsole(config: KafkaConfig) { val props: Properties = new Properties(); props.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, config.getBootstrapServer) props.put(AdminClientConfig.REQUEST_TIMEOUT_MS_CONFIG, config.getRequestTimeoutMs()) - props.put(CommonClientConfigs.SECURITY_PROTOCOL_CONFIG, config.getSecurityProtocol()) - props.put(SaslConfigs.SASL_MECHANISM, config.getSaslMechanism()) - props.put(SaslConfigs.SASL_JAAS_CONFIG, config.getSaslJaasConfig()) + if (config.isEnableAcl) { + props.put(CommonClientConfigs.SECURITY_PROTOCOL_CONFIG, config.getSecurityProtocol()) + props.put(SaslConfigs.SASL_MECHANISM, config.getSaslMechanism()) + props.put(SaslConfigs.SASL_JAAS_CONFIG, config.getSaslJaasConfig()) + } Admin.create(props) } diff --git a/ui/src/App.vue b/ui/src/App.vue index 2d3e4b6..533db4a 100644 --- a/ui/src/App.vue +++ b/ui/src/App.vue @@ -2,16 +2,39 @@
+