add h2 and save user info to db

This commit is contained in:
许晓东
2021-09-06 16:48:21 +08:00
parent b25cb13373
commit dbd9906bc6
13 changed files with 242 additions and 4 deletions

View File

@@ -1,3 +1,33 @@
# kafka可视化管理平台
目前支持部分acl功能管理操作
实现spring boot + scala + vue + kafka
# 打包、部署
## 打包
环境要求
* maven 3+
* jdk 8
```
git clone https://github.com/xxd763795151/kafka-console-ui.git
cd kafka-console-ui
sh package.sh
```
打包成功输出文件target/kafka-console-ui.tar.gz
## 部署
```
# 解压缩
tar -zxvf kafka-console-ui.tar.gz
# 进入解压缩后的目录
cd kafka-console-ui
# 编辑配置
vim config/application.yml
# 启动
sh bin/start.sh
# 停止
sh bin/shutdown.sh
```
# 开发环境
* jdk 8
* idea
* scala 2.13
* maven 3+
* webstorm

13
pom.xml
View File

@@ -23,6 +23,7 @@
<compiler.version>1.8</compiler.version>
<kafka.version>2.8.0</kafka.version>
<maven.assembly.plugin.version>3.0.0</maven.assembly.plugin.version>
<mybatis-plus-boot-starter.version>3.4.2</mybatis-plus-boot-starter.version>
</properties>
<dependencies>
<dependency>
@@ -52,6 +53,18 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus-boot-starter.version}</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>

View File

@@ -1,9 +1,13 @@
package com.xuxd.kafka.console;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@MapperScan("com.xuxd.kafka.console.dao")
@SpringBootApplication
@EnableScheduling
public class KafkaConsoleUiApplication {
public static void main(String[] args) {

View File

@@ -0,0 +1,26 @@
package com.xuxd.kafka.console.beans.dos;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
/**
* kafka-console-ui.
*
* @author xuxd
* @date 2021-09-06 15:09:23
**/
@Data
@TableName("t_kafka_user")
public class KafkaUserDO {
@TableId(type = IdType.AUTO)
private Long id;
private String username;
private String password;
private String updateTime;
}

View File

@@ -0,0 +1,19 @@
package com.xuxd.kafka.console.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* kafka-console-ui.
*
* @author xuxd
* @date 2021-09-06 16:23:30
**/
@Data
@Configuration
@ConfigurationProperties(prefix = "cron")
public class CronConfig {
private String clearDirtyUser;
}

View File

@@ -0,0 +1,15 @@
package com.xuxd.kafka.console.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xuxd.kafka.console.beans.dos.KafkaUserDO;
/**
* kafka-console-ui.
*
* @author xuxd
* @date 2021-09-06 15:12:19
**/
public interface KafkaUserMapper extends BaseMapper<KafkaUserDO> {
}

View File

@@ -0,0 +1,45 @@
package com.xuxd.kafka.console.schedule;
import com.xuxd.kafka.console.dao.KafkaUserMapper;
import java.util.Set;
import kafka.console.KafkaConfigConsole;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
/**
* kafka-console-ui.
*
* @author xuxd
* @date 2021-09-06 16:22:33
**/
@Slf4j
@Component
public class KafkaAclSchedule {
private final KafkaUserMapper userMapper;
private final KafkaConfigConsole configConsole;
public KafkaAclSchedule(KafkaUserMapper userMapper, KafkaConfigConsole configConsole) {
this.userMapper = userMapper;
this.configConsole = configConsole;
}
@Scheduled(cron = "${cron.clear-dirty-user}")
public void clearDirtyKafkaUser() {
log.info("Start clear dirty data for kafka user from database.");
Set<String> userSet = configConsole.getUserList(null);
userMapper.selectList(null).forEach(u -> {
if (!userSet.contains(u.getUsername())) {
log.info("clear user: {} from database.", u.getUsername());
try {
userMapper.deleteById(u.getId());
} catch (Exception e) {
log.error("userMapper.deleteById error, user: " + u, e);
}
}
});
log.info("Clear end.");
}
}

View File

@@ -4,7 +4,9 @@ import com.xuxd.kafka.console.beans.AclEntry;
import com.xuxd.kafka.console.beans.CounterList;
import com.xuxd.kafka.console.beans.CounterMap;
import com.xuxd.kafka.console.beans.ResponseData;
import com.xuxd.kafka.console.beans.dos.KafkaUserDO;
import com.xuxd.kafka.console.config.KafkaConfig;
import com.xuxd.kafka.console.dao.KafkaUserMapper;
import com.xuxd.kafka.console.service.AclService;
import java.util.Arrays;
import java.util.Collections;
@@ -20,6 +22,7 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.kafka.clients.admin.UserScramCredentialsDescription;
import org.apache.kafka.common.acl.AclBinding;
import org.apache.kafka.common.acl.AclOperation;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -44,6 +47,12 @@ public class AclServiceImpl implements AclService, SmartInitializingSingleton {
@Autowired
private KafkaConfig kafkaConfig;
private final KafkaUserMapper kafkaUserMapper;
public AclServiceImpl(ObjectProvider<KafkaUserMapper> kafkaUserMapper) {
this.kafkaUserMapper = kafkaUserMapper.getIfAvailable();
}
@Override public ResponseData<Set<String>> getUserList() {
try {
return ResponseData.create(Set.class).data(configConsole.getUserList(null)).success();
@@ -55,7 +64,24 @@ public class AclServiceImpl implements AclService, SmartInitializingSingleton {
@Override public ResponseData addOrUpdateUser(String name, String pass) {
log.info("add or update user, username: {}, password: {}", name, pass);
return configConsole.addOrUpdateUser(name, pass) ? ResponseData.create().success() : ResponseData.create().failed();
if (!configConsole.addOrUpdateUser(name, pass)) {
log.error("add user to kafka failed.");
return ResponseData.create().failed("add user to kafka failed");
}
// save user info to database.
KafkaUserDO userDO = new KafkaUserDO();
userDO.setUsername(name);
userDO.setPassword(pass);
try {
Map<String, Object> map = new HashMap<>();
map.put("username", name);
kafkaUserMapper.deleteByMap(map);
kafkaUserMapper.insert(userDO);
}catch (Exception e) {
log.error("kafkaUserMapper.insert error.", e);
return ResponseData.create().failed(e.getMessage());
}
return ResponseData.create().success();
}
@Override public ResponseData deleteUser(String name) {

View File

@@ -24,6 +24,26 @@ kafka:
spring:
application:
name: kafka-console-ui
# h2 database
datasource:
# url: jdbc:h2:file:/data/demo
url: jdbc:h2:mem:testdb
driver-class-name: org.h2.Driver
username: sa
password: password
schema: classpath:db/schema-h2.sql
# data: classpath:db/data-h2.sql
h2:
console:
enabled: true
logging:
home: ./
home: ./
cron:
# clear-dirty-user: 0 * * * * ?
clear-dirty-user: 0 0 1 * * ?
#spring.jpa.database-platform=org.hibernate.dialect.H2Dialect

View File

@@ -0,0 +1,5 @@
-- DELETE FROM t_kafka_user;
--
-- INSERT INTO t_kafka_user (id, username, password) VALUES
-- (1, 'Jone', 'p1'),
-- (2, 'Jack', 'p2');

View File

@@ -0,0 +1,12 @@
-- DROP TABLE IF EXISTS T_KAKFA_USER;
CREATE TABLE if not exists T_KAFKA_USER
(
ID IDENTITY NOT NULL COMMENT '主键ID',
USERNAME VARCHAR(50) NOT NULL DEFAULT '' COMMENT '姓名',
PASSWORD VARCHAR(50) NOT NULL DEFAULT '' COMMENT '年龄',
UPDATE_TIME TIMESTAMP NOT NULL DEFAULT NOW() COMMENT '更新时间',
PRIMARY KEY (ID),
UNIQUE (USERNAME)
);

View File

@@ -0,0 +1,23 @@
package com.xuxd.kafka.console.dao;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
/**
* kafka-console-ui.
*
* @author xuxd
* @date 2021-09-06 15:14:09
**/
@SpringBootTest
public class KafkaUserMapperTest {
@Autowired
private KafkaUserMapper userMapper;
@Test
public void testSelect() {
userMapper.selectList(null).forEach(System.out::println);
}
}

View File

@@ -17,7 +17,7 @@
<a-input
placeholder="username"
:allowClear="true"
:maxLength="50"
:maxLength="30"
v-decorator="[
'username',
{
@@ -30,7 +30,7 @@
<a-input
placeholder="password"
:allowClear="true"
:maxLength="50"
:maxLength="30"
v-decorator="[
'password',
{