This is an automated email from the ASF dual-hosted git repository.

xiatian pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/eventmesh-dashboard.git


The following commit(s) were added to refs/heads/develop by this push:
     new 0bed675  [ISSUE #26] CRUD the basic tables of Topic, Group, 
GroupMember, and Operation (#28)
0bed675 is described below

commit 0bed675b67006144c2806f3f61c59773bd62b484
Author: zzx <[email protected]>
AuthorDate: Tue Feb 6 00:13:54 2024 +0800

    [ISSUE #26] CRUD the basic tables of Topic, Group, GroupMember, and 
Operation (#28)
    
    * refactor: add dependency of console module and move controllers into 
console module.
    
    * fix: add logback config, fix application-dev.yml and move 
`</dependencyManagement>` to root `pom.xml` as pointed out in PR#19.
    
    * FirstCommit
    
    * remerge
    
    * first improve
    
    * second improve
    
    * third improve
    
    * fourth improve
    
    * fourth improve
    
    * fourth improve
    
    * Update and rename EventmeshConsoleApplication.java to 
EventMeshDashboardApplication.java
    
    * rename this starter class file to EventMeshDashboardApplication
    
    * rename this starter class file to EventMeshDashboardApplication
    
    * change some resource file
    
    * improve name
    
    * improve name
    
    * Modify the fields of the synchronized log table
    
    * improve name
    
    * improve name
    
    ---------
    
    Co-authored-by: lambert@arch <[email protected]>
---
 eventmesh-dashboard-console/pom.xml                |  14 ++
 .../console/EventMeshDashboardApplication.java     |  14 +-
 .../EmLog.java}                                    |  26 ++-
 .../group/GroupEntity.java}                        |  43 +++--
 .../groupmember/GroupMemberEntity.java}            |  40 ++--
 .../log/LogEntity.java}                            |  44 +++--
 .../topic/TopicEntity.java}                        |  43 +++--
 .../eventmesh/dashboard/console/log/OprLog.java    | 122 ++++++++++++
 .../console/mapper/group/OprGroupMapper.java       |  73 ++++++++
 .../mapper/groupmember/OprGroupMemberMapper.java   |  81 ++++++++
 .../dashboard/console/mapper/log/OprLogMapper.java |  60 ++++++
 .../console/mapper/topic/TopicMapper.java          |  70 +++++++
 .../group/GroupService.java}                       |  38 ++--
 .../console/service/group/GroupServiceImpl.java    | 103 ++++++++++
 .../service/groupmember/GroupMemberService.java    |  44 +++++
 .../service/groupmember/GroupMemberServiceImp.java |  78 ++++++++
 .../log/LogService.java}                           |  31 +--
 .../console/service/log/LogServiceImpl.java        |  51 +++++
 .../topic/TopicService.java}                       |  34 ++--
 .../console/service/topic/TopicServiceImpl.java    |  82 ++++++++
 .../src/main/resources/application-dev.yml         |   9 +-
 .../src/main/resources/eventmesh-dashboard.sql     | 208 +++++++++++++++------
 .../dashboard/console/linkage/log/TestOprLog.java  |  43 +++++
 .../console/unit/group/TestGroupMapper.java        | 102 ++++++++++
 .../unit/groupmember/testGroupMemberMapper.java    | 141 ++++++++++++++
 .../console/unit/topic/testTopicMapper.java        | 116 ++++++++++++
 26 files changed, 1519 insertions(+), 191 deletions(-)

diff --git a/eventmesh-dashboard-console/pom.xml 
b/eventmesh-dashboard-console/pom.xml
index fa06c45..ddf6595 100644
--- a/eventmesh-dashboard-console/pom.xml
+++ b/eventmesh-dashboard-console/pom.xml
@@ -69,6 +69,20 @@
             <artifactId>mysql-connector-j</artifactId>
             <scope>runtime</scope>
         </dependency>
+
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-aspects</artifactId>
+            <version>5.1.2.RELEASE</version>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.13.2</version>
+            <scope>test</scope>
+        </dependency>
+
+
     </dependencies>
 
 </project>
\ No newline at end of file
diff --git 
a/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/EventMeshDashboardApplication.java
 
b/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/EventMeshDashboardApplication.java
index 79fc03d..117dd06 100644
--- 
a/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/EventMeshDashboardApplication.java
+++ 
b/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/EventMeshDashboardApplication.java
@@ -19,19 +19,21 @@ package org.apache.eventmesh.dashboard.console;
 
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.context.annotation.ComponentScan;
-import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
 
 import lombok.extern.slf4j.Slf4j;
 
 @Slf4j
 @SpringBootApplication
-@EnableScheduling
-@ComponentScan({"org.apache.eventmesh.dashboard.service", 
"org.apache.eventmesh.dashboard.console"})
+@EnableTransactionManagement
 public class EventMeshDashboardApplication {
 
     public static void main(String[] args) {
-        SpringApplication.run(EventMeshDashboardApplication.class, args);
-        log.info("{} Successfully booted.", 
EventMeshDashboardApplication.class.getSimpleName());
+        try {
+            SpringApplication.run(EventMeshDashboardApplication.class, args);
+            log.info("{} Successfully booted.", 
EventMeshDashboardApplication.class.getSimpleName());
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        }
     }
 }
diff --git 
a/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/EventMeshDashboardApplication.java
 
b/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/annotation/EmLog.java
similarity index 51%
copy from 
eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/EventMeshDashboardApplication.java
copy to 
eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/annotation/EmLog.java
index 79fc03d..efae3a5 100644
--- 
a/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/EventMeshDashboardApplication.java
+++ 
b/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/annotation/EmLog.java
@@ -15,23 +15,19 @@
  * limitations under the License.
  */
 
-package org.apache.eventmesh.dashboard.console;
+package org.apache.eventmesh.dashboard.console.annotation;
 
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.context.annotation.ComponentScan;
-import org.springframework.scheduling.annotation.EnableScheduling;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
 
-import lombok.extern.slf4j.Slf4j;
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface EmLog {
 
-@Slf4j
-@SpringBootApplication
-@EnableScheduling
-@ComponentScan({"org.apache.eventmesh.dashboard.service", 
"org.apache.eventmesh.dashboard.console"})
-public class EventMeshDashboardApplication {
+    String OprType() default "";
+
+    String OprTarget() default "";
 
-    public static void main(String[] args) {
-        SpringApplication.run(EventMeshDashboardApplication.class, args);
-        log.info("{} Successfully booted.", 
EventMeshDashboardApplication.class.getSimpleName());
-    }
 }
diff --git 
a/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/EventMeshDashboardApplication.java
 
b/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/entity/group/GroupEntity.java
similarity index 51%
copy from 
eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/EventMeshDashboardApplication.java
copy to 
eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/entity/group/GroupEntity.java
index 79fc03d..c395bac 100644
--- 
a/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/EventMeshDashboardApplication.java
+++ 
b/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/entity/group/GroupEntity.java
@@ -15,23 +15,36 @@
  * limitations under the License.
  */
 
-package org.apache.eventmesh.dashboard.console;
+package org.apache.eventmesh.dashboard.console.entity.group;
 
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.context.annotation.ComponentScan;
-import org.springframework.scheduling.annotation.EnableScheduling;
+import java.sql.Timestamp;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@NoArgsConstructor
+@AllArgsConstructor
+@Data
+public class GroupEntity {
+    private Long id;
+
+    private Long clusterId;
+
+    private String name;
+
+    private Integer memberCount;
+
+    private String members;
+
+    private Integer type;
+
+    private String state;
+
+    private Timestamp createTime;
+
+    private Timestamp updateTime;
 
-import lombok.extern.slf4j.Slf4j;
 
-@Slf4j
-@SpringBootApplication
-@EnableScheduling
-@ComponentScan({"org.apache.eventmesh.dashboard.service", 
"org.apache.eventmesh.dashboard.console"})
-public class EventMeshDashboardApplication {
 
-    public static void main(String[] args) {
-        SpringApplication.run(EventMeshDashboardApplication.class, args);
-        log.info("{} Successfully booted.", 
EventMeshDashboardApplication.class.getSimpleName());
-    }
 }
diff --git 
a/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/EventMeshDashboardApplication.java
 
b/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/entity/groupmember/GroupMemberEntity.java
similarity index 51%
copy from 
eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/EventMeshDashboardApplication.java
copy to 
eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/entity/groupmember/GroupMemberEntity.java
index 79fc03d..dbadc1e 100644
--- 
a/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/EventMeshDashboardApplication.java
+++ 
b/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/entity/groupmember/GroupMemberEntity.java
@@ -15,23 +15,33 @@
  * limitations under the License.
  */
 
-package org.apache.eventmesh.dashboard.console;
+package org.apache.eventmesh.dashboard.console.entity.groupmember;
 
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.context.annotation.ComponentScan;
-import org.springframework.scheduling.annotation.EnableScheduling;
+import java.sql.Timestamp;
 
-import lombok.extern.slf4j.Slf4j;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class GroupMemberEntity {
+    private Long id;
+
+    private Long clusterId;
+
+    private String topicName;
+
+    private String groupName;
+
+    private String eventMeshUser;
+
+    private String state;
+
+    private Timestamp createTime;
+
+    private Timestamp updateTime;
 
-@Slf4j
-@SpringBootApplication
-@EnableScheduling
-@ComponentScan({"org.apache.eventmesh.dashboard.service", 
"org.apache.eventmesh.dashboard.console"})
-public class EventMeshDashboardApplication {
 
-    public static void main(String[] args) {
-        SpringApplication.run(EventMeshDashboardApplication.class, args);
-        log.info("{} Successfully booted.", 
EventMeshDashboardApplication.class.getSimpleName());
-    }
 }
diff --git 
a/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/EventMeshDashboardApplication.java
 
b/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/entity/log/LogEntity.java
similarity index 51%
copy from 
eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/EventMeshDashboardApplication.java
copy to 
eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/entity/log/LogEntity.java
index 79fc03d..ac7c30a 100644
--- 
a/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/EventMeshDashboardApplication.java
+++ 
b/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/entity/log/LogEntity.java
@@ -15,23 +15,37 @@
  * limitations under the License.
  */
 
-package org.apache.eventmesh.dashboard.console;
+package org.apache.eventmesh.dashboard.console.entity.log;
 
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.context.annotation.ComponentScan;
-import org.springframework.scheduling.annotation.EnableScheduling;
+import java.sql.Timestamp;
 
-import lombok.extern.slf4j.Slf4j;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
 
-@Slf4j
-@SpringBootApplication
-@EnableScheduling
-@ComponentScan({"org.apache.eventmesh.dashboard.service", 
"org.apache.eventmesh.dashboard.console"})
-public class EventMeshDashboardApplication {
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class LogEntity {
+
+    private Long id;
+
+    private Long clusterId;
+
+    private String operationType;
+
+    private String targetType;
+
+    private Integer status;
+
+    private String content;
+
+    private Timestamp createTime;
+
+    private Timestamp endTime;
+
+    private String operationUser;
+
+    private String result;
 
-    public static void main(String[] args) {
-        SpringApplication.run(EventMeshDashboardApplication.class, args);
-        log.info("{} Successfully booted.", 
EventMeshDashboardApplication.class.getSimpleName());
-    }
 }
diff --git 
a/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/EventMeshDashboardApplication.java
 
b/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/entity/topic/TopicEntity.java
similarity index 51%
copy from 
eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/EventMeshDashboardApplication.java
copy to 
eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/entity/topic/TopicEntity.java
index 79fc03d..6b4bd09 100644
--- 
a/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/EventMeshDashboardApplication.java
+++ 
b/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/entity/topic/TopicEntity.java
@@ -15,23 +15,36 @@
  * limitations under the License.
  */
 
-package org.apache.eventmesh.dashboard.console;
+package org.apache.eventmesh.dashboard.console.entity.topic;
 
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.context.annotation.ComponentScan;
-import org.springframework.scheduling.annotation.EnableScheduling;
+import java.sql.Timestamp;
 
-import lombok.extern.slf4j.Slf4j;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
 
-@Slf4j
-@SpringBootApplication
-@EnableScheduling
-@ComponentScan({"org.apache.eventmesh.dashboard.service", 
"org.apache.eventmesh.dashboard.console"})
-public class EventMeshDashboardApplication {
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class TopicEntity {
+    private Long id;
+
+    private Long clusterId;
+
+    private String topicName;
+
+    private String runtimeId;
+
+    private String storageId;
+
+    private Long retentionMs;
+
+    private Integer type;
+
+    private String description;
+
+    private Timestamp createTime;
+
+    private Timestamp updateTime;
 
-    public static void main(String[] args) {
-        SpringApplication.run(EventMeshDashboardApplication.class, args);
-        log.info("{} Successfully booted.", 
EventMeshDashboardApplication.class.getSimpleName());
-    }
 }
diff --git 
a/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/log/OprLog.java
 
b/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/log/OprLog.java
new file mode 100644
index 0000000..9df7e23
--- /dev/null
+++ 
b/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/log/OprLog.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.eventmesh.dashboard.console.log;
+
+import org.apache.eventmesh.dashboard.console.annotation.EmLog;
+import org.apache.eventmesh.dashboard.console.entity.log.LogEntity;
+import org.apache.eventmesh.dashboard.console.service.log.LogService;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.sql.Timestamp;
+import java.util.Objects;
+
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.core.Ordered;
+import org.springframework.stereotype.Service;
+import org.springframework.util.ClassUtils;
+
+@Aspect
+@Service
+public class OprLog implements Ordered, ApplicationContextAware {
+
+    private int order = LOWEST_PRECEDENCE - 1000; // Specify the order of 
execution
+
+    private LogService logService;
+
+    private ApplicationContext applicationContext;
+
+
+    @Pointcut("within(org.apache.eventmesh.dashboard.console.service..*)")
+    public void pointCut() {
+    }
+
+
+    @Around("pointCut()")
+    public Object logStart(ProceedingJoinPoint joinPoint) throws Throwable {
+        if (Objects.isNull(this.logService)) {
+            this.logService = applicationContext.getBean(LogService.class);
+        }
+        EmLog declaredAnnotation = this.getTargetEmlog(joinPoint);
+        //Get the Emlog annotation on the method
+        if (Objects.isNull(declaredAnnotation)) {
+            return joinPoint.proceed();
+        }
+        LogEntity logEntity = this.productLoEntity(declaredAnnotation, 
joinPoint);
+        logService.addLog(logEntity);
+        logEntity.setEndTime(new Timestamp(System.currentTimeMillis()));
+        Object proceed = null;
+        try {
+            proceed = joinPoint.proceed();
+            logEntity.setStatus(2);
+            logEntity.setResult(Objects.isNull(proceed) ? "" : 
proceed.toString());
+            return proceed;
+        } catch (Throwable e) {
+            logEntity.setStatus(3);
+            throw new RuntimeException(e);
+        } finally {
+            logEntity.setResult(proceed.toString());
+            logService.updateLog(logEntity);
+        }
+
+
+    }
+
+    public LogEntity productLoEntity(EmLog declaredAnnotation, 
ProceedingJoinPoint joinPoint) throws NoSuchFieldException, 
IllegalAccessException {
+        LogEntity logEntity = new LogEntity();
+        Object[] args = joinPoint.getArgs();
+        Object model = args[0];
+        //Obtaining the Input Parameter of the Operation Method (Specified as 
the First)
+        Field clusterPhyId = model.getClass().getDeclaredField("clusterId");
+        clusterPhyId.setAccessible(true);
+        Long opClusterPhyId = (Long) clusterPhyId.get(model);
+        //The clusterId is obtained from the parameter object, and the 
operation is described as the object itself
+        logEntity.setClusterId(opClusterPhyId);
+        logEntity.setContent(model.toString());
+        logEntity.setOperationType(declaredAnnotation.OprType());
+        logEntity.setTargetType(declaredAnnotation.OprTarget());
+        logEntity.setStatus(1);
+        logEntity.setCreateTime(new Timestamp(System.currentTimeMillis()));
+        return logEntity;
+    }
+
+    public EmLog getTargetEmlog(ProceedingJoinPoint joinPoint) {
+        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
+        Method method = signature.getMethod();
+        Method mostSpecificMethod = ClassUtils.getMostSpecificMethod(method, 
joinPoint.getTarget().getClass());
+        EmLog declaredAnnotation = 
mostSpecificMethod.getAnnotation(EmLog.class);
+        return declaredAnnotation;
+    }
+
+    @Override
+    public int getOrder() {
+        return order;
+    }
+
+    @Override
+    public void setApplicationContext(ApplicationContext applicationContext) 
throws BeansException {
+        this.applicationContext = applicationContext;
+    }
+}
diff --git 
a/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/mapper/group/OprGroupMapper.java
 
b/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/mapper/group/OprGroupMapper.java
new file mode 100644
index 0000000..f1a91ed
--- /dev/null
+++ 
b/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/mapper/group/OprGroupMapper.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.eventmesh.dashboard.console.mapper.group;
+
+import org.apache.eventmesh.dashboard.console.entity.group.GroupEntity;
+
+import org.apache.ibatis.annotations.Delete;
+import org.apache.ibatis.annotations.Insert;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Options;
+import org.apache.ibatis.annotations.Select;
+import org.apache.ibatis.annotations.Update;
+
+import java.util.List;
+
+/**
+ * operate Group mapper
+ **/
+@Mapper
+public interface OprGroupMapper {
+
+    @Insert("INSERT INTO `group` (cluster_id, name, member_count, members, 
type, state)"
+        + "VALUE 
(#{clusterId},#{name},#{memberCount},#{members},#{type},#{state}) "
+        + "on duplicate key update is_delete=0")
+    @Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
+    void addGroup(GroupEntity groupEntity);
+
+    @Update("update `group`set member_count=#{memberCount},"
+        + "members=#{members},type=#{type},state=#{state} where id=#{id}")
+    @Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
+    Integer updateGroup(GroupEntity groupEntity);
+
+    @Delete("update `group` set  is_delete=1 where id=#{id}")
+    @Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
+    Integer deleteGroup(GroupEntity groupEntity);
+
+    @Select("select * from `group` where cluster_id=#{clusterId} and 
name=#{name} and is_delete=0")
+    GroupEntity selectGroupByUnique(GroupEntity groupEntity);
+
+    @Select("select * from `group` where id=#{id} and is_delete=0")
+    GroupEntity selectGroupById(GroupEntity groupEntity);
+
+    @Select("<script>"
+        + "select * from `group`"
+        + "<where>"
+        + "<if test='clusterId != null'>"
+        + "cluster_id=#{clusterId}"
+        + "</if>"
+        + "<if test='name != null'>"
+        + "and name like concat('%',#{name},'%')"
+        + "</if>"
+        + "and is_delete=0"
+        + "</where>"
+        + "</script>")
+    List<GroupEntity> selectGroup(GroupEntity groupEntity);
+
+
+}
diff --git 
a/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/mapper/groupmember/OprGroupMemberMapper.java
 
b/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/mapper/groupmember/OprGroupMemberMapper.java
new file mode 100644
index 0000000..3179eff
--- /dev/null
+++ 
b/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/mapper/groupmember/OprGroupMemberMapper.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.eventmesh.dashboard.console.mapper.groupmember;
+
+
+import 
org.apache.eventmesh.dashboard.console.entity.groupmember.GroupMemberEntity;
+
+import org.apache.ibatis.annotations.Delete;
+import org.apache.ibatis.annotations.Insert;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Options;
+import org.apache.ibatis.annotations.Select;
+import org.apache.ibatis.annotations.Update;
+
+import java.util.List;
+
+/**
+ * operate GroupMember mapper
+ **/
+
+@Mapper
+public interface OprGroupMemberMapper {
+
+    @Select("select * from group_member where cluster_id=#{clusterId} and 
is_delete=0")
+    List<GroupMemberEntity> getGroupByClusterId(GroupMemberEntity 
groupMemberEntity);
+
+    @Insert("insert into group_member (cluster_id, topic_name, group_name, 
eventmesh_user,state)"
+        + " VALUE 
(#{clusterId},#{topicName},#{groupName},#{eventMeshUser},#{state})"
+        + "on duplicate key update is_delete=0")
+    @Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
+    void addGroupMember(GroupMemberEntity groupMemberEntity);
+
+    @Update("update group_member set state=#{state} where id=#{id}")
+    @Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
+    void updateGroupMember(GroupMemberEntity groupMemberEntity);
+
+    @Delete("update group_member set is_delete=1 where id=#{id} ")
+    @Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
+    GroupMemberEntity deleteGroupMember(GroupMemberEntity groupMemberEntity);
+
+    @Select("select * from group_member where cluster_id=#{clusterId} and 
group_name=#{groupName} and topic_name=#{topicName} and is_delete=0")
+    GroupMemberEntity selectGroupMemberByUnique(GroupMemberEntity 
groupMemberEntity);
+
+    @Select("select * from group_member where id=#{id} and is_delete=0")
+    GroupMemberEntity selectGroupMemberById(GroupMemberEntity 
groupMemberEntity);
+
+    @Select("<script>"
+        + "select * from group_member"
+        + "<where>"
+        + "<if test='clusterId != null'>"
+        + "cluster_id=#{clusterId}"
+        + "</if>"
+        + "<if test='groupName != null'>"
+        + "and group_name=#{groupName}"
+        + "</if>"
+        + "<if test='topicName != null'>"
+        + "and topic_name=#{topicName}"
+        + "</if>"
+        + "</where>"
+        + "and is_delete=0"
+        + "</script>")
+    List<GroupMemberEntity> selectMember(GroupMemberEntity groupMemberEntity);
+
+    @Update("update group_member set state=#{state} where 
topic_name=#{topicName}")
+    void updateMemberByTopic(GroupMemberEntity groupMemberEntity);
+}
\ No newline at end of file
diff --git 
a/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/mapper/log/OprLogMapper.java
 
b/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/mapper/log/OprLogMapper.java
new file mode 100644
index 0000000..d6c96f7
--- /dev/null
+++ 
b/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/mapper/log/OprLogMapper.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.eventmesh.dashboard.console.mapper.log;
+
+import org.apache.eventmesh.dashboard.console.entity.log.LogEntity;
+
+import org.apache.ibatis.annotations.Insert;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Select;
+import org.apache.ibatis.annotations.SelectKey;
+import org.apache.ibatis.annotations.Update;
+
+import java.util.List;
+
+/**
+ * operate operationLog mapper
+ **/
+@Mapper
+public interface OprLogMapper {
+
+    @Select("<script>"
+        + "select * from operation_log"
+        + "<where>"
+        + "<if test='targetType!=null'>"
+        + "target_type=#{targetType}"
+        + "</if>"
+        + "<if test='operationUser!=null'>"
+        + "and operation_user=#{operationUser}"
+        + "</if>"
+        + "<if test='clusterId!=null'>"
+        + "and cluster_id=#{clusterId} "
+        + "</if>"
+        + "and is_delete=0"
+        + "</where>"
+        + "</script>")
+    List<LogEntity> getLogList(LogEntity logEntity);
+
+    @Insert("insert into operation_log ( cluster_id, 
operation_type,target_Type, description,operation_user,result_content)"
+        + "VALUE 
(#{clusterId},#{operationType},#{targetType},#{description},#{operationUser},#{resultContent})")
+    @SelectKey(keyColumn = "id", statement = {" select last_insert_id()"}, 
keyProperty = "id", before = false, resultType = Long.class)
+    Long addLog(LogEntity logEntity);
+
+    @Update("update operation_log set status=#{status} 
,result_content=#{resultContent} where id=#{id}")
+    Integer updateLog(LogEntity logEntity);
+}
diff --git 
a/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/mapper/topic/TopicMapper.java
 
b/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/mapper/topic/TopicMapper.java
new file mode 100644
index 0000000..8a396be
--- /dev/null
+++ 
b/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/mapper/topic/TopicMapper.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.eventmesh.dashboard.console.mapper.topic;
+
+
+import org.apache.eventmesh.dashboard.console.entity.topic.TopicEntity;
+
+import org.apache.ibatis.annotations.Delete;
+import org.apache.ibatis.annotations.Insert;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Options;
+import org.apache.ibatis.annotations.Select;
+import org.apache.ibatis.annotations.Update;
+
+import java.util.List;
+
+/**
+ * operate Topic mapper
+ **/
+@Mapper
+public interface TopicMapper {
+
+    @Select("<script>"
+        + "select * from topic"
+        + "<where>"
+        + "<if test='topicName!=null'>"
+        + "and topic_name=#{topicName}"
+        + "</if>"
+        + "<if test='clusterId!=null'>"
+        + "and cluster_id=#{clusterId} "
+        + "</if>"
+        + "and is_delete=0"
+        + "</where>"
+        + "</script>")
+    List<TopicEntity> getTopicList(TopicEntity topicEntity);
+
+    @Insert("INSERT INTO topic (cluster_id, topic_name, runtime_id, 
storage_id, retention_ms, type, description) "
+        + "VALUE 
(#{clusterId},#{topicName},#{runtimeId},#{storageId},#{retentionMs},#{type},#{description})"
+        + "on duplicate key update is_delete = 0")
+    @Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
+    void addTopic(TopicEntity topicEntity);
+
+    @Update("update topic set type=#{type},description=#{description} where 
id=#{id}")
+    void updateTopic(TopicEntity topicEntity);
+
+    @Delete("update `topic` set is_delete=1 where id=#{id}")
+    void deleteTopic(TopicEntity topicEntity);
+
+    @Select("select * from topic where cluster_id=#{clusterId} and 
topic_name=#{topicName}")
+    TopicEntity selectTopicByUnique(TopicEntity topicEntity);
+
+    @Select("select * from topic where id=#{id}")
+    TopicEntity selectTopicById(TopicEntity topicEntity);
+
+}
\ No newline at end of file
diff --git 
a/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/EventMeshDashboardApplication.java
 
b/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/service/group/GroupService.java
similarity index 51%
copy from 
eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/EventMeshDashboardApplication.java
copy to 
eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/service/group/GroupService.java
index 79fc03d..e5a80c5 100644
--- 
a/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/EventMeshDashboardApplication.java
+++ 
b/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/service/group/GroupService.java
@@ -15,23 +15,31 @@
  * limitations under the License.
  */
 
-package org.apache.eventmesh.dashboard.console;
+package org.apache.eventmesh.dashboard.console.service.group;
 
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.context.annotation.ComponentScan;
-import org.springframework.scheduling.annotation.EnableScheduling;
+import org.apache.eventmesh.dashboard.console.entity.group.GroupEntity;
+import 
org.apache.eventmesh.dashboard.console.entity.groupmember.GroupMemberEntity;
 
-import lombok.extern.slf4j.Slf4j;
 
-@Slf4j
-@SpringBootApplication
-@EnableScheduling
-@ComponentScan({"org.apache.eventmesh.dashboard.service", 
"org.apache.eventmesh.dashboard.console"})
-public class EventMeshDashboardApplication {
+import java.util.List;
 
-    public static void main(String[] args) {
-        SpringApplication.run(EventMeshDashboardApplication.class, args);
-        log.info("{} Successfully booted.", 
EventMeshDashboardApplication.class.getSimpleName());
-    }
+/**
+ * operate Group Service
+ */
+
+public interface GroupService {
+
+    List<GroupEntity> getGroupByClusterId(GroupEntity groupEntity);
+
+    GroupEntity addGroup(GroupEntity groupEntity);
+
+    void updateGroup(GroupEntity groupEntity);
+
+    Integer deleteGroup(GroupEntity groupEntity);
+
+    GroupEntity selectGroup(GroupEntity groupEntity);
+
+    Integer insertMemberToGroup(GroupMemberEntity groupMemberEntity);
+
+    Integer deleteMemberFromGroup(GroupMemberEntity groupMemberEntity);
 }
diff --git 
a/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/service/group/GroupServiceImpl.java
 
b/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/service/group/GroupServiceImpl.java
new file mode 100644
index 0000000..3647a5a
--- /dev/null
+++ 
b/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/service/group/GroupServiceImpl.java
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.eventmesh.dashboard.console.service.group;
+
+import org.apache.eventmesh.dashboard.console.annotation.EmLog;
+import org.apache.eventmesh.dashboard.console.entity.group.GroupEntity;
+import 
org.apache.eventmesh.dashboard.console.entity.groupmember.GroupMemberEntity;
+import org.apache.eventmesh.dashboard.console.mapper.group.OprGroupMapper;
+import 
org.apache.eventmesh.dashboard.console.service.groupmember.GroupMemberService;
+
+import java.sql.Timestamp;
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class GroupServiceImpl implements GroupService {
+
+    @Autowired
+    OprGroupMapper oprGroupMapper;
+
+    @Autowired
+    GroupMemberService groupMemberService;
+
+    @EmLog(OprType = "search", OprTarget = "Group")
+    @Override
+    public List<GroupEntity> getGroupByClusterId(GroupEntity groupEntity) {
+        return oprGroupMapper.selectGroup(groupEntity);
+
+    }
+
+    @EmLog(OprType = "add", OprTarget = "Group")
+    @Override
+    public GroupEntity addGroup(GroupEntity groupEntity) {
+        oprGroupMapper.addGroup(groupEntity);
+        return groupEntity;
+    }
+
+    @Override
+    public void updateGroup(GroupEntity groupEntity) {
+        oprGroupMapper.updateGroup(groupEntity);
+    }
+
+    @Override
+    public Integer deleteGroup(GroupEntity groupEntity) {
+        return oprGroupMapper.deleteGroup(groupEntity);
+    }
+
+    @Override
+    public GroupEntity selectGroup(GroupEntity groupEntity) {
+        return oprGroupMapper.selectGroupById(groupEntity);
+    }
+
+    @Override
+    public Integer insertMemberToGroup(GroupMemberEntity groupMemberEntity) {
+        groupMemberService.addGroupMember(groupMemberEntity);
+        GroupEntity groupEntity = new GroupEntity();
+        groupEntity.setName(groupMemberEntity.getGroupName());
+        groupEntity.setClusterId(groupMemberEntity.getClusterId());
+        GroupEntity groupEntity1 = 
oprGroupMapper.selectGroupByUnique(groupEntity);
+        //^Obtain the group to which the member belongs
+        groupEntity1.setMembers(groupMemberEntity.getId() + "" + "," + 
groupEntity1.getMembers());
+        //Concatenate the members of the group
+        groupEntity1.setMemberCount(groupEntity1.getMemberCount() + 1);
+        groupEntity1.setUpdateTime(new Timestamp(System.currentTimeMillis()));
+        oprGroupMapper.updateGroup(groupEntity1);
+        return 1;
+        //Modify the group member information
+    }
+
+    @Override
+    public Integer deleteMemberFromGroup(GroupMemberEntity groupMemberEntity) {
+        groupMemberService.deleteGroupMember(groupMemberEntity);
+        GroupEntity groupEntity = new GroupEntity();
+        groupEntity.setName(groupMemberEntity.getGroupName());
+        groupEntity.setClusterId(groupMemberEntity.getClusterId());
+        GroupEntity groupEntity1 = 
oprGroupMapper.selectGroupByUnique(groupEntity);
+        //^Obtain the group to which the member belongs
+        
groupEntity1.setMembers(groupEntity1.getMembers().replaceAll(groupMemberEntity.getId()
 + "" + ",", ""));
+        groupEntity1.setMemberCount(groupEntity1.getMemberCount() - 1);
+        groupEntity1.setUpdateTime(new Timestamp(System.currentTimeMillis()));
+        oprGroupMapper.updateGroup(groupEntity1);
+        return 1;
+    }
+
+
+}
diff --git 
a/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/service/groupmember/GroupMemberService.java
 
b/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/service/groupmember/GroupMemberService.java
new file mode 100644
index 0000000..28f9516
--- /dev/null
+++ 
b/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/service/groupmember/GroupMemberService.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.eventmesh.dashboard.console.service.groupmember;
+
+import org.apache.eventmesh.dashboard.console.entity.group.GroupEntity;
+import 
org.apache.eventmesh.dashboard.console.entity.groupmember.GroupMemberEntity;
+
+import java.util.List;
+
+/**
+ * Service About GroupMember
+ */
+public interface GroupMemberService {
+
+    List<GroupMemberEntity> getGroupMemberByClusterId(GroupMemberEntity 
groupMemberEntity);
+
+    void addGroupMember(GroupMemberEntity groupMemberEntity);
+
+    void updateGroupMember(GroupMemberEntity groupMemberEntity);
+
+    GroupMemberEntity deleteGroupMember(GroupMemberEntity groupMemberEntity);
+
+    GroupMemberEntity selectGroupMemberById(GroupMemberEntity 
groupMemberEntity);
+
+    List<GroupMemberEntity> selectGroupMemberByGroup(GroupEntity groupEntity);
+
+    List<GroupMemberEntity> selectAllMemberByTopic(GroupMemberEntity 
groupMemberEntity);
+
+}
diff --git 
a/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/service/groupmember/GroupMemberServiceImp.java
 
b/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/service/groupmember/GroupMemberServiceImp.java
new file mode 100644
index 0000000..d50173e
--- /dev/null
+++ 
b/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/service/groupmember/GroupMemberServiceImp.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.eventmesh.dashboard.console.service.groupmember;
+
+import org.apache.eventmesh.dashboard.console.annotation.EmLog;
+import org.apache.eventmesh.dashboard.console.entity.group.GroupEntity;
+import 
org.apache.eventmesh.dashboard.console.entity.groupmember.GroupMemberEntity;
+import 
org.apache.eventmesh.dashboard.console.mapper.groupmember.OprGroupMemberMapper;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class GroupMemberServiceImp implements GroupMemberService {
+
+    @Autowired
+    OprGroupMemberMapper oprGroupMemberMapper;
+
+    @Override
+    @EmLog(OprType = "View", OprTarget = "GroupMember")
+    public List<GroupMemberEntity> getGroupMemberByClusterId(GroupMemberEntity 
groupMemberEntity) {
+        return oprGroupMemberMapper.getGroupByClusterId(groupMemberEntity);
+    }
+
+    @Override
+    @EmLog(OprType = "add", OprTarget = "GroupMember")
+    public void addGroupMember(GroupMemberEntity groupMemberEntity) {
+        oprGroupMemberMapper.addGroupMember(groupMemberEntity);
+    }
+
+    @Override
+    public void updateGroupMember(GroupMemberEntity groupMemberEntity) {
+        oprGroupMemberMapper.updateGroupMember(groupMemberEntity);
+    }
+
+    @Override
+    public GroupMemberEntity deleteGroupMember(GroupMemberEntity 
groupMemberEntity) {
+        return oprGroupMemberMapper.deleteGroupMember(groupMemberEntity);
+    }
+
+    @Override
+    public GroupMemberEntity selectGroupMemberById(GroupMemberEntity 
groupMemberEntity) {
+        return oprGroupMemberMapper.selectGroupMemberById(groupMemberEntity);
+    }
+
+    @Override
+    public List<GroupMemberEntity> selectGroupMemberByGroup(GroupEntity 
groupEntity) {
+        GroupMemberEntity groupMemberEntity = new GroupMemberEntity();
+        groupMemberEntity.setGroupName(groupEntity.getName());
+        groupMemberEntity.setClusterId(groupEntity.getClusterId());
+        //Obtain a member who meets the conditions of a group
+        return oprGroupMemberMapper.selectMember(groupMemberEntity);
+    }
+
+    @Override
+    public List<GroupMemberEntity> selectAllMemberByTopic(GroupMemberEntity 
groupMemberEntity) {
+        List<GroupMemberEntity> groupMemberEntities = 
oprGroupMemberMapper.selectMember(groupMemberEntity);
+        return groupMemberEntities;
+    }
+
+}
diff --git 
a/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/EventMeshDashboardApplication.java
 
b/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/service/log/LogService.java
similarity index 51%
copy from 
eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/EventMeshDashboardApplication.java
copy to 
eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/service/log/LogService.java
index 79fc03d..d496ae6 100644
--- 
a/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/EventMeshDashboardApplication.java
+++ 
b/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/service/log/LogService.java
@@ -15,23 +15,24 @@
  * limitations under the License.
  */
 
-package org.apache.eventmesh.dashboard.console;
+package org.apache.eventmesh.dashboard.console.service.log;
 
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.context.annotation.ComponentScan;
-import org.springframework.scheduling.annotation.EnableScheduling;
+import org.apache.eventmesh.dashboard.console.entity.log.LogEntity;
 
-import lombok.extern.slf4j.Slf4j;
+import java.util.List;
 
-@Slf4j
-@SpringBootApplication
-@EnableScheduling
-@ComponentScan({"org.apache.eventmesh.dashboard.service", 
"org.apache.eventmesh.dashboard.console"})
-public class EventMeshDashboardApplication {
+/**
+ *
+ * operation service
+ *
+ */
+
+public interface LogService {
+
+    List<LogEntity> getLogListByCluster(LogEntity logEntity);
+
+    Long addLog(LogEntity logEntity);
+
+    Integer updateLog(LogEntity logEntity);
 
-    public static void main(String[] args) {
-        SpringApplication.run(EventMeshDashboardApplication.class, args);
-        log.info("{} Successfully booted.", 
EventMeshDashboardApplication.class.getSimpleName());
-    }
 }
diff --git 
a/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/service/log/LogServiceImpl.java
 
b/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/service/log/LogServiceImpl.java
new file mode 100644
index 0000000..7bd680b
--- /dev/null
+++ 
b/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/service/log/LogServiceImpl.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.eventmesh.dashboard.console.service.log;
+
+import org.apache.eventmesh.dashboard.console.entity.log.LogEntity;
+import org.apache.eventmesh.dashboard.console.mapper.log.OprLogMapper;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class LogServiceImpl implements LogService {
+
+    @Autowired
+    OprLogMapper oprLogMapper;
+
+    @Override
+    public List<LogEntity> getLogListByCluster(LogEntity logEntity) {
+
+        return oprLogMapper.getLogList(logEntity);
+    }
+
+    @Override
+    public Long addLog(LogEntity logEntity) {
+
+        return oprLogMapper.addLog(logEntity);
+    }
+
+    @Override
+    public Integer updateLog(LogEntity logEntity) {
+
+        return oprLogMapper.updateLog(logEntity);
+    }
+}
diff --git 
a/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/EventMeshDashboardApplication.java
 
b/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/service/topic/TopicService.java
similarity index 51%
copy from 
eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/EventMeshDashboardApplication.java
copy to 
eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/service/topic/TopicService.java
index 79fc03d..95c8a32 100644
--- 
a/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/EventMeshDashboardApplication.java
+++ 
b/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/service/topic/TopicService.java
@@ -15,23 +15,27 @@
  * limitations under the License.
  */
 
-package org.apache.eventmesh.dashboard.console;
+package org.apache.eventmesh.dashboard.console.service.topic;
 
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.context.annotation.ComponentScan;
-import org.springframework.scheduling.annotation.EnableScheduling;
+import org.apache.eventmesh.dashboard.console.entity.topic.TopicEntity;
 
-import lombok.extern.slf4j.Slf4j;
+import java.util.List;
 
-@Slf4j
-@SpringBootApplication
-@EnableScheduling
-@ComponentScan({"org.apache.eventmesh.dashboard.service", 
"org.apache.eventmesh.dashboard.console"})
-public class EventMeshDashboardApplication {
+/**
+ * Service about Topic
+ */
+public interface TopicService {
+    List<TopicEntity> getTopicList(TopicEntity topicEntity);
+
+    void addTopic_plus(TopicEntity topicEntity);
+
+    void updateTopic(TopicEntity topicEntity);
+
+    void deleteTopicById(TopicEntity topicEntity);
+
+    TopicEntity selectTopicById(TopicEntity topicEntity);
+
+    TopicEntity selectTopicByUnique(TopicEntity topicEntity);
 
-    public static void main(String[] args) {
-        SpringApplication.run(EventMeshDashboardApplication.class, args);
-        log.info("{} Successfully booted.", 
EventMeshDashboardApplication.class.getSimpleName());
-    }
+    void deleteTopic(TopicEntity topicEntity);
 }
diff --git 
a/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/service/topic/TopicServiceImpl.java
 
b/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/service/topic/TopicServiceImpl.java
new file mode 100644
index 0000000..aa42e7b
--- /dev/null
+++ 
b/eventmesh-dashboard-console/src/main/java/org/apache/eventmesh/dashboard/console/service/topic/TopicServiceImpl.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.eventmesh.dashboard.console.service.topic;
+
+import 
org.apache.eventmesh.dashboard.console.entity.groupmember.GroupMemberEntity;
+import org.apache.eventmesh.dashboard.console.entity.topic.TopicEntity;
+import 
org.apache.eventmesh.dashboard.console.mapper.groupmember.OprGroupMemberMapper;
+import org.apache.eventmesh.dashboard.console.mapper.topic.TopicMapper;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class TopicServiceImpl implements TopicService {
+
+    @Autowired
+    TopicMapper topicMapper;
+
+    @Autowired
+    OprGroupMemberMapper oprGroupMemberMapper;
+
+
+    @Override
+    public List<TopicEntity> getTopicList(TopicEntity topicEntity) {
+        return topicMapper.getTopicList(topicEntity);
+    }
+
+    @Override
+    public void addTopic_plus(TopicEntity topicEntity) {
+        GroupMemberEntity groupMemberEntity = new GroupMemberEntity();
+        groupMemberEntity.setTopicName(topicEntity.getTopicName());
+        groupMemberEntity.setState("active");
+        oprGroupMemberMapper.updateMemberByTopic(groupMemberEntity);
+        topicMapper.addTopic(topicEntity);
+    }
+
+    @Override
+    public void updateTopic(TopicEntity topicEntity) {
+        topicMapper.updateTopic(topicEntity);
+    }
+
+    @Override
+    public void deleteTopicById(TopicEntity topicEntity) {
+        topicMapper.deleteTopic(topicEntity);
+    }
+
+    @Override
+    public TopicEntity selectTopicById(TopicEntity topicEntity) {
+        return topicMapper.selectTopicById(topicEntity);
+    }
+
+    @Override
+    public TopicEntity selectTopicByUnique(TopicEntity topicEntity) {
+        return topicMapper.selectTopicByUnique(topicEntity);
+    }
+
+    @Override
+    public void deleteTopic(TopicEntity topicEntity) {
+        GroupMemberEntity groupMemberEntity = new GroupMemberEntity();
+        groupMemberEntity.setTopicName(topicEntity.getTopicName());
+        groupMemberEntity.setState("empty");
+        oprGroupMemberMapper.updateMemberByTopic(groupMemberEntity);
+        topicMapper.deleteTopic(topicEntity);
+    }
+}
diff --git a/eventmesh-dashboard-console/src/main/resources/application-dev.yml 
b/eventmesh-dashboard-console/src/main/resources/application-dev.yml
index 1c5e840..0ff18a1 100644
--- a/eventmesh-dashboard-console/src/main/resources/application-dev.yml
+++ b/eventmesh-dashboard-console/src/main/resources/application-dev.yml
@@ -32,7 +32,7 @@ spring:
       driver-class-name: com.mysql.cj.jdbc.Driver
       url: 
jdbc:mysql://localhost:3306/eventmesh-dashboard?useSSL=false&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull&allowPublicKeyRetrieval=true
       username: root
-      password: root
+      password: 123456
 
       initial-size: 1
       max-active: 50
@@ -44,9 +44,12 @@ spring:
       test-while-idle: true
       min-evictable-idle-time-millis: 300000
 
+mybatis:
+  type-aliases-package: org.apache.eventmesh.dashboard.console.entity
+
 # cron job config, use cron expression
 cron:
-    #health check job
-    health: "0/15 * * * * ? *"
+  #health check job
+  health: "0/15 * * * * ? *"
 
 
diff --git 
a/eventmesh-dashboard-console/src/main/resources/eventmesh-dashboard.sql 
b/eventmesh-dashboard-console/src/main/resources/eventmesh-dashboard.sql
index 8de09e7..96cf1e3 100644
--- a/eventmesh-dashboard-console/src/main/resources/eventmesh-dashboard.sql
+++ b/eventmesh-dashboard-console/src/main/resources/eventmesh-dashboard.sql
@@ -14,28 +14,112 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+CREATE TABLE `group`
+(
+    `id`           bigint unsigned                                  NOT NULL 
AUTO_INCREMENT COMMENT 'id',
+    `cluster_id`   bigint                                           NOT NULL 
DEFAULT '-1' COMMENT '集群id',
+    `name`         varchar(192) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL 
DEFAULT '' COMMENT 'Group名称',
+    `member_count` int unsigned                                     NOT NULL 
DEFAULT '0' COMMENT '成员数',
+    `members`      text COMMENT 'group的member列表',
+    `type`         tinyint                                          NOT NULL 
COMMENT 'group类型 0:consumer 1:producer',
+    `state`        varchar(64)                                      NOT NULL 
DEFAULT '' COMMENT '状态',
+    `create_time`  timestamp                                        NOT NULL 
DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+    `update_time`  timestamp                                        NOT NULL 
DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
+    `is_delete`    int                                              NOT NULL 
DEFAULT '0',
+    PRIMARY KEY (`id`),
+    UNIQUE KEY `uniq_cluster_phy_id_name` (`cluster_id`, `name`),
+    KEY `cluster_id` (`cluster_id`, `name`)
+) ENGINE = InnoDB
+  AUTO_INCREMENT = 322
+  DEFAULT CHARSET = utf8mb3 COMMENT ='Group信息表'
+
+
+
+CREATE TABLE `group_member`
+(
+    `id`             bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
+    `cluster_id`     bigint          NOT NULL DEFAULT '-1' COMMENT '集群ID',
+    `topic_name`     varchar(192)    NOT NULL DEFAULT '' COMMENT 'Topic名称',
+    `group_name`     varchar(192)    NOT NULL DEFAULT '' COMMENT 'Group名称',
+    `eventmesh_user` varchar(192)    NOT NULL DEFAULT '' COMMENT 'EventMesh用户',
+    `state`          varchar(64)     NOT NULL DEFAULT '' COMMENT '状态',
+    `create_time`    timestamp       NOT NULL DEFAULT CURRENT_TIMESTAMP 
COMMENT '创建时间',
+    `update_time`    timestamp       NOT NULL DEFAULT CURRENT_TIMESTAMP ON 
UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
+    `is_delete`      int             NOT NULL DEFAULT '0',
+    PRIMARY KEY (`id`),
+    UNIQUE KEY `uniq_cluster_topic_group` (`cluster_id`, `topic_name`, 
`group_name`),
+    KEY `cluster_id` (`cluster_id`, `topic_name`, `group_name`)
+) ENGINE = InnoDB
+  AUTO_INCREMENT = 257
+  DEFAULT CHARSET = utf8mb3 COMMENT ='GroupMember信息表'
+
+
+
+CREATE TABLE `operation_log`
+(
+    `id`             bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
+    `cluster_id`     bigint          NOT NULL DEFAULT '-1' COMMENT '物理集群ID',
+    `operation_type` varchar(192)    NOT NULL DEFAULT '' COMMENT 
'操作类型,如:启动,停止,重启,添加,删除,修改',
+    `status`         int             NOT NULL DEFAULT '0' COMMENT '操作状态 
0:未知,1:执行中,2:成功,3:失败',
+    `content`    text COMMENT '备注信息',
+    `create_time`    timestamp       NOT NULL DEFAULT CURRENT_TIMESTAMP 
COMMENT '创建时间',
+    `end_time`       timestamp       NULL     DEFAULT CURRENT_TIMESTAMP 
COMMENT '结束时间',
+    `operation_user` varchar(192)             DEFAULT NULL,
+    `result` text,
+    `target_type`    varchar(192)    NOT NULL,
+    `is_delete`      int             NOT NULL DEFAULT '0',
+    PRIMARY KEY (`id`),
+    KEY `idx_cluster_phy_id` (`cluster_id`),
+    KEY `idx_status` (`status`)
+) ENGINE = InnoDB
+  AUTO_INCREMENT = 68
+  DEFAULT CHARSET = utf8mb3 COMMENT ='操作记录信息表'
+
+
+
+CREATE TABLE `topic`
+(
+    `id`           bigint unsigned                                  NOT NULL 
AUTO_INCREMENT COMMENT 'id',
+    `cluster_id`   bigint                                           NOT NULL 
DEFAULT '-1' COMMENT '集群ID',
+    `topic_name`   varchar(192) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL 
DEFAULT '' COMMENT 'Topic名称',
+    `runtime_id`   varchar(2048)                                    NOT NULL 
DEFAULT '' COMMENT 'RuntimeId',
+    `storage_id`   varchar(2048)                                    NOT NULL 
DEFAULT '' COMMENT 'StorageId',
+    `retention_ms` bigint                                           NOT NULL 
DEFAULT '-2' COMMENT '保存时间,-2:未知,-1:无限制,>=0对应时间,单位ms',
+    `type`         tinyint                                          NOT NULL 
DEFAULT '0' COMMENT 'Topic类型,默认0,0:普通,1:EventMesh内部',
+    `description`  text COMMENT '备注信息',
+    `create_time`  timestamp                                        NOT NULL 
DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间(尽量与Topic实际创建时间一致)',
+    `update_time`  timestamp                                        NOT NULL 
DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间(尽量与Topic实际创建时间一致)',
+    `is_delete`    int                                              NOT NULL 
DEFAULT '0',
+    PRIMARY KEY (`id`),
+    UNIQUE KEY `uniq_cluster_phy_id_topic_name` (`cluster_id`, `topic_name`),
+    KEY `cluster_id` (`cluster_id`, `topic_name`)
+) ENGINE = InnoDB
+  AUTO_INCREMENT = 562
+  DEFAULT CHARSET = utf8mb3 COMMENT ='Topic信息表'
+
+
 
 DROP TABLE IF EXISTS `client`;
 CREATE TABLE `client`
 (
-    `id`             bigint(20)          NOT NULL AUTO_INCREMENT COMMENT 'id',
-    `cluster_id` bigint(20)          NOT NULL DEFAULT '-1' COMMENT '集群ID',
-    `name`           varchar(192)        NOT NULL DEFAULT '' COMMENT '客户端名称',
-    `platform`       varchar(192)        NOT NULL DEFAULT '' COMMENT '客户端平台',
-    `language`       varchar(192)        NOT NULL DEFAULT '' COMMENT '客户端语言',
-    `pid`            bigint(22)          NOT NULL DEFAULT '-1' COMMENT 
'客户端进程ID',
-    `host`           varchar(128)        NOT NULL DEFAULT '' COMMENT '客户端地址',
-    `port`           int(16)             NOT NULL DEFAULT '-1' COMMENT '客户端端口',
-    `protocol`       varchar(192)        NOT NULL DEFAULT '' COMMENT '协议类型',
-    `status`         tinyint(4) unsigned NOT NULL DEFAULT '0' COMMENT '状态: 
1启用,0未启用',
-    `config_ids`     text                NOT NULL DEFAULT '' COMMENT 'csv 
config id list, like:1,3,7',
-    `description`    text                NOT NULL DEFAULT '' COMMENT '客户端描述',
-    `create_time`    timestamp           NOT NULL DEFAULT CURRENT_TIMESTAMP 
COMMENT '创建时间',
-    `end_time`       timestamp           NOT NULL DEFAULT CURRENT_TIMESTAMP 
COMMENT '结束时间',
-    `update_time`    timestamp           NOT NULL DEFAULT CURRENT_TIMESTAMP ON 
UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
+    `id`          bigint(20)          NOT NULL AUTO_INCREMENT COMMENT 'id',
+    `cluster_id`  bigint(20)          NOT NULL DEFAULT '-1' COMMENT '集群ID',
+    `name`        varchar(192)        NOT NULL DEFAULT '' COMMENT '客户端名称',
+    `platform`    varchar(192)        NOT NULL DEFAULT '' COMMENT '客户端平台',
+    `language`    varchar(192)        NOT NULL DEFAULT '' COMMENT '客户端语言',
+    `pid`         bigint(22)          NOT NULL DEFAULT '-1' COMMENT '客户端进程ID',
+    `host`        varchar(128)        NOT NULL DEFAULT '' COMMENT '客户端地址',
+    `port`        int(16)             NOT NULL DEFAULT '-1' COMMENT '客户端端口',
+    `protocol`    varchar(192)        NOT NULL DEFAULT '' COMMENT '协议类型',
+    `status`      tinyint(4) unsigned NOT NULL DEFAULT '0' COMMENT '状态: 
1启用,0未启用',
+    `config_ids`  text                NOT NULL DEFAULT '' COMMENT 'csv config 
id list, like:1,3,7',
+    `description` text                NOT NULL DEFAULT '' COMMENT '客户端描述',
+    `create_time` timestamp           NOT NULL DEFAULT CURRENT_TIMESTAMP 
COMMENT '创建时间',
+    `end_time`    timestamp           NOT NULL DEFAULT CURRENT_TIMESTAMP 
COMMENT '结束时间',
+    `update_time` timestamp           NOT NULL DEFAULT CURRENT_TIMESTAMP ON 
UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
 
     PRIMARY KEY (`id`),
-    INDEX  `idx_cluster_id` (`cluster_id`)
+    INDEX `idx_cluster_id` (`cluster_id`)
 ) ENGINE = InnoDB
   DEFAULT CHARSET = utf8 COMMENT ='客户端信息表';
 
@@ -44,16 +128,16 @@ CREATE TABLE `client`
 DROP TABLE IF EXISTS `connector`;
 CREATE TABLE `connector`
 (
-    `id`                 bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 
'id',
-    `cluster_id`     bigint(20)          NOT NULL DEFAULT '-1' COMMENT '集群ID',
-    `name`               varchar(512)        NOT NULL DEFAULT '' COMMENT 
'Connector名称',
-    `class_name`         varchar(512)        NOT NULL DEFAULT '' COMMENT 
'Connector类',
-    `type`               varchar(32)         NOT NULL DEFAULT '' COMMENT 
'Connector类型',
-    `status`             tinyint(4) unsigned NOT NULL DEFAULT '0' COMMENT '状态: 
1启用,0未启用',
-    `pod_state`          tinyint(4) unsigned NOT NULL DEFAULT '0' COMMENT 'k8s 
pod状态。0: pending;1: running;2: success;3: failed;4: unknown',
-    `config_ids`         text                NOT NULL DEFAULT '' COMMENT 'csv 
config id list, like:1,3,7',
-    `create_time`        timestamp           NOT NULL DEFAULT 
CURRENT_TIMESTAMP COMMENT '创建时间',
-    `update_time`        timestamp           NOT NULL DEFAULT 
CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
+    `id`          bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
+    `cluster_id`  bigint(20)          NOT NULL DEFAULT '-1' COMMENT '集群ID',
+    `name`        varchar(512)        NOT NULL DEFAULT '' COMMENT 
'Connector名称',
+    `class_name`  varchar(512)        NOT NULL DEFAULT '' COMMENT 'Connector类',
+    `type`        varchar(32)         NOT NULL DEFAULT '' COMMENT 
'Connector类型',
+    `status`      tinyint(4) unsigned NOT NULL DEFAULT '0' COMMENT '状态: 
1启用,0未启用',
+    `pod_state`   tinyint(4) unsigned NOT NULL DEFAULT '0' COMMENT 'k8s 
pod状态。0: pending;1: running;2: success;3: failed;4: unknown',
+    `config_ids`  text                NOT NULL DEFAULT '' COMMENT 'csv config 
id list, like:1,3,7',
+    `create_time` timestamp           NOT NULL DEFAULT CURRENT_TIMESTAMP 
COMMENT '创建时间',
+    `update_time` timestamp           NOT NULL DEFAULT CURRENT_TIMESTAMP ON 
UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
     PRIMARY KEY (`id`),
     INDEX `idx_cluster_id` (`cluster_id`)
 ) ENGINE = InnoDB
@@ -62,20 +146,20 @@ CREATE TABLE `connector`
 DROP TABLE IF EXISTS `connection`;
 CREATE TABLE `connection`
 (
-    `id`             bigint(20)          NOT NULL AUTO_INCREMENT COMMENT 'id',
-    `cluster_id` bigint(20)          NOT NULL DEFAULT '-1' COMMENT '集群ID',
-    `source_type`    varchar(64)         NOT NULL DEFAULT '' COMMENT 
'source类型,可以为client或source connector',
-    `source_id`      bigint(20)          NOT NULL DEFAULT '-1' COMMENT 
'client或source connector ID',
-    `sink_type`      varchar(64)         NOT NULL DEFAULT '' COMMENT 
'sink类型,可以为client或sink connector',
-    `sink_id`        bigint(20)          NOT NULL DEFAULT '-1' COMMENT 
'client或sink connector ID',
-    `runtime_id`     bigint(20)          NOT NULL DEFAULT '-1' COMMENT 
'对应runtime id',
-    `status`         tinyint(4) unsigned NOT NULL DEFAULT '0' COMMENT '状态: 
1启用,0未启用',
-    `topic`          varchar(192)        NOT NULL DEFAULT '' COMMENT 'topic 
name',
-    `group_id`       bigint(20)          NOT NULL DEFAULT '-1' COMMENT 
'GroupID',
-    `description`    text                NOT NULL DEFAULT '' COMMENT '客户端描述',
-    `create_time`    timestamp           NOT NULL DEFAULT CURRENT_TIMESTAMP 
COMMENT '创建时间',
-    `end_time`       timestamp           NOT NULL DEFAULT CURRENT_TIMESTAMP 
COMMENT '结束时间',
-    `update_time`    timestamp           NOT NULL DEFAULT CURRENT_TIMESTAMP ON 
UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
+    `id`          bigint(20)          NOT NULL AUTO_INCREMENT COMMENT 'id',
+    `cluster_id`  bigint(20)          NOT NULL DEFAULT '-1' COMMENT '集群ID',
+    `source_type` varchar(64)         NOT NULL DEFAULT '' COMMENT 
'source类型,可以为client或source connector',
+    `source_id`   bigint(20)          NOT NULL DEFAULT '-1' COMMENT 
'client或source connector ID',
+    `sink_type`   varchar(64)         NOT NULL DEFAULT '' COMMENT 
'sink类型,可以为client或sink connector',
+    `sink_id`     bigint(20)          NOT NULL DEFAULT '-1' COMMENT 
'client或sink connector ID',
+    `runtime_id`  bigint(20)          NOT NULL DEFAULT '-1' COMMENT '对应runtime 
id',
+    `status`      tinyint(4) unsigned NOT NULL DEFAULT '0' COMMENT '状态: 
1启用,0未启用',
+    `topic`       varchar(192)        NOT NULL DEFAULT '' COMMENT 'topic name',
+    `group_id`    bigint(20)          NOT NULL DEFAULT '-1' COMMENT 'GroupID',
+    `description` text                NOT NULL DEFAULT '' COMMENT '客户端描述',
+    `create_time` timestamp           NOT NULL DEFAULT CURRENT_TIMESTAMP 
COMMENT '创建时间',
+    `end_time`    timestamp           NOT NULL DEFAULT CURRENT_TIMESTAMP 
COMMENT '结束时间',
+    `update_time` timestamp           NOT NULL DEFAULT CURRENT_TIMESTAMP ON 
UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
 
     PRIMARY KEY (`id`),
     INDEX `idx_cluster_id` (`cluster_id`),
@@ -89,14 +173,14 @@ CREATE TABLE `connection`
 DROP TABLE IF EXISTS `health_check_result`;
 CREATE TABLE `health_check_result`
 (
-    `id`             bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 
'自增id',
-    `dimension`      int(11)             NOT NULL DEFAULT '0' COMMENT 
'检查维度(0:未知,1:Cluster,2:Runtime,3:Topic,4:Group)',
-    `config_name`    varchar(192)        NOT NULL DEFAULT '' COMMENT '配置名',
-    `cluster_id` bigint(20)          NOT NULL DEFAULT '0' COMMENT '集群ID',
-    `res_name`       varchar(192)        NOT NULL DEFAULT '' COMMENT '资源名称',
-    `passed`         tinyint(4)          NOT NULL DEFAULT '0' COMMENT 
'检查通过(0:未通过,1:通过)',
-    `create_time`    timestamp           NOT NULL DEFAULT CURRENT_TIMESTAMP 
COMMENT '创建时间',
-    `update_time`    timestamp           NOT NULL DEFAULT CURRENT_TIMESTAMP ON 
UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+    `id`          bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增id',
+    `dimension`   int(11)             NOT NULL DEFAULT '0' COMMENT 
'检查维度(0:未知,1:Cluster,2:Runtime,3:Topic,4:Group)',
+    `config_name` varchar(192)        NOT NULL DEFAULT '' COMMENT '配置名',
+    `cluster_id`  bigint(20)          NOT NULL DEFAULT '0' COMMENT '集群ID',
+    `res_name`    varchar(192)        NOT NULL DEFAULT '' COMMENT '资源名称',
+    `passed`      tinyint(4)          NOT NULL DEFAULT '0' COMMENT 
'检查通过(0:未通过,1:通过)',
+    `create_time` timestamp           NOT NULL DEFAULT CURRENT_TIMESTAMP 
COMMENT '创建时间',
+    `update_time` timestamp           NOT NULL DEFAULT CURRENT_TIMESTAMP ON 
UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
     PRIMARY KEY (`id`),
     INDEX `idx_cluster_id` (`cluster_id`),
     UNIQUE KEY `uniq_dimension_config_cluster_res` (`dimension`, 
`config_name`, `cluster_id`, `res_name`)
@@ -106,20 +190,20 @@ CREATE TABLE `health_check_result`
 DROP TABLE IF EXISTS `meta`;
 CREATE TABLE `meta`
 (
-    `id`                   bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 
'id',
-    `name`                 varchar(192)        NOT NULL DEFAULT '' COMMENT 
'注册中心名称',
-    `type`                 varchar(192)        NOT NULL DEFAULT '' COMMENT 
'注册中心类型,nacos,etcd,zookeeper',
-    `version`              varchar(128)        NOT NULL DEFAULT '' COMMENT 
'注册中心版本',
-    `cluster_id`       bigint(20)          NOT NULL DEFAULT '-1' COMMENT 
'集群ID',
-    `host`                 varchar(128)        NOT NULL DEFAULT '' COMMENT 
'注册中心地址',
-    `port`                 int(16)             NOT NULL DEFAULT '-1' COMMENT 
'注册中心端口',
-    `role`                 varchar(16)         NOT NULL DEFAULT '-1' COMMENT 
'角色, leader follower observer',
-    `username`             varchar(192)        NOT NULL DEFAULT '' COMMENT 
'注册中心用户名',
-    `params`               varchar(192)        NOT NULL DEFAULT '' COMMENT 
'注册中心启动参数',
-    `status`               tinyint(4) unsigned NOT NULL DEFAULT '0' COMMENT 
'状态: 1启用,0未启用',
-
-    `create_time`          timestamp           NOT NULL DEFAULT 
CURRENT_TIMESTAMP COMMENT '创建时间',
-    `update_time`          timestamp           NOT NULL DEFAULT 
CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
+    `id`          bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
+    `name`        varchar(192)        NOT NULL DEFAULT '' COMMENT '注册中心名称',
+    `type`        varchar(192)        NOT NULL DEFAULT '' COMMENT 
'注册中心类型,nacos,etcd,zookeeper',
+    `version`     varchar(128)        NOT NULL DEFAULT '' COMMENT '注册中心版本',
+    `cluster_id`  bigint(20)          NOT NULL DEFAULT '-1' COMMENT '集群ID',
+    `host`        varchar(128)        NOT NULL DEFAULT '' COMMENT '注册中心地址',
+    `port`        int(16)             NOT NULL DEFAULT '-1' COMMENT '注册中心端口',
+    `role`        varchar(16)         NOT NULL DEFAULT '-1' COMMENT '角色, 
leader follower observer',
+    `username`    varchar(192)        NOT NULL DEFAULT '' COMMENT '注册中心用户名',
+    `params`      varchar(192)        NOT NULL DEFAULT '' COMMENT '注册中心启动参数',
+    `status`      tinyint(4) unsigned NOT NULL DEFAULT '0' COMMENT '状态: 
1启用,0未启用',
+
+    `create_time` timestamp           NOT NULL DEFAULT CURRENT_TIMESTAMP 
COMMENT '创建时间',
+    `update_time` timestamp           NOT NULL DEFAULT CURRENT_TIMESTAMP ON 
UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
 
     PRIMARY KEY (`id`),
     INDEX `idx_cluster_id` (`cluster_id`)
diff --git 
a/eventmesh-dashboard-console/src/test/java/org/apache/eventmesh/dashboard/console/linkage/log/TestOprLog.java
 
b/eventmesh-dashboard-console/src/test/java/org/apache/eventmesh/dashboard/console/linkage/log/TestOprLog.java
new file mode 100644
index 0000000..afaf8d8
--- /dev/null
+++ 
b/eventmesh-dashboard-console/src/test/java/org/apache/eventmesh/dashboard/console/linkage/log/TestOprLog.java
@@ -0,0 +1,43 @@
+package org.apache.eventmesh.dashboard.console.linkage.log;
+
+import org.apache.eventmesh.dashboard.console.EventMeshDashboardApplication;
+import org.apache.eventmesh.dashboard.console.entity.group.GroupEntity;
+import org.apache.eventmesh.dashboard.console.entity.log.LogEntity;
+import org.apache.eventmesh.dashboard.console.service.group.GroupService;
+import org.apache.eventmesh.dashboard.console.service.log.LogService;
+
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = EventMeshDashboardApplication.class)
+public class TestOprLog {
+
+    @Autowired
+    private GroupService groupService;
+
+    @Autowired
+    private LogService logService;
+
+    @Test
+    public void testGroupServiceOprLog() {
+        GroupEntity groupEntity = new GroupEntity(null, 1L, "logTest", 0, 
null, 1, "OK", null, null);
+        GroupEntity groupEntity1 = groupService.addGroup(groupEntity);
+        LogEntity logEntity = new LogEntity(null, 1L, "add", "Group", 2, 
groupEntity1.toString(), null, null, null, null);
+        logEntity.setResult(groupEntity.toString());
+        logEntity.setId(groupEntity1.getId());
+        List<LogEntity> logListByCluster = 
logService.getLogListByCluster(logEntity);
+        logListByCluster.get(0).setId(null);
+        logListByCluster.get(0).setCreateTime(null);
+        logListByCluster.get(0).setEndTime(null);
+        Assert.assertEquals(logListByCluster.get(0), logEntity);
+        Assert.assertEquals(logListByCluster.size(), 1);
+    }
+
+}
diff --git 
a/eventmesh-dashboard-console/src/test/java/org/apache/eventmesh/dashboard/console/unit/group/TestGroupMapper.java
 
b/eventmesh-dashboard-console/src/test/java/org/apache/eventmesh/dashboard/console/unit/group/TestGroupMapper.java
new file mode 100644
index 0000000..f247c3f
--- /dev/null
+++ 
b/eventmesh-dashboard-console/src/test/java/org/apache/eventmesh/dashboard/console/unit/group/TestGroupMapper.java
@@ -0,0 +1,102 @@
+package org.apache.eventmesh.dashboard.console.unit.group;
+
+import org.apache.eventmesh.dashboard.console.EventMeshDashboardApplication;
+
+import org.apache.eventmesh.dashboard.console.entity.group.GroupEntity;
+import org.apache.eventmesh.dashboard.console.mapper.group.OprGroupMapper;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = EventMeshDashboardApplication.class)
+public class TestGroupMapper {
+
+    @Autowired
+    private OprGroupMapper groupMapper;
+
+    public List<GroupEntity> insertGroupData(String name) {
+        List<GroupEntity> groupEntities = new ArrayList<>();
+        for (int i = 0; i < 10; i++) {
+            GroupEntity groupEntity = new GroupEntity(null, (long) i, name, 0, 
null, 1, "OK", null, null);
+            groupMapper.addGroup(groupEntity);
+            groupEntities.add(groupEntity);
+        }
+        return groupEntities;
+    }
+
+    public List<GroupEntity> getRemovedTimeList(String name) {
+        GroupEntity groupEntity = new GroupEntity();
+        groupEntity.setName(name);
+        List<GroupEntity> groupEntities = groupMapper.selectGroup(groupEntity);
+        for (GroupEntity groupEntity1 : groupEntities) {
+            groupEntity1.setCreateTime(null);
+            groupEntity1.setUpdateTime(null);
+        }
+        return groupEntities;
+    }
+
+    @Test
+    public void testAddGroup() {
+        List<GroupEntity> groupEntities = this.insertGroupData("addGroup");
+        GroupEntity groupEntity = new GroupEntity();
+        groupEntity.setName("addGroup");
+        List<GroupEntity> groupEntities1 = 
groupMapper.selectGroup(groupEntity);
+        Assert.assertEquals(groupEntities, 
this.getRemovedTimeList("addGroup"));
+    }
+
+    @Test
+    public void testUpdateGroupById() {
+        List<GroupEntity> groupEntities = this.insertGroupData("updateById2");
+        GroupEntity groupEntity = groupEntities.get(9);
+        groupEntity.setType(3);
+        groupEntity.setMembers("1,");
+        groupEntity.setState("fail");
+        groupEntity.setMemberCount(1);
+        groupMapper.updateGroup(groupEntity);
+        Assert.assertEquals(groupEntities, 
this.getRemovedTimeList("updateById2"));
+    }
+
+    @Test
+    public void testDeleteGroupById() {
+        List<GroupEntity> groupEntities = this.insertGroupData("deleteById");
+        GroupEntity groupEntity = groupEntities.get(9);
+        groupMapper.deleteGroup(groupEntity);
+        groupEntities.remove(9);
+        Assert.assertEquals(groupEntities, 
this.getRemovedTimeList("deleteById"));
+    }
+
+    @Test
+    public void testSelectGroupById() {
+        List<GroupEntity> groupEntities = this.insertGroupData("selectById");
+        GroupEntity groupEntity = 
groupMapper.selectGroupById(groupEntities.get(0));
+        groupEntity.setCreateTime(null);
+        groupEntity.setUpdateTime(null);
+        Assert.assertEquals(groupEntities.get(0), groupEntity);
+    }
+
+    @Test
+    public void testSelectGroupByClusterId() {
+        List<GroupEntity> groupEntities = 
this.insertGroupData("selectByUnique");
+        GroupEntity groupEntity1 = new GroupEntity();
+        groupEntity1.setClusterId(groupEntities.get(0).getClusterId());
+        groupEntity1.setName(groupEntities.get(0).getName());
+        GroupEntity groupEntity = 
groupMapper.selectGroupByUnique(groupEntity1);
+        groupEntity.setCreateTime(null);
+        groupEntity.setUpdateTime(null);
+        Assert.assertEquals(groupEntities.get(0), groupEntity);
+    }
+
+    @Test
+    public void testSelectGroup() {
+        List<GroupEntity> groupEntities = 
this.insertGroupData("selectByDynamic1");
+        Assert.assertEquals(groupEntities, 
this.getRemovedTimeList("Dynamic1"));
+    }
+}
diff --git 
a/eventmesh-dashboard-console/src/test/java/org/apache/eventmesh/dashboard/console/unit/groupmember/testGroupMemberMapper.java
 
b/eventmesh-dashboard-console/src/test/java/org/apache/eventmesh/dashboard/console/unit/groupmember/testGroupMemberMapper.java
new file mode 100644
index 0000000..d3a20a0
--- /dev/null
+++ 
b/eventmesh-dashboard-console/src/test/java/org/apache/eventmesh/dashboard/console/unit/groupmember/testGroupMemberMapper.java
@@ -0,0 +1,141 @@
+package org.apache.eventmesh.dashboard.console.unit.groupmember;
+
+import org.apache.eventmesh.dashboard.console.EventMeshDashboardApplication;
+import 
org.apache.eventmesh.dashboard.console.entity.groupmember.GroupMemberEntity;
+import 
org.apache.eventmesh.dashboard.console.mapper.groupmember.OprGroupMemberMapper;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = EventMeshDashboardApplication.class)
+public class testGroupMemberMapper {
+
+    @Autowired
+    OprGroupMemberMapper groupMemberMapper;
+
+    public List<GroupMemberEntity> insertGroupData(String topicName, String 
groupName) {
+        List<GroupMemberEntity> groupMemberEntities = new ArrayList<>();
+        for (int i = 0; i < 10; i++) {
+            GroupMemberEntity groupMemberEntity = new GroupMemberEntity(null, 
(long) i, topicName, groupName, "admin", "active", null, null);
+            groupMemberMapper.addGroupMember(groupMemberEntity);
+            groupMemberEntities.add(groupMemberEntity);
+        }
+        return groupMemberEntities;
+    }
+
+    public List<GroupMemberEntity> getRemovedTimeList(String topicName, String 
groupName) {
+        GroupMemberEntity groupMemberEntity = new GroupMemberEntity();
+        groupMemberEntity.setTopicName(topicName);
+        groupMemberEntity.setGroupName(groupName);
+        List<GroupMemberEntity> groupEntities = 
groupMemberMapper.selectMember(groupMemberEntity);
+        for (GroupMemberEntity groupEntity1 : groupEntities) {
+            groupEntity1.setCreateTime(null);
+            groupEntity1.setUpdateTime(null);
+        }
+        return groupEntities;
+    }
+
+    @Test
+    public void testAddGroupMember() {
+        List<GroupMemberEntity> add1 = this.insertGroupData("add1", 
"groupMember");
+        Assert.assertEquals(add1, this.getRemovedTimeList("add1", 
"groupMember"));
+    }
+
+    @Test
+    public void testGetGroupMemberByClusterId() {
+        List<GroupMemberEntity> add1 = this.insertGroupData("getByCluster", 
"groupMember");
+        GroupMemberEntity groupMemberEntity = new GroupMemberEntity();
+        groupMemberEntity.setClusterId(add1.get(1).getClusterId());
+        List<GroupMemberEntity> groupByClusterId = 
groupMemberMapper.getGroupByClusterId(groupMemberEntity);
+        GroupMemberEntity groupMemberEntity1 = groupByClusterId.get(0);
+        groupMemberEntity1.setCreateTime(null);
+        groupMemberEntity1.setUpdateTime(null);
+        Assert.assertEquals(1, groupByClusterId.size());
+        Assert.assertEquals(add1.get(1), groupMemberEntity1);
+    }
+
+    @Test
+    public void testDeleteGroupMemberById() {
+        List<GroupMemberEntity> add1 = this.insertGroupData("getById", 
"groupMember");
+        GroupMemberEntity groupMemberEntity = new GroupMemberEntity();
+        groupMemberEntity.setId(add1.get(2).getId());
+        GroupMemberEntity groupMemberEntity1 = 
groupMemberMapper.selectGroupMemberById(groupMemberEntity);
+        groupMemberEntity1.setUpdateTime(null);
+        groupMemberEntity1.setCreateTime(null);
+        Assert.assertEquals(groupMemberEntity1, add1.get(2));
+    }
+
+    @Test
+    public void testUpdateGroupMemberById() {
+        List<GroupMemberEntity> add1 = this.insertGroupData("updateById", 
"groupMember");
+        GroupMemberEntity groupMemberEntity = new GroupMemberEntity();
+        add1.get(1).setState("fail1");
+        groupMemberEntity.setState("fail1");
+        groupMemberEntity.setId(add1.get(1).getId());
+        groupMemberMapper.updateGroupMember(groupMemberEntity);
+        GroupMemberEntity groupMemberEntity1 = 
groupMemberMapper.selectGroupMemberById(add1.get(1));
+        groupMemberEntity1.setUpdateTime(null);
+        groupMemberEntity1.setCreateTime(null);
+        Assert.assertEquals(groupMemberEntity1, add1.get(1));
+    }
+
+    @Test
+    public void testSelectGroupMemberByUnique() {
+        List<GroupMemberEntity> groupMemberEntities = 
this.insertGroupData("selectByUnique", "groupMember");
+        GroupMemberEntity groupMemberEntity = new GroupMemberEntity();
+        
groupMemberEntity.setClusterId(groupMemberEntities.get(1).getClusterId());
+        
groupMemberEntity.setTopicName(groupMemberEntities.get(1).getTopicName());
+        
groupMemberEntity.setGroupName(groupMemberEntities.get(1).getGroupName());
+        GroupMemberEntity groupMemberEntity1 = 
groupMemberMapper.selectGroupMemberByUnique(groupMemberEntity);
+        groupMemberEntity1.setUpdateTime(null);
+        groupMemberEntity1.setCreateTime(null);
+        Assert.assertEquals(groupMemberEntity1, groupMemberEntities.get(1));
+    }
+
+    @Test
+    public void testSelectGroupMemberByGroup() {
+        List<GroupMemberEntity> groupMemberEntities = 
this.insertGroupData("selectByGroup1", "groupMember1");
+        List<GroupMemberEntity> removedTimeList = 
this.getRemovedTimeList(null, "groupMember1");
+        Assert.assertEquals(groupMemberEntities, removedTimeList);
+    }
+
+    @Test
+    public void testSelectGroupMemberByTopic() {
+        List<GroupMemberEntity> groupMemberEntities = 
this.insertGroupData("selectByTopic1", "groupMember2");
+        List<GroupMemberEntity> removedTimeList = 
this.getRemovedTimeList("selectByTopic1", null);
+        Assert.assertEquals(groupMemberEntities, removedTimeList);
+    }
+
+    @Test
+    public void testUpdateGroupMemberByTopic() {
+        List<GroupMemberEntity> groupMemberEntities = 
this.insertGroupData("updateByTopic1", "groupMember2");
+        for (GroupMemberEntity groupMemberEntity : groupMemberEntities) {
+            groupMemberEntity.setState("fail2");
+        }
+        GroupMemberEntity groupMemberEntity = new GroupMemberEntity();
+        groupMemberEntity.setState("fail2");
+        groupMemberEntity.setTopicName("updateByTopic1");
+        groupMemberMapper.updateMemberByTopic(groupMemberEntity);
+        Assert.assertEquals(this.getRemovedTimeList("updateByTopic1", null), 
groupMemberEntities);
+    }
+
+    @Test
+    public void testSelectGroupMemberById() {
+        List<GroupMemberEntity> groupMemberEntities = 
this.insertGroupData("updateById1", "groupMember2");
+        GroupMemberEntity groupMemberEntity = new GroupMemberEntity();
+        groupMemberEntity.setId(groupMemberEntities.get(5).getId());
+        GroupMemberEntity groupMemberEntity1 = 
groupMemberMapper.selectGroupMemberById(groupMemberEntity);
+        groupMemberEntity1.setCreateTime(null);
+        groupMemberEntity1.setUpdateTime(null);
+        Assert.assertEquals(groupMemberEntity1, groupMemberEntities.get(5));
+    }
+
+}
diff --git 
a/eventmesh-dashboard-console/src/test/java/org/apache/eventmesh/dashboard/console/unit/topic/testTopicMapper.java
 
b/eventmesh-dashboard-console/src/test/java/org/apache/eventmesh/dashboard/console/unit/topic/testTopicMapper.java
new file mode 100644
index 0000000..7472792
--- /dev/null
+++ 
b/eventmesh-dashboard-console/src/test/java/org/apache/eventmesh/dashboard/console/unit/topic/testTopicMapper.java
@@ -0,0 +1,116 @@
+package org.apache.eventmesh.dashboard.console.unit.topic;
+
+import org.apache.eventmesh.dashboard.console.EventMeshDashboardApplication;
+import org.apache.eventmesh.dashboard.console.entity.topic.TopicEntity;
+import org.apache.eventmesh.dashboard.console.mapper.topic.TopicMapper;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = EventMeshDashboardApplication.class)
+public class testTopicMapper {
+
+    @Autowired
+    private TopicMapper topicMapper;
+
+    public List<TopicEntity> insertGroupData(String topicName) {
+        List<TopicEntity> topicEntities = new ArrayList<>();
+        for (int i = 0; i < 10; i++) {
+            TopicEntity topicEntity = new TopicEntity(null, (long) i, 
topicName, "10", "10", 100L, 1, "testTopic", null, null);
+            topicMapper.addTopic(topicEntity);
+            topicEntities.add(topicEntity);
+        }
+        return topicEntities;
+    }
+
+    public List<TopicEntity> getRemovedTimeList(String topicName, Long 
clusterId) {
+        TopicEntity topicEntity = new TopicEntity();
+        topicEntity.setTopicName(topicName);
+        topicEntity.setClusterId(clusterId);
+        List<TopicEntity> topicEntities = 
topicMapper.getTopicList(topicEntity);
+        for (TopicEntity topic : topicEntities) {
+            topic.setCreateTime(null);
+            topic.setUpdateTime(null);
+        }
+        return topicEntities;
+    }
+
+    @Test
+    public void testSelectTopicByClusterId() {
+        List<TopicEntity> topicEntities = 
this.insertGroupData("SelectById111");
+        TopicEntity topicEntity = new TopicEntity();
+        topicEntity.setClusterId(topicEntities.get(9).getClusterId());
+        List<TopicEntity> topicEntity1 = topicMapper.getTopicList(topicEntity);
+        topicEntity1.get(0).setCreateTime(null);
+        topicEntity1.get(0).setUpdateTime(null);
+        Assert.assertEquals(topicEntity1.get(0), topicEntities.get(9));
+        Assert.assertEquals(1, topicEntity1.size());
+    }
+
+    @Test
+    public void testAddTopic() {
+        List<TopicEntity> topicEntities = this.insertGroupData("add111");
+        List<TopicEntity> add111 = this.getRemovedTimeList("add111", null);
+        Assert.assertEquals(add111, topicEntities);
+    }
+
+    @Test
+    public void testUpdateTopic() {
+        List<TopicEntity> topicEntities = this.insertGroupData("update2");
+        topicEntities.get(5).setDescription("updateTest1");
+        topicEntities.get(5).setType(-1);
+        TopicEntity topicEntity = new TopicEntity();
+        topicEntity.setDescription("updateTest1");
+        topicEntity.setType(-1);
+        topicEntity.setId(topicEntities.get(5).getId());
+        topicMapper.updateTopic(topicEntity);
+        TopicEntity topicEntity1 = topicMapper.selectTopicById(topicEntity);
+        topicEntity1.setUpdateTime(null);
+        topicEntity1.setCreateTime(null);
+        Assert.assertEquals(topicEntity1, topicEntities.get(5));
+    }
+
+    @Test
+    public void testDeleteTopic() {
+        List<TopicEntity> topicEntities = this.insertGroupData("update72");
+        TopicEntity topicEntity = new TopicEntity();
+        topicEntity.setId(topicEntities.get(5).getId());
+        topicEntity.setClusterId(topicEntities.get(5).getClusterId());
+        topicEntity.setTopicName("update72");
+        topicMapper.deleteTopic(topicEntity);
+        List<TopicEntity> topicEntity1 = topicMapper.getTopicList(topicEntity);
+        Assert.assertEquals(true, topicEntity1.isEmpty());
+    }
+
+    @Test
+    public void testSelectTopicByUnique() {
+        List<TopicEntity> topicEntities = this.insertGroupData("unique11");
+        TopicEntity topicEntity = new TopicEntity();
+        topicEntity.setTopicName("unique11");
+        topicEntity.setClusterId(topicEntities.get(1).getClusterId());
+        TopicEntity topicEntity1 = 
topicMapper.selectTopicByUnique(topicEntity);
+        topicEntity1.setUpdateTime(null);
+        topicEntity1.setCreateTime(null);
+        Assert.assertEquals(topicEntity1, topicEntities.get(1));
+    }
+
+    @Test
+    public void testSelectTopicById() {
+        List<TopicEntity> topicEntities = this.insertGroupData("id1");
+        TopicEntity topicEntity = new TopicEntity();
+        topicEntity.setId(topicEntities.get(2).getId());
+        TopicEntity topicEntity1 = topicMapper.selectTopicById(topicEntity);
+        topicEntity1.setCreateTime(null);
+        topicEntity1.setUpdateTime(null);
+        Assert.assertEquals(topicEntity1, topicEntities.get(2));
+    }
+
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]


Reply via email to