From 4538593236ed2374627ff1b208886bec45559855 Mon Sep 17 00:00:00 2001 From: xuguang Date: Wed, 8 Dec 2021 15:50:53 +0800 Subject: [PATCH 01/10] =?UTF-8?q?=E5=AE=9E=E7=8E=B0core=E5=8C=85=E4=B8=8BT?= =?UTF-8?q?opicReportService=E6=8E=A5=E5=8F=A3=E5=8D=95=E5=85=83=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=20&=20TopicReportDao.xml=E4=B8=AD=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E5=92=8C=E5=85=B3=E9=94=AE=E5=AD=97=E9=94=99=E8=AF=AF=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gateway/TopicReportServiceTest.java | 47 +++++++++++++++++++ .../main/resources/mapper/TopicReportDao.xml | 4 +- 2 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/gateway/TopicReportServiceTest.java diff --git a/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/gateway/TopicReportServiceTest.java b/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/gateway/TopicReportServiceTest.java new file mode 100644 index 00000000..82a4c8b3 --- /dev/null +++ b/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/gateway/TopicReportServiceTest.java @@ -0,0 +1,47 @@ +package com.xiaojukeji.kafka.manager.service.service.gateway; + +import com.xiaojukeji.kafka.manager.common.entity.pojo.gateway.TopicReportDO; +import com.xiaojukeji.kafka.manager.dao.gateway.TopicReportDao; +import com.xiaojukeji.kafka.manager.service.config.BaseTest; +import org.springframework.beans.factory.annotation.Autowired; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.util.Date; +import java.util.List; + +/** + * @author xuguang + * @Date 2021/12/7 + */ +public class TopicReportServiceTest extends BaseTest { + + @Autowired + private TopicReportService topicReportService; + + @Autowired + private TopicReportDao topicReportDao; + + @DataProvider(name = "provideTopicReportDO") + public static Object[][] provideTopicReportDO() { + TopicReportDO topicReportDO = new TopicReportDO(); + topicReportDO.setId(1L); + topicReportDO.setClusterId(1L); + topicReportDO.setTopicName("xgTest"); + topicReportDO.setStartTime(new Date(1638786493173L)); + topicReportDO.setEndTime(new Date(1638786493173L)); + topicReportDO.setModifyTime(new Date(1638786493173L)); + topicReportDO.setCreateTime(new Date(1638786493173L)); + return new Object[][] {{topicReportDO}}; + } + + @Test(dataProvider = "provideTopicReportDO") + public void getNeedReportTopicTest(TopicReportDO topicReportDO) { + // 数据库中插入数据 + int replace = topicReportDao.replace(topicReportDO); + List result = topicReportService.getNeedReportTopic(1L); + Assert.assertEquals(result.size(), 1); + Assert.assertEquals(result.get(0).toString(), topicReportDO.toString()); + } +} diff --git a/kafka-manager-dao/src/main/resources/mapper/TopicReportDao.xml b/kafka-manager-dao/src/main/resources/mapper/TopicReportDao.xml index 80d459b0..bb75ca97 100644 --- a/kafka-manager-dao/src/main/resources/mapper/TopicReportDao.xml +++ b/kafka-manager-dao/src/main/resources/mapper/TopicReportDao.xml @@ -27,13 +27,13 @@ ]]> - = #{now}) + AND end_time >= #{now}) ]]> From 1b8ea61e873b2371d21f8300c95bddbb7d267afb Mon Sep 17 00:00:00 2001 From: xuguang Date: Mon, 13 Dec 2021 18:16:23 +0800 Subject: [PATCH 02/10] =?UTF-8?q?openTopicJmx=E6=96=B9=E6=B3=95=E7=9A=84?= =?UTF-8?q?=E5=8F=82=E6=95=B0jmxSwitch=E9=9C=80=E8=A6=81=E5=88=A4=E7=A9=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../manager/service/service/impl/ZookeeperServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kafka-manager-core/src/main/java/com/xiaojukeji/kafka/manager/service/service/impl/ZookeeperServiceImpl.java b/kafka-manager-core/src/main/java/com/xiaojukeji/kafka/manager/service/service/impl/ZookeeperServiceImpl.java index c4c89513..cb9827bd 100644 --- a/kafka-manager-core/src/main/java/com/xiaojukeji/kafka/manager/service/service/impl/ZookeeperServiceImpl.java +++ b/kafka-manager-core/src/main/java/com/xiaojukeji/kafka/manager/service/service/impl/ZookeeperServiceImpl.java @@ -28,7 +28,7 @@ public class ZookeeperServiceImpl implements ZookeeperService { @Override public Result openTopicJmx(Long clusterId, String topicName, TopicJmxSwitch jmxSwitch) { - if (ValidateUtils.isNull(clusterId) || ValidateUtils.isNull(topicName)) { + if (ValidateUtils.isNull(clusterId) || ValidateUtils.isNull(topicName) || ValidateUtils.isNull(jmxSwitch)) { return Result.buildFrom(ResultStatus.PARAM_ILLEGAL); } From 41c000cf4788f52b0da8a5ad8c21b63f3e10ae7a Mon Sep 17 00:00:00 2001 From: xuguang Date: Tue, 14 Dec 2021 18:30:12 +0800 Subject: [PATCH 03/10] =?UTF-8?q?AuthorityServiceTest=20&&=20SecurityServi?= =?UTF-8?q?ceTest=20&&=20TopicReportServiceTest=20&&=20ClusterServiceTest?= =?UTF-8?q?=20&&=20ZookeeperServiceTest=E5=8D=95=E5=85=83=E6=B5=8B?= =?UTF-8?q?=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/service/ClusterServiceTest.java | 493 ++++++++++++++++++ .../service/LogicalClusterServiceTest.java | 428 +++++++++++++++ .../service/service/ZookeeperServiceTest.java | 235 +++++++++ .../service/gateway/AuthorityServiceTest.java | 172 ++++-- .../service/gateway/SecurityServiceTest.java | 76 +++ .../gateway/TopicReportServiceTest.java | 7 + 6 files changed, 1356 insertions(+), 55 deletions(-) create mode 100644 kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/ClusterServiceTest.java create mode 100644 kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/LogicalClusterServiceTest.java create mode 100644 kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/ZookeeperServiceTest.java create mode 100644 kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/gateway/SecurityServiceTest.java diff --git a/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/ClusterServiceTest.java b/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/ClusterServiceTest.java new file mode 100644 index 00000000..f0aaea7a --- /dev/null +++ b/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/ClusterServiceTest.java @@ -0,0 +1,493 @@ +package com.xiaojukeji.kafka.manager.service.service; + +import com.xiaojukeji.kafka.manager.common.bizenum.DBStatusEnum; +import com.xiaojukeji.kafka.manager.common.entity.Result; +import com.xiaojukeji.kafka.manager.common.entity.ResultStatus; +import com.xiaojukeji.kafka.manager.common.entity.ao.ClusterDetailDTO; +import com.xiaojukeji.kafka.manager.common.entity.ao.cluster.ControllerPreferredCandidate; +import com.xiaojukeji.kafka.manager.common.entity.pojo.*; +import com.xiaojukeji.kafka.manager.common.entity.vo.normal.cluster.ClusterNameDTO; +import com.xiaojukeji.kafka.manager.dao.ClusterMetricsDao; +import com.xiaojukeji.kafka.manager.dao.ControllerDao; +import com.xiaojukeji.kafka.manager.service.cache.LogicalClusterMetadataManager; +import com.xiaojukeji.kafka.manager.service.cache.PhysicalClusterMetadataManager; +import com.xiaojukeji.kafka.manager.service.config.BaseTest; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.springframework.beans.factory.annotation.Autowired; +import org.testng.Assert; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.util.*; + +import static org.mockito.Mockito.when; + +/** + * @author xuguang + * @Date 2021/12/8 + */ +public class ClusterServiceTest extends BaseTest { + + @Autowired + @InjectMocks + private ClusterService clusterService; + + @Autowired + private ClusterMetricsDao clusterMetricsDao; + + @Autowired + private ControllerDao controllerDao; + + @Mock + private RegionService regionService; + + @Mock + private LogicalClusterMetadataManager logicalClusterMetadataManager; + + @Mock + private PhysicalClusterMetadataManager physicalClusterMetadataManager; + + @Mock + private ZookeeperService zookeeperService; + + @BeforeMethod + public void setup() { + MockitoAnnotations.initMocks(this); + } + + @DataProvider(name = "provideClusterDO") + public static Object[][] provideClusterDO() { + ClusterDO clusterDO = new ClusterDO(); + clusterDO.setId(3L); + clusterDO.setClusterName("LogiKM_moduleTest"); + clusterDO.setZookeeper("10.190.46.198:2181,10.190.14.237:2181,10.190.50.65:2181/xg"); + clusterDO.setBootstrapServers("10.190.46.198:9093,10.190.14.237:9093,10.190.50.65:9093"); + clusterDO.setSecurityProperties("{ \t\"security.protocol\": \"SASL_PLAINTEXT\", \t\"sasl.mechanism\": \"PLAIN\", \t\"sasl.jaas.config\": \"org.apache.kafka.common.security.plain.PlainLoginModule required username=\\\"dkm_admin\\\" password=\\\"km_kMl4N8as1Kp0CCY\\\";\" }"); + clusterDO.setStatus(1); + clusterDO.setGmtCreate(new Date()); + clusterDO.setGmtModify(new Date()); + return new Object[][] {{clusterDO}}; + } + + @DataProvider(name = "provideClusterMetricsDO") + public static Object[][] provideClusterMetricsDO() { + ClusterMetricsDO clusterMetricsDO = new ClusterMetricsDO(); + clusterMetricsDO.setId(10L); + clusterMetricsDO.setClusterId(1L); + clusterMetricsDO.setMetrics("{\"PartitionNum\":52,\"BrokerNum\":0,\"CreateTime\":1638235221102,\"TopicNum\":2}"); + clusterMetricsDO.setGmtCreate(new Date()); + return new Object[][] {{clusterMetricsDO}}; + } + + @DataProvider(name = "provideControllerDO") + public static Object[][] provideControllerDO() { + ControllerDO controllerDO = new ControllerDO(); + controllerDO.setClusterId(1L); + controllerDO.setBrokerId(1); + controllerDO.setHost("127.0.0.1"); + controllerDO.setTimestamp(0L); + controllerDO.setVersion(1); + return new Object[][] {{controllerDO}}; + } + + @Test(dataProvider = "provideClusterDO", description = "测试新增物理集群") + public void addNewTest(ClusterDO clusterDO) { + // 测试新增物理集群成功 + addaddNew2SuccessTest(clusterDO); + // 测试新增物理集群时键重复 + addaddNew2DuplicateKeyTest(clusterDO); + // 测试新增物理集群时数据库插入失败 + addaddNew2MysqlErrorTest(clusterDO); + // 测试新增物理集群时参数有误 + addNew2ParamIllegalTest(clusterDO); + // 测试新增物理集群时zk无法连接 + addNew2ZookeeperConnectFailedTest(clusterDO); + } + + private void addNew2ParamIllegalTest(ClusterDO clusterDO) { + ResultStatus result1 = clusterService.addNew(clusterDO, null); + Assert.assertEquals(result1.getCode(), ResultStatus.PARAM_ILLEGAL.getCode()); + + ResultStatus result2 = clusterService.addNew(null, "admin"); + Assert.assertEquals(result2.getCode(), ResultStatus.PARAM_ILLEGAL.getCode()); + } + + private void addNew2ZookeeperConnectFailedTest(ClusterDO clusterDO) { + clusterDO.setZookeeper("xxx"); + ResultStatus result = clusterService.addNew(clusterDO, "admin"); + Assert.assertEquals(result.getCode(), ResultStatus.ZOOKEEPER_CONNECT_FAILED.getCode()); + } + + private void addaddNew2SuccessTest(ClusterDO clusterDO) { + ResultStatus result = clusterService.addNew(clusterDO, "admin"); + Assert.assertEquals(result.getCode(), ResultStatus.SUCCESS.getCode()); + } + + public void addaddNew2DuplicateKeyTest(ClusterDO clusterDO) { + + ResultStatus result = clusterService.addNew(clusterDO, "admin"); + Assert.assertEquals(result.getCode(), ResultStatus.RESOURCE_ALREADY_EXISTED.getCode()); + } + + public void addaddNew2MysqlErrorTest(ClusterDO clusterDO) { + // operateRecord数据库插入失败 + clusterDO.setClusterName(null); + ResultStatus result = clusterService.addNew(clusterDO, "admin"); + Assert.assertEquals(result.getCode(), ResultStatus.MYSQL_ERROR.getCode()); + + // cluster数据库插入失败 + clusterDO.setClusterName("clusterTest"); + clusterDO.setBootstrapServers(null); + ResultStatus result2 = clusterService.addNew(clusterDO, "admin"); + Assert.assertEquals(result2.getCode(), ResultStatus.MYSQL_ERROR.getCode()); + } + + @Test(dataProvider = "provideClusterDO", description = "测试由id获取ClusterDO") + public void getById(ClusterDO clusterDO) { + // 测试由id获取ClusterDO时,返回null + getById2NullTest(); + // 测试由id获取ClusterDO时,返回成功 + getById2SuccessTest(clusterDO); + } + + private void getById2NullTest() { + ClusterDO clusterDO = clusterService.getById(null); + Assert.assertNull(clusterDO); + } + + private void getById2SuccessTest(ClusterDO clusterDO) { + clusterService.addNew(clusterDO, "admin"); + + ClusterDO result = clusterService.getById(clusterDO.getId()); + Assert.assertNotNull(result); + Assert.assertEquals(result, clusterDO); + } + + @Test(dataProvider = "provideClusterDO", description = "测试修改物理集群") + public void updateById(ClusterDO clusterDO) { + // 测试修改物理集群时参数有误 + updateById2ParamIllegalTest(clusterDO); + // 测试修改物理集群时,集群不存在 + updateById2ClusterNotExistTest(clusterDO); + // 测试修改物理集群时,zk配置不能修改 + updateById2ChangeZookeeperForbiddenTest(clusterDO); + } + + @Test(dataProvider = "provideClusterDO", description = "测试修改物理集群时,mysqlError") + public void updateById2mysqlErrorTest(ClusterDO clusterDO) { + clusterService.addNew(clusterDO, "admin"); + + clusterDO.setBootstrapServers(null); + ResultStatus result1 = clusterService.updateById(clusterDO, "admin"); + Assert.assertEquals(result1.getCode(), ResultStatus.MYSQL_ERROR.getCode()); + } + + @Test(dataProvider = "provideClusterDO", description = "测试修改物理集群成功") + public void updateById2SuccessTest(ClusterDO clusterDO) { + clusterService.addNew(clusterDO, "admin"); + + clusterDO.setJmxProperties("jmx"); + ResultStatus result1 = clusterService.updateById(clusterDO, "admin"); + Assert.assertEquals(result1.getCode(), ResultStatus.SUCCESS.getCode()); + } + + private void updateById2ParamIllegalTest(ClusterDO clusterDO) { + ResultStatus result1 = clusterService.updateById(clusterDO, null); + Assert.assertEquals(result1.getCode(), ResultStatus.PARAM_ILLEGAL.getCode()); + + ResultStatus result2 = clusterService.updateById(null, "admin"); + Assert.assertEquals(result2.getCode(), ResultStatus.PARAM_ILLEGAL.getCode()); + } + + private void updateById2ClusterNotExistTest(ClusterDO clusterDO) { + clusterDO.setId(100L); + ResultStatus result1 = clusterService.updateById(clusterDO, "admin"); + Assert.assertEquals(result1.getCode(), ResultStatus.CLUSTER_NOT_EXIST.getCode()); + } + + private void updateById2ChangeZookeeperForbiddenTest(ClusterDO clusterDO) { + clusterDO.setZookeeper("zzz"); + clusterDO.setId(1L); + ResultStatus result1 = clusterService.updateById(clusterDO, "admin"); + Assert.assertEquals(result1.getCode(), ResultStatus.CHANGE_ZOOKEEPER_FORBIDDEN.getCode()); + } + + @Test(dataProvider = "provideClusterDO", description = "测试修改物理集群状态") + public void modifyStatusTest(ClusterDO clusterDO) { + // 测试修改物理集群状态时参数有误 + modifyStatus2ParamIllegalTest(); + // 测试修改物理集群状态时,集群不存在 + modifyStatus2ClusterNotExistTest(); + // 测试修改物理集群状态成功 + modifyStatus2SuccessTest(clusterDO); + } + + public void modifyStatus2ParamIllegalTest() { + ResultStatus result1 = clusterService.modifyStatus(null, 0, "admin"); + Assert.assertEquals(result1.getCode(), ResultStatus.PARAM_ILLEGAL.getCode()); + + ResultStatus result2 = clusterService.modifyStatus(1L, null,"admin"); + Assert.assertEquals(result2.getCode(), ResultStatus.PARAM_ILLEGAL.getCode()); + } + + public void modifyStatus2ClusterNotExistTest() { + ResultStatus result1 = clusterService.modifyStatus(100L, 0, "admin"); + Assert.assertEquals(result1.getCode(), ResultStatus.CLUSTER_NOT_EXIST.getCode()); + } + + public void modifyStatus2SuccessTest(ClusterDO clusterDO) { + clusterService.addNew(clusterDO, "admin"); + + ResultStatus result1 = clusterService.modifyStatus(clusterDO.getId(), clusterDO.getStatus(), "admin"); + Assert.assertEquals(result1.getCode(), ResultStatus.SUCCESS.getCode()); + } + + @Test(dataProvider = "provideClusterDO") + public void listTest(ClusterDO clusterDO) { + clusterService.addNew(clusterDO, "admin"); + + List list = clusterService.list(); + Assert.assertEquals(list.size(), 1); + Assert.assertEquals(list.get(0), clusterDO); + } + + @Test(dataProvider = "provideClusterDO") + public void listMapTest(ClusterDO clusterDO) { + clusterService.addNew(clusterDO, "admin"); + + Map longClusterDOMap = clusterService.listMap(); + Assert.assertEquals(longClusterDOMap.size(), 1); + Assert.assertEquals(longClusterDOMap.get(clusterDO.getId()), clusterDO); + } + + @Test(dataProvider = "provideClusterDO") + public void listAllTest(ClusterDO clusterDO) { + clusterService.addNew(clusterDO, "admin"); + + List list = clusterService.listAll(); + list.forEach(System.out::println); + + Assert.assertEquals(list.size(), 1); + Assert.assertEquals(list.get(0), clusterDO); + } + + @Test(dataProvider = "provideClusterMetricsDO") + public void getClusterMetricsFromDBTest(ClusterMetricsDO clusterMetricsDO) { + clusterMetricsDao.batchAdd(Arrays.asList(clusterMetricsDO)); + + List clusterMetricsDOList = clusterService.getClusterMetricsFromDB( + clusterMetricsDO.getClusterId(), + new Date(0L), new Date() + ); + + Assert.assertNotNull(clusterMetricsDOList); + Assert.assertEquals(clusterMetricsDOList.size(), 1); + Assert.assertTrue(clusterMetricsDOList.stream().allMatch(clusterMetricsDO1 -> + clusterMetricsDO1.getMetrics().equals(clusterMetricsDO.getMetrics()) && + clusterMetricsDO1.getClusterId().equals(clusterMetricsDO.getClusterId()))); + + } + + @Test(dataProvider = "provideControllerDO") + public void getKafkaControllerHistoryTest(ControllerDO controllerDO) { + controllerDao.insert(controllerDO); + + List kafkaControllerHistory = clusterService.getKafkaControllerHistory(controllerDO.getClusterId()); + Assert.assertNotNull(kafkaControllerHistory); + Assert.assertTrue(kafkaControllerHistory.stream() + .filter(controllerDO1 -> controllerDO1.getTimestamp().equals(0L)) + .allMatch(controllerDO1 -> + controllerDO1.getClusterId().equals(controllerDO.getClusterId()) && + controllerDO1.getBrokerId().equals(controllerDO.getBrokerId()) && + controllerDO1.getTimestamp().equals(controllerDO.getTimestamp())) + ); + } + + @Test(dataProvider = "provideClusterDO", description = "参数needDetail为false") + public void getClusterDetailDTOListWithFalseNeedDetailTest(ClusterDO clusterDO) { + clusterService.addNew(clusterDO, "admin"); + + String kafkaVersion = "2.7"; + when(physicalClusterMetadataManager.getKafkaVersionFromCache(Mockito.anyLong())).thenReturn(kafkaVersion); + + List clusterDetailDTOList = clusterService.getClusterDetailDTOList(false); + Assert.assertNotNull(clusterDetailDTOList); + Assert.assertTrue(clusterDetailDTOList.stream().allMatch(clusterDetailDTO -> + clusterDetailDTO.getBootstrapServers().equals(clusterDO.getBootstrapServers()) && + clusterDetailDTO.getZookeeper().equals(clusterDO.getZookeeper()) && + clusterDetailDTO.getKafkaVersion().equals(kafkaVersion))); + } + + @Test(dataProvider = "provideClusterDO", description = "参数needDetail为true") + public void getClusterDetailDTOListWithTrueNeedDetailTest(ClusterDO clusterDO) { + List clusterDetailDTOList = clusterService.getClusterDetailDTOList(true); + Assert.assertNotNull(clusterDetailDTOList); + Assert.assertTrue(clusterDetailDTOList.stream().allMatch(clusterDetailDTO -> + clusterDetailDTO.getBootstrapServers().equals(clusterDO.getBootstrapServers()) && + clusterDetailDTO.getZookeeper().equals(clusterDO.getZookeeper()) && + clusterDetailDTO.getClusterName().equals("LogiKM_xg") && + clusterDetailDTO.getBrokerNum().equals(1))); + } + + @Test(description = "测试获取ClusterNameDTO时,无对应的逻辑集群") + public void getClusterName2EmptyTest() { + when(logicalClusterMetadataManager.getLogicalCluster(Mockito.anyLong())).thenReturn(null); + ClusterNameDTO clusterName = clusterService.getClusterName(10L); + Assert.assertEquals(clusterName.toString(), new ClusterNameDTO().toString()); + } + + @Test(dataProvider = "provideClusterDO", description = "测试获取ClusterNameDTO成功") + public void getClusterName2SuccessTest(ClusterDO clusterDO) { + clusterService.addNew(clusterDO, "admin"); + + LogicalClusterDO logicalClusterDO = new LogicalClusterDO(); + logicalClusterDO.setIdentification("logical"); + logicalClusterDO.setClusterId(clusterDO.getId()); + logicalClusterDO.setId(1L); + when(logicalClusterMetadataManager.getLogicalCluster(Mockito.anyLong())).thenReturn(logicalClusterDO); + ClusterNameDTO clusterName = clusterService.getClusterName(logicalClusterDO.getId()); + Assert.assertEquals(clusterName.getLogicalClusterName(), logicalClusterDO.getName()); + Assert.assertEquals(clusterName.getLogicalClusterId(), logicalClusterDO.getId()); + Assert.assertEquals(clusterName.getPhysicalClusterId(), logicalClusterDO.getClusterId()); + Assert.assertEquals(clusterName.getPhysicalClusterName(), clusterDO.getClusterName()); + } + + @Test(description = "测试删除集群时,该集群下还有region,禁止删除") + public void deleteById2OperationForbiddenTest() { + when(regionService.getByClusterId(Mockito.anyLong())).thenReturn(Arrays.asList(new RegionDO())); + ResultStatus resultStatus = clusterService.deleteById(1L, "admin"); + Assert.assertEquals(resultStatus.getCode(), ResultStatus.OPERATION_FORBIDDEN.getCode()); + } + + @Test(dataProvider = "provideClusterDO", description = "测试删除集群成功") + public void deleteById2SuccessTest(ClusterDO clusterDO) { + clusterService.addNew(clusterDO, "admin"); + + when(regionService.getByClusterId(Mockito.anyLong())).thenReturn(Collections.emptyList()); + ResultStatus resultStatus = clusterService.deleteById(clusterDO.getId(), "admin"); + Assert.assertEquals(resultStatus.getCode(), ResultStatus.SUCCESS.getCode()); + + } + + @Test(description = "测试删除集群成功") + public void deleteById2MysqlErrorTest() { + when(regionService.getByClusterId(Mockito.anyLong())).thenReturn(Collections.emptyList()); + ResultStatus resultStatus = clusterService.deleteById(100L, "admin"); + Assert.assertEquals(resultStatus.getCode(), ResultStatus.MYSQL_ERROR.getCode()); + } + + @Test(description = "测试从zk中获取被选举的broker") + public void getControllerPreferredCandidatesTest() { + // "测试从zk中获取被选举的broker失败" + getControllerPreferredCandidates2FailedTest(); + // 测试从zk中获取被选举的broker为空 + getControllerPreferredCandidates2BrokersEmptyTest(); + // 测试从zk中获取被选举的broker的brokerMetadata为null + getControllerPreferredCandidates2BrokerMetadataNullTest(); + // 测试从zk中获取被选举的broker成功 + getControllerPreferredCandidates2SuccessTest(); + } + + private void getControllerPreferredCandidates2FailedTest() { + when(zookeeperService.getControllerPreferredCandidates(Mockito.anyLong())).thenReturn(new Result<>(-1, "fail")); + + Result> result = clusterService.getControllerPreferredCandidates(1L); + Assert.assertTrue(result.getCode() != ResultStatus.SUCCESS.getCode()); + } + + private void getControllerPreferredCandidates2BrokersEmptyTest() { + when(zookeeperService.getControllerPreferredCandidates(Mockito.anyLong())).thenReturn(new Result<>(0, new ArrayList<>(), "fail")); + + Result> result = clusterService.getControllerPreferredCandidates(1L); + Assert.assertEquals(result.getCode(), ResultStatus.SUCCESS.getCode()); + Assert.assertTrue(result.getData().isEmpty()); + } + + private void getControllerPreferredCandidates2BrokerMetadataNullTest() { + when(zookeeperService.getControllerPreferredCandidates(Mockito.anyLong())).thenReturn(new Result<>(0, Arrays.asList(100), "fail")); + + Result> result = clusterService.getControllerPreferredCandidates(1L); + Assert.assertEquals(result.getCode(), ResultStatus.SUCCESS.getCode()); + Assert.assertEquals((int) result.getData().get(0).getStatus(), DBStatusEnum.DEAD.getStatus()); + } + + private void getControllerPreferredCandidates2SuccessTest() { + when(zookeeperService.getControllerPreferredCandidates(Mockito.anyLong())).thenReturn(new Result<>(0, Arrays.asList(2), "fail")); + + Result> result = clusterService.getControllerPreferredCandidates(1L); + Assert.assertEquals(result.getCode(), ResultStatus.SUCCESS.getCode()); + Assert.assertEquals((int) result.getData().get(0).getStatus(), DBStatusEnum.ALIVE.getStatus()); + } + + @Test(description = "增加优先被选举为controller的broker") + public void addControllerPreferredCandidatesTest() { + // 增加优先被选举为controller的broker时参数错误 + addControllerPreferredCandidates2ParamIllegalTest(); + // 增加优先被选举为controller的broker时broker不存活 + addControllerPreferredCandidates2BrokerNotExistTest(); + // 增加优先被选举为controller的broker失败 + addControllerPreferredCandidates2FailedTest(); + // 增加优先被选举为controller的broker成功 + addControllerPreferredCandidates2SuccessTest(); + } + + private void addControllerPreferredCandidates2ParamIllegalTest() { + Result result1 = clusterService.addControllerPreferredCandidates(null, Arrays.asList(1)); + Assert.assertEquals(result1.getCode(), ResultStatus.PARAM_ILLEGAL.getCode()); + + Result result2 = clusterService.addControllerPreferredCandidates(1L, Collections.emptyList()); + Assert.assertEquals(result2.getCode(), ResultStatus.PARAM_ILLEGAL.getCode()); + } + + private void addControllerPreferredCandidates2BrokerNotExistTest() { + Result result1 = clusterService.addControllerPreferredCandidates(1L, Arrays.asList(100)); + Assert.assertEquals(result1.getCode(), ResultStatus.BROKER_NOT_EXIST.getCode()); + } + + private void addControllerPreferredCandidates2FailedTest() { + when(zookeeperService.addControllerPreferredCandidate(Mockito.anyLong(), Mockito.anyInt())).thenReturn(new Result(-1, "fail")); + Result result1 = clusterService.addControllerPreferredCandidates(1L, Arrays.asList(2)); + Assert.assertNotEquals(result1.getCode(), ResultStatus.SUCCESS.getCode()); + } + + private void addControllerPreferredCandidates2SuccessTest() { + when(zookeeperService.addControllerPreferredCandidate(Mockito.anyLong(), Mockito.anyInt())).thenReturn(new Result(0, "fail")); + Result result1 = clusterService.addControllerPreferredCandidates(1L, Arrays.asList(2)); + Assert.assertEquals(result1.getCode(), ResultStatus.SUCCESS.getCode()); + } + + @Test(description = "删除优先被选举为controller的broker") + public void deleteControllerPreferredCandidates() { + // 删除优先被选举为controller的broker时参数错误 + deleteControllerPreferredCandidates2ParamIllegal(); + // 删除优先被选举为controller的broker失败 + deleteControllerPreferredCandidates2FailedTest(); + // 删除优先被选举为controller的broker成功 + deleteControllerPreferredCandidates2SuccessTest(); + } + + private void deleteControllerPreferredCandidates2ParamIllegal() { + Result result1 = clusterService.deleteControllerPreferredCandidates(null, Arrays.asList(1)); + Assert.assertEquals(result1.getCode(), ResultStatus.PARAM_ILLEGAL.getCode()); + + Result result2 = clusterService.deleteControllerPreferredCandidates(1L, Collections.emptyList()); + Assert.assertEquals(result2.getCode(), ResultStatus.PARAM_ILLEGAL.getCode()); + } + + private void deleteControllerPreferredCandidates2FailedTest() { + when(zookeeperService.deleteControllerPreferredCandidate(Mockito.anyLong(), Mockito.anyInt())).thenReturn(new Result(-1, "fail")); + Result result1 = clusterService.deleteControllerPreferredCandidates(1L, Arrays.asList(2)); + Assert.assertNotEquals(result1.getCode(), ResultStatus.SUCCESS.getCode()); + } + + private void deleteControllerPreferredCandidates2SuccessTest() { + when(zookeeperService.deleteControllerPreferredCandidate(Mockito.anyLong(), Mockito.anyInt())).thenReturn(new Result(0, "fail")); + Result result1 = clusterService.deleteControllerPreferredCandidates(1L, Arrays.asList(2)); + Assert.assertEquals(result1.getCode(), ResultStatus.SUCCESS.getCode()); + } + +} diff --git a/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/LogicalClusterServiceTest.java b/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/LogicalClusterServiceTest.java new file mode 100644 index 00000000..4c4c2a92 --- /dev/null +++ b/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/LogicalClusterServiceTest.java @@ -0,0 +1,428 @@ +package com.xiaojukeji.kafka.manager.service.service; + +import com.xiaojukeji.kafka.manager.common.entity.ResultStatus; +import com.xiaojukeji.kafka.manager.common.entity.ao.cluster.LogicalCluster; +import com.xiaojukeji.kafka.manager.common.entity.ao.cluster.LogicalClusterMetrics; +import com.xiaojukeji.kafka.manager.common.entity.pojo.LogicalClusterDO; +import com.xiaojukeji.kafka.manager.common.entity.pojo.gateway.AppDO; +import com.xiaojukeji.kafka.manager.common.zookeeper.znode.brokers.BrokerMetadata; +import com.xiaojukeji.kafka.manager.common.zookeeper.znode.brokers.TopicMetadata; +import com.xiaojukeji.kafka.manager.dao.LogicalClusterDao; +import com.xiaojukeji.kafka.manager.service.cache.LogicalClusterMetadataManager; +import com.xiaojukeji.kafka.manager.service.config.BaseTest; +import com.xiaojukeji.kafka.manager.service.service.gateway.AppService; +import org.apache.kafka.clients.Metadata; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DuplicateKeyException; +import org.testng.Assert; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.util.*; + +/** + * @author xuguang + * @Date 2021/12/10 + */ +public class LogicalClusterServiceTest extends BaseTest { + + @Autowired + @InjectMocks + private LogicalClusterService logicalClusterService; + + @Mock + private LogicalClusterDao logicalClusterDao; + + @Mock + private LogicalClusterMetadataManager logicalClusterMetadataManager; + + @Mock + private AppService appService; + + @BeforeMethod + public void setup() { + MockitoAnnotations.initMocks(this); + } + + @DataProvider(name = "provideLogicalClusterDO") + public Object[][] provideLogicalClusterDO() { + LogicalClusterDO logicalClusterDO = new LogicalClusterDO(); + logicalClusterDO.setId(100L); + logicalClusterDO.setClusterId(1L); + logicalClusterDO.setIdentification("moduleTestLogicalCluster"); + logicalClusterDO.setName("moduleTestLogicalCluster"); + logicalClusterDO.setMode(1); + logicalClusterDO.setRegionList("2,3"); + logicalClusterDO.setAppId("moduleTest"); + logicalClusterDO.setGmtCreate(new Date()); + logicalClusterDO.setGmtModify(new Date()); + return new Object[][] {{logicalClusterDO}}; + } + + private LogicalClusterDO getLogicalClusterDO() { + LogicalClusterDO logicalClusterDO = new LogicalClusterDO(); + logicalClusterDO.setId(100L); + logicalClusterDO.setClusterId(1L); + logicalClusterDO.setIdentification("moduleTestLogicalCluster"); + logicalClusterDO.setName("moduleTestLogicalCluster"); + logicalClusterDO.setMode(0); + logicalClusterDO.setRegionList("2,3"); + logicalClusterDO.setAppId(""); + logicalClusterDO.setGmtCreate(new Date()); + logicalClusterDO.setGmtModify(new Date()); + return logicalClusterDO; + } + + public AppDO getAppDO() { + AppDO appDO = new AppDO(); + appDO.setId(4L); + appDO.setAppId("moduleTest"); + appDO.setName("moduleTestApp"); + appDO.setPassword("moduleTestApp"); + appDO.setType(1); + appDO.setApplicant("admin"); + appDO.setPrincipals("module"); + appDO.setDescription("moduleTestApp"); + appDO.setCreateTime(new Date(1638786493173L)); + appDO.setModifyTime(new Date(1638786493173L)); + return appDO; + } + + @Test(description = "创建逻辑集群时参数错误") + public void createLogicalCluster2paramIllegalTest() { + ResultStatus result = logicalClusterService.createLogicalCluster(null); + Assert.assertEquals(result.getCode(), ResultStatus.PARAM_ILLEGAL.getCode()); + } + + @Test(dataProvider = "provideLogicalClusterDO", description = "创建逻辑集群时,region已使用") + public void createLogicalCluster2existRegionAlreadyInUseTest(LogicalClusterDO logicalClusterDO) { + // 物理集群Id为null + logicalClusterDO.setClusterId(null); + ResultStatus result1 = logicalClusterService.createLogicalCluster(logicalClusterDO); + Assert.assertEquals(result1.getCode(), ResultStatus.RESOURCE_ALREADY_USED.getCode()); + + // regionList为空情况 + logicalClusterDO.setClusterId(1L); + logicalClusterDO.setRegionList(""); + ResultStatus result2 = logicalClusterService.createLogicalCluster(logicalClusterDO); + Assert.assertEquals(result2.getCode(), ResultStatus.RESOURCE_ALREADY_USED.getCode()); + + // region已存在使用 + logicalClusterDao.insert(logicalClusterDO); + ResultStatus result3 = logicalClusterService.createLogicalCluster(logicalClusterDO); + Assert.assertEquals(result3.getCode(), ResultStatus.RESOURCE_ALREADY_USED.getCode()); + } + + @Test(dataProvider = "provideLogicalClusterDO", description = "创建逻辑集群时,物理集群不存在") + public void createLogicalCluster2PhysicalClusterNotExistTest(LogicalClusterDO logicalClusterDO) { + Mockito.when(logicalClusterDao.insert(Mockito.any())).thenReturn(1); + // 不存在该物理集群情况 + logicalClusterDO.setClusterId(100L); + ResultStatus result1 = logicalClusterService.createLogicalCluster(logicalClusterDO); + Assert.assertNotEquals(result1.getCode(), ResultStatus.RESOURCE_ALREADY_USED.getCode()); + Assert.assertEquals(result1.getCode(), ResultStatus.SUCCESS.getCode()); + } + + @Test(dataProvider = "provideLogicalClusterDO", description = "创建逻辑集群时,不存在region已使用") + public void createLogicalCluster2NotexistRegionAlreadyInUseTest(LogicalClusterDO logicalClusterDO) { + Mockito.when(logicalClusterDao.insert(Mockito.any())).thenReturn(1); + // region没有存在使用 + ResultStatus result2 = logicalClusterService.createLogicalCluster(logicalClusterDO); + Assert.assertNotEquals(result2.getCode(), ResultStatus.RESOURCE_ALREADY_USED.getCode()); + Assert.assertEquals(result2.getCode(), ResultStatus.SUCCESS.getCode()); + } + + @Test(dataProvider = "provideLogicalClusterDO", description = "创建逻辑集群时,不存在region已使用") + public void createLogicalCluster2DuplicateKeyTest(LogicalClusterDO logicalClusterDO) { + Mockito.when(logicalClusterDao.insert(Mockito.any())).thenThrow(DuplicateKeyException.class); + logicalClusterDO.setRegionList("100"); + ResultStatus result3 = logicalClusterService.createLogicalCluster(logicalClusterDO); + Assert.assertEquals(result3.getCode(), ResultStatus.RESOURCE_ALREADY_EXISTED.getCode()); + } + + @Test(dataProvider = "provideLogicalClusterDO", description = "创建逻辑集群成功") + public void createLogicalCluster2SuccessTest(LogicalClusterDO logicalClusterDO) { + Mockito.when(logicalClusterDao.insert(Mockito.any())).thenReturn(1); + + ResultStatus result3 = logicalClusterService.createLogicalCluster(logicalClusterDO); + Assert.assertEquals(result3.getCode(), ResultStatus.SUCCESS.getCode()); + } + + @Test(dataProvider = "provideLogicalClusterDO", description = "通过物理集群ID查找") + public void getByPhysicalClusterIdTest(LogicalClusterDO logicalClusterDO) { + logicalClusterDO.setClusterId(2L); + logicalClusterDao.insert(logicalClusterDO); + List result = logicalClusterService.getByPhysicalClusterId(logicalClusterDO.getClusterId()); + Assert.assertFalse(result.isEmpty()); + Assert.assertTrue(result.stream().allMatch(logicalClusterDO1 -> + logicalClusterDO1.getClusterId().equals(logicalClusterDO.getClusterId()) && + logicalClusterDO1.getIdentification().equals(logicalClusterDO.getIdentification()))); + } + + @Test(dataProvider = "provideLogicalClusterDO", description = "通过逻辑集群ID查找") + public void getByIdTest(LogicalClusterDO logicalClusterDO) { + LogicalClusterDO result = logicalClusterService.getById(7L); + Assert.assertNotNull(result); + Assert.assertEquals(result.getIdentification(), logicalClusterDO.getIdentification()); + } + + @Test(description = "测试删除集群") + public void deleteByIdTest() { + // 删除集群成功 + deleteById2SuccessTest(); + // 删除集群时参数错误 + deleteById2paramIllegalTest(); + // 删除集群时无该集群 + deleteById2ResourceNotExistTest(); + // 删除集群时,mysqlError + deleteById2MysqlErrorTest(); + } + + private void deleteById2paramIllegalTest() { + ResultStatus resultStatus = logicalClusterService.deleteById(null); + Assert.assertEquals(resultStatus.getCode(), ResultStatus.PARAM_ILLEGAL.getCode()); + } + + private void deleteById2ResourceNotExistTest() { + Mockito.when(logicalClusterDao.deleteById(Mockito.anyLong())).thenReturn(-1); + + ResultStatus resultStatus = logicalClusterService.deleteById(100L); + Assert.assertEquals(resultStatus.getCode(), ResultStatus.RESOURCE_NOT_EXIST.getCode()); + } + + private void deleteById2MysqlErrorTest() { + Mockito.when(logicalClusterDao.deleteById(Mockito.anyLong())).thenThrow(RuntimeException.class); + + ResultStatus resultStatus = logicalClusterService.deleteById(7L); + Assert.assertEquals(resultStatus.getCode(), ResultStatus.MYSQL_ERROR.getCode()); + } + + private void deleteById2SuccessTest() { + Mockito.when(logicalClusterDao.deleteById(Mockito.anyLong())).thenReturn(1); + ResultStatus resultStatus = logicalClusterService.deleteById(7L); + Assert.assertEquals(resultStatus.getCode(), ResultStatus.SUCCESS.getCode()); + } + + @Test(dataProvider = "provideLogicalClusterDO", description = "修改集群时参数错误") + public void updateById2paramIllegalTest(LogicalClusterDO logicalClusterDO) { + logicalClusterDO.setId(null); + ResultStatus resultStatus = logicalClusterService.updateById(logicalClusterDO); + Assert.assertEquals(resultStatus.getCode(), ResultStatus.PARAM_ILLEGAL.getCode()); + + logicalClusterDO = null; + ResultStatus resultStatus2 = logicalClusterService.updateById(logicalClusterDO); + Assert.assertEquals(resultStatus2.getCode(), ResultStatus.PARAM_ILLEGAL.getCode()); + } + + @Test(dataProvider = "provideLogicalClusterDO", description = "修改集群时无对应逻辑集群") + public void updateById2ResourceNotExistTest(LogicalClusterDO logicalClusterDO) { + logicalClusterDO.setId(100L); + ResultStatus resultStatus2 = logicalClusterService.updateById(logicalClusterDO); + Assert.assertEquals(resultStatus2.getCode(), ResultStatus.RESOURCE_NOT_EXIST.getCode()); + } + + @Test(dataProvider = "provideLogicalClusterDO", description = "修改集群时,region已在使用") + public void updateById2existRegionAlreadyInUseTest(LogicalClusterDO logicalClusterDO) { + Mockito.when(logicalClusterDao.getById(Mockito.anyLong())).thenReturn(logicalClusterDO); + + // 物理集群Id为null + logicalClusterDO.setClusterId(null); + ResultStatus result1 = logicalClusterService.updateById(logicalClusterDO); + Assert.assertEquals(result1.getCode(), ResultStatus.RESOURCE_ALREADY_USED.getCode()); + + // regionList为空情况 + logicalClusterDO.setClusterId(1L); + logicalClusterDO.setRegionList(""); + ResultStatus result2 = logicalClusterService.updateById(logicalClusterDO); + Assert.assertEquals(result2.getCode(), ResultStatus.RESOURCE_ALREADY_USED.getCode()); + + // region已存在使用 + logicalClusterDao.insert(logicalClusterDO); + ResultStatus result3 = logicalClusterService.updateById(logicalClusterDO); + Assert.assertEquals(result3.getCode(), ResultStatus.RESOURCE_ALREADY_USED.getCode()); + } + + @Test(dataProvider = "provideLogicalClusterDO", description = "修改集群成功") + public void updateById2SuccessTest(LogicalClusterDO logicalClusterDO) { + Mockito.when(logicalClusterDao.updateById(Mockito.any())).thenReturn(1); + Mockito.when(logicalClusterDao.getById(Mockito.anyLong())).thenReturn(logicalClusterDO); + + ResultStatus result3 = logicalClusterService.updateById(logicalClusterDO); + Assert.assertEquals(result3.getCode(), ResultStatus.SUCCESS.getCode()); + } + + @Test(dataProvider = "provideLogicalClusterDO", description = "测试获取所有逻辑集群") + public void listAllTest(LogicalClusterDO logicalClusterDO) { + Mockito.when(logicalClusterDao.listAll()).thenReturn(Arrays.asList(logicalClusterDO)); + + List logicalClusterDOS = logicalClusterService.listAll(); + Assert.assertFalse(logicalClusterDOS.isEmpty()); + Assert.assertTrue(logicalClusterDOS.stream().allMatch(logicalClusterDO1 -> + logicalClusterDO1.getIdentification().equals(logicalClusterDO.getIdentification()))); + } + + @Test(dataProvider = "provideLogicalClusterDO", description = "从缓存中获取所有的逻辑集群") + public void getAllLogicalClusterTest(LogicalClusterDO logicalClusterDO) { + // 从缓存中获取所有的逻辑集群为空 + getAllLogicalCluster2NullTest(logicalClusterDO); + // 从缓存中获取所有的逻辑集群不为空 + getAllLogicalCluster2NotNullTest(logicalClusterDO); + } + + @Test(dataProvider = "provideLogicalClusterDO", description = "从缓存中获取所有的逻辑集群为空") + private void getAllLogicalCluster2NullTest(LogicalClusterDO logicalClusterDO) { + Mockito.when(logicalClusterMetadataManager.getLogicalClusterList()).thenReturn(Collections.emptyList()); + + List allLogicalCluster = logicalClusterService.getAllLogicalCluster(); + Assert.assertNotNull(allLogicalCluster); + Assert.assertTrue(allLogicalCluster.isEmpty()); + } + + @Test(dataProvider = "provideLogicalClusterDO", description = "从缓存中获取所有的逻辑集群不为空") + private void getAllLogicalCluster2NotNullTest(LogicalClusterDO logicalClusterDO) { + Mockito.when(logicalClusterMetadataManager.getLogicalClusterList()).thenReturn(Arrays.asList(logicalClusterDO)); + + List allLogicalCluster = logicalClusterService.getAllLogicalCluster(); + Assert.assertNotNull(allLogicalCluster); + Assert.assertEquals(allLogicalCluster.get(0).getLogicalClusterIdentification(), logicalClusterDO.getIdentification()); + } + + @Test(dataProvider = "provideLogicalClusterDO", description = "获取逻辑集群信息测试") + public void getLogicalClusterTest(LogicalClusterDO logicalClusterDO) { + // 获取逻辑集群信息失败 + getLogicalCluster2NullTest(); + // 测试获取逻辑集群成功 + getLogicalCluster2SuccessTest(logicalClusterDO); + } + + private void getLogicalCluster2NullTest() { + LogicalCluster logicalCluster = logicalClusterService.getLogicalCluster(100L); + Assert.assertNull(logicalCluster); + } + + private void getLogicalCluster2SuccessTest(LogicalClusterDO logicalClusterDO) { + Mockito.when(logicalClusterMetadataManager.getLogicalCluster(Mockito.anyLong())).thenReturn(logicalClusterDO); + + LogicalCluster logicalCluster = logicalClusterService.getLogicalCluster(logicalClusterDO.getId()); + Assert.assertNotNull(logicalCluster); + Assert.assertEquals(logicalCluster.getLogicalClusterIdentification(), logicalClusterDO.getIdentification()); + } + + @Test(dataProvider = "provideLogicalClusterDO", description = "获取逻辑集群信息测试") + public void getLogicalClusterListByPrincipal(LogicalClusterDO logicalClusterDO) { + // 责任人为空 + getLogicalClusterListByPrincipal2PrincipalIsBlankTest(); + // 获取的appDOList为空 + getLogicalClusterListByPrincipal2AppIsEmptyTest(); + // 完整流程 + getLogicalClusterListByPrincipal2Test(logicalClusterDO); + } + + private void getLogicalClusterListByPrincipal2PrincipalIsBlankTest() { + Mockito.when(logicalClusterMetadataManager.getLogicalClusterList()).thenReturn(Collections.emptyList()); + + List list = logicalClusterService.getLogicalClusterListByPrincipal(""); + Assert.assertNotNull(list); + Assert.assertTrue(list.isEmpty()); + } + + private void getLogicalClusterListByPrincipal2AppIsEmptyTest() { + Mockito.when(logicalClusterMetadataManager.getLogicalClusterList()).thenReturn(Collections.emptyList()); + Mockito.when(appService.getByPrincipal(Mockito.anyString())).thenReturn(Collections.emptyList()); + + List list = logicalClusterService.getLogicalClusterListByPrincipal("admin"); + Assert.assertNotNull(list); + Assert.assertTrue(list.isEmpty()); + } + + private void getLogicalClusterListByPrincipal2Test(LogicalClusterDO logicalClusterDO) { + List LogicalClusterDOList = new ArrayList<>(); + LogicalClusterDOList.add(logicalClusterDO); + LogicalClusterDOList.add(getLogicalClusterDO()); + Mockito.when(logicalClusterMetadataManager.getLogicalClusterList()).thenReturn(LogicalClusterDOList); + Mockito.when(appService.getByPrincipal(Mockito.anyString())).thenReturn(Arrays.asList(getAppDO())); + + List list = logicalClusterService.getLogicalClusterListByPrincipal("module"); + Assert.assertNotNull(list); + Assert.assertEquals(list.size(), 2); + Assert.assertTrue(list.stream().allMatch(logicalCluster -> + logicalCluster.getLogicalClusterName().equals(logicalClusterDO.getName()))); + } + + @Test(dataProvider = "provideLogicalClusterDO", description = "逻辑集群下Topic元信息测试") + public void getTopicMetadatasTest(LogicalClusterDO logicalClusterDO) { + // 传入的logicalClusterDO为空 + getTopicMetadatas2ParamisNullTest(); + // 获取逻辑集群下Topic元信息成功 + getTopicMetadatas2SuccessTest(logicalClusterDO); + } + + private void getTopicMetadatas2ParamisNullTest() { + List topicMetadatas = logicalClusterService.getTopicMetadatas(null); + Assert.assertTrue(topicMetadatas.isEmpty()); + } + + private void getTopicMetadatas2SuccessTest(LogicalClusterDO logicalClusterDO) { + Set set = new HashSet<>(); + set.add("xgTest"); + set.add("topicTest"); + Mockito.when(logicalClusterMetadataManager.getTopicNameSet(Mockito.anyLong())) + .thenReturn(set); + + List topicMetadatas = logicalClusterService.getTopicMetadatas(logicalClusterDO); + Assert.assertFalse(topicMetadatas.isEmpty()); + Assert.assertTrue(topicMetadatas.stream().allMatch(topicMetadata -> + topicMetadata.getTopic().equals("xgTest"))); + } + + @Test(dataProvider = "provideLogicalClusterDO", description = "逻辑集群下broker元信息测试") + public void getBrokerMetadatasTest(LogicalClusterDO logicalClusterDO) { + // 传入的logicalClusterDO为空 + getBrokerMetadatas2ParamisNullTest(); + // 获取逻辑集群下broker元信息成功 + getTopicBroker2SuccessTest(logicalClusterDO); + } + + private void getBrokerMetadatas2ParamisNullTest() { + List brokerMetadatas = logicalClusterService.getBrokerMetadatas(null); + Assert.assertTrue(brokerMetadatas.isEmpty()); + } + + private void getTopicBroker2SuccessTest(LogicalClusterDO logicalClusterDO) { + Set set = new HashSet<>(); + set.add(1); + set.add(111); + Mockito.when(logicalClusterMetadataManager.getBrokerIdSet(Mockito.anyLong())) + .thenReturn(set); + + List brokerMetadatas = logicalClusterService.getBrokerMetadatas(logicalClusterDO); + Assert.assertFalse(brokerMetadatas.isEmpty()); + Assert.assertTrue(brokerMetadatas.stream().allMatch(brokerMetadata -> + brokerMetadata.getBrokerId() == 1)); + } + + @Test(dataProvider = "provideLogicalClusterDO", description = "获取逻辑集群流量测试") + public void getLogicalClusterMetricsFromDBTest(LogicalClusterDO logicalClusterDO) { + Set set = new HashSet<>(); + set.add(1); + set.add(111); + Mockito.when(logicalClusterMetadataManager.getBrokerIdSet(Mockito.anyLong())) + .thenReturn(set); + + long startTime = 1639360565000L; + long endTime = 1639407365000L; + List list = logicalClusterService.getLogicalClusterMetricsFromDB( + logicalClusterDO, new Date(startTime), new Date(endTime)); + Assert.assertFalse(list.isEmpty()); + Assert.assertTrue(list.stream().allMatch(logicalClusterMetrics -> + logicalClusterMetrics.getGmtCreate().compareTo(startTime) > 0 && + logicalClusterMetrics.getGmtCreate().compareTo(endTime) < 0)); + } + + +} diff --git a/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/ZookeeperServiceTest.java b/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/ZookeeperServiceTest.java new file mode 100644 index 00000000..d7db6352 --- /dev/null +++ b/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/ZookeeperServiceTest.java @@ -0,0 +1,235 @@ +package com.xiaojukeji.kafka.manager.service.service; + +import com.xiaojukeji.kafka.manager.common.entity.Result; +import com.xiaojukeji.kafka.manager.common.entity.ResultStatus; +import com.xiaojukeji.kafka.manager.common.exception.ConfigException; +import com.xiaojukeji.kafka.manager.common.zookeeper.ZkConfigImpl; +import com.xiaojukeji.kafka.manager.common.zookeeper.ZkPathUtil; +import com.xiaojukeji.kafka.manager.common.zookeeper.znode.didi.TopicJmxSwitch; +import com.xiaojukeji.kafka.manager.service.config.BaseTest; +import org.mockito.MockitoAnnotations; +import org.springframework.beans.factory.annotation.Autowired; +import org.testng.Assert; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.util.List; + +/** + * @author xuguang + * @Date 2021/12/9 + */ +public class ZookeeperServiceTest extends BaseTest { + + @Autowired + private ZookeeperService zookeeperService; + + private final static String ZOOKEEPER_ADDRESS = "10.190.46.198:2181,10.190.14.237:2181,10.190.50.65:2181/xg"; + + @DataProvider(name = "extendsAndCandidatesZnodeExist") + public static Object[][] extendsAndCandidatesZnodeExist() { + // zk中 config下extends节点是否存在,extends节点下candidates节点是否存在 + return new Object[][] {{false, false}, {false, true}, {true, false}, {true, true}}; + } + + @BeforeMethod + public void setup() { + MockitoAnnotations.initMocks(this); + } + + @Test(description = "开启JMX参数测试") + public void openTopicJmxTest() { + // 开启JMX参数有误 + openTopicJmx2ParamIllegalTest(); + // 开启JMX, 无topic + openTopicJmx2TopicNotExistTest(); + // 开启JMX成功 + openTopicJmx2SuccessTest(); + } + + private void openTopicJmx2ParamIllegalTest() { + Result result1 = zookeeperService.openTopicJmx(null, "xgTest", null); + Assert.assertEquals(result1.getCode(), ResultStatus.PARAM_ILLEGAL.getCode()); + + Result result2 = zookeeperService.openTopicJmx(1L, null, null); + Assert.assertEquals(result2.getCode(), ResultStatus.PARAM_ILLEGAL.getCode()); + } + + private void openTopicJmx2TopicNotExistTest() { + Result result1 = zookeeperService.openTopicJmx(1L, "xgTestxxx", + new TopicJmxSwitch(true, true, true)); + Assert.assertEquals(result1.getCode(), ResultStatus.TOPIC_NOT_EXIST.getCode()); + } + + private void openTopicJmx2SuccessTest() { + Result result1 = zookeeperService.openTopicJmx(1L, "xgTest", + new TopicJmxSwitch(true, true, true)); + Assert.assertEquals(result1.getCode(), ResultStatus.SUCCESS.getCode()); + } + + @Test(description = "获取优先被选举为controller的broker") + public void getControllerPreferredCandidatesTest() throws ConfigException { + // 获取优先被选举为controller的broker时参数错误 + getControllerPreferredCandidates2ParamIllegalTest(); + // 获取优先被选举为controller的broker时参数错误 + getControllerPreferredCandidates2ZookeeperConnectFailedTest(); + // 获取优先被选举为controller的broker时, zk路径不存在 + getControllerPreferredCandidates2NoZkRootTest(); + // 获取优先被选举为controller的broker时,broker为空 + getControllerPreferredCandidates2BrokerEmptyTest(); + // 获取优先被选举为controller的broker成功 + getControllerPreferredCandidates2SuccessTest(); + } + + private void getControllerPreferredCandidates2ParamIllegalTest() { + Result> brokerIds = zookeeperService.getControllerPreferredCandidates(null); + Assert.assertEquals(brokerIds.getCode(), ResultStatus.PARAM_ILLEGAL.getCode()); + } + + private void getControllerPreferredCandidates2ZookeeperConnectFailedTest() { + Result> brokerIds = zookeeperService.getControllerPreferredCandidates(100L); + Assert.assertEquals(brokerIds.getCode(), ResultStatus.ZOOKEEPER_CONNECT_FAILED.getCode()); + } + + private void getControllerPreferredCandidates2NoZkRootTest() { + Result> brokerIds = zookeeperService.getControllerPreferredCandidates(1L); + Assert.assertEquals(brokerIds.getCode(), ResultStatus.SUCCESS.getCode()); + Assert.assertTrue(brokerIds.getData().isEmpty()); + } + + private void getControllerPreferredCandidates2BrokerEmptyTest() throws ConfigException { + ZkConfigImpl zkConfig = new ZkConfigImpl(ZOOKEEPER_ADDRESS); + zkConfig.setOrCreatePersistentNodeStat(ZkPathUtil.D_CONFIG_EXTENSION_ROOT_NODE, ""); + zkConfig.setOrCreatePersistentNodeStat(ZkPathUtil.D_CONTROLLER_CANDIDATES, ""); + + Result> brokerIds = zookeeperService.getControllerPreferredCandidates(1L); + Assert.assertEquals(brokerIds.getCode(), ResultStatus.SUCCESS.getCode()); + Assert.assertTrue(brokerIds.getData().isEmpty()); + + zkConfig.delete(ZkPathUtil.D_CONTROLLER_CANDIDATES); + zkConfig.delete(ZkPathUtil.D_CONFIG_EXTENSION_ROOT_NODE); + zkConfig.close(); + } + + private void getControllerPreferredCandidates2SuccessTest() throws ConfigException { + ZkConfigImpl zkConfig = new ZkConfigImpl(ZOOKEEPER_ADDRESS); + zkConfig.setOrCreatePersistentNodeStat(ZkPathUtil.D_CONFIG_EXTENSION_ROOT_NODE, ""); + zkConfig.setOrCreatePersistentNodeStat(ZkPathUtil.D_CONTROLLER_CANDIDATES, ""); + zkConfig.setOrCreatePersistentNodeStat(ZkPathUtil.D_CONTROLLER_CANDIDATES + "/1", ""); + + Result> brokerIds = zookeeperService.getControllerPreferredCandidates(1L); + Assert.assertEquals(brokerIds.getCode(), ResultStatus.SUCCESS.getCode()); + Assert.assertFalse(brokerIds.getData().isEmpty()); + Assert.assertEquals(brokerIds.getData().get(0), Integer.valueOf(1)); + + zkConfig.delete(ZkPathUtil.D_CONTROLLER_CANDIDATES + "/1"); + zkConfig.delete(ZkPathUtil.D_CONTROLLER_CANDIDATES); + zkConfig.delete(ZkPathUtil.D_CONFIG_EXTENSION_ROOT_NODE); + zkConfig.close(); + } + + @Test(dataProvider = "extendsAndCandidatesZnodeExist", description = "增加优先被选举为controller的broker") + public void addControllerPreferredCandidateTest(boolean extendsExist, boolean candidatesExist) throws ConfigException { + // 增加优先被选举为controller的broker时参数错误 + addControllerPreferredCandidate2ParamIllegalTest(); + // 增加优先被选举为controller的broker时,zk无法连接 + addControllerPreferredCandidate2zkConnectFailedTest(); + // 增加优先被选举为controller的broker时,节点已经存在 + addControllerPreferredCandidate2zkExistTest(); + // 增加优先被选举为controller的broker成功,四种情况 + addControllerPreferredCandidate2SuccessTest(extendsExist, candidatesExist); + } + + private void addControllerPreferredCandidate2ParamIllegalTest() { + Result result = zookeeperService.addControllerPreferredCandidate(null, 100); + Assert.assertEquals(result.getCode(),ResultStatus.PARAM_ILLEGAL.getCode()); + } + + private void addControllerPreferredCandidate2zkConnectFailedTest() { + Result result = zookeeperService.addControllerPreferredCandidate(100L, 100); + Assert.assertEquals(result.getCode(),ResultStatus.ZOOKEEPER_CONNECT_FAILED.getCode()); + } + + private void addControllerPreferredCandidate2zkExistTest() throws ConfigException { + ZkConfigImpl zkConfig = new ZkConfigImpl(ZOOKEEPER_ADDRESS); + zkConfig.setOrCreatePersistentNodeStat(ZkPathUtil.D_CONFIG_EXTENSION_ROOT_NODE, ""); + zkConfig.setOrCreatePersistentNodeStat(ZkPathUtil.D_CONTROLLER_CANDIDATES, ""); + zkConfig.setOrCreatePersistentNodeStat(ZkPathUtil.D_CONTROLLER_CANDIDATES + "/1", ""); + + Result result = zookeeperService.addControllerPreferredCandidate(1L, 1); + Assert.assertEquals(result.getCode(),ResultStatus.SUCCESS.getCode()); + + zkConfig.delete(ZkPathUtil.D_CONTROLLER_CANDIDATES + "/1"); + zkConfig.delete(ZkPathUtil.D_CONTROLLER_CANDIDATES); + zkConfig.delete(ZkPathUtil.D_CONFIG_EXTENSION_ROOT_NODE); + zkConfig.close(); + } + + private void addControllerPreferredCandidate2SuccessTest(boolean extendsExist, boolean candidatesExist) throws ConfigException { + ZkConfigImpl zkConfig = new ZkConfigImpl(ZOOKEEPER_ADDRESS); + if (extendsExist) { + zkConfig.setOrCreatePersistentNodeStat(ZkPathUtil.D_CONFIG_EXTENSION_ROOT_NODE, ""); + } + if (extendsExist && candidatesExist) { + zkConfig.setOrCreatePersistentNodeStat(ZkPathUtil.D_CONTROLLER_CANDIDATES, ""); + } + + Result result = zookeeperService.addControllerPreferredCandidate(1L, 1); + Assert.assertEquals(result.getCode(),ResultStatus.SUCCESS.getCode()); + + zkConfig.delete(ZkPathUtil.D_CONTROLLER_CANDIDATES + "/1"); + zkConfig.delete(ZkPathUtil.D_CONTROLLER_CANDIDATES); + zkConfig.delete(ZkPathUtil.D_CONFIG_EXTENSION_ROOT_NODE); + zkConfig.close(); + } + + @Test(description = "减少优先被选举为controller的broker") + public void deleteControllerPreferredCandidate() throws ConfigException { + // 减少优先被选举为controller的broker时参数错误 + deleteControllerPreferredCandidate2ParamIllegalTest(); + // 减少优先被选举为controller的broker时,zk无法连接 + deleteControllerPreferredCandidate2zkConnectFailedTest(); + // 减少优先被选举为controller的broker时,节点已经存在 + addControllerPreferredCandidate2zkNodeNotExistTest(); + // 减少优先被选举为controller的broker成功 + addControllerPreferredCandidate2SuccessTest(); + } + + private void deleteControllerPreferredCandidate2ParamIllegalTest() { + Result result = zookeeperService.deleteControllerPreferredCandidate(null, 100); + Assert.assertEquals(result.getCode(), ResultStatus.PARAM_ILLEGAL.getCode()); + } + + private void deleteControllerPreferredCandidate2zkConnectFailedTest() { + Result result = zookeeperService.addControllerPreferredCandidate(100L, 100); + Assert.assertEquals(result.getCode(), ResultStatus.ZOOKEEPER_CONNECT_FAILED.getCode()); + } + + private void addControllerPreferredCandidate2zkNodeNotExistTest() throws ConfigException { + ZkConfigImpl zkConfig = new ZkConfigImpl(ZOOKEEPER_ADDRESS); + zkConfig.setOrCreatePersistentNodeStat(ZkPathUtil.D_CONFIG_EXTENSION_ROOT_NODE, ""); + zkConfig.setOrCreatePersistentNodeStat(ZkPathUtil.D_CONTROLLER_CANDIDATES, ""); + + Result result = zookeeperService.deleteControllerPreferredCandidate(1L, 1); + Assert.assertEquals(result.getCode(), ResultStatus.SUCCESS.getCode()); + + zkConfig.delete(ZkPathUtil.D_CONTROLLER_CANDIDATES); + zkConfig.delete(ZkPathUtil.D_CONFIG_EXTENSION_ROOT_NODE); + zkConfig.close(); + } + + private void addControllerPreferredCandidate2SuccessTest() throws ConfigException { + ZkConfigImpl zkConfig = new ZkConfigImpl(ZOOKEEPER_ADDRESS); + zkConfig.setOrCreatePersistentNodeStat(ZkPathUtil.D_CONFIG_EXTENSION_ROOT_NODE, ""); + zkConfig.setOrCreatePersistentNodeStat(ZkPathUtil.D_CONTROLLER_CANDIDATES, ""); + zkConfig.setOrCreatePersistentNodeStat(ZkPathUtil.D_CONTROLLER_CANDIDATES + "/1", ""); + + Result result = zookeeperService.deleteControllerPreferredCandidate(1L, 1); + Assert.assertEquals(result.getCode(), ResultStatus.SUCCESS.getCode()); + + zkConfig.delete(ZkPathUtil.D_CONTROLLER_CANDIDATES); + zkConfig.delete(ZkPathUtil.D_CONFIG_EXTENSION_ROOT_NODE); + zkConfig.close(); + } +} diff --git a/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/gateway/AuthorityServiceTest.java b/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/gateway/AuthorityServiceTest.java index ac8475be..2e192fcf 100644 --- a/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/gateway/AuthorityServiceTest.java +++ b/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/gateway/AuthorityServiceTest.java @@ -1,14 +1,22 @@ package com.xiaojukeji.kafka.manager.service.service.gateway; +import com.xiaojukeji.kafka.manager.common.bizenum.TopicAuthorityEnum; import com.xiaojukeji.kafka.manager.common.entity.ResultStatus; +import com.xiaojukeji.kafka.manager.common.entity.ao.gateway.TopicQuota; import com.xiaojukeji.kafka.manager.common.entity.pojo.gateway.AuthorityDO; import com.xiaojukeji.kafka.manager.service.config.BaseTest; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; import org.testng.Assert; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.annotation.Rollback; +import org.testng.annotations.BeforeMethod; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; @@ -26,17 +34,31 @@ public class AuthorityServiceTest extends BaseTest { public Object[][] provideAuthorityDO() { AuthorityDO authorityDO = new AuthorityDO(); authorityDO.setId(4L); - authorityDO.setAppId("testAppId"); + authorityDO.setAppId("appIdModuleTest"); authorityDO.setClusterId(1L); - authorityDO.setTopicName("moduleTest"); + authorityDO.setTopicName("topicModuleTest"); authorityDO.setAccess(2); authorityDO.setCreateTime(new Date(1638786493173L)); authorityDO.setModifyTime(new Date(1638786493173L)); return new Object[][] {{authorityDO}}; } + public TopicQuota getTopicQuota() { + TopicQuota topicQuotaDO = new TopicQuota(); + topicQuotaDO.setAppId("testAppId"); + topicQuotaDO.setClusterId(1L); + topicQuotaDO.setTopicName("moduleTest"); + topicQuotaDO.setProduceQuota(100000L); + topicQuotaDO.setConsumeQuota(100000L); + return topicQuotaDO; + } + + @BeforeMethod + public void setup() { + MockitoAnnotations.initMocks(this); + } + @Test(dataProvider = "provideAuthorityDO") - @Rollback(value = false) public void addAuthorityTest(AuthorityDO authorityDO) { // 测试新增权限对象 addNewAuthority(authorityDO); @@ -46,40 +68,37 @@ public class AuthorityServiceTest extends BaseTest { addNewAuthorityAccessTest(authorityDO); // 测试新增权限失败 addNewAuthority2Failure(); - } private void addNewAuthority(AuthorityDO authorityDO) { int result = authorityService.addAuthority(authorityDO); - Assert.assertEquals( 1, result); + Assert.assertEquals(result, 1); } private void newAccessEqualOldAccessTest(AuthorityDO authorityDO) { int result = authorityService.addAuthority(authorityDO); - Assert.assertEquals( 0, result); + Assert.assertEquals(result, 0); } private void addNewAuthorityAccessTest(AuthorityDO authorityDO) { authorityDO.setAccess(3); int result = authorityService.addAuthority(authorityDO); - Assert.assertEquals( 1, result); + Assert.assertEquals(result, 1); } private void addNewAuthority2Failure() { int result = authorityService.addAuthority(new AuthorityDO()); - Assert.assertEquals( 0, result); + Assert.assertEquals(result, 0); } - public void deleteSpecifiedAccess() { + @Test(dataProvider = "provideAuthorityDO", description = "测试删除权限对象") + public void deleteSpecifiedAccess(AuthorityDO authorityDO) { // 测试删除权限对象时无该对象 deleteSpecifiedAccess2AuthorityNotExist(); - - // 测试删除权限对象时参数错误, 传入的access为3,数据库中为2 - deleteSpecifiedAccess2ParamIllegal(); - - // 测试删除权限对象成功,传入的access为3,数据库中为3 - deleteSpecifiedAccess2Success(); - + // 测试删除权限对象时参数错误 + deleteSpecifiedAccess2ParamIllegal(authorityDO); + // 测试删除权限对象成功 + deleteSpecifiedAccess2Success(authorityDO); } private void deleteSpecifiedAccess2AuthorityNotExist() { @@ -87,37 +106,57 @@ public class AuthorityServiceTest extends BaseTest { Assert.assertEquals(ResultStatus.AUTHORITY_NOT_EXIST.getCode(), result.getCode()); } - private void deleteSpecifiedAccess2ParamIllegal() { - ResultStatus result = authorityService.deleteSpecifiedAccess("dkm_admin", 1L, "xgTest", 3, "admin"); - Assert.assertEquals(ResultStatus.PARAM_ILLEGAL.getCode(), result.getCode()); + private void deleteSpecifiedAccess2ParamIllegal(AuthorityDO authorityDO) { + authorityService.addAuthority(authorityDO); + + ResultStatus result = authorityService.deleteSpecifiedAccess( + authorityDO.getAppId(), + authorityDO.getClusterId(), + authorityDO.getTopicName(), + 3, "admin" + ); + Assert.assertEquals(result.getCode(), ResultStatus.PARAM_ILLEGAL.getCode()); } - private void deleteSpecifiedAccess2Success() { - ResultStatus result = authorityService.deleteSpecifiedAccess("dkm_admin", 1L, "xgTest", 3, "admin"); + private void deleteSpecifiedAccess2Success(AuthorityDO authorityDO) { + authorityDO.setAccess(3); + authorityDO.setAppId("sss"); + authorityService.addAuthority(authorityDO); + + ResultStatus result = authorityService.deleteSpecifiedAccess( + authorityDO.getAppId(), + authorityDO.getClusterId(), + authorityDO.getTopicName(), + 3, "admin" + ); Assert.assertEquals(ResultStatus.SUCCESS.getCode(), result.getCode()); } - @Test(dataProvider = "provideAuthorityDO") + @Test(dataProvider = "provideAuthorityDO", description = "测试查询") public void getAuthorityTest(AuthorityDO authorityDO) { // 测试查询成功 getAuthority2SuccessTest(authorityDO); // 测试查询为null - getAuthority2NullTest(authorityDO); - + getAuthority2NullTest(); } private void getAuthority2SuccessTest(AuthorityDO authorityDO) { - AuthorityDO result = authorityService.getAuthority(1L, "moduleTest", "testAppId"); - Assert.assertEquals(result.toString(), authorityDO.toString()); + authorityService.addAuthority(authorityDO); + + AuthorityDO result = authorityService.getAuthority(authorityDO.getClusterId(), authorityDO.getTopicName(), authorityDO.getAppId()); + Assert.assertEquals(result.getClusterId(), authorityDO.getClusterId()); + Assert.assertEquals(result.getAppId(), authorityDO.getAppId()); + Assert.assertEquals(result.getTopicName(), authorityDO.getTopicName()); + Assert.assertEquals(result.getAccess(), authorityDO.getAccess()); } - private void getAuthority2NullTest(AuthorityDO authorityDO) { + private void getAuthority2NullTest() { AuthorityDO result = authorityService.getAuthority(10L, "moduleTest", "testAppId"); Assert.assertNull(result); } - @Test(dataProvider = "provideAuthorityDO") - public void getAuthorityByTopic(AuthorityDO authorityDO) { + @Test(dataProvider = "provideAuthorityDO", description = "测试查询") + public void getAuthorityByTopicTest(AuthorityDO authorityDO) { // 测试查询成功 getAuthorityByTopic2SuccessTest(authorityDO); // 测试查询为null @@ -125,29 +164,36 @@ public class AuthorityServiceTest extends BaseTest { } private void getAuthorityByTopic2SuccessTest(AuthorityDO authorityDO) { - List result = authorityService.getAuthorityByTopic(1L, "moduleTest"); - Assert.assertEquals(result.size(), 1); - Assert.assertEquals(result.get(0).toString(), authorityDO.toString()); + authorityService.addAuthority(authorityDO); + + List result = authorityService.getAuthorityByTopic(authorityDO.getClusterId(), authorityDO.getTopicName()); + Assert.assertNotNull(result); + Assert.assertTrue(result.stream() + .allMatch(authorityDO1 -> authorityDO1.getTopicName().equals(authorityDO.getTopicName()) && + authorityDO1.getClusterId().equals(authorityDO.getClusterId()))); } private void getAuthorityByTopic2NullTest() { - List result = authorityService.getAuthorityByTopic(10L, "moduleTest"); + List result = authorityService.getAuthorityByTopic(100L, "moduleTestxxx"); Assert.assertTrue(result.isEmpty()); } - @Test(dataProvider = "provideAuthorityDO") + @Test(dataProvider = "provideAuthorityDO", description = "测试查询") public void getAuthorityByAppIdTest(AuthorityDO authorityDO) { // 测试查询成功 getAuthorityByAppId2SuccessTest(authorityDO); - // 测试查询为null getAuthorityByAppId2NullTest(); } private void getAuthorityByAppId2SuccessTest(AuthorityDO authorityDO) { - List result = authorityService.getAuthority("testAppId"); - Assert.assertEquals(result.size(), 1); - Assert.assertEquals(result.get(0).toString(), authorityDO.toString()); + authorityService.addAuthority(authorityDO); + + List result = authorityService.getAuthority(authorityDO.getAppId()); + Assert.assertNotNull(result); + Assert.assertTrue(result.stream(). + allMatch(authorityDO1 -> authorityDO1.getAppId().equals(authorityDO.getAppId()) && + !authorityDO1.getAccess().equals(TopicAuthorityEnum.DENY.getCode()))); } private void getAuthorityByAppId2NullTest() { @@ -155,42 +201,58 @@ public class AuthorityServiceTest extends BaseTest { Assert.assertTrue(result.isEmpty()); } - @Test - public void listAllTest() { + @Test(dataProvider = "provideAuthorityDO") + public void listAllTest(AuthorityDO authorityDO) { + authorityService.addAuthority(authorityDO); + List result = authorityService.listAll(); - Assert.assertEquals(result.size(), 2); + Assert.assertEquals(result.size(), 1); } - @Test + @Test(dataProvider = "provideAuthorityDO", description = "添加权限和quota") public void addAuthorityAndQuotaTest(AuthorityDO authorityDO) { - + // 添加权限和quota成功 + addAuthorityAndQuota2SuccessTest(authorityDO); + // 添加权限和quota失败 + addAuthorityAndQuota2FaliureTest(authorityDO); } private void addAuthorityAndQuota2SuccessTest(AuthorityDO authorityDO) { - + int result = authorityService.addAuthorityAndQuota(authorityDO, getTopicQuota()); + Assert.assertEquals(result, 1); } - @Test - public void getAllAuthorityTest() { + private void addAuthorityAndQuota2FaliureTest(AuthorityDO authorityDO) { + authorityService.addAuthority(authorityDO); + // 重复插入 + int result2 = authorityService.addAuthorityAndQuota(authorityDO, getTopicQuota()); + Assert.assertEquals(result2, 0); + } + + @Test(dataProvider = "provideAuthorityDO") + public void getAllAuthorityTest(AuthorityDO authorityDO) { + authorityService.addAuthority(authorityDO); + Map>> allAuthority = authorityService.getAllAuthority(); - Assert.assertEquals(allAuthority.size(), 2); + Assert.assertEquals(allAuthority.size(), 1); } - @Test - public void deleteAuthorityByTopicTest() { - // 测试查询成功 - deleteAuthorityByTopic2SuccessTest(); - // 测试查询为null + @Test(dataProvider = "provideAuthorityDO", description = "测试删除") + public void deleteAuthorityByTopicTest(AuthorityDO authorityDO) { + // 测试删除成功 + deleteAuthorityByTopic2SuccessTest(authorityDO); + // 测试删除失败 deleteAuthorityByTopic2FailureTest(); } - private void deleteAuthorityByTopic2SuccessTest() { - int result = authorityService.deleteAuthorityByTopic(1L, "moduleTest"); + private void deleteAuthorityByTopic2SuccessTest(AuthorityDO authorityDO) { + authorityService.addAuthority(authorityDO); + int result = authorityService.deleteAuthorityByTopic(authorityDO.getClusterId(), authorityDO.getTopicName()); Assert.assertEquals(result, 1); } private void deleteAuthorityByTopic2FailureTest() { - int result = authorityService.deleteAuthorityByTopic(10L, "moduleTest"); + int result = authorityService.deleteAuthorityByTopic(100L, "moduleTest"); Assert.assertEquals(result, 0); } } diff --git a/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/gateway/SecurityServiceTest.java b/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/gateway/SecurityServiceTest.java new file mode 100644 index 00000000..7825746f --- /dev/null +++ b/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/gateway/SecurityServiceTest.java @@ -0,0 +1,76 @@ +package com.xiaojukeji.kafka.manager.service.service.gateway; + +import com.xiaojukeji.kafka.manager.common.entity.pojo.gateway.KafkaAclDO; +import com.xiaojukeji.kafka.manager.common.entity.pojo.gateway.KafkaUserDO; +import com.xiaojukeji.kafka.manager.dao.gateway.KafkaAclDao; +import com.xiaojukeji.kafka.manager.dao.gateway.KafkaUserDao; +import com.xiaojukeji.kafka.manager.service.config.BaseTest; +import org.springframework.beans.factory.annotation.Autowired; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.util.Date; +import java.util.List; + +/** + * @author xuguang + * @Date 2021/12/7 + */ +public class SecurityServiceTest extends BaseTest { + + @Autowired + private SecurityService securityService; + + @Autowired + private KafkaUserDao kafkaUserDao; + + @Autowired + private KafkaAclDao kafkaAclDao; + + @DataProvider(name = "provideKafkaUserDO") + public static Object[][] provideKafkaUserDO() { + KafkaUserDO kafkaUserDO = new KafkaUserDO(); + kafkaUserDO.setAppId("AppIdModuleTest"); + kafkaUserDO.setPassword("AppIdTest"); + kafkaUserDO.setUserType(1); + kafkaUserDO.setOperation(0); + return new Object[][] {{kafkaUserDO}}; + } + + @DataProvider(name = "provideKafkaAclDO") + public static Object[][] provideKafkaAclDO() { + KafkaAclDO kafkaAclDO = new KafkaAclDO(); + kafkaAclDO.setAppId("AppIdModuleTest"); + kafkaAclDO.setClusterId(1L); + kafkaAclDO.setTopicName("topicModuleTest"); + kafkaAclDO.setAccess(3); + kafkaAclDO.setOperation(0); + return new Object[][] {{kafkaAclDO}}; + } + + @Test(dataProvider = "provideKafkaUserDO") + public void getKafkaUsersTest(KafkaUserDO kafkaUserDO) { + kafkaUserDao.insert(kafkaUserDO); + + long now = System.currentTimeMillis(); + List kafkaUsers = securityService.getKafkaUsers(0L, now); + Assert.assertFalse(kafkaUsers.isEmpty()); + Assert.assertTrue(kafkaUsers.stream() + .allMatch( kafkaUser -> kafkaUser.getCreateTime().after(new Date(0L)) && + kafkaUser.getCreateTime().before( new Date(now)))); + } + + @Test(dataProvider = "provideKafkaAclDO") + public void getKafkaAclsTest(KafkaAclDO kafkaAclDO) { + kafkaAclDao.insert(kafkaAclDO); + + long now = System.currentTimeMillis(); + List kafkaAcls = securityService.getKafkaAcls(kafkaAclDO.getClusterId(), 0L, now); + Assert.assertFalse(kafkaAcls.isEmpty()); + Assert.assertTrue(kafkaAcls.stream() + .allMatch(kafkaUser -> kafkaUser.getCreateTime().after(new Date(0L)) && + kafkaUser.getCreateTime().before( new Date(now)) && + kafkaUser.getClusterId().equals(kafkaAclDO.getClusterId()))); + } +} diff --git a/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/gateway/TopicReportServiceTest.java b/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/gateway/TopicReportServiceTest.java index 82a4c8b3..ae662854 100644 --- a/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/gateway/TopicReportServiceTest.java +++ b/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/gateway/TopicReportServiceTest.java @@ -40,8 +40,15 @@ public class TopicReportServiceTest extends BaseTest { public void getNeedReportTopicTest(TopicReportDO topicReportDO) { // 数据库中插入数据 int replace = topicReportDao.replace(topicReportDO); + List result = topicReportService.getNeedReportTopic(1L); Assert.assertEquals(result.size(), 1); Assert.assertEquals(result.get(0).toString(), topicReportDO.toString()); } + + @Test(dataProvider = "provideTopicReportDO") + public void replaceTest(TopicReportDO topicReportDO) { + int replace = topicReportDao.replace(topicReportDO); + Assert.assertEquals(replace, 2); + } } From 39cccd568e226ec4c7862ab896fce4fdf88fd841 Mon Sep 17 00:00:00 2001 From: xuguang Date: Thu, 16 Dec 2021 14:17:45 +0800 Subject: [PATCH 04/10] =?UTF-8?q?DiDiHealthScoreStrategy=E7=B1=BB=E4=B8=AD?= =?UTF-8?q?=E6=9F=90=E4=BA=9B=E5=8F=98=E9=87=8F=E5=BC=80=E5=A4=B4=E5=AD=97?= =?UTF-8?q?=E6=AF=8D=E6=94=B9=E6=88=90=E5=B0=8F=E5=86=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../healthscore/DidiHealthScoreStrategy.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/kafka-manager-core/src/main/java/com/xiaojukeji/kafka/manager/service/strategy/healthscore/DidiHealthScoreStrategy.java b/kafka-manager-core/src/main/java/com/xiaojukeji/kafka/manager/service/strategy/healthscore/DidiHealthScoreStrategy.java index d75dec5a..fed4ccda 100644 --- a/kafka-manager-core/src/main/java/com/xiaojukeji/kafka/manager/service/strategy/healthscore/DidiHealthScoreStrategy.java +++ b/kafka-manager-core/src/main/java/com/xiaojukeji/kafka/manager/service/strategy/healthscore/DidiHealthScoreStrategy.java @@ -89,15 +89,15 @@ public class DidiHealthScoreStrategy extends AbstractHealthScoreStrategy { return HEALTH_SCORE_BAD; } - Object RequestHandlerAvgIdlePercentOneMinuteRate = metrics.getMetricsMap().get("RequestHandlerAvgIdlePercentOneMinuteRate"); - Object NetworkProcessorAvgIdlePercentValue = metrics.getMetricsMap().get("NetworkProcessorAvgIdlePercentValue"); - if (ValidateUtils.isNull(RequestHandlerAvgIdlePercentOneMinuteRate) - || ValidateUtils.isNull(NetworkProcessorAvgIdlePercentValue)) { + Object requestHandlerAvgIdlePercentOneMinuteRate = metrics.getMetricsMap().get("RequestHandlerAvgIdlePercentOneMinuteRate"); + Object networkProcessorAvgIdlePercentValue = metrics.getMetricsMap().get("NetworkProcessorAvgIdlePercentValue"); + if (ValidateUtils.isNull(requestHandlerAvgIdlePercentOneMinuteRate) + || ValidateUtils.isNull(networkProcessorAvgIdlePercentValue)) { // 数据获取失败 return Constant.INVALID_CODE; } - if (((Double) RequestHandlerAvgIdlePercentOneMinuteRate) < MIN_IDLE * KAFKA_REQUEST_HANDLER_POOL_SIZE - || ((Double) NetworkProcessorAvgIdlePercentValue) < MIN_IDLE) { + if (((Double) requestHandlerAvgIdlePercentOneMinuteRate) < MIN_IDLE * KAFKA_REQUEST_HANDLER_POOL_SIZE + || ((Double) networkProcessorAvgIdlePercentValue) < MIN_IDLE) { return HEALTH_SCORE_NORMAL; } return HEALTH_SCORE_HEALTHY; From ad131f5a2c0d21f632c063fbcc064eb01e22dc08 Mon Sep 17 00:00:00 2001 From: xuguang Date: Fri, 17 Dec 2021 14:41:04 +0800 Subject: [PATCH 05/10] =?UTF-8?q?bugfix:=20DidiHealthScoreStrategy.calTopi?= =?UTF-8?q?cHealthScore=E8=AE=A1=E7=AE=97topic=E5=81=A5=E5=BA=B7=E5=88=86?= =?UTF-8?q?=E6=97=B6=EF=BC=8C=E8=8E=B7=E5=8F=96topic=E7=9A=84brokerId?= =?UTF-8?q?=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/strategy/healthscore/DidiHealthScoreStrategy.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kafka-manager-core/src/main/java/com/xiaojukeji/kafka/manager/service/strategy/healthscore/DidiHealthScoreStrategy.java b/kafka-manager-core/src/main/java/com/xiaojukeji/kafka/manager/service/strategy/healthscore/DidiHealthScoreStrategy.java index fed4ccda..11adf30c 100644 --- a/kafka-manager-core/src/main/java/com/xiaojukeji/kafka/manager/service/strategy/healthscore/DidiHealthScoreStrategy.java +++ b/kafka-manager-core/src/main/java/com/xiaojukeji/kafka/manager/service/strategy/healthscore/DidiHealthScoreStrategy.java @@ -114,7 +114,7 @@ public class DidiHealthScoreStrategy extends AbstractHealthScoreStrategy { return Constant.INVALID_CODE; } - List brokerIdList = new ArrayList<>(metadata.getBrokerIdSet().size()); + List brokerIdList = new ArrayList<>(metadata.getBrokerIdSet()); FutureTask[] taskList = new FutureTask[brokerIdList.size()]; for (int i = 0; i < brokerIdList.size(); ++i) { From 9e9bb72e1784eb31e08cf6a60209cab157d10039 Mon Sep 17 00:00:00 2001 From: xuguang Date: Mon, 20 Dec 2021 10:26:43 +0800 Subject: [PATCH 06/10] =?UTF-8?q?BrokerServiceTest=20&&=20KafkaBillService?= =?UTF-8?q?=20&&=20LogicalClusterServiceTest=20&&=20AbstractAllocateQuotaS?= =?UTF-8?q?trategy=20&&=20AbstractHealthScoreStrategy=20=E5=8D=95=E5=85=83?= =?UTF-8?q?=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/service/BrokerServiceTest.java | 300 ++++++++++++++++++ .../service/service/KafkaBillServiceTest.java | 172 ++++++++++ .../service/LogicalClusterServiceTest.java | 38 ++- .../AbstractAllocateQuotaStrategyTest.java | 35 ++ .../AbstractHealthScoreStrategyTest.java | 231 ++++++++++++++ 5 files changed, 764 insertions(+), 12 deletions(-) create mode 100644 kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/BrokerServiceTest.java create mode 100644 kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/KafkaBillServiceTest.java create mode 100644 kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/strategy/AbstractAllocateQuotaStrategyTest.java create mode 100644 kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/strategy/AbstractHealthScoreStrategyTest.java diff --git a/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/BrokerServiceTest.java b/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/BrokerServiceTest.java new file mode 100644 index 00000000..0ea97a1b --- /dev/null +++ b/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/BrokerServiceTest.java @@ -0,0 +1,300 @@ +package com.xiaojukeji.kafka.manager.service.service; + +import com.xiaojukeji.kafka.manager.common.entity.ResultStatus; +import com.xiaojukeji.kafka.manager.common.entity.ao.BrokerBasicDTO; +import com.xiaojukeji.kafka.manager.common.entity.ao.BrokerOverviewDTO; +import com.xiaojukeji.kafka.manager.common.entity.ao.TopicDiskLocation; +import com.xiaojukeji.kafka.manager.common.entity.metrics.BrokerMetrics; +import com.xiaojukeji.kafka.manager.common.entity.pojo.BrokerDO; +import com.xiaojukeji.kafka.manager.common.entity.pojo.BrokerMetricsDO; +import com.xiaojukeji.kafka.manager.common.zookeeper.znode.brokers.BrokerMetadata; +import com.xiaojukeji.kafka.manager.service.config.BaseTest; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.springframework.beans.factory.annotation.Autowired; +import org.testng.Assert; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.util.*; + +/** + * @author xuguang + * @Date 2021/12/10 + */ +public class BrokerServiceTest extends BaseTest { + + @Autowired + @InjectMocks + private BrokerService brokerService; + + @Mock + private JmxService jmxService; + + @BeforeMethod + public void setup() { + MockitoAnnotations.initMocks(this); + } + + @DataProvider(name = "provideBrokerDO") + public static Object[][] provideBrokerDO() { + BrokerDO brokerDO = new BrokerDO(); + brokerDO.setClusterId(1L); + brokerDO.setBrokerId(100); + brokerDO.setHost("127.0.0.1"); + brokerDO.setPort(9093); + brokerDO.setTimestamp(1638605696062L); + brokerDO.setMaxAvgBytesIn(0d); + brokerDO.setStatus(0); + brokerDO.setGmtCreate(new Date(1638605696062L)); + brokerDO.setGmtModify(new Date(1638605696062L)); + return new Object[][]{{brokerDO}}; + } + + @DataProvider(name = "provideBrokerMetadata") + public static Object[][] provideBrokerMetadata() { + BrokerMetadata brokerMetadata = new BrokerMetadata(); + brokerMetadata.setBrokerId(1); + brokerMetadata.setClusterId(1L); + brokerMetadata.setHost("127.0.0.1"); + brokerMetadata.setPort(9092); + brokerMetadata.setEndpoints(Arrays.asList("SASL_PLAINTEXT://10.179.162.202:9093")); + brokerMetadata.setTimestamp(1638605696062L); + brokerMetadata.setJmxPort(9999); + brokerMetadata.setRack("CY"); + brokerMetadata.setVersion("2"); + return new Object[][] {{brokerMetadata}}; + } + + public BrokerMetrics getBrokerMetrics() { + BrokerMetrics brokerMetrics = new BrokerMetrics(1L, 1); + Map metricsMap = new HashMap<>(); + metricsMap.put("PartitionCountValue", 100); + metricsMap.put("LeaderCountValue", 100); + brokerMetrics.setMetricsMap(metricsMap); + return brokerMetrics; + } + + @Test(dataProvider = "provideBrokerDO") + public void replaceTest(BrokerDO brokerDO) { + int result = brokerService.replace(brokerDO); + Assert.assertEquals(result, 2); + } + + public void delete2operationFailedTest(BrokerDO brokerDO) { + brokerService.replace(brokerDO); + + ResultStatus res = brokerService.delete(100L, brokerDO.getBrokerId()); + Assert.assertEquals(res.getCode(), ResultStatus.OPERATION_FAILED.getCode()); + } + + public void delete2SuccessTest(BrokerDO brokerDO) { + brokerService.replace(brokerDO); + + ResultStatus res = brokerService.delete(1L, brokerDO.getBrokerId()); + Assert.assertEquals(res.getCode(), ResultStatus.SUCCESS.getCode()); + } + + @Test(dataProvider = "provideBrokerDO", description = "测试删除broker") + public void deleteTest(BrokerDO brokerDO) { + // 删除broker成功 + delete2SuccessTest(brokerDO); + // 删除broker时,出现operation failed + delete2operationFailedTest(brokerDO); + } + + @Test(dataProvider = "provideBrokerDO") + public void listAllTest(BrokerDO brokerDO) { + brokerService.replace(brokerDO); + + List brokerDOS = brokerService.listAll(); + Assert.assertFalse(brokerDOS.isEmpty()); + Assert.assertTrue(brokerDOS.stream().allMatch(broker -> + broker.getClusterId().equals(brokerDO.getClusterId()))); + } + + @Test + public void getBrokerVersionTest() { + String version = "1.4"; + Mockito.when(jmxService.getBrokerVersion(Mockito.anyLong(), Mockito.anyInt())).thenReturn(version); + + String brokerVersion = brokerService.getBrokerVersion(1L, 1); + Assert.assertNotNull(brokerVersion); + Assert.assertEquals(brokerVersion, version); + } + + @Test(description = "根据Cluster和brokerId获取broker的具体信息测试") + public void getBrokerBasicDTO() { + // 测试结果为null + getBrokerBasicDTO2nullTest(); + // 获取的brokerMetrics为空 + getBrokerBasicDTO2brokerMetricsNullTest(); + // 获取的brokerMetrics不为空 + getBrokerBasicDTO2brokerMetricsNotNullTest(); + } + + private void getBrokerBasicDTO2nullTest() { + BrokerBasicDTO result1 = brokerService.getBrokerBasicDTO(null, 1); + Assert.assertNull(result1); + + BrokerBasicDTO result2 = brokerService.getBrokerBasicDTO(1L, null); + Assert.assertNull(result2); + + BrokerBasicDTO result3 = brokerService.getBrokerBasicDTO(100L, 100); + Assert.assertNull(result3); + } + + private void getBrokerBasicDTO2brokerMetricsNullTest() { + BrokerBasicDTO result1 = brokerService.getBrokerBasicDTO(1L, 1); + Assert.assertNotNull(result1); + Assert.assertNull(result1.getPartitionCount()); + Assert.assertNull(result1.getLeaderCount()); + } + + private void getBrokerBasicDTO2brokerMetricsNotNullTest() { + Mockito.when(jmxService.getBrokerMetrics( + Mockito.anyLong(), Mockito.anyInt(), Mockito.anyInt())).thenReturn(getBrokerMetrics()); + + BrokerBasicDTO result1 = brokerService.getBrokerBasicDTO(1L, 1); + Assert.assertNotNull(result1); + Assert.assertNotNull(result1.getPartitionCount()); + Assert.assertNotNull(result1.getLeaderCount()); + } + + @Test(description = "根据时间区间获取Broker监控数据测试") + public void getBrokerMetricsFromDBTest() { + long startTime = 1639360565000L; + long endTime = 1639407365000L; + List brokerMetricsDOList = brokerService.getBrokerMetricsFromDB( + 1L, 1, new Date(startTime), new Date(endTime)); + Assert.assertFalse(brokerMetricsDOList.isEmpty()); + Assert.assertTrue(brokerMetricsDOList.stream().allMatch(brokerMetricsDO -> + brokerMetricsDO.getClusterId().equals(1L) && + brokerMetricsDO.getBrokerId().equals(1) && + brokerMetricsDO.getGmtCreate().after(new Date(startTime)) && + brokerMetricsDO.getGmtCreate().before(new Date(endTime)))); + } + + @Test + public void getBrokerTopicLocationTest() { + // TODO 待补充, jmxService和topicService测试完成后 + List brokerTopicLocations = brokerService.getBrokerTopicLocation(1L, 1); + Assert.assertFalse(brokerTopicLocations.isEmpty()); + Assert.assertTrue(brokerTopicLocations.stream().allMatch(brokerTopicLocation -> + brokerTopicLocation.getClusterId().equals(1L) && + brokerTopicLocation.getBrokerId().equals(1))); + } + + @Test(description = "计算Broker的峰值均值流量测试") + public void calBrokerMaxAvgBytesInTest() { + // 参数异常 + calBrokerMaxAvgBytesIn2ParamIllegalTest(); + // 获取的指标为空 + calBrokerMaxAvgBytesIn2ZeroTest(); + // 整个流程 + calBrokerMaxAvgBytesIn2Success(); + } + + private void calBrokerMaxAvgBytesIn2ParamIllegalTest() { + Double result1 = brokerService.calBrokerMaxAvgBytesIn(null, 1, 1, new Date(), new Date()); + Assert.assertEquals(result1, -1.0); + Double result2 = brokerService.calBrokerMaxAvgBytesIn(1L, null, 1, new Date(), new Date()); + Assert.assertEquals(result2, -1.0); + Double result3 = brokerService.calBrokerMaxAvgBytesIn(1L, 1, null, new Date(), new Date()); + Assert.assertEquals(result3, -1.0); + Double result4 = brokerService.calBrokerMaxAvgBytesIn(1L, 1, 1, null, new Date()); + Assert.assertEquals(result4, -1.0); + Double result5 = brokerService.calBrokerMaxAvgBytesIn(1L, 1, 1, new Date(), null); + Assert.assertEquals(result5, -1.0); + } + + private void calBrokerMaxAvgBytesIn2ZeroTest() { + Double result = brokerService.calBrokerMaxAvgBytesIn(1L, 100, 100, new Date(), new Date()); + Assert.assertEquals(result, 0.0); + } + + private void calBrokerMaxAvgBytesIn2Success() { + long startTime = 1639360565000L; + long endTime = 1639407365000L; + Double result = brokerService.calBrokerMaxAvgBytesIn( + 1L, 1, 2, new Date(startTime), new Date(endTime)); + Assert.assertTrue(result > 0.0); + } + + @Test(description = "获取BrokerMetrics信息测试,单个broker") + public void getBrokerMetricsFromJmxTest() { + // 参数错误 + getBrokerMetricsFromJmx2ParamIllegalTest(); + // 返回为null + getBrokerMetricsFromJmx2nullTest(); + // 获取成功 + getBrokerMetricsFromJmx2SuccessTest(); + } + + private void getBrokerMetricsFromJmx2ParamIllegalTest() { + BrokerMetrics result1 = brokerService.getBrokerMetricsFromJmx(null, 1, 200); + Assert.assertNull(result1); + + BrokerMetrics result3 = brokerService.getBrokerMetricsFromJmx(1L, 1, null); + Assert.assertNull(result3); + } + + private void getBrokerMetricsFromJmx2nullTest() { + BrokerMetrics result1 = brokerService.getBrokerMetricsFromJmx(1L, 1, 200); + Assert.assertNull(result1); + } + + private void getBrokerMetricsFromJmx2SuccessTest() { + Mockito.when(jmxService.getBrokerMetrics( + Mockito.anyLong(), Mockito.anyInt(), Mockito.anyInt())).thenReturn(new BrokerMetrics(1L, 1)); + BrokerMetrics result1 = brokerService.getBrokerMetricsFromJmx(1L, 1, 200); + Assert.assertNotNull(result1); + Assert.assertEquals(Optional.ofNullable(result1.getClusterId()), Optional.ofNullable(1L)); + Assert.assertEquals(Optional.ofNullable(result1.getBrokerId()), Optional.ofNullable(1)); + } + + @Test(description = "获取BrokerMetrics信息测试,多个broker") + public void getBrokerMetricsFromJmxWithMoreBrokersTest() { + Mockito.when(jmxService.getBrokerMetrics( + Mockito.anyLong(), Mockito.anyInt(), Mockito.anyInt())).thenReturn(new BrokerMetrics(1L, 1)); + + Set set = new HashSet<>(); + set.add(1); + set.add(2); + set.add(3); + List result = brokerService.getBrokerMetricsFromJmx(1L, set, 200); + Assert.assertNotNull(result); + Assert.assertTrue(result.stream().allMatch(brokerMetric -> + brokerMetric.getClusterId().equals(1L))); + } + + @Test(description = "获取Broker列表信息") + public void getBrokerOverviewListTest() { + // brokerIdSet为空时 + getBrokerOverviewList2BrokerIdSetIsNullTest(); + // brokerIdSet不为空时 + getBrokerOverviewList2BrokerIdSetNotNullTest(); + } + + private void getBrokerOverviewList2BrokerIdSetIsNullTest() { + List brokerOverviewList = brokerService.getBrokerOverviewList(1L, null); + Assert.assertFalse(brokerOverviewList.isEmpty()); + Assert.assertTrue(brokerOverviewList.stream().allMatch(brokerOverviewDTO -> + brokerOverviewDTO.getPort().equals(9093))); + } + + private void getBrokerOverviewList2BrokerIdSetNotNullTest() { + Set set = new HashSet<>(); + set.add(1); + set.add(2); + List brokerOverviewList = brokerService.getBrokerOverviewList(1L, set); + Assert.assertFalse(brokerOverviewList.isEmpty()); + Assert.assertTrue(brokerOverviewList.stream().allMatch(brokerOverviewDTO -> + brokerOverviewDTO.getPort().equals(9093))); + } + + +} diff --git a/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/KafkaBillServiceTest.java b/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/KafkaBillServiceTest.java new file mode 100644 index 00000000..8cf514a9 --- /dev/null +++ b/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/KafkaBillServiceTest.java @@ -0,0 +1,172 @@ +package com.xiaojukeji.kafka.manager.service.service; + +import com.xiaojukeji.kafka.manager.common.entity.pojo.KafkaBillDO; +import com.xiaojukeji.kafka.manager.dao.KafkaBillDao; +import com.xiaojukeji.kafka.manager.service.config.BaseTest; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.springframework.beans.factory.annotation.Autowired; +import org.testng.Assert; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +/** + * @author xuguang + * @Date 2021/12/14 + */ +public class KafkaBillServiceTest extends BaseTest { + + @Autowired + @InjectMocks + private KafkaBillService kafkaBillService; + + @Mock + private KafkaBillDao kafkaBillDao; + + @BeforeMethod + public void setup() { + MockitoAnnotations.initMocks(this); + } + + @DataProvider(name = "provideKafkaBillDO") + public static Object[][] provideKafkaBillDO() { + KafkaBillDO kafkaBillDO = new KafkaBillDO(); + kafkaBillDO.setClusterId(1L); + kafkaBillDO.setCost(100.0d); + kafkaBillDO.setGmtCreate(new Date(1638605696062L)); + kafkaBillDO.setGmtDay("10"); + kafkaBillDO.setPrincipal("admin"); + kafkaBillDO.setQuota(1000.0d); + kafkaBillDO.setTopicName("moduleTest"); + return new Object[][] {{kafkaBillDO}}; + } + + @Test(dataProvider = "provideKafkaBillDO") + public void replaceTest(KafkaBillDO kafkaBillDO) { + // 插入成功 + replace2SuccessTest(kafkaBillDO); + // 插入失败 + replace2ExceptionTest(kafkaBillDO); + } + + private void replace2SuccessTest(KafkaBillDO kafkaBillDO) { + Mockito.when(kafkaBillDao.replace(Mockito.any())).thenReturn(1); + int result = kafkaBillService.replace(kafkaBillDO); + Assert.assertEquals(result, 1); + } + + private void replace2ExceptionTest(KafkaBillDO kafkaBillDO) { + Mockito.when(kafkaBillDao.replace(Mockito.any())).thenThrow(RuntimeException.class); + int result = kafkaBillService.replace(kafkaBillDO); + Assert.assertEquals(result, 0); + } + + @Test(dataProvider = "provideKafkaBillDO") + public void getByTopicNameTest(KafkaBillDO kafkaBillDO) { + // 查询成功 + getByTopicName2SuccessTest(kafkaBillDO); + // 查询异常 + getByTopicName2ExceptionTest(); + + } + + private void getByTopicName2SuccessTest(KafkaBillDO kafkaBillDO) { + Mockito.when(kafkaBillDao.getByTopicName( + Mockito.anyLong(), Mockito.anyString(), Mockito.any(), Mockito.any())).thenReturn(Arrays.asList(kafkaBillDO)); + List result = kafkaBillService.getByTopicName(1L, "moudleTest", new Date(0L), new Date()); + Assert.assertFalse(result.isEmpty()); + Assert.assertTrue(result.stream().allMatch(kafkaBillDO1 -> + kafkaBillDO1.getTopicName().equals(kafkaBillDO.getTopicName()) && + kafkaBillDO1.getClusterId().equals(kafkaBillDO.getClusterId()))); + } + + private void getByTopicName2ExceptionTest() { + Mockito.when(kafkaBillDao.getByTopicName( + Mockito.anyLong(), Mockito.anyString(), Mockito.any(), Mockito.any())).thenThrow(RuntimeException.class); + List result = kafkaBillService.getByTopicName(1L, "moudleTest", new Date(0L), new Date()); + Assert.assertTrue(result.isEmpty()); + } + + @Test(dataProvider = "provideKafkaBillDO") + public void getByPrincipalTest(KafkaBillDO kafkaBillDO) { + // 查询成功 + getByPrincipal2SuccessTest(kafkaBillDO); + // 查询失败 + getByPrincipal2ExceptionTest(); + } + + private void getByPrincipal2SuccessTest(KafkaBillDO kafkaBillDO) { + Mockito.when(kafkaBillDao.getByPrincipal( + Mockito.anyString(), Mockito.any(), Mockito.any())).thenReturn(Arrays.asList(kafkaBillDO)); + List result = kafkaBillService.getByPrincipal("admin", new Date(0L), new Date()); + Assert.assertFalse(result.isEmpty()); + Assert.assertTrue(result.stream().allMatch(kafkaBillDO1 -> + kafkaBillDO1.getTopicName().equals(kafkaBillDO.getTopicName()) && + kafkaBillDO1.getClusterId().equals(kafkaBillDO.getClusterId()))); + } + + private void getByPrincipal2ExceptionTest() { + Mockito.when(kafkaBillDao.getByPrincipal( + Mockito.anyString(), Mockito.any(), Mockito.any())).thenThrow(RuntimeException.class); + List result = kafkaBillService.getByPrincipal("admin", new Date(0L), new Date()); + Assert.assertTrue(result.isEmpty()); + } + + @Test(dataProvider = "provideKafkaBillDO") + public void getByTimeBetweenTest(KafkaBillDO kafkaBillDO) { + // 查询成功 + getByTimeBetween2SuccessTest(kafkaBillDO); + // 查询失败 + getByTimeBetween2ExceptionTest(); + } + + private void getByTimeBetween2SuccessTest(KafkaBillDO kafkaBillDO) { + Mockito.when(kafkaBillDao.getByTimeBetween( + Mockito.any(), Mockito.any())).thenReturn(Arrays.asList(kafkaBillDO)); + List result = kafkaBillService.getByTimeBetween(new Date(0L), new Date()); + Assert.assertFalse(result.isEmpty()); + Assert.assertTrue(result.stream().allMatch(kafkaBillDO1 -> + kafkaBillDO1.getTopicName().equals(kafkaBillDO.getTopicName()) && + kafkaBillDO1.getClusterId().equals(kafkaBillDO.getClusterId()))); + } + + private void getByTimeBetween2ExceptionTest() { + Mockito.when(kafkaBillDao.getByTimeBetween( + Mockito.any(), Mockito.any())).thenThrow(RuntimeException.class); + List result = kafkaBillService.getByTimeBetween(new Date(0L), new Date()); + Assert.assertTrue(result.isEmpty()); + } + + @Test(dataProvider = "provideKafkaBillDO") + public void getByGmtDayTest(KafkaBillDO kafkaBillDO) { + // 查询成功 + getByGmtDay2SuccessTest(kafkaBillDO); + // 查询失败 + getByGmtDay2ExceptionTest(); + } + + private void getByGmtDay2SuccessTest(KafkaBillDO kafkaBillDO) { + Mockito.when(kafkaBillDao.getByGmtDay( + Mockito.anyString())).thenReturn(Arrays.asList(kafkaBillDO)); + List result = kafkaBillService.getByGmtDay("10"); + Assert.assertFalse(result.isEmpty()); + Assert.assertTrue(result.stream().allMatch(kafkaBillDO1 -> + kafkaBillDO1.getTopicName().equals(kafkaBillDO.getTopicName()) && + kafkaBillDO1.getClusterId().equals(kafkaBillDO.getClusterId()))); + } + + private void getByGmtDay2ExceptionTest() { + Mockito.when(kafkaBillDao.getByGmtDay( + Mockito.anyString())).thenThrow(RuntimeException.class); + List result = kafkaBillService.getByGmtDay("10"); + Assert.assertTrue(result.isEmpty()); + } + +} diff --git a/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/LogicalClusterServiceTest.java b/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/LogicalClusterServiceTest.java index 4c4c2a92..92d62c27 100644 --- a/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/LogicalClusterServiceTest.java +++ b/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/LogicalClusterServiceTest.java @@ -93,14 +93,27 @@ public class LogicalClusterServiceTest extends BaseTest { return appDO; } - @Test(description = "创建逻辑集群时参数错误") - public void createLogicalCluster2paramIllegalTest() { + @Test(description = "测试创建逻辑集群") + public void createLogicalCluster() { + // 创建逻辑集群时参数错误 + createLogicalCluster2paramIllegalTest(); + // 创建逻辑集群时,region已使用 + createLogicalCluster2existRegionAlreadyInUseTest(); + // 创建逻辑集群时,物理集群不存在 + createLogicalCluster2PhysicalClusterNotExistTest(); + // 创建逻辑集群时,不存在region已使用 + createLogicalCluster2NotexistRegionAlreadyInUseTest(); + // 创建逻辑集群成功 + createLogicalCluster2SuccessTest(); + } + + private void createLogicalCluster2paramIllegalTest() { ResultStatus result = logicalClusterService.createLogicalCluster(null); Assert.assertEquals(result.getCode(), ResultStatus.PARAM_ILLEGAL.getCode()); } - @Test(dataProvider = "provideLogicalClusterDO", description = "创建逻辑集群时,region已使用") - public void createLogicalCluster2existRegionAlreadyInUseTest(LogicalClusterDO logicalClusterDO) { + private void createLogicalCluster2existRegionAlreadyInUseTest() { + LogicalClusterDO logicalClusterDO = getLogicalClusterDO(); // 物理集群Id为null logicalClusterDO.setClusterId(null); ResultStatus result1 = logicalClusterService.createLogicalCluster(logicalClusterDO); @@ -118,8 +131,8 @@ public class LogicalClusterServiceTest extends BaseTest { Assert.assertEquals(result3.getCode(), ResultStatus.RESOURCE_ALREADY_USED.getCode()); } - @Test(dataProvider = "provideLogicalClusterDO", description = "创建逻辑集群时,物理集群不存在") - public void createLogicalCluster2PhysicalClusterNotExistTest(LogicalClusterDO logicalClusterDO) { + private void createLogicalCluster2PhysicalClusterNotExistTest() { + LogicalClusterDO logicalClusterDO = getLogicalClusterDO(); Mockito.when(logicalClusterDao.insert(Mockito.any())).thenReturn(1); // 不存在该物理集群情况 logicalClusterDO.setClusterId(100L); @@ -128,8 +141,8 @@ public class LogicalClusterServiceTest extends BaseTest { Assert.assertEquals(result1.getCode(), ResultStatus.SUCCESS.getCode()); } - @Test(dataProvider = "provideLogicalClusterDO", description = "创建逻辑集群时,不存在region已使用") - public void createLogicalCluster2NotexistRegionAlreadyInUseTest(LogicalClusterDO logicalClusterDO) { + private void createLogicalCluster2NotexistRegionAlreadyInUseTest() { + LogicalClusterDO logicalClusterDO = getLogicalClusterDO(); Mockito.when(logicalClusterDao.insert(Mockito.any())).thenReturn(1); // region没有存在使用 ResultStatus result2 = logicalClusterService.createLogicalCluster(logicalClusterDO); @@ -137,16 +150,17 @@ public class LogicalClusterServiceTest extends BaseTest { Assert.assertEquals(result2.getCode(), ResultStatus.SUCCESS.getCode()); } - @Test(dataProvider = "provideLogicalClusterDO", description = "创建逻辑集群时,不存在region已使用") - public void createLogicalCluster2DuplicateKeyTest(LogicalClusterDO logicalClusterDO) { + @Test(description = "创建逻辑集群时,不存在region已使用(键重复)") + private void createLogicalCluster2DuplicateKeyTest() { + LogicalClusterDO logicalClusterDO = getLogicalClusterDO(); Mockito.when(logicalClusterDao.insert(Mockito.any())).thenThrow(DuplicateKeyException.class); logicalClusterDO.setRegionList("100"); ResultStatus result3 = logicalClusterService.createLogicalCluster(logicalClusterDO); Assert.assertEquals(result3.getCode(), ResultStatus.RESOURCE_ALREADY_EXISTED.getCode()); } - @Test(dataProvider = "provideLogicalClusterDO", description = "创建逻辑集群成功") - public void createLogicalCluster2SuccessTest(LogicalClusterDO logicalClusterDO) { + private void createLogicalCluster2SuccessTest() { + LogicalClusterDO logicalClusterDO = getLogicalClusterDO(); Mockito.when(logicalClusterDao.insert(Mockito.any())).thenReturn(1); ResultStatus result3 = logicalClusterService.createLogicalCluster(logicalClusterDO); diff --git a/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/strategy/AbstractAllocateQuotaStrategyTest.java b/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/strategy/AbstractAllocateQuotaStrategyTest.java new file mode 100644 index 00000000..80b5e1b4 --- /dev/null +++ b/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/strategy/AbstractAllocateQuotaStrategyTest.java @@ -0,0 +1,35 @@ +package com.xiaojukeji.kafka.manager.service.strategy; + +import com.xiaojukeji.kafka.manager.common.entity.ao.gateway.TopicQuota; +import com.xiaojukeji.kafka.manager.service.config.BaseTest; +import org.junit.Assert; +import org.springframework.beans.factory.annotation.Autowired; +import org.testng.annotations.Test; + +/** + * @author xuguang + * @Date 2021/12/15 + */ +public class AbstractAllocateQuotaStrategyTest extends BaseTest { + + @Autowired + private AbstractAllocateQuotaStrategy abstractAllocateQuotaStrategy; + + private TopicQuota getTopicQuota() { + TopicQuota topicQuota = new TopicQuota(); + topicQuota.setTopicName("xxx"); + topicQuota.setConsumeQuota(1000L); + topicQuota.setProduceQuota(1000L); + topicQuota.setAppId("xxxAppId"); + topicQuota.setClusterId(1L); + return topicQuota; + } + + @Test + public void getNewTopicQuotaTest() { + TopicQuota topicQuota = getTopicQuota(); + TopicQuota newTopicQuota = abstractAllocateQuotaStrategy.getNewTopicQuota(topicQuota, 3, 1000L); + Assert.assertNotNull(newTopicQuota); + Assert.assertEquals(newTopicQuota.toString(), topicQuota.toString()); + } +} diff --git a/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/strategy/AbstractHealthScoreStrategyTest.java b/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/strategy/AbstractHealthScoreStrategyTest.java new file mode 100644 index 00000000..5cc67486 --- /dev/null +++ b/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/strategy/AbstractHealthScoreStrategyTest.java @@ -0,0 +1,231 @@ +package com.xiaojukeji.kafka.manager.service.strategy; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.xiaojukeji.kafka.manager.common.constant.Constant; +import com.xiaojukeji.kafka.manager.common.entity.metrics.BrokerMetrics; +import com.xiaojukeji.kafka.manager.service.config.BaseTest; +import com.xiaojukeji.kafka.manager.service.service.JmxService; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.springframework.beans.factory.annotation.Autowired; +import org.testng.Assert; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author xuguang + * @Date 2021/12/15 + */ +public class AbstractHealthScoreStrategyTest extends BaseTest { + + private BrokerMetrics getBrokerMetrics() { + BrokerMetrics brokerMetrics = new BrokerMetrics(1L, 1); + String metrics = "{\"TotalFetchRequestsPerSecFiveMinuteRate\":4.132236103122026,\"BytesRejectedPerSecFiveMinuteRate\":0.0,\"TotalFetchRequestsPerSecFifteenMinuteRate\":1.5799208507558833,\"ProduceTotalTimeMs98thPercentile\":0.0,\"MessagesInPerSecMeanRate\":0.0,\"ProduceTotalTimeMs75thPercentile\":0.0,\"ProduceTotalTimeMs99thPercentile\":0.0,\"TotalProduceRequestsPerSecOneMinuteRate\":0.0,\"FailedProduceRequestsPerSecFifteenMinuteRate\":0.0,\"BytesInPerSecMeanRate\":0.0,\"TotalProduceRequestsPerSecFiveMinuteRate\":0.0,\"FetchConsumerTotalTimeMs999thPercentile\":0.0,\"FetchConsumerTotalTimeMs98thPercentile\":0.0,\"FetchConsumerTotalTimeMsMean\":0.0,\"FetchConsumerTotalTimeMs99thPercentile\":0.0,\"FailedFetchRequestsPerSecFifteenMinuteRate\":0.0,\"MessagesInPerSecFiveMinuteRate\":0.0,\"RequestHandlerAvgIdlePercentOneMinuteRate\":0.999221766772746,\"ProduceTotalTimeMsMean\":0.0,\"BytesInPerSecFiveMinuteRate\":0.0,\"FailedProduceRequestsPerSecMeanRate\":0.0,\"FailedFetchRequestsPerSecMeanRate\":0.0,\"FailedProduceRequestsPerSecFiveMinuteRate\":0.0,\"BytesOutPerSecFifteenMinuteRate\":0.0,\"BytesInPerSecOneMinuteRate\":0.0,\"BytesOutPerSecFiveMinuteRate\":0.0,\"HealthScore\":90,\"FailedFetchRequestsPerSecOneMinuteRate\":0.0,\"MessagesInPerSecOneMinuteRate\":0.0,\"BytesRejectedPerSecFifteenMinuteRate\":0.0,\"FailedFetchRequestsPerSecFiveMinuteRate\":0.0,\"RequestHandlerAvgIdlePercentFiveMinuteRate\":0.999803118809842,\"BytesOutPerSecOneMinuteRate\":0.0,\"ResponseQueueSizeValue\":0,\"MessagesInPerSecFifteenMinuteRate\":0.0,\"TotalProduceRequestsPerSecMeanRate\":0.0,\"BytesRejectedPerSecMeanRate\":0.0,\"TotalFetchRequestsPerSecMeanRate\":1.2674449706628523,\"NetworkProcessorAvgIdlePercentValue\":1.0,\"TotalFetchRequestsPerSecOneMinuteRate\":10.457259856316893,\"BytesInPerSecFifteenMinuteRate\":0.0,\"BytesOutPerSecMeanRate\":0.0,\"TotalProduceRequestsPerSecFifteenMinuteRate\":0.0,\"FetchConsumerTotalTimeMs50thPercentile\":0.0,\"RequestHandlerAvgIdlePercentFifteenMinuteRate\":0.9999287809186348,\"FetchConsumerTotalTimeMs95thPercentile\":0.0,\"FailedProduceRequestsPerSecOneMinuteRate\":0.0,\"CreateTime\":1638792321071,\"FetchConsumerTotalTimeMs75thPercentile\":0.0,\"ProduceTotalTimeMs999thPercentile\":0.0,\"RequestQueueSizeValue\":0,\"ProduceTotalTimeMs50thPercentile\":0.0,\"BytesRejectedPerSecOneMinuteRate\":0.0,\"RequestHandlerAvgIdlePercentMeanRate\":0.9999649184090593,\"ProduceTotalTimeMs95thPercentile\":0.0}"; + JSONObject jsonObject = JSON.parseObject(metrics); + Map metricsMap = new HashMap<>(); + for (Map.Entry stringObjectEntry : jsonObject.entrySet()) { + metricsMap.put(stringObjectEntry.getKey(), stringObjectEntry.getValue()); + } + brokerMetrics.setMetricsMap(metricsMap); + return brokerMetrics; + } + + @Autowired + @InjectMocks + private AbstractHealthScoreStrategy didiHealthScoreStrategy; + + @Mock + private JmxService jmxService; + + @BeforeMethod + public void setup() { + MockitoAnnotations.initMocks(this); + } + + @Test(description = "测试计算broker健康分") + public void calBrokerHealthScoreWithBrokerMetricsTest() { + // brokerMetrics为空时 + calBrokerHealthScoreWithBrokerMetrics2InvideCodeTest(); + // HEALTH_SCORE_VERY_BAD + calBrokerHealthScoreWithBrokerMetrics2HealthScoreVeryBadTest(); + // requestQueueSizeValue is Null or responseQueueSizeValue is Null + calBrokerHealthScoreWithBrokerMetrics2requestQueueSizeValueNullTest(); + // HEALTH_SCORE_BAD + calBrokerHealthScoreWithBrokerMetrics2HealthScoreBadTest(); + // requestHandlerAvgIdlePercentOneMinuteRate is null + calBrokerHealthScoreWithBrokerMetrics2InvideCode3Test(); + // HEALTH_SCORE_NORMAL + calBrokerHealthScoreWithBrokerMetrics2HealthScoreNormalTest(); + // HEALTH_SCORE_Healthy + calBrokerHealthScoreWithBrokerMetrics2HealthScoreHealthyTest(); + // exception + calBrokerHealthScoreWithBrokerMetrics2ExceptionTest(); + } + + private void calBrokerHealthScoreWithBrokerMetrics2InvideCodeTest() { + Integer result1 = didiHealthScoreStrategy.calBrokerHealthScore(1L, 1, null); + Assert.assertEquals(result1, Constant.INVALID_CODE); + + Integer result2 = didiHealthScoreStrategy.calBrokerHealthScore(1L, 1, new BrokerMetrics(1L, 1)); + Assert.assertEquals(result2, Constant.INVALID_CODE); + } + + private void calBrokerHealthScoreWithBrokerMetrics2HealthScoreVeryBadTest() { + BrokerMetrics brokerMetrics = getBrokerMetrics(); + Map metricsMap = brokerMetrics.getMetricsMap(); + metricsMap.put("FailedFetchRequestsPerSecOneMinuteRate", 0.02); + metricsMap.put("FailedProduceRequestsPerSecOneMinuteRate", 0.02); + + Integer result = didiHealthScoreStrategy.calBrokerHealthScore(1L, 1, brokerMetrics); + Assert.assertEquals(result, Integer.valueOf(30)); + } + + private void calBrokerHealthScoreWithBrokerMetrics2requestQueueSizeValueNullTest() { + BrokerMetrics brokerMetrics = getBrokerMetrics(); + Map metricsMap = brokerMetrics.getMetricsMap(); + metricsMap.put("FailedFetchRequestsPerSecOneMinuteRate", 0.0); + metricsMap.put("FailedProduceRequestsPerSecOneMinuteRate", 0.0); + metricsMap.put("RequestQueueSizeValue", null); + metricsMap.put("ResponseQueueSizeValue", null); + + Integer result = didiHealthScoreStrategy.calBrokerHealthScore(1L, 1, brokerMetrics); + Assert.assertEquals(result, Constant.INVALID_CODE); + } + + private void calBrokerHealthScoreWithBrokerMetrics2HealthScoreBadTest() { + BrokerMetrics brokerMetrics = getBrokerMetrics(); + Map metricsMap = brokerMetrics.getMetricsMap(); + metricsMap.put("FailedFetchRequestsPerSecOneMinuteRate", 0.0); + metricsMap.put("FailedProduceRequestsPerSecOneMinuteRate", 0.0); + metricsMap.put("RequestQueueSizeValue", 500); + metricsMap.put("ResponseQueueSizeValue", 500); + + Integer result = didiHealthScoreStrategy.calBrokerHealthScore(1L, 1, brokerMetrics); + Assert.assertEquals(result, Integer.valueOf(60)); + } + + private void calBrokerHealthScoreWithBrokerMetrics2InvideCode3Test() { + BrokerMetrics brokerMetrics = getBrokerMetrics(); + Map metricsMap = brokerMetrics.getMetricsMap(); + metricsMap.put("FailedFetchRequestsPerSecOneMinuteRate", 0.0); + metricsMap.put("FailedProduceRequestsPerSecOneMinuteRate", 0.0); + metricsMap.put("RequestQueueSizeValue", 300); + metricsMap.put("ResponseQueueSizeValue", 300); + metricsMap.put("RequestHandlerAvgIdlePercentOneMinuteRate", null); + metricsMap.put("NetworkProcessorAvgIdlePercentValue", null); + + Integer result = didiHealthScoreStrategy.calBrokerHealthScore(1L, 1, brokerMetrics); + Assert.assertEquals(result, Constant.INVALID_CODE); + } + + private void calBrokerHealthScoreWithBrokerMetrics2HealthScoreNormalTest() { + BrokerMetrics brokerMetrics = getBrokerMetrics(); + Map metricsMap = brokerMetrics.getMetricsMap(); + metricsMap.put("FailedFetchRequestsPerSecOneMinuteRate", 0.0); + metricsMap.put("FailedProduceRequestsPerSecOneMinuteRate", 0.0); + metricsMap.put("RequestQueueSizeValue", 300); + metricsMap.put("ResponseQueueSizeValue", 300); + metricsMap.put("RequestHandlerAvgIdlePercentOneMinuteRate", 0.0); + metricsMap.put("NetworkProcessorAvgIdlePercentValue", 0.0); + + Integer result = didiHealthScoreStrategy.calBrokerHealthScore(1L, 1, brokerMetrics); + Assert.assertEquals(result, Integer.valueOf(90)); + } + + private void calBrokerHealthScoreWithBrokerMetrics2HealthScoreHealthyTest() { + BrokerMetrics brokerMetrics = getBrokerMetrics(); + Map metricsMap = brokerMetrics.getMetricsMap(); + metricsMap.put("FailedFetchRequestsPerSecOneMinuteRate", 0.0); + metricsMap.put("FailedProduceRequestsPerSecOneMinuteRate", 0.0); + metricsMap.put("RequestQueueSizeValue", 300); + metricsMap.put("ResponseQueueSizeValue", 300); + metricsMap.put("RequestHandlerAvgIdlePercentOneMinuteRate", 100.0); + metricsMap.put("NetworkProcessorAvgIdlePercentValue", 100.0); + + Integer result = didiHealthScoreStrategy.calBrokerHealthScore(1L, 1, brokerMetrics); + Assert.assertEquals(result, Integer.valueOf(100)); + } + + private void calBrokerHealthScoreWithBrokerMetrics2ExceptionTest() { + BrokerMetrics brokerMetrics = getBrokerMetrics(); + Map metricsMap = brokerMetrics.getMetricsMap(); + metricsMap.put("FailedFetchRequestsPerSecOneMinuteRate", 0.0); + metricsMap.put("FailedProduceRequestsPerSecOneMinuteRate", 0.0); + metricsMap.put("RequestQueueSizeValue", 300); + metricsMap.put("ResponseQueueSizeValue", 300); + // Integer转Double出现异常 + metricsMap.put("RequestHandlerAvgIdlePercentOneMinuteRate", 100); + metricsMap.put("NetworkProcessorAvgIdlePercentValue", 100); + + Integer result = didiHealthScoreStrategy.calBrokerHealthScore(1L, 1, brokerMetrics); + Assert.assertEquals(result, Constant.INVALID_CODE); + } + + @Test(description = "测试计算broker健康分") + public void calBrokerHealthScoreTest() { + // BrokerMetadata is Null + calBrokerHealthScore2BrokerMetadataIsNullTest(); + // INVALID_CODE + calBrokerHealthScore2InvideCodeTest(); + // success + calBrokerHealthScore2SuccessTest(); + } + + private void calBrokerHealthScore2BrokerMetadataIsNullTest() { + Integer result = didiHealthScoreStrategy.calBrokerHealthScore(1L, 100); + Assert.assertEquals(result, Integer.valueOf(100)); + } + + private void calBrokerHealthScore2InvideCodeTest() { + Mockito.when(jmxService.getBrokerMetrics(Mockito.anyLong(), Mockito.anyInt(), Mockito.anyInt())).thenReturn(null); + Integer result = didiHealthScoreStrategy.calBrokerHealthScore(1L, 1); + Assert.assertEquals(result, Constant.INVALID_CODE); + } + + private void calBrokerHealthScore2SuccessTest() { + BrokerMetrics brokerMetrics = getBrokerMetrics(); + Map metricsMap = brokerMetrics.getMetricsMap(); + metricsMap.put("FailedFetchRequestsPerSecOneMinuteRate", 0.0); + metricsMap.put("FailedProduceRequestsPerSecOneMinuteRate", 0.0); + metricsMap.put("RequestQueueSizeValue", 500); + metricsMap.put("ResponseQueueSizeValue", 500); + + Mockito.when(jmxService.getBrokerMetrics(Mockito.anyLong(), Mockito.anyInt(), Mockito.anyInt())).thenReturn(brokerMetrics); + Integer result = didiHealthScoreStrategy.calBrokerHealthScore(1L, 1); + Assert.assertEquals(result, Integer.valueOf(60)); + } + + @Test(description = "测试计算健康分") + public void calTopicHealthScore() { + // TopicMetadata为空 + calTopicHealthScore2InvadeCodeTest(); + // 测试计算topic健康分成功 + calTopicHealthScore2SuccessTest(); + } + + private void calTopicHealthScore2InvadeCodeTest() { + Integer result = didiHealthScoreStrategy.calTopicHealthScore(1L, "xxx"); + Assert.assertEquals(result, Constant.INVALID_CODE); + } + + private void calTopicHealthScore2SuccessTest() { + BrokerMetrics brokerMetrics = getBrokerMetrics(); + Map metricsMap = brokerMetrics.getMetricsMap(); + metricsMap.put("FailedFetchRequestsPerSecOneMinuteRate", 0.0); + metricsMap.put("FailedProduceRequestsPerSecOneMinuteRate", 0.0); + metricsMap.put("RequestQueueSizeValue", 500); + metricsMap.put("ResponseQueueSizeValue", 500); + + Mockito.when(jmxService.getBrokerMetrics(Mockito.anyLong(), Mockito.anyInt(), Mockito.anyInt())).thenReturn(brokerMetrics); + + Integer result = didiHealthScoreStrategy.calTopicHealthScore(1L, "xgTest"); + Assert.assertNotEquals(result, Constant.INVALID_CODE); + } + +} From 19c61c52e66538cafa8a9e8cee9e3c9785fc1c04 Mon Sep 17 00:00:00 2001 From: xuguang Date: Wed, 22 Dec 2021 16:04:06 +0800 Subject: [PATCH 07/10] bugfix: TopicService && TopicServiceImpl && ZookeeperServiceImpl --- .../kafka/manager/service/service/TopicService.java | 7 +++++++ .../manager/service/service/impl/TopicServiceImpl.java | 10 +++++----- .../service/service/impl/ZookeeperServiceImpl.java | 2 +- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/kafka-manager-core/src/main/java/com/xiaojukeji/kafka/manager/service/service/TopicService.java b/kafka-manager-core/src/main/java/com/xiaojukeji/kafka/manager/service/service/TopicService.java index 9e4c244c..7a0e3eb0 100644 --- a/kafka-manager-core/src/main/java/com/xiaojukeji/kafka/manager/service/service/TopicService.java +++ b/kafka-manager-core/src/main/java/com/xiaojukeji/kafka/manager/service/service/TopicService.java @@ -104,6 +104,13 @@ public interface TopicService { */ List getTopicBrokerList(Long clusterId, String topicName); + /** + * 判断topic是否有数据写入,即分区topic的offset变化 + * @param physicalClusterId 物理集群Id + * @param topicName topic名称 + * @param latestTime 离当前多久开始计算 + * @return + */ Result checkTopicOffsetChanged(Long physicalClusterId, String topicName, Long latestTime); } diff --git a/kafka-manager-core/src/main/java/com/xiaojukeji/kafka/manager/service/service/impl/TopicServiceImpl.java b/kafka-manager-core/src/main/java/com/xiaojukeji/kafka/manager/service/service/impl/TopicServiceImpl.java index 154faf77..70ef139c 100644 --- a/kafka-manager-core/src/main/java/com/xiaojukeji/kafka/manager/service/service/impl/TopicServiceImpl.java +++ b/kafka-manager-core/src/main/java/com/xiaojukeji/kafka/manager/service/service/impl/TopicServiceImpl.java @@ -247,11 +247,11 @@ public class TopicServiceImpl implements TopicService { @Override public List getTopicPartitionDTO(ClusterDO clusterDO, String topicName, Boolean needDetail) { if (ValidateUtils.isNull(clusterDO) || ValidateUtils.isNull(topicName)) { - return null; + return new ArrayList<>(); } TopicMetadata topicMetadata = PhysicalClusterMetadataManager.getTopicMetadata(clusterDO.getId(), topicName); if (ValidateUtils.isNull(topicMetadata)) { - return null; + return new ArrayList<>(); } List partitionStateList = KafkaZookeeperUtils.getTopicPartitionState( @@ -528,7 +528,7 @@ public class TopicServiceImpl implements TopicService { public List getPartitionOffsetList(ClusterDO clusterDO, String topicName, Long timestamp) { TopicMetadata topicMetadata = PhysicalClusterMetadataManager.getTopicMetadata(clusterDO.getId(), topicName); if (topicMetadata == null) { - return null; + return new ArrayList<>(); } Map timestampsToSearch = new HashMap<>(); for (Integer partitionId : topicMetadata.getPartitionMap().getPartitions().keySet()) { @@ -572,7 +572,7 @@ public class TopicServiceImpl implements TopicService { kafkaConsumer.close(); } } - return null; + return new ArrayList<>(); } private List fetchTopicData(KafkaConsumer kafkaConsumer, ClusterDO clusterDO, String topicName, TopicDataSampleDTO reqObj) { @@ -585,7 +585,7 @@ public class TopicServiceImpl implements TopicService { tpList.add(new TopicPartition(topicName, partitionId)); } if (ValidateUtils.isEmptyList(tpList)) { - return null; + return new ArrayList<>(); } kafkaConsumer.assign(tpList); diff --git a/kafka-manager-core/src/main/java/com/xiaojukeji/kafka/manager/service/service/impl/ZookeeperServiceImpl.java b/kafka-manager-core/src/main/java/com/xiaojukeji/kafka/manager/service/service/impl/ZookeeperServiceImpl.java index cb9827bd..c4c89513 100644 --- a/kafka-manager-core/src/main/java/com/xiaojukeji/kafka/manager/service/service/impl/ZookeeperServiceImpl.java +++ b/kafka-manager-core/src/main/java/com/xiaojukeji/kafka/manager/service/service/impl/ZookeeperServiceImpl.java @@ -28,7 +28,7 @@ public class ZookeeperServiceImpl implements ZookeeperService { @Override public Result openTopicJmx(Long clusterId, String topicName, TopicJmxSwitch jmxSwitch) { - if (ValidateUtils.isNull(clusterId) || ValidateUtils.isNull(topicName) || ValidateUtils.isNull(jmxSwitch)) { + if (ValidateUtils.isNull(clusterId) || ValidateUtils.isNull(topicName)) { return Result.buildFrom(ResultStatus.PARAM_ILLEGAL); } From f2cb5bd77c755e156cfc784be294401a10e2b7db Mon Sep 17 00:00:00 2001 From: xuguang Date: Thu, 23 Dec 2021 18:15:40 +0800 Subject: [PATCH 08/10] bugfix: TopicServiceImpl && JmxServiceImpl && ConsumerService && ConsumerServiceImpl --- .../service/service/ConsumerService.java | 20 +++++++++++++++++++ .../service/impl/ConsumerServiceImpl.java | 7 ++----- .../service/service/impl/JmxServiceImpl.java | 4 +++- .../service/impl/TopicServiceImpl.java | 3 --- 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/kafka-manager-core/src/main/java/com/xiaojukeji/kafka/manager/service/service/ConsumerService.java b/kafka-manager-core/src/main/java/com/xiaojukeji/kafka/manager/service/service/ConsumerService.java index 3eab40b8..07c92bc6 100644 --- a/kafka-manager-core/src/main/java/com/xiaojukeji/kafka/manager/service/service/ConsumerService.java +++ b/kafka-manager-core/src/main/java/com/xiaojukeji/kafka/manager/service/service/ConsumerService.java @@ -42,6 +42,13 @@ public interface ConsumerService { */ List getConsumerGroupConsumedTopicList(Long clusterId, String consumerGroup, String location); + /** + * 获取消费者offset + * @param clusterDO 集群 + * @param topicName topic + * @param consumerGroup 消费组 + * @return Map + */ Map getConsumerOffset(ClusterDO clusterDO, String topicName, ConsumerGroup consumerGroup); /** @@ -52,7 +59,20 @@ public interface ConsumerService { ConsumerGroup consumerGroup, List partitionOffsetDTOList); + /** + * 获取每个集群消费组的个数 + * @param clusterDOList 物理集群列表 + * @return Map + */ Map getConsumerGroupNumMap(List clusterDOList); + /** + * 验证消费组是否存在 + * @param offsetLocation offset存放位置 + * @param id 集群id + * @param topicName topic + * @param consumerGroup 消费组 + * @return true:存在,false:不存在 + */ boolean checkConsumerGroupExist(OffsetLocationEnum offsetLocation, Long id, String topicName, String consumerGroup); } diff --git a/kafka-manager-core/src/main/java/com/xiaojukeji/kafka/manager/service/service/impl/ConsumerServiceImpl.java b/kafka-manager-core/src/main/java/com/xiaojukeji/kafka/manager/service/service/impl/ConsumerServiceImpl.java index 913316ef..e59aa2bc 100644 --- a/kafka-manager-core/src/main/java/com/xiaojukeji/kafka/manager/service/service/impl/ConsumerServiceImpl.java +++ b/kafka-manager-core/src/main/java/com/xiaojukeji/kafka/manager/service/service/impl/ConsumerServiceImpl.java @@ -159,7 +159,7 @@ public class ConsumerServiceImpl implements ConsumerService { if (topicMetadata == null) { logger.warn("class=ConsumerServiceImpl||method=getConsumeDetail||clusterId={}||topicName={}||msg=topicMetadata is null!", clusterDO.getId(), topicName); - return null; + return Collections.emptyList(); } List consumerGroupDetailDTOList = null; @@ -170,7 +170,7 @@ public class ConsumerServiceImpl implements ConsumerService { } if (consumerGroupDetailDTOList == null) { logger.info("class=ConsumerServiceImpl||method=getConsumeDetail||msg=consumerGroupDetailDTOList is null!"); - return null; + return Collections.emptyList(); } Map topicPartitionLongMap = topicService.getPartitionOffset(clusterDO, topicName, OffsetPosEnum.END); @@ -317,9 +317,6 @@ public class ConsumerServiceImpl implements ConsumerService { String consumerGroup) { Map stringOffsetMap = getOffsetByGroupAndTopicFromBroker(clusterDO, consumerGroup, topicName); - if (ValidateUtils.isNull(stringOffsetMap)) { - return new HashMap<>(0); - } Map offsetMap = new HashMap<>(stringOffsetMap.size()); for (Map.Entry entry: stringOffsetMap.entrySet()) { diff --git a/kafka-manager-core/src/main/java/com/xiaojukeji/kafka/manager/service/service/impl/JmxServiceImpl.java b/kafka-manager-core/src/main/java/com/xiaojukeji/kafka/manager/service/service/impl/JmxServiceImpl.java index 611dc203..1dc3b011 100644 --- a/kafka-manager-core/src/main/java/com/xiaojukeji/kafka/manager/service/service/impl/JmxServiceImpl.java +++ b/kafka-manager-core/src/main/java/com/xiaojukeji/kafka/manager/service/service/impl/JmxServiceImpl.java @@ -164,9 +164,11 @@ public class JmxServiceImpl implements JmxService { if (ValidateUtils.isNull(jmxConnectorWrap)|| !jmxConnectorWrap.checkJmxConnectionAndInitIfNeed()) { return null; } + + KafkaVersion kafkaVersion = physicalClusterMetadataManager.getKafkaVersion(clusterId, brokerId); + TopicMetrics metrics = new TopicMetrics(clusterId, topicName); for (MbeanV2 mbeanV2: mbeanV2List) { - KafkaVersion kafkaVersion = physicalClusterMetadataManager.getKafkaVersion(clusterId, brokerId); try { getAndSupplyAttributes2BaseMetrics( metrics, diff --git a/kafka-manager-core/src/main/java/com/xiaojukeji/kafka/manager/service/service/impl/TopicServiceImpl.java b/kafka-manager-core/src/main/java/com/xiaojukeji/kafka/manager/service/service/impl/TopicServiceImpl.java index 70ef139c..94b3f88f 100644 --- a/kafka-manager-core/src/main/java/com/xiaojukeji/kafka/manager/service/service/impl/TopicServiceImpl.java +++ b/kafka-manager-core/src/main/java/com/xiaojukeji/kafka/manager/service/service/impl/TopicServiceImpl.java @@ -416,9 +416,6 @@ public class TopicServiceImpl implements TopicService { topicDO, appDO ); - if (ValidateUtils.isNull(overview)) { - continue; - } dtoList.add(overview); } From b2091e9aedeb8bb28ee60be9d1a3e3543e977258 Mon Sep 17 00:00:00 2001 From: xuguang Date: Thu, 23 Dec 2021 18:17:47 +0800 Subject: [PATCH 09/10] =?UTF-8?q?=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=EF=BC=9AAnalysisServiceTest=20&&=20ConsumerServiceTest=20&&=20?= =?UTF-8?q?JmxServiceTest=20&&=20LogicalClusterServiceTest=20&&=20Reassign?= =?UTF-8?q?ServiceTest=20&&=20TopicServiceTest?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/service/AnalysisServiceTest.java | 54 ++ .../service/service/ConsumerServiceTest.java | 264 +++++++ .../service/service/JmxServiceTest.java | 386 +++++++++ .../service/LogicalClusterServiceTest.java | 24 +- .../service/service/ReassignServiceTest.java | 458 +++++++++++ .../service/service/TopicServiceTest.java | 741 ++++++++++++++++++ 6 files changed, 1917 insertions(+), 10 deletions(-) create mode 100644 kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/AnalysisServiceTest.java create mode 100644 kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/ConsumerServiceTest.java create mode 100644 kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/JmxServiceTest.java create mode 100644 kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/ReassignServiceTest.java create mode 100644 kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/TopicServiceTest.java diff --git a/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/AnalysisServiceTest.java b/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/AnalysisServiceTest.java new file mode 100644 index 00000000..b4d3657d --- /dev/null +++ b/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/AnalysisServiceTest.java @@ -0,0 +1,54 @@ +package com.xiaojukeji.kafka.manager.service.service; + +import com.xiaojukeji.kafka.manager.common.entity.ao.analysis.AnalysisBrokerDTO; +import com.xiaojukeji.kafka.manager.service.config.BaseTest; + +import org.springframework.beans.factory.annotation.Autowired; +import org.testng.Assert; +import org.testng.annotations.Test; + +/** + * @author xuguang + * @Date 2021/12/23 + */ +public class AnalysisServiceTest extends BaseTest { + + private final static Long REAL_CLUSTER_ID_IN_MYSQL = 1L; + + private final static Integer REAL_BROKER_ID_IN_ZK = 1; + + private final static Long INVALID_CLUSTER_ID = -1L; + + @Autowired + private AnalysisService analysisService; + + @Test + public void doAnalysisBrokerTest() { + // brokerMetrics is null + doAnalysisBroker2brokerMetricsIsNullTest(); + // brokerMetrics is not null + doAnalysisBroker2brokerMetricsIsNotNullTest(); + } + + private void doAnalysisBroker2brokerMetricsIsNullTest() { + AnalysisBrokerDTO analysisBrokerDTO = analysisService.doAnalysisBroker( + INVALID_CLUSTER_ID, + REAL_BROKER_ID_IN_ZK + ); + Assert.assertNotNull(analysisBrokerDTO); + Assert.assertEquals(analysisBrokerDTO.getBrokerId(), REAL_BROKER_ID_IN_ZK); + Assert.assertEquals(analysisBrokerDTO.getClusterId(), INVALID_CLUSTER_ID); + Assert.assertNull(analysisBrokerDTO.getBytesIn()); + } + + private void doAnalysisBroker2brokerMetricsIsNotNullTest() { + AnalysisBrokerDTO analysisBrokerDTO = analysisService.doAnalysisBroker( + REAL_CLUSTER_ID_IN_MYSQL, + REAL_BROKER_ID_IN_ZK + ); + Assert.assertNotNull(analysisBrokerDTO); + Assert.assertEquals(analysisBrokerDTO.getBrokerId(), REAL_BROKER_ID_IN_ZK); + Assert.assertEquals(analysisBrokerDTO.getClusterId(), REAL_CLUSTER_ID_IN_MYSQL); + Assert.assertNotNull(analysisBrokerDTO.getBytesIn()); + } +} diff --git a/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/ConsumerServiceTest.java b/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/ConsumerServiceTest.java new file mode 100644 index 00000000..21162aee --- /dev/null +++ b/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/ConsumerServiceTest.java @@ -0,0 +1,264 @@ +package com.xiaojukeji.kafka.manager.service.service; + +import com.xiaojukeji.kafka.manager.common.bizenum.OffsetLocationEnum; +import com.xiaojukeji.kafka.manager.common.entity.Result; +import com.xiaojukeji.kafka.manager.common.entity.ResultStatus; +import com.xiaojukeji.kafka.manager.common.entity.ao.PartitionOffsetDTO; +import com.xiaojukeji.kafka.manager.common.entity.ao.consumer.ConsumeDetailDTO; +import com.xiaojukeji.kafka.manager.common.entity.ao.consumer.ConsumerGroup; +import com.xiaojukeji.kafka.manager.common.entity.ao.consumer.ConsumerGroupSummary; +import com.xiaojukeji.kafka.manager.common.entity.pojo.ClusterDO; +import com.xiaojukeji.kafka.manager.service.config.BaseTest; + +import org.springframework.beans.factory.annotation.Autowired; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + * 测试消费组消费情况需要保证集群中存在消费组 + * @author xuguang + * @Date 2021/12/23 + */ +public class ConsumerServiceTest extends BaseTest { + + private final static Long REAL_CLUSTER_ID_IN_MYSQL = 1L; + + private final static Integer REAL_BROKER_ID_IN_ZK = 1; + + private final static Long INVALID_CLUSTER_ID = -1L; + + /** + * 集群共包括三个broker:1,2,3, 该topic 1分区 1副本因子,在broker1上 + */ + private final static String REAL_TOPIC1_IN_ZK = "moduleTest"; + + /** + * 集群共包括三个broker:1,2,3, 该topic 2分区 3副本因子,在broker1,2,3上 + */ + private final static String REAL_TOPIC2_IN_ZK = "xgTest"; + + private final static String INVALID_TOPIC = "xxxxxx"; + + private final static String REAL_CONSUMER_GROUP_NAME = "moduleTestGroup"; + + private final static String INVALID_CONSUMER_GROUP_NAME = "xxxxxxxx"; + + @Autowired + private ConsumerService consumerService; + + private ClusterDO getClusterDO() { + ClusterDO clusterDO = new ClusterDO(); + clusterDO.setId(1L); + clusterDO.setClusterName("LogiKM_moduleTest"); + clusterDO.setZookeeper("10.190.46.198:2181,10.190.14.237:2181,10.190.50.65:2181/xg"); + clusterDO.setBootstrapServers("10.190.46.198:9093,10.190.14.237:9093,10.190.50.65:9093"); + clusterDO.setSecurityProperties("{ \t\"security.protocol\": \"SASL_PLAINTEXT\", \t\"sasl.mechanism\": \"PLAIN\", \t\"sasl.jaas.config\": \"org.apache.kafka.common.security.plain.PlainLoginModule required username=\\\"dkm_admin\\\" password=\\\"km_kMl4N8as1Kp0CCY\\\";\" }"); + clusterDO.setStatus(1); + clusterDO.setGmtCreate(new Date()); + clusterDO.setGmtModify(new Date()); + return clusterDO; + } + + private ConsumerGroup getConsumerGroup() { + return new ConsumerGroup( + REAL_CLUSTER_ID_IN_MYSQL, + REAL_CONSUMER_GROUP_NAME, + OffsetLocationEnum.BROKER); + } + + private PartitionOffsetDTO getPartitionOffsetDTO() { + PartitionOffsetDTO partitionOffsetDTO = new PartitionOffsetDTO(); + partitionOffsetDTO.setOffset(0L); + partitionOffsetDTO.setPartitionId(0); + return partitionOffsetDTO; + } + + @Test(description = "测试获取消费组列表") + public void getConsumerGroupListTest() { + List consumerGroupList = consumerService.getConsumerGroupList(REAL_CLUSTER_ID_IN_MYSQL); + Assert.assertFalse(consumerGroupList.isEmpty()); + Assert.assertTrue(consumerGroupList.stream().allMatch(consumerGroup -> + consumerGroup.getClusterId().equals(REAL_CLUSTER_ID_IN_MYSQL))); + } + + @Test(description = "测试查询消费Topic的消费组") + public void getConsumerGroupListWithTopicTest() { + List consumerGroupList = consumerService.getConsumerGroupList( + REAL_CLUSTER_ID_IN_MYSQL, + REAL_TOPIC1_IN_ZK + ); + Assert.assertFalse(consumerGroupList.isEmpty()); + Assert.assertTrue(consumerGroupList.stream().allMatch(consumerGroup -> + consumerGroup.getClusterId().equals(REAL_CLUSTER_ID_IN_MYSQL))); + } + + @Test(description = "测试获取消费Topic的消费组概要信息") + public void getConsumerGroupSummariesTest() { + // result is empty + getConsumerGroupSummaries2EmptyTest(); + // result is not empty + getConsumerGroupSummaries2NotEmptyTest(); + } + + private void getConsumerGroupSummaries2EmptyTest() { + List consumerGroupSummaries = consumerService.getConsumerGroupSummaries( + REAL_CLUSTER_ID_IN_MYSQL, + INVALID_TOPIC + ); + Assert.assertTrue(consumerGroupSummaries.isEmpty()); + } + + private void getConsumerGroupSummaries2NotEmptyTest() { + List consumerGroupSummaries = consumerService.getConsumerGroupSummaries( + REAL_CLUSTER_ID_IN_MYSQL, + REAL_TOPIC1_IN_ZK + ); + Assert.assertFalse(consumerGroupSummaries.isEmpty()); + } + + @Test(description = "测试查询消费详情") + public void getConsumeDetail() { + // result is empty + getConsumeDetail2Empty(); + // result is not empty + getConsumeDetail2NotEmpty(); + } + + private void getConsumeDetail2Empty() { + ClusterDO clusterDO = getClusterDO(); + List consumeDetail1 = + consumerService.getConsumeDetail(clusterDO, INVALID_TOPIC, null); + Assert.assertTrue(consumeDetail1.isEmpty()); + + ConsumerGroup consumerGroup = getConsumerGroup(); + consumerGroup.setOffsetStoreLocation(null); + List consumeDetail2 = + consumerService.getConsumeDetail(clusterDO, REAL_TOPIC1_IN_ZK, consumerGroup); + Assert.assertTrue(consumeDetail2.isEmpty()); + } + + private void getConsumeDetail2NotEmpty() { + ClusterDO clusterDO = getClusterDO(); + ConsumerGroup consumerGroup = getConsumerGroup(); + List consumeDetail1 = + consumerService.getConsumeDetail(clusterDO, REAL_TOPIC1_IN_ZK, consumerGroup); + Assert.assertFalse(consumeDetail1.isEmpty()); + } + + @Test(description = "测试获取消费组消费的Topic列表") + public void getConsumerGroupConsumedTopicListTest() { + // result is empty + getConsumerGroupConsumedTopicList2Empty(); + // result is not empty + getConsumerGroupConsumedTopicList2NotEmpty(); + } + + private void getConsumerGroupConsumedTopicList2Empty() { + List list = consumerService.getConsumerGroupConsumedTopicList( + null, + null, + null); + Assert.assertTrue(list.isEmpty()); + } + + private void getConsumerGroupConsumedTopicList2NotEmpty() { + List list = consumerService.getConsumerGroupConsumedTopicList( + REAL_CLUSTER_ID_IN_MYSQL, + REAL_CONSUMER_GROUP_NAME, + "broker"); + Assert.assertFalse(list.isEmpty()); + } + + @Test(description = "测试获取消费者offset") + public void getConsumerOffsetTest() { + // result is null + getConsumerOffset2NullTest(); + // result is not null + getConsumerOffset2NotNullTest(); + } + + private void getConsumerOffset2NullTest() { + Map consumerOffset1 = consumerService.getConsumerOffset(null, null, null); + Assert.assertNull(consumerOffset1); + + ClusterDO clusterDO = getClusterDO(); + ConsumerGroup consumerGroup = getConsumerGroup(); + consumerGroup.setOffsetStoreLocation(null); + Map consumerOffset2 = consumerService.getConsumerOffset( + clusterDO, + REAL_TOPIC1_IN_ZK, + consumerGroup + ); + Assert.assertNull(consumerOffset2); + } + + private void getConsumerOffset2NotNullTest() { + ClusterDO clusterDO = getClusterDO(); + ConsumerGroup consumerGroup = getConsumerGroup(); + Map consumerOffset = consumerService.getConsumerOffset( + clusterDO, + REAL_TOPIC1_IN_ZK, + consumerGroup + ); + Assert.assertNotNull(consumerOffset); + Assert.assertFalse(consumerOffset.isEmpty()); + } + + @Test(description = "测试获取每个集群消费组的个数") + public void getConsumerGroupNumMapTest() { + ClusterDO clusterDO = getClusterDO(); + Map map = consumerService.getConsumerGroupNumMap(Arrays.asList(clusterDO)); + Assert.assertFalse(map.isEmpty()); + Assert.assertTrue(clusterDO.getId() >= 0); + } + + @Test(description = "验证消费组是否存在") + public void checkConsumerGroupExistTest() { + // 不存在 + checkConsumerGroupExist2FalseTest(); + // 存在 + checkConsumerGroupExist2TrueTest(); + } + + private void checkConsumerGroupExist2FalseTest() { + boolean result = consumerService.checkConsumerGroupExist( + OffsetLocationEnum.BROKER, + REAL_CLUSTER_ID_IN_MYSQL, + REAL_TOPIC1_IN_ZK, + INVALID_CONSUMER_GROUP_NAME + ); + Assert.assertFalse(result); + } + + private void checkConsumerGroupExist2TrueTest() { + boolean result = consumerService.checkConsumerGroupExist( + OffsetLocationEnum.BROKER, + REAL_CLUSTER_ID_IN_MYSQL, + REAL_TOPIC1_IN_ZK, + REAL_CONSUMER_GROUP_NAME + ); + Assert.assertTrue(result); + } + + @Test(description = "测试重置offset") + public void resetConsumerOffsetTest() { + ClusterDO clusterDO = getClusterDO(); + ConsumerGroup consumerGroup = getConsumerGroup(); + PartitionOffsetDTO partitionOffsetDTO1 = getPartitionOffsetDTO(); + List results = consumerService.resetConsumerOffset( + clusterDO, + REAL_TOPIC1_IN_ZK, + consumerGroup, + Arrays.asList(partitionOffsetDTO1) + ); + Assert.assertFalse(results.isEmpty()); + Assert.assertTrue(results.stream().allMatch(result -> + result.getCode() == ResultStatus.SUCCESS.getCode())); + } + +} diff --git a/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/JmxServiceTest.java b/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/JmxServiceTest.java new file mode 100644 index 00000000..c813c275 --- /dev/null +++ b/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/JmxServiceTest.java @@ -0,0 +1,386 @@ +package com.xiaojukeji.kafka.manager.service.service; + +import com.xiaojukeji.kafka.manager.common.bizenum.KafkaClientEnum; +import com.xiaojukeji.kafka.manager.common.constant.KafkaMetricsCollections; +import com.xiaojukeji.kafka.manager.common.entity.ao.PartitionAttributeDTO; +import com.xiaojukeji.kafka.manager.common.entity.metrics.BrokerMetrics; +import com.xiaojukeji.kafka.manager.common.entity.metrics.TopicMetrics; +import com.xiaojukeji.kafka.manager.common.zookeeper.znode.brokers.PartitionState; +import com.xiaojukeji.kafka.manager.service.config.BaseTest; +import org.apache.kafka.common.TopicPartition; +import org.springframework.beans.factory.annotation.Autowired; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.util.*; + +/** + * @author xuguang + * @Date 2021/12/14 + */ +public class JmxServiceTest extends BaseTest { + /** + * 集群共包括三个broker:1,2,3, 该topic 1分区 1副本因子,在broker1上 + */ + private final static String REAL_TOPIC1_IN_ZK = "moduleTest"; + + /** + * 集群共包括三个broker:1,2,3, 该topic 2分区 3副本因子,在broker1,2,3上 + */ + private final static String REAL_TOPIC2_IN_ZK = "xgTest"; + + private final static String INVALID_TOPIC = "xxxxx"; + + private final static String ZK_DEFAULT_TOPIC = "_consumer_offsets"; + + private final static String NO_OFFSET_CHANGE_TOPIC_IN_ZK = "NoOffsetChangeTopic"; + + private final static Long REAL_CLUSTER_ID_IN_MYSQL = 1L; + + private final static Integer REAL_BROKER_ID_IN_ZK = 1; + + private final static Integer INVALID_BROKER_ID = -1; + + private final static Long INVALID_CLUSTER_ID = -1L; + + private final static Integer INVALID_PARTITION_ID = -1; + + private final static String CLIENT_ID = "dkm_admin.moduleTest"; + + private final static Integer INVALID_METRICS_CODE = -1; + + @Autowired + private JmxService jmxService; + + private PartitionState getPartitionState() { + PartitionState partitionState = new PartitionState(); + partitionState.setPartitionId(0); + partitionState.setLeader(2); + return partitionState; + } + + @Test + public void getBrokerMetricsTest() { + // 结果为空 + getBrokerMetrics2NullTest(); + // mbeanV2ListEmpty + getBrokerMetrics2mbeanV2ListEmptyTest(); + // 获取成功 + getBrokerMetrics2SuccessTest(); + } + + private void getBrokerMetrics2NullTest() { + BrokerMetrics brokerMetrics1 = jmxService.getBrokerMetrics(null, null, null); + Assert.assertNull(brokerMetrics1); + + BrokerMetrics brokerMetrics2 = jmxService.getBrokerMetrics( + REAL_CLUSTER_ID_IN_MYSQL, + INVALID_BROKER_ID, + KafkaMetricsCollections.BROKER_ANALYSIS_METRICS); + Assert.assertNull(brokerMetrics2); + } + + private void getBrokerMetrics2mbeanV2ListEmptyTest() { + BrokerMetrics brokerMetrics2 = jmxService.getBrokerMetrics( + REAL_CLUSTER_ID_IN_MYSQL, + REAL_BROKER_ID_IN_ZK, + -1); + Assert.assertNotNull(brokerMetrics2); + Assert.assertEquals(brokerMetrics2.getClusterId(), REAL_CLUSTER_ID_IN_MYSQL); + Assert.assertEquals(brokerMetrics2.getBrokerId(), REAL_BROKER_ID_IN_ZK); + Assert.assertTrue(brokerMetrics2.getMetricsMap().isEmpty()); + } + + private void getBrokerMetrics2SuccessTest() { + BrokerMetrics brokerMetrics2 = jmxService.getBrokerMetrics( + REAL_CLUSTER_ID_IN_MYSQL, + REAL_BROKER_ID_IN_ZK, + KafkaMetricsCollections.BROKER_ANALYSIS_METRICS); + Assert.assertNotNull(brokerMetrics2); + Assert.assertEquals(brokerMetrics2.getClusterId(), REAL_CLUSTER_ID_IN_MYSQL); + Assert.assertEquals(brokerMetrics2.getBrokerId(), REAL_BROKER_ID_IN_ZK); + Assert.assertFalse(brokerMetrics2.getMetricsMap().isEmpty()); + } + + @Test + public void getTopicMetricsWithBrokerIdTest() { + // 结果为空 + getTopicMetricsWithBrokerId2nullTest(); + // 获取的metrics为空 + getTopicMetricsWithBrokerId2MetricsIsNullTest(); + // 获取指标成功 + getTopicMetricsWithBrokerId2SuccessTest(); + } + + private void getTopicMetricsWithBrokerId2nullTest() { + TopicMetrics topicMetrics1 = jmxService.getTopicMetrics( + REAL_CLUSTER_ID_IN_MYSQL, + REAL_BROKER_ID_IN_ZK, + REAL_TOPIC1_IN_ZK, + -1, true); + Assert.assertNull(topicMetrics1); + + TopicMetrics topicMetrics2 = jmxService.getTopicMetrics( + REAL_CLUSTER_ID_IN_MYSQL, + INVALID_BROKER_ID, + REAL_TOPIC1_IN_ZK, + KafkaMetricsCollections.BROKER_ANALYSIS_METRICS + , true); + Assert.assertNull(topicMetrics2); + } + + private void getTopicMetricsWithBrokerId2MetricsIsNullTest() { + // brokerId为3,不在该topic下 + TopicMetrics topicMetrics2 = jmxService.getTopicMetrics( + REAL_CLUSTER_ID_IN_MYSQL, + 3, + REAL_TOPIC1_IN_ZK, + KafkaMetricsCollections.BROKER_ANALYSIS_METRICS + , true); + Assert.assertNotNull(topicMetrics2); + Assert.assertEquals(topicMetrics2.getClusterId(), REAL_CLUSTER_ID_IN_MYSQL); + Assert.assertEquals(topicMetrics2.getTopicName(), REAL_TOPIC1_IN_ZK); + Assert.assertTrue(topicMetrics2.getMetricsMap().isEmpty()); + } + + private void getTopicMetricsWithBrokerId2SuccessTest() { + TopicMetrics topicMetrics2 = jmxService.getTopicMetrics( + REAL_CLUSTER_ID_IN_MYSQL, + REAL_BROKER_ID_IN_ZK, + REAL_TOPIC1_IN_ZK, + KafkaMetricsCollections.TOPIC_REQUEST_TIME_METRICS_TO_DB + , true); + Assert.assertNotNull(topicMetrics2); + Assert.assertEquals(topicMetrics2.getClusterId(), REAL_CLUSTER_ID_IN_MYSQL); + Assert.assertEquals(topicMetrics2.getTopicName(), REAL_TOPIC1_IN_ZK); + Assert.assertFalse(topicMetrics2.getMetricsMap().isEmpty()); + } + + @Test + public void getTopicMetricsWithoutBrokerId() { + // 返回为空 + getTopicMetricsWithoutBrokerId2Null(); + // add + getTopicMetricsWithoutBrokerId2Add(); + // max + getTopicMetricsWithoutBrokerId2Max(); + } + + private void getTopicMetricsWithoutBrokerId2Null() { + TopicMetrics topicMetrics = jmxService.getTopicMetrics( + REAL_CLUSTER_ID_IN_MYSQL, + INVALID_TOPIC, + KafkaMetricsCollections.TOPIC_METRICS_TO_DB + , true); + Assert.assertNull(topicMetrics); + } + + private void getTopicMetricsWithoutBrokerId2Add() { + TopicMetrics topicMetrics = jmxService.getTopicMetrics( + REAL_CLUSTER_ID_IN_MYSQL, + REAL_TOPIC1_IN_ZK, + KafkaMetricsCollections.TOPIC_REQUEST_TIME_METRICS_TO_DB + , true); + Assert.assertNotNull(topicMetrics); + Assert.assertNotNull(topicMetrics.getBrokerMetricsList()); + Assert.assertNotNull(topicMetrics.getMetricsMap()); + } + + private void getTopicMetricsWithoutBrokerId2Max() { + TopicMetrics topicMetrics = jmxService.getTopicMetrics( + REAL_CLUSTER_ID_IN_MYSQL, + REAL_TOPIC2_IN_ZK, + KafkaMetricsCollections.TOPIC_REQUEST_TIME_METRICS_TO_DB + , false); + Assert.assertNotNull(topicMetrics); + Assert.assertNotNull(topicMetrics.getBrokerMetricsList()); + Assert.assertNotNull(topicMetrics.getMetricsMap()); + } + + @Test(description = "测试获取集群下所有topic指标") + public void getTopicMetricsList() { + List topicMetrics = jmxService.getTopicMetrics( + REAL_CLUSTER_ID_IN_MYSQL, + KafkaMetricsCollections.TOPIC_REQUEST_TIME_METRICS_TO_DB + , false); + Assert.assertFalse(topicMetrics.isEmpty()); + Assert.assertTrue(topicMetrics.stream().allMatch(topicMetric -> + topicMetric.getClusterId().equals(REAL_CLUSTER_ID_IN_MYSQL))); + } + + @Test(description = "测试获取broker版本") + public void getBrokerVersion() { + // 结果为空 + getBrokerVersion2Empty(); + // 结果不为空 + getBrokerVersion2NotEmpty(); + } + + private void getBrokerVersion2Empty() { + String brokerVersion = jmxService.getBrokerVersion( + REAL_CLUSTER_ID_IN_MYSQL, + INVALID_BROKER_ID); + Assert.assertEquals(brokerVersion, ""); + } + + private void getBrokerVersion2NotEmpty() { + String brokerVersion = jmxService.getBrokerVersion( + REAL_CLUSTER_ID_IN_MYSQL, + REAL_BROKER_ID_IN_ZK); + Assert.assertNotEquals(brokerVersion, ""); + } + + @Test(description = "获取客户端限流信息") + public void getTopicAppThrottleTest() { + // 结果为0 + getTopicAppThrottle2ZeroTest(); + // 结果不为0 + getTopicAppThrottle2NotZeroTest(); + } + + private void getTopicAppThrottle2ZeroTest() { + double topicAppThrottle = jmxService.getTopicAppThrottle( + REAL_CLUSTER_ID_IN_MYSQL, + INVALID_BROKER_ID, + "1", + KafkaClientEnum.FETCH_CLIENT); + Assert.assertEquals(topicAppThrottle, 0.0d); + } + + private void getTopicAppThrottle2NotZeroTest() { + double topicAppThrottle = jmxService.getTopicAppThrottle( + REAL_CLUSTER_ID_IN_MYSQL, + REAL_BROKER_ID_IN_ZK, + CLIENT_ID, + KafkaClientEnum.FETCH_CLIENT); + // 未设置限流,所以还是为0 + Assert.assertEquals(topicAppThrottle, 0.0d); + } + + @Test(description = "获取被限流信息") + public void getBrokerThrottleClientsTest() { + // 结果为空 + getBrokerThrottleClients2EmptyTest(); + // 构造限流client,返回结果不为空 + getBrokerThrottleClients2NotEmptyTest(); + } + + private void getBrokerThrottleClients2EmptyTest() { + Set brokerThrottleClients = jmxService.getBrokerThrottleClients( + REAL_CLUSTER_ID_IN_MYSQL, + INVALID_BROKER_ID, + KafkaClientEnum.FETCH_CLIENT); + Assert.assertTrue(brokerThrottleClients.isEmpty()); + } + + private void getBrokerThrottleClients2NotEmptyTest() { + Set brokerThrottleClients = jmxService.getBrokerThrottleClients( + REAL_CLUSTER_ID_IN_MYSQL, + REAL_BROKER_ID_IN_ZK, + KafkaClientEnum.FETCH_CLIENT); + Assert.assertFalse(brokerThrottleClients.isEmpty()); + } + + @Test(description = "测试获取topic消息压缩指标") + public void getTopicCodeCValueTest() { + // 结果为null + getTopicCodeCValue2NullTest(); + // 结果不为null + getTopicCodeCValue2SuccessTest(); + } + + private void getTopicCodeCValue2NullTest() { + String result = jmxService.getTopicCodeCValue(REAL_CLUSTER_ID_IN_MYSQL, INVALID_TOPIC); + Assert.assertNull(result); + } + + private void getTopicCodeCValue2SuccessTest() { + String result = jmxService.getTopicCodeCValue( + REAL_CLUSTER_ID_IN_MYSQL, + REAL_TOPIC2_IN_ZK); + Assert.assertNotNull(result); + } + + @Test(description = "测试从JMX中获取appId维度的的流量信息") + public void getTopicAppMetricsTest() { + // result is empty + getTopicAppMetrics2Empty(); + // result is not empty + getTopicAppMetrics2NotEmpty(); + } + + private void getTopicAppMetrics2Empty() { + List topicAppMetrics = jmxService.getTopicAppMetrics( + REAL_CLUSTER_ID_IN_MYSQL, + INVALID_METRICS_CODE); + Assert.assertTrue(topicAppMetrics.isEmpty()); + + List topicAppMetrics2 = jmxService.getTopicAppMetrics( + INVALID_CLUSTER_ID, + KafkaMetricsCollections.APP_TOPIC_METRICS_TO_DB); + Assert.assertTrue(topicAppMetrics2.isEmpty()); + } + + private void getTopicAppMetrics2NotEmpty() { + List topicAppMetrics = jmxService.getTopicAppMetrics( + REAL_CLUSTER_ID_IN_MYSQL, + KafkaMetricsCollections.APP_TOPIC_METRICS_TO_DB + ); + Assert.assertFalse(topicAppMetrics.isEmpty()); + } + + @Test + public void getBrokerTopicLocationTest() { + // result is empty + getBrokerTopicLocation2EmptyTest(); + // result is not empty + getBrokerTopicLocation2NotEmptyTest(); + } + + private void getBrokerTopicLocation2EmptyTest() { + Map brokerTopicLocation = jmxService.getBrokerTopicLocation( + REAL_CLUSTER_ID_IN_MYSQL, + INVALID_BROKER_ID + ); + Assert.assertTrue(brokerTopicLocation.isEmpty()); + } + + private void getBrokerTopicLocation2NotEmptyTest() { + Map brokerTopicLocation = jmxService.getBrokerTopicLocation( + REAL_CLUSTER_ID_IN_MYSQL, + 2 + ); + Assert.assertFalse(brokerTopicLocation.isEmpty()); + } + + @Test + public void getPartitionAttributeTest() { + // result is empty + getPartitionAttribute2EmptyTest(); + // result is not empty + getPartitionAttribute2NotEmptyTest(); + } + + private void getPartitionAttribute2EmptyTest() { + Map list = jmxService.getPartitionAttribute( + REAL_CLUSTER_ID_IN_MYSQL, + REAL_TOPIC2_IN_ZK, + Collections.emptyList()); + Assert.assertTrue(list.isEmpty()); + } + + private void getPartitionAttribute2NotEmptyTest() { + // 需要确定leader所在broker + PartitionState partitionState1 = getPartitionState(); + PartitionState partitionState2 = getPartitionState(); + partitionState2.setLeader(3); + partitionState2.setPartitionId(1); + + Map list = jmxService.getPartitionAttribute( + REAL_CLUSTER_ID_IN_MYSQL, + REAL_TOPIC2_IN_ZK, + Arrays.asList(partitionState1, partitionState1, partitionState2) + ); + Assert.assertFalse(list.isEmpty()); + } +} diff --git a/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/LogicalClusterServiceTest.java b/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/LogicalClusterServiceTest.java index 92d62c27..73a8ae3f 100644 --- a/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/LogicalClusterServiceTest.java +++ b/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/LogicalClusterServiceTest.java @@ -31,6 +31,10 @@ import java.util.*; */ public class LogicalClusterServiceTest extends BaseTest { + private final static Long INVALID_CLUSTER_ID = -1L; + + private final static Long REAL_CLUSTER_ID_IN_MYSQL = 1L; + @Autowired @InjectMocks private LogicalClusterService logicalClusterService; @@ -52,8 +56,8 @@ public class LogicalClusterServiceTest extends BaseTest { @DataProvider(name = "provideLogicalClusterDO") public Object[][] provideLogicalClusterDO() { LogicalClusterDO logicalClusterDO = new LogicalClusterDO(); - logicalClusterDO.setId(100L); - logicalClusterDO.setClusterId(1L); + logicalClusterDO.setId(INVALID_CLUSTER_ID); + logicalClusterDO.setClusterId(REAL_CLUSTER_ID_IN_MYSQL); logicalClusterDO.setIdentification("moduleTestLogicalCluster"); logicalClusterDO.setName("moduleTestLogicalCluster"); logicalClusterDO.setMode(1); @@ -66,8 +70,8 @@ public class LogicalClusterServiceTest extends BaseTest { private LogicalClusterDO getLogicalClusterDO() { LogicalClusterDO logicalClusterDO = new LogicalClusterDO(); - logicalClusterDO.setId(100L); - logicalClusterDO.setClusterId(1L); + logicalClusterDO.setId(INVALID_CLUSTER_ID); + logicalClusterDO.setClusterId(REAL_CLUSTER_ID_IN_MYSQL); logicalClusterDO.setIdentification("moduleTestLogicalCluster"); logicalClusterDO.setName("moduleTestLogicalCluster"); logicalClusterDO.setMode(0); @@ -120,7 +124,7 @@ public class LogicalClusterServiceTest extends BaseTest { Assert.assertEquals(result1.getCode(), ResultStatus.RESOURCE_ALREADY_USED.getCode()); // regionList为空情况 - logicalClusterDO.setClusterId(1L); + logicalClusterDO.setClusterId(REAL_CLUSTER_ID_IN_MYSQL); logicalClusterDO.setRegionList(""); ResultStatus result2 = logicalClusterService.createLogicalCluster(logicalClusterDO); Assert.assertEquals(result2.getCode(), ResultStatus.RESOURCE_ALREADY_USED.getCode()); @@ -135,7 +139,7 @@ public class LogicalClusterServiceTest extends BaseTest { LogicalClusterDO logicalClusterDO = getLogicalClusterDO(); Mockito.when(logicalClusterDao.insert(Mockito.any())).thenReturn(1); // 不存在该物理集群情况 - logicalClusterDO.setClusterId(100L); + logicalClusterDO.setClusterId(INVALID_CLUSTER_ID); ResultStatus result1 = logicalClusterService.createLogicalCluster(logicalClusterDO); Assert.assertNotEquals(result1.getCode(), ResultStatus.RESOURCE_ALREADY_USED.getCode()); Assert.assertEquals(result1.getCode(), ResultStatus.SUCCESS.getCode()); @@ -205,7 +209,7 @@ public class LogicalClusterServiceTest extends BaseTest { private void deleteById2ResourceNotExistTest() { Mockito.when(logicalClusterDao.deleteById(Mockito.anyLong())).thenReturn(-1); - ResultStatus resultStatus = logicalClusterService.deleteById(100L); + ResultStatus resultStatus = logicalClusterService.deleteById(INVALID_CLUSTER_ID); Assert.assertEquals(resultStatus.getCode(), ResultStatus.RESOURCE_NOT_EXIST.getCode()); } @@ -235,7 +239,7 @@ public class LogicalClusterServiceTest extends BaseTest { @Test(dataProvider = "provideLogicalClusterDO", description = "修改集群时无对应逻辑集群") public void updateById2ResourceNotExistTest(LogicalClusterDO logicalClusterDO) { - logicalClusterDO.setId(100L); + logicalClusterDO.setId(INVALID_CLUSTER_ID); ResultStatus resultStatus2 = logicalClusterService.updateById(logicalClusterDO); Assert.assertEquals(resultStatus2.getCode(), ResultStatus.RESOURCE_NOT_EXIST.getCode()); } @@ -250,7 +254,7 @@ public class LogicalClusterServiceTest extends BaseTest { Assert.assertEquals(result1.getCode(), ResultStatus.RESOURCE_ALREADY_USED.getCode()); // regionList为空情况 - logicalClusterDO.setClusterId(1L); + logicalClusterDO.setClusterId(REAL_CLUSTER_ID_IN_MYSQL); logicalClusterDO.setRegionList(""); ResultStatus result2 = logicalClusterService.updateById(logicalClusterDO); Assert.assertEquals(result2.getCode(), ResultStatus.RESOURCE_ALREADY_USED.getCode()); @@ -315,7 +319,7 @@ public class LogicalClusterServiceTest extends BaseTest { } private void getLogicalCluster2NullTest() { - LogicalCluster logicalCluster = logicalClusterService.getLogicalCluster(100L); + LogicalCluster logicalCluster = logicalClusterService.getLogicalCluster(INVALID_CLUSTER_ID); Assert.assertNull(logicalCluster); } diff --git a/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/ReassignServiceTest.java b/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/ReassignServiceTest.java new file mode 100644 index 00000000..a517c05d --- /dev/null +++ b/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/ReassignServiceTest.java @@ -0,0 +1,458 @@ +package com.xiaojukeji.kafka.manager.service.service; + +import com.xiaojukeji.kafka.manager.common.bizenum.TaskStatusReassignEnum; +import com.xiaojukeji.kafka.manager.common.bizenum.TopicReassignActionEnum; +import com.xiaojukeji.kafka.manager.common.entity.Result; +import com.xiaojukeji.kafka.manager.common.entity.ResultStatus; +import com.xiaojukeji.kafka.manager.common.entity.ao.reassign.ReassignStatus; +import com.xiaojukeji.kafka.manager.common.entity.dto.op.reassign.ReassignExecDTO; +import com.xiaojukeji.kafka.manager.common.entity.dto.op.reassign.ReassignExecSubDTO; +import com.xiaojukeji.kafka.manager.common.entity.dto.op.reassign.ReassignTopicDTO; +import com.xiaojukeji.kafka.manager.common.entity.pojo.ClusterDO; +import com.xiaojukeji.kafka.manager.common.entity.pojo.ReassignTaskDO; +import com.xiaojukeji.kafka.manager.dao.ReassignTaskDao; +import com.xiaojukeji.kafka.manager.service.config.BaseTest; +import kafka.common.TopicAndPartition; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.springframework.beans.factory.annotation.Autowired; +import org.testng.Assert; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import java.util.*; + +/** + * @author xuguang + * @Date 2021/12/14 + */ +public class ReassignServiceTest extends BaseTest { + + /** + * 集群共包括三个broker:1,2,3, 该topic 2分区 3副本因子,在broker1,2,3上 + */ + private final static String REAL_TOPIC2_IN_ZK = "xgTest"; + + private final static String ADMIN_OPERATOR = "admin"; + + @Autowired + @InjectMocks + private ReassignService reassignService; + + @Mock + private RegionService regionService; + + @Mock + private ClusterService clusterService; + + @Mock + private ReassignTaskDao reassignTaskDao; + + @BeforeMethod + public void setup() { + MockitoAnnotations.initMocks(this); + } + + private final static String ZOOKEEPER_ADDRESS = "10.190.46.198:2181,10.190.14.237:2181,10.190.50.65:2181/xg"; + + private final static String REASSIGNMENTJSON = + "{ \"version\": 1, \"partitions\": [ { \"topic\": \"reassignTest\", \"partition\": 1, \"replicas\": [ 1,2,3 ], \"log_dirs\": [ \"any\",\"any\",\"any\" ] }, { \"topic\": \"reassignTest\", \"partition\": 0, \"replicas\": [ 1,2,3 ], \"log_dirs\": [ \"any\",\"any\",\"any\" ] } ] }"; + + private ReassignTopicDTO getReassignTopicDTO() { + ReassignTopicDTO reassignTopicDTO = new ReassignTopicDTO(); + reassignTopicDTO.setClusterId(1L); + reassignTopicDTO.setTopicName(REAL_TOPIC2_IN_ZK); + reassignTopicDTO.setBrokerIdList(Arrays.asList(2,3)); + reassignTopicDTO.setRegionId(2L); + reassignTopicDTO.setPartitionIdList(Arrays.asList(0, 1)); + reassignTopicDTO.setThrottle(100000L); + reassignTopicDTO.setMaxThrottle(100000L); + reassignTopicDTO.setMinThrottle(100000L); + reassignTopicDTO.setOriginalRetentionTime(10000L); + reassignTopicDTO.setReassignRetentionTime(10000L); + reassignTopicDTO.setBeginTime(100000L); + reassignTopicDTO.setDescription(""); + return reassignTopicDTO; + } + + private ReassignExecDTO getReassignExecDTO() { + ReassignExecDTO reassignExecDTO = new ReassignExecDTO(); + reassignExecDTO.setTaskId(1L); + reassignExecDTO.setAction("modify"); + reassignExecDTO.setBeginTime(0L); + return reassignExecDTO; + } + + private ReassignTaskDO getReassignTaskDO() { + ReassignTaskDO reassignTaskDO = new ReassignTaskDO(); + reassignTaskDO.setId(1L); + reassignTaskDO.setClusterId(1L); + reassignTaskDO.setStatus(0); + reassignTaskDO.setTaskId(1L); + reassignTaskDO.setTopicName(REAL_TOPIC2_IN_ZK); + reassignTaskDO.setPartitions("0,1,2"); + reassignTaskDO.setReassignmentJson(""); + reassignTaskDO.setRealThrottle(1000L); + reassignTaskDO.setMaxThrottle(1000L); + reassignTaskDO.setMinThrottle(1000L); + reassignTaskDO.setBeginTime(new Date()); + reassignTaskDO.setSrcBrokers("0"); + reassignTaskDO.setDestBrokers("1"); + reassignTaskDO.setReassignRetentionTime(1000L); + reassignTaskDO.setOriginalRetentionTime(1000L); + reassignTaskDO.setDescription("测试迁移任务"); + reassignTaskDO.setOperator(ADMIN_OPERATOR); + return reassignTaskDO; + } + + private ReassignExecSubDTO getReassignExecSubDTO() { + ReassignExecSubDTO reassignExecSubDTO = new ReassignExecSubDTO(); + reassignExecSubDTO.setSubTaskId(1L); + reassignExecSubDTO.setAction("modify"); + reassignExecSubDTO.setThrottle(100000L); + reassignExecSubDTO.setMaxThrottle(100000L); + reassignExecSubDTO.setMinThrottle(100000L); + return reassignExecSubDTO; + } + + private ClusterDO getClusterDO() { + ClusterDO clusterDO = new ClusterDO(); + clusterDO.setId(1L); + clusterDO.setClusterName("LogiKM_moduleTest"); + clusterDO.setZookeeper("10.190.46.198:2181,10.190.14.237:2181,10.190.50.65:2181/xg"); + clusterDO.setBootstrapServers("10.190.46.198:9093,10.190.14.237:9093,10.190.50.65:9093"); + clusterDO.setSecurityProperties("{ \t\"security.protocol\": \"SASL_PLAINTEXT\", \t\"sasl.mechanism\": \"PLAIN\", \t\"sasl.jaas.config\": \"org.apache.kafka.common.security.plain.PlainLoginModule required username=\\\"dkm_admin\\\" password=\\\"km_kMl4N8as1Kp0CCY\\\";\" }"); + clusterDO.setStatus(1); + clusterDO.setGmtCreate(new Date()); + clusterDO.setGmtModify(new Date()); + return clusterDO; + } + + @Test(description = "创建迁移任务") + public void createTaskTest() { + // 参数错误 + createTask2paramIllegalTest(); + // 物理集群不存在 + createTask2ClusterNotExistTest(); + // topic不存在 + createTask2TopicNotExistTest(); + // broker数量不足 + createTask2BrokerNumNotEnoughTest(); + // broker不存在 + createTask2BrokerNotExistTest(); + // broker数量不足, checkParamLegal()方法中 + createTask2BrokerNumNotEnough2Test(); + // 参数错误, checkParamLegal()方法中 + createTask2ParamIllegal2Test(); + // 分区为空 + createTask2PartitionIdListEmptyTest(); + // 分区不存在 + createTask2PartitionNotExistTest(); + // 创建任务成功 + createTask2SuccessTest(); + } + + private void createTask2paramIllegalTest() { + ResultStatus result = reassignService.createTask(Collections.emptyList(), ADMIN_OPERATOR); + Assert.assertEquals(result.getCode(), ResultStatus.PARAM_ILLEGAL.getCode()); + } + + private void createTask2ClusterNotExistTest() { + ReassignTopicDTO reassignTopicDTO = getReassignTopicDTO(); + reassignTopicDTO.setClusterId(-1L); + ResultStatus result = reassignService.createTask(Arrays.asList(reassignTopicDTO), ADMIN_OPERATOR); + Assert.assertEquals(result.getCode(), ResultStatus.CLUSTER_NOT_EXIST.getCode()); + } + + private void createTask2TopicNotExistTest() { + ReassignTopicDTO reassignTopicDTO = getReassignTopicDTO(); + reassignTopicDTO.setClusterId(1L); + reassignTopicDTO.setTopicName("xxx"); + ResultStatus result = reassignService.createTask(Arrays.asList(reassignTopicDTO), ADMIN_OPERATOR); + Assert.assertEquals(result.getCode(), ResultStatus.TOPIC_NOT_EXIST.getCode()); + } + + private void createTask2BrokerNumNotEnoughTest() { + Mockito.when(regionService.getFullBrokerIdList( + Mockito.anyLong(), Mockito.anyLong(), Mockito.anyList())).thenReturn(null); + + ReassignTopicDTO reassignTopicDTO = getReassignTopicDTO(); + reassignTopicDTO.setClusterId(1L); + reassignTopicDTO.setTopicName(REAL_TOPIC2_IN_ZK); + ResultStatus result = reassignService.createTask(Arrays.asList(reassignTopicDTO), ADMIN_OPERATOR); + Assert.assertEquals(result.getCode(), ResultStatus.BROKER_NUM_NOT_ENOUGH.getCode()); + } + + private void createTask2BrokerNotExistTest() { + Mockito.when(regionService.getFullBrokerIdList( + Mockito.anyLong(), Mockito.anyLong(), Mockito.anyList())).thenReturn(Arrays.asList(100, 2, 3)); + + ReassignTopicDTO reassignTopicDTO = getReassignTopicDTO(); + reassignTopicDTO.setClusterId(1L); + reassignTopicDTO.setTopicName(REAL_TOPIC2_IN_ZK); + ResultStatus result = reassignService.createTask(Arrays.asList(reassignTopicDTO), ADMIN_OPERATOR); + Assert.assertEquals(result.getCode(), ResultStatus.BROKER_NOT_EXIST.getCode()); + } + + private void createTask2BrokerNumNotEnough2Test() { + Mockito.when(regionService.getFullBrokerIdList( + Mockito.anyLong(), Mockito.anyLong(), Mockito.anyList())).thenReturn(Arrays.asList(2, 3)); + + ReassignTopicDTO reassignTopicDTO = getReassignTopicDTO(); + reassignTopicDTO.setClusterId(1L); + reassignTopicDTO.setTopicName(REAL_TOPIC2_IN_ZK); + ResultStatus result = reassignService.createTask(Arrays.asList(reassignTopicDTO), ADMIN_OPERATOR); + Assert.assertEquals(result.getCode(), ResultStatus.BROKER_NUM_NOT_ENOUGH.getCode()); + } + + private void createTask2ParamIllegal2Test() { + Mockito.when(regionService.getFullBrokerIdList( + Mockito.anyLong(), Mockito.anyLong(), Mockito.anyList())).thenReturn(Arrays.asList(1, 2, 3)); + + ReassignTopicDTO reassignTopicDTO = getReassignTopicDTO(); + reassignTopicDTO.setClusterId(1L); + reassignTopicDTO.setTopicName(REAL_TOPIC2_IN_ZK); + ResultStatus result = reassignService.createTask(Arrays.asList(reassignTopicDTO), ADMIN_OPERATOR); + Assert.assertEquals(result.getCode(), ResultStatus.PARAM_ILLEGAL.getCode()); + } + + private void createTask2PartitionIdListEmptyTest() { + Mockito.when(regionService.getFullBrokerIdList( + Mockito.anyLong(), Mockito.anyLong(), Mockito.anyList())).thenReturn(Arrays.asList(1, 2, 3)); + + ReassignTopicDTO reassignTopicDTO = getReassignTopicDTO(); + reassignTopicDTO.setClusterId(1L); + reassignTopicDTO.setTopicName(REAL_TOPIC2_IN_ZK); + reassignTopicDTO.setOriginalRetentionTime(168 * 3600000L); + reassignTopicDTO.setPartitionIdList(Collections.emptyList()); + ResultStatus result = reassignService.createTask(Arrays.asList(reassignTopicDTO), ADMIN_OPERATOR); + Assert.assertEquals(result.getCode(), ResultStatus.PARAM_ILLEGAL.getCode()); + } + + private void createTask2PartitionNotExistTest() { + Mockito.when(regionService.getFullBrokerIdList( + Mockito.anyLong(), Mockito.anyLong(), Mockito.anyList())).thenReturn(Arrays.asList(1, 2, 3)); + + ReassignTopicDTO reassignTopicDTO = getReassignTopicDTO(); + reassignTopicDTO.setClusterId(1L); + reassignTopicDTO.setTopicName(REAL_TOPIC2_IN_ZK); + reassignTopicDTO.setOriginalRetentionTime(168 * 3600000L); + reassignTopicDTO.setPartitionIdList(Arrays.asList(100, 0)); + ResultStatus result = reassignService.createTask(Arrays.asList(reassignTopicDTO), ADMIN_OPERATOR); + Assert.assertEquals(result.getCode(), ResultStatus.PARTITION_NOT_EXIST.getCode()); + } + + private void createTask2SuccessTest() { + Mockito.when(regionService.getFullBrokerIdList( + Mockito.anyLong(), Mockito.anyLong(), Mockito.anyList())).thenReturn(Arrays.asList(1, 2, 3)); + + ReassignTopicDTO reassignTopicDTO = getReassignTopicDTO(); + reassignTopicDTO.setTopicName(REAL_TOPIC2_IN_ZK); + reassignTopicDTO.setOriginalRetentionTime(168 * 3600000L); + ResultStatus result = reassignService.createTask(Arrays.asList(reassignTopicDTO), ADMIN_OPERATOR); + Assert.assertEquals(result.getCode(), ResultStatus.SUCCESS.getCode()); + } + + @Test(description = "测试获取迁移任务") + public void getTaskTest() { + // 测试获取成功 + getTaskTest2Success(); + // 测试获取失败 + getTaskTest2Exception(); + } + + private void getTaskTest2Success() { + ReassignTaskDO reassignTask = getReassignTaskDO(); + Mockito.when(reassignTaskDao.getByTaskId(Mockito.anyLong())).thenReturn(Arrays.asList(reassignTask)); + + List task = reassignService.getTask(reassignTask.getTaskId()); + Assert.assertFalse(task.isEmpty()); + Assert.assertTrue(task.stream().allMatch(reassignTaskDO -> + reassignTaskDO.getTaskId().equals(reassignTask.getTaskId()) && + reassignTaskDO.getClusterId().equals(reassignTask.getClusterId()) && + reassignTaskDO.getStatus().equals(reassignTask.getStatus()))); + } + + private void getTaskTest2Exception() { + ReassignTaskDO reassignTask = getReassignTaskDO(); + Mockito.when(reassignTaskDao.getByTaskId(Mockito.anyLong())).thenThrow(RuntimeException.class); + + List task = reassignService.getTask(reassignTask.getTaskId()); + Assert.assertNull(task); + } + + @Test(description = "修改迁移任务") + public void modifyTask() { + // operation forbidden + modifyTask2OperationForbiddenTest(); + // 修改成功 + modifyTask2Success(); + // mysqlError + modifyTask2MysqlError(); + // 任务不存在 + modifyTask2TaskNotExistTest(); + } + + private void modifyTask2TaskNotExistTest() { + Mockito.when(reassignTaskDao.getByTaskId(Mockito.anyLong())).thenThrow(RuntimeException.class); + + ReassignExecDTO reassignExecDTO = getReassignExecDTO(); + reassignExecDTO.setTaskId(100L); + ResultStatus resultStatus = reassignService.modifyTask(reassignExecDTO, TopicReassignActionEnum.START); + Assert.assertEquals(resultStatus.getCode(), ResultStatus.TASK_NOT_EXIST.getCode()); + } + + private void modifyTask2OperationForbiddenTest() { + ReassignTaskDO reassignTask = getReassignTaskDO(); + reassignTask.setStatus(1); + Mockito.when(reassignTaskDao.getByTaskId(Mockito.anyLong())).thenReturn(Arrays.asList(reassignTask)); + + ReassignExecDTO reassignExecDTO = getReassignExecDTO(); + ResultStatus resultStatus1 = reassignService.modifyTask(reassignExecDTO, TopicReassignActionEnum.START); + Assert.assertEquals(resultStatus1.getCode(), ResultStatus.OPERATION_FORBIDDEN.getCode()); + } + + private void modifyTask2Success() { + ReassignTaskDO reassignTask = getReassignTaskDO(); + reassignTask.setStatus(0); + Mockito.when(reassignTaskDao.getByTaskId(Mockito.anyLong())).thenReturn(Arrays.asList(reassignTask)); + + ReassignExecDTO reassignExecDTO = getReassignExecDTO(); + // cancel action + ResultStatus resultStatus1 = reassignService.modifyTask(reassignExecDTO, TopicReassignActionEnum.CANCEL); + Assert.assertEquals(resultStatus1.getCode(), ResultStatus.SUCCESS.getCode()); + + // start action + reassignTask.setStatus(0); + Mockito.when(reassignTaskDao.getByTaskId(Mockito.anyLong())).thenReturn(Arrays.asList(reassignTask)); + ResultStatus resultStatus2 = reassignService.modifyTask(reassignExecDTO, TopicReassignActionEnum.START); + Assert.assertEquals(resultStatus2.getCode(), ResultStatus.SUCCESS.getCode()); + + // modify action + reassignTask.setStatus(0); + Mockito.when(reassignTaskDao.getByTaskId(Mockito.anyLong())).thenReturn(Arrays.asList(reassignTask)); + ResultStatus resultStatus3 = reassignService.modifyTask(reassignExecDTO, TopicReassignActionEnum.MODIFY); + Assert.assertEquals(resultStatus3.getCode(), ResultStatus.SUCCESS.getCode()); + } + + private void modifyTask2MysqlError() { + ReassignTaskDO reassignTask = getReassignTaskDO(); + reassignTask.setStatus(0); + Mockito.when(reassignTaskDao.getByTaskId(Mockito.anyLong())).thenReturn(Arrays.asList(reassignTask)); + + ReassignExecDTO reassignExecDTO = getReassignExecDTO(); + // cancel action + Mockito.doThrow(RuntimeException.class).when(reassignTaskDao).batchUpdate(Mockito.anyList()); + ResultStatus resultStatus1 = reassignService.modifyTask(reassignExecDTO, TopicReassignActionEnum.CANCEL); + Assert.assertEquals(resultStatus1.getCode(), ResultStatus.MYSQL_ERROR.getCode()); + + // start action + reassignTask.setStatus(0); + Mockito.when(reassignTaskDao.getByTaskId(Mockito.anyLong())).thenReturn(Arrays.asList(reassignTask)); + Mockito.doThrow(RuntimeException.class).when(reassignTaskDao).batchUpdate(Mockito.anyList()); + ResultStatus resultStatus2 = reassignService.modifyTask(reassignExecDTO, TopicReassignActionEnum.START); + Assert.assertEquals(resultStatus2.getCode(), ResultStatus.MYSQL_ERROR.getCode()); + + // modify action + reassignTask.setStatus(0); + Mockito.when(reassignTaskDao.getByTaskId(Mockito.anyLong())).thenReturn(Arrays.asList(reassignTask)); + Mockito.doThrow(RuntimeException.class).when(reassignTaskDao).batchUpdate(Mockito.anyList()); + ResultStatus resultStatus3 = reassignService.modifyTask(reassignExecDTO, TopicReassignActionEnum.MODIFY); + Assert.assertEquals(resultStatus3.getCode(), ResultStatus.MYSQL_ERROR.getCode()); + } + + @Test(description = "修改子任务测试") + public void modifySubTaskTest() { + // 任务不存在 + modifySubTask2TaskNotExist(); + // 修改任务成功 + modifySubTask2Success(); + // 修改任务失败 + modifySubTask2MysqlError(); + } + + private void modifySubTask2TaskNotExist() { + Mockito.when(reassignTaskDao.getSubTask(Mockito.anyLong())).thenReturn(null); + ResultStatus resultStatus = reassignService.modifySubTask(new ReassignExecSubDTO()); + Assert.assertEquals(resultStatus.getCode(), ResultStatus.TASK_NOT_EXIST.getCode()); + } + + private void modifySubTask2Success() { + ReassignTaskDO reassignTask = getReassignTaskDO(); + Mockito.when(reassignTaskDao.getSubTask(Mockito.anyLong())).thenReturn(reassignTask); + ReassignExecSubDTO reassignExecSubDTO = getReassignExecSubDTO(); + ResultStatus resultStatus = reassignService.modifySubTask(reassignExecSubDTO); + Assert.assertEquals(resultStatus.getCode(), ResultStatus.SUCCESS.getCode()); + } + + private void modifySubTask2MysqlError() { + ReassignTaskDO reassignTask = getReassignTaskDO(); + Mockito.when(reassignTaskDao.getSubTask(Mockito.anyLong())).thenReturn(reassignTask); + Mockito.when(reassignTaskDao.updateById(Mockito.any())).thenThrow(RuntimeException.class); + ReassignExecSubDTO reassignExecSubDTO = getReassignExecSubDTO(); + ResultStatus resultStatus = reassignService.modifySubTask(reassignExecSubDTO); + Assert.assertEquals(resultStatus.getCode(), ResultStatus.MYSQL_ERROR.getCode()); + } + + @Test() + public void getReassignTaskListTest() { + // 获取成功 + getReassignTaskList2Success(); + // 获取失败 + getReassignTaskList2Empty(); + } + + private void getReassignTaskList2Success() { + Mockito.when(reassignTaskDao.listAll()).thenReturn(Arrays.asList(new ReassignTaskDO())); + List reassignTaskList = reassignService.getReassignTaskList(); + Assert.assertFalse(reassignTaskList.isEmpty()); + } + + private void getReassignTaskList2Empty() { + Mockito.when(reassignTaskDao.listAll()).thenThrow(RuntimeException.class); + List reassignTaskList = reassignService.getReassignTaskList(); + Assert.assertTrue(reassignTaskList.isEmpty()); + } + + @Test + public void getReassignStatusTest() { + // 获取成功 + getReassignStatus2Success(); + // task不存在 + getReassignStatus2TaskNotExistTest(); + } + + private void getReassignStatus2TaskNotExistTest() { + Mockito.when(reassignTaskDao.getByTaskId(Mockito.anyLong())).thenThrow(RuntimeException.class); + Result> reassignStatus = reassignService.getReassignStatus(1L); + Assert.assertEquals(reassignStatus.getCode(), ResultStatus.TASK_NOT_EXIST.getCode()); + } + + private void getReassignStatus2Success() { + ClusterDO clusterDO1 = getClusterDO(); + ClusterDO clusterDO2 = getClusterDO(); + clusterDO2.setId(100L); + Map map = new HashMap<>(); + map.put(clusterDO1.getId(), clusterDO1); + map.put(clusterDO2.getId(), clusterDO2); + Mockito.when(clusterService.listMap()).thenReturn(map); + + ReassignTaskDO reassignTaskDO1 = getReassignTaskDO(); + ReassignTaskDO reassignTaskDO2 = getReassignTaskDO(); + reassignTaskDO2.setStatus(TaskStatusReassignEnum.RUNNING.getCode()); + + Mockito.when(reassignTaskDao.getByTaskId(Mockito.anyLong())).thenReturn(Arrays.asList(reassignTaskDO1, reassignTaskDO2)); + Result> reassignStatus = reassignService.getReassignStatus(1L); + Assert.assertFalse(reassignStatus.getData().isEmpty()); + Assert.assertEquals(reassignStatus.getCode(), ResultStatus.SUCCESS.getCode()); + } + + @Test + public void verifyAssignmenTest() { + Map map = reassignService.verifyAssignment(ZOOKEEPER_ADDRESS, REASSIGNMENTJSON); + Assert.assertFalse(map.isEmpty()); + } + +} diff --git a/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/TopicServiceTest.java b/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/TopicServiceTest.java new file mode 100644 index 00000000..3570aee6 --- /dev/null +++ b/kafka-manager-core/src/test/java/com/xiaojukeji/kafka/manager/service/service/TopicServiceTest.java @@ -0,0 +1,741 @@ +package com.xiaojukeji.kafka.manager.service.service; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.xiaojukeji.kafka.manager.common.bizenum.OffsetPosEnum; +import com.xiaojukeji.kafka.manager.common.bizenum.TopicOffsetChangedEnum; +import com.xiaojukeji.kafka.manager.common.constant.TopicSampleConstant; +import com.xiaojukeji.kafka.manager.common.entity.Result; +import com.xiaojukeji.kafka.manager.common.entity.ResultStatus; +import com.xiaojukeji.kafka.manager.common.entity.ao.PartitionAttributeDTO; +import com.xiaojukeji.kafka.manager.common.entity.ao.PartitionOffsetDTO; +import com.xiaojukeji.kafka.manager.common.entity.ao.topic.*; +import com.xiaojukeji.kafka.manager.common.entity.dto.normal.TopicDataSampleDTO; +import com.xiaojukeji.kafka.manager.common.entity.metrics.BaseMetrics; +import com.xiaojukeji.kafka.manager.common.entity.metrics.TopicMetrics; +import com.xiaojukeji.kafka.manager.common.entity.pojo.ClusterDO; +import com.xiaojukeji.kafka.manager.common.entity.pojo.TopicDO; +import com.xiaojukeji.kafka.manager.common.entity.pojo.TopicMetricsDO; +import com.xiaojukeji.kafka.manager.common.entity.pojo.gateway.AppDO; +import com.xiaojukeji.kafka.manager.common.zookeeper.znode.brokers.PartitionState; +import com.xiaojukeji.kafka.manager.dao.TopicRequestMetricsDao; +import com.xiaojukeji.kafka.manager.service.config.BaseTest; +import com.xiaojukeji.kafka.manager.service.service.gateway.AppService; +import org.apache.kafka.common.TopicPartition; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.springframework.beans.factory.annotation.Autowired; +import org.testng.Assert; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import java.util.*; + +/** + * @author xuguang + * @Date 2021/12/20 + */ +public class TopicServiceTest extends BaseTest { + + /** + * 集群共包括三个broker:1,2,3, 该topic 1分区 1副本因子,在broker1上 + */ + private final static String REAL_TOPIC1_IN_ZK = "moduleTest"; + + /** + * 集群共包括三个broker:1,2,3, 该topic 2分区 3副本因子,在broker1,2,3上 + */ + private final static String REAL_TOPIC2_IN_ZK = "xgTest"; + + private final static String INVALID_TOPIC = "xxxxx"; + + private final static String ZK_DEFAULT_TOPIC = "_consumer_offsets"; + + private final static String NO_OFFSET_CHANGE_TOPIC_IN_ZK = "NoOffsetChangeTopic"; + + private final static Long REAL_CLUSTER_ID_IN_MYSQL = 1L; + + private final static Integer REAL_BROKER_ID_IN_ZK = 3; + + private final static Long INVALID_CLUSTER_ID = -1L; + + private final static Integer INVALID_PARTITION_ID = -1; + + @Autowired + @InjectMocks + private TopicService topicService; + + @Mock + private TopicManagerService topicManagerService; + + @Mock + private AppService appService; + + @Mock + private JmxService jmxService; + + @Autowired + private TopicRequestMetricsDao topicRequestMetricsDao; + + @BeforeMethod + public void setup() { + MockitoAnnotations.initMocks(this); + } + + private TopicMetricsDO getTopicMetricsDO() { + TopicMetricsDO topicMetricsDO = new TopicMetricsDO(); + topicMetricsDO.setClusterId(REAL_CLUSTER_ID_IN_MYSQL); + topicMetricsDO.setAppId("moduleTestAppId"); + topicMetricsDO.setTopicName(REAL_TOPIC1_IN_ZK); + topicMetricsDO.setMetrics(""); + topicMetricsDO.setGmtCreate(new Date()); + return topicMetricsDO; + } + + private TopicDO getTopicDO() { + TopicDO topicDO = new TopicDO(); + topicDO.setClusterId(REAL_CLUSTER_ID_IN_MYSQL); + topicDO.setTopicName(REAL_TOPIC1_IN_ZK); + topicDO.setAppId("moduleTestAppId"); + topicDO.setDescription(INVALID_TOPIC); + topicDO.setPeakBytesIn(100000L); + return topicDO; + } + + private AppDO getAppDO() { + AppDO appDO = new AppDO(); + appDO.setId(4L); + appDO.setAppId("moduleTestAppId"); + appDO.setName("moduleTestApp"); + appDO.setPassword("moduleTestApp"); + appDO.setType(1); + appDO.setApplicant("admin"); + appDO.setPrincipals("admin"); + appDO.setDescription("moduleTestApp"); + appDO.setCreateTime(new Date(1638786493173L)); + appDO.setModifyTime(new Date(1638786493173L)); + return appDO; + } + + public ClusterDO getClusterDO() { + ClusterDO clusterDO = new ClusterDO(); + clusterDO.setId(REAL_CLUSTER_ID_IN_MYSQL); + clusterDO.setClusterName("LogiKM_moduleTest"); + clusterDO.setZookeeper("10.190.46.198:2181,10.190.14.237:2181,10.190.50.65:2181/xg"); + clusterDO.setBootstrapServers("10.190.46.198:9093,10.190.14.237:9093,10.190.50.65:9093"); + clusterDO.setSecurityProperties("{ \t\"security.protocol\": \"SASL_PLAINTEXT\", \t\"sasl.mechanism\": \"PLAIN\", \t\"sasl.jaas.config\": \"org.apache.kafka.common.security.plain.PlainLoginModule required username=\\\"dkm_admin\\\" password=\\\"km_kMl4N8as1Kp0CCY\\\";\" }"); + clusterDO.setStatus(1); + clusterDO.setGmtCreate(new Date()); + clusterDO.setGmtModify(new Date()); + return clusterDO; + } + + private TopicDataSampleDTO getTopicDataSampleDTO() { + TopicDataSampleDTO topicDataSampleDTO = new TopicDataSampleDTO(); + topicDataSampleDTO.setPartitionId(0); + topicDataSampleDTO.setOffset(0L); + topicDataSampleDTO.setTimeout(5000); + topicDataSampleDTO.setTruncate(true); + topicDataSampleDTO.setMaxMsgNum(90); + return topicDataSampleDTO; + } + + private TopicMetrics getTopicMetrics() { + TopicMetrics topicMetrics = new TopicMetrics(REAL_CLUSTER_ID_IN_MYSQL, REAL_TOPIC1_IN_ZK); + String metrics = "{\"TotalFetchRequestsPerSecFiveMinuteRate\":4.132236103122026,\"BytesRejectedPerSecFiveMinuteRate\":0.0,\"TotalFetchRequestsPerSecFifteenMinuteRate\":1.5799208507558833,\"ProduceTotalTimeMs98thPercentile\":0.0,\"MessagesInPerSecMeanRate\":0.0,\"ProduceTotalTimeMs75thPercentile\":0.0,\"ProduceTotalTimeMs99thPercentile\":0.0,\"TotalProduceRequestsPerSecOneMinuteRate\":0.0,\"FailedProduceRequestsPerSecFifteenMinuteRate\":0.0,\"BytesInPerSecMeanRate\":0.0,\"TotalProduceRequestsPerSecFiveMinuteRate\":0.0,\"FetchConsumerTotalTimeMs999thPercentile\":0.0,\"FetchConsumerTotalTimeMs98thPercentile\":0.0,\"FetchConsumerTotalTimeMsMean\":0.0,\"FetchConsumerTotalTimeMs99thPercentile\":0.0,\"FailedFetchRequestsPerSecFifteenMinuteRate\":0.0,\"MessagesInPerSecFiveMinuteRate\":0.0,\"RequestHandlerAvgIdlePercentOneMinuteRate\":0.999221766772746,\"ProduceTotalTimeMsMean\":0.0,\"BytesInPerSecFiveMinuteRate\":0.0,\"FailedProduceRequestsPerSecMeanRate\":0.0,\"FailedFetchRequestsPerSecMeanRate\":0.0,\"FailedProduceRequestsPerSecFiveMinuteRate\":0.0,\"BytesOutPerSecFifteenMinuteRate\":0.0,\"BytesInPerSecOneMinuteRate\":0.0,\"BytesOutPerSecFiveMinuteRate\":0.0,\"HealthScore\":90,\"FailedFetchRequestsPerSecOneMinuteRate\":0.0,\"MessagesInPerSecOneMinuteRate\":0.0,\"BytesRejectedPerSecFifteenMinuteRate\":0.0,\"FailedFetchRequestsPerSecFiveMinuteRate\":0.0,\"RequestHandlerAvgIdlePercentFiveMinuteRate\":0.999803118809842,\"BytesOutPerSecOneMinuteRate\":0.0,\"ResponseQueueSizeValue\":0,\"MessagesInPerSecFifteenMinuteRate\":0.0,\"TotalProduceRequestsPerSecMeanRate\":0.0,\"BytesRejectedPerSecMeanRate\":0.0,\"TotalFetchRequestsPerSecMeanRate\":1.2674449706628523,\"NetworkProcessorAvgIdlePercentValue\":1.0,\"TotalFetchRequestsPerSecOneMinuteRate\":10.457259856316893,\"BytesInPerSecFifteenMinuteRate\":0.0,\"BytesOutPerSecMeanRate\":0.0,\"TotalProduceRequestsPerSecFifteenMinuteRate\":0.0,\"FetchConsumerTotalTimeMs50thPercentile\":0.0,\"RequestHandlerAvgIdlePercentFifteenMinuteRate\":0.9999287809186348,\"FetchConsumerTotalTimeMs95thPercentile\":0.0,\"FailedProduceRequestsPerSecOneMinuteRate\":0.0,\"CreateTime\":1638792321071,\"FetchConsumerTotalTimeMs75thPercentile\":0.0,\"ProduceTotalTimeMs999thPercentile\":0.0,\"RequestQueueSizeValue\":0,\"ProduceTotalTimeMs50thPercentile\":0.0,\"BytesRejectedPerSecOneMinuteRate\":0.0,\"RequestHandlerAvgIdlePercentMeanRate\":0.9999649184090593,\"ProduceTotalTimeMs95thPercentile\":0.0}"; + JSONObject jsonObject = JSON.parseObject(metrics); + Map metricsMap = new HashMap<>(); + for (Map.Entry stringObjectEntry : jsonObject.entrySet()) { + metricsMap.put(stringObjectEntry.getKey(), stringObjectEntry.getValue()); + } + topicMetrics.setMetricsMap(metricsMap); + return topicMetrics; + } + + @Test(description = "测试从DB获取监控数据") + public void getTopicMetricsFromDBTest() { + List list = topicService.getTopicMetricsFromDB(REAL_CLUSTER_ID_IN_MYSQL, REAL_TOPIC1_IN_ZK, new Date(0L), new Date()); + Assert.assertFalse(list.isEmpty()); + Assert.assertTrue(list.stream().allMatch(topicMetricsDO -> + topicMetricsDO.getClusterId().equals(REAL_CLUSTER_ID_IN_MYSQL) && + topicMetricsDO.getTopicName().equals(REAL_TOPIC1_IN_ZK))); + } + + @Test + public void getTopicMetricsFromDBWithAppIdTest() { + List list = topicService.getTopicMetricsFromDB("1", REAL_CLUSTER_ID_IN_MYSQL, REAL_TOPIC1_IN_ZK, new Date(0L), new Date()); + Assert.assertFalse(list.isEmpty()); + } + + @Test(description = "测试获取指定时间段内的峰值的均值流量") + public void getMaxAvgBytesInFromDBTest() { + // 为空 + getMaxAvgBytesInFromDB2NullTest(); + // 获取成功 + getMaxAvgBytesInFromDB2SuccessTest(); + } + + private void getMaxAvgBytesInFromDB2NullTest() { + Double result = topicService.getMaxAvgBytesInFromDB(REAL_CLUSTER_ID_IN_MYSQL, INVALID_TOPIC, new Date(0L), new Date()); + Assert.assertNull(result); + } + + private void getMaxAvgBytesInFromDB2SuccessTest() { + Double result = topicService.getMaxAvgBytesInFromDB(REAL_CLUSTER_ID_IN_MYSQL, REAL_TOPIC1_IN_ZK, new Date(0L), new Date()); + Assert.assertNotNull(result); + } + + @Test(description = "获取brokerId下所有的Topic及其对应的PartitionId") + public void getTopicPartitionIdMapTest() { + Map> topicPartitionIdMap = topicService.getTopicPartitionIdMap(REAL_CLUSTER_ID_IN_MYSQL, 1); + Assert.assertFalse(topicPartitionIdMap.isEmpty()); + Assert.assertTrue(topicPartitionIdMap.containsKey(REAL_TOPIC1_IN_ZK)); + } + + @Test(description = "测试获取 Topic 的 basic-info 信息") + public void getTopicBasicDTOTest() { + // TopicMetadata is Null + getTopicBasicDTO2TopicMetadataIsNull(); + // TopicDO is Null + getTopicBasicDTO2TopicMetadata2TopicDOIsNull(); + // TopicDO is not Null + getTopicBasicDTO2TopicMetadata2TopicDOIsNotNull(); + } + + private void getTopicBasicDTO2TopicMetadataIsNull() { + TopicBasicDTO result = topicService.getTopicBasicDTO(REAL_CLUSTER_ID_IN_MYSQL, INVALID_TOPIC); + Assert.assertEquals(result.getClusterId(), Long.valueOf(REAL_CLUSTER_ID_IN_MYSQL)); + Assert.assertEquals(result.getTopicName(), INVALID_TOPIC); + Assert.assertNull(result.getAppId()); + } + + private void getTopicBasicDTO2TopicMetadata2TopicDOIsNull() { + Mockito.when(topicManagerService.getByTopicName(Mockito.anyLong(), Mockito.anyString())).thenReturn(null); + TopicBasicDTO result = topicService.getTopicBasicDTO(REAL_CLUSTER_ID_IN_MYSQL, REAL_TOPIC1_IN_ZK); + Assert.assertNotNull(result); + Assert.assertEquals(result.getClusterId(), Long.valueOf(REAL_CLUSTER_ID_IN_MYSQL)); + Assert.assertEquals(result.getTopicName(), REAL_TOPIC1_IN_ZK); + Assert.assertNull(result.getDescription()); + Assert.assertNull(result.getAppId()); + } + + private void getTopicBasicDTO2TopicMetadata2TopicDOIsNotNull() { + TopicDO topicDO = getTopicDO(); + Mockito.when(topicManagerService.getByTopicName(Mockito.anyLong(), Mockito.anyString())).thenReturn(topicDO); + Mockito.when(appService.getByAppId(Mockito.anyString())).thenReturn(null); + TopicBasicDTO result = topicService.getTopicBasicDTO(REAL_CLUSTER_ID_IN_MYSQL, REAL_TOPIC1_IN_ZK); + Assert.assertNotNull(result); + Assert.assertEquals(result.getClusterId(), Long.valueOf(REAL_CLUSTER_ID_IN_MYSQL)); + Assert.assertEquals(result.getTopicName(), REAL_TOPIC1_IN_ZK); + Assert.assertEquals(result.getDescription(), topicDO.getDescription()); + // appId不存在 + Assert.assertNull(result.getAppId()); + // appId存在 + topicDO.setAppId("moduleTestAppId"); + Mockito.when(topicManagerService.getByTopicName(Mockito.anyLong(), Mockito.anyString())).thenReturn(topicDO); + Mockito.when(appService.getByAppId(Mockito.anyString())).thenReturn(getAppDO()); + TopicBasicDTO result2 = topicService.getTopicBasicDTO(REAL_CLUSTER_ID_IN_MYSQL, REAL_TOPIC1_IN_ZK); + Assert.assertNotNull(result2); + Assert.assertEquals(result2.getClusterId(), Long.valueOf(REAL_CLUSTER_ID_IN_MYSQL)); + Assert.assertEquals(result2.getTopicName(), REAL_TOPIC1_IN_ZK); + Assert.assertEquals(result2.getDescription(), topicDO.getDescription()); + Assert.assertEquals(result2.getAppId(), topicDO.getAppId()); + } + + @Test(description = "获取Topic的PartitionState信息") + public void getTopicPartitionDTOTest() { + // result is emptyList + getTopicPartitionDTO2EmptyTest(); + // needDetail is false + getTopicPartitionDTO2NeedDetailFalseTest(); + // needDetail is true + getTopicPartitionDTO2NeedDetailTrueTest(); + } + + private void getTopicPartitionDTO2EmptyTest() { + List list = topicService.getTopicPartitionDTO(null, null, true); + Assert.assertTrue(list.isEmpty()); + + ClusterDO clusterDO = new ClusterDO(); + clusterDO.setId(REAL_CLUSTER_ID_IN_MYSQL); + List list2 = topicService.getTopicPartitionDTO(clusterDO, INVALID_TOPIC, true); + Assert.assertTrue(list2.isEmpty()); + } + + private void getTopicPartitionDTO2NeedDetailFalseTest() { + Map map = new HashMap<>(); + PartitionAttributeDTO partitionAttributeDTO1 = new PartitionAttributeDTO(); + partitionAttributeDTO1.setLogSize(0L); + map.put(0, partitionAttributeDTO1); + map.put(1, null); + Mockito.when(jmxService.getPartitionAttribute( + Mockito.anyLong(), Mockito.anyString(), Mockito.anyList())).thenReturn(map); + + ClusterDO clusterDO = getClusterDO(); + List list = topicService.getTopicPartitionDTO(clusterDO, REAL_TOPIC1_IN_ZK, false); + Assert.assertFalse(list.isEmpty()); + Assert.assertEquals(list.size(), 2); + Assert.assertTrue(list.stream().allMatch(topicPartitionDTO -> + topicPartitionDTO.getBeginningOffset() == null && + topicPartitionDTO.getEndOffset() == null)); + } + + private void getTopicPartitionDTO2NeedDetailTrueTest() { + Map map = new HashMap<>(); + PartitionAttributeDTO partitionAttributeDTO1 = new PartitionAttributeDTO(); + partitionAttributeDTO1.setLogSize(0L); + map.put(0, partitionAttributeDTO1); + map.put(1, null); + Mockito.when(jmxService.getPartitionAttribute( + Mockito.anyLong(), Mockito.anyString(), Mockito.anyList())).thenReturn(map); + + ClusterDO clusterDO = getClusterDO(); + List list = topicService.getTopicPartitionDTO(clusterDO, REAL_TOPIC1_IN_ZK, true); + Assert.assertFalse(list.isEmpty()); + Assert.assertEquals(list.size(), 2); + Assert.assertTrue(list.stream().allMatch(topicPartitionDTO -> + topicPartitionDTO.getBeginningOffset() != null && + topicPartitionDTO.getEndOffset() != null)); + } + + @Test + public void getTopicMetricsFromJMXTest() { + Mockito.when(jmxService.getTopicMetrics( + Mockito.anyLong(), Mockito.anyString(), Mockito.anyInt(), Mockito.anyBoolean())).thenReturn(new TopicMetrics(REAL_CLUSTER_ID_IN_MYSQL, REAL_TOPIC1_IN_ZK)); + BaseMetrics result = topicService.getTopicMetricsFromJMX(REAL_CLUSTER_ID_IN_MYSQL, REAL_TOPIC1_IN_ZK, 200, true); + Assert.assertNotNull(result); + } + + @Test(description = "测试获取Topic的分区的offset") + public void getPartitionOffsetTest() { + // 结果为空 + getPartitionOffset2EmptyTest(); + // 获取成功 + getPartitionOffset2SuccessTest(); + } + + private void getPartitionOffset2EmptyTest() { + ClusterDO clusterDO = getClusterDO(); + Map partitionOffset = topicService.getPartitionOffset( + null, null, OffsetPosEnum.BEGINNING); + Assert.assertTrue(partitionOffset.isEmpty()); + + Map partitionOffset2 = topicService.getPartitionOffset( + clusterDO, INVALID_TOPIC, OffsetPosEnum.BEGINNING); + Assert.assertTrue(partitionOffset2.isEmpty()); + } + + private void getPartitionOffset2SuccessTest() { + ClusterDO clusterDO = getClusterDO(); + // 获取beginning offset + Map partitionOffset1 = topicService.getPartitionOffset( + clusterDO, REAL_TOPIC1_IN_ZK, OffsetPosEnum.BEGINNING); + Assert.assertFalse(partitionOffset1.isEmpty()); + // 获取end offset + Map partitionOffset2 = topicService.getPartitionOffset( + clusterDO, REAL_TOPIC1_IN_ZK, OffsetPosEnum.END); + Assert.assertFalse(partitionOffset2.isEmpty()); + } + + @Test(description = "测试获取Topic概览信息,参数clusterId, brokerId") + public void getTopicOverviewListTest() { + // 结果为空 + getTopicOverviewList2EmptyTest(); + // 获取成功 + getTopicOverviewList2SuccessTest(); + } + + private void getTopicOverviewList2EmptyTest() { + List topicOverviewList = topicService.getTopicOverviewList(null, 1); + Assert.assertTrue(topicOverviewList.isEmpty()); + } + + private void getTopicOverviewList2SuccessTest() { + List topicOverviewList = topicService.getTopicOverviewList(REAL_CLUSTER_ID_IN_MYSQL, 1); + Assert.assertFalse(topicOverviewList.isEmpty()); + } + + @Test(description = "测试获取Topic概览信息,参数clusterId, topicNameList") + public void getTopicOverviewListWithTopicList() { + // 结果为空 + getTopicOverviewListWithTopicList2EmptyTest(); + + // topicDOList is null,appDOList is null, metrics is null + getTopicOverviewListWithTopicList2TopicAndApp1Test(); + + // topicDOList is null,appDOList is null, metrics is not null + getTopicOverviewListWithTopicList2TopicAndApp2Test(); + + // topicDOList is null,appDOList is not null, metrics is null + getTopicOverviewListWithTopicList2TopicAndApp3Test(); + + // topicDOList is null,appDOList is not null, metrics is not null + getTopicOverviewListWithTopicList2TopicAndApp4Test(); + + // topicDOList is not null,appDOList is null, metrics is null + getTopicOverviewListWithTopicList2TopicAndApp5Test(); + + // topicDOList is not null,appDOList is null, metrics is not null + getTopicOverviewListWithTopicList2TopicAndApp6Test(); + + // topicDOList is not null,appDOList is not null, metrics is null + getTopicOverviewListWithTopicList2TopicAndApp7Test(); + + // topicDOList is not null,appDOList is not null, metrics is not null + getTopicOverviewListWithTopicList2TopicAndApp8Test(); + + } + + private void getTopicOverviewListWithTopicList2EmptyTest() { + List topicOverviewList = topicService.getTopicOverviewList(null, Arrays.asList(REAL_TOPIC1_IN_ZK, ZK_DEFAULT_TOPIC, INVALID_TOPIC)); + Assert.assertTrue(topicOverviewList.isEmpty()); + } + + private void getTopicOverviewListWithTopicList2TopicAndApp1Test() { + Mockito.when(topicManagerService.getByClusterIdFromCache(Mockito.anyLong())).thenReturn(null); + Mockito.when(appService.listAll()).thenReturn(null); + Mockito.when(jmxService.getTopicMetrics( + Mockito.anyLong(), Mockito.anyString(), Mockito.anyInt(), Mockito.anyBoolean())).thenReturn(null); + + List topics = Arrays.asList(REAL_TOPIC1_IN_ZK, ZK_DEFAULT_TOPIC, INVALID_TOPIC); + List topicOverviewList = topicService.getTopicOverviewList(REAL_CLUSTER_ID_IN_MYSQL, topics); + Assert.assertFalse(topicOverviewList.isEmpty()); + Assert.assertTrue(topicOverviewList.stream().allMatch(topicOverview -> + topicOverview.getClusterId().equals(REAL_CLUSTER_ID_IN_MYSQL) && + topics.contains(topicOverview.getTopicName()) && + topicOverview.getAppId() == null && + topicOverview.getAppName() == null && + topicOverview.getByteIn() == null)); + } + + private void getTopicOverviewListWithTopicList2TopicAndApp2Test() { + Mockito.when(topicManagerService.getByClusterIdFromCache(Mockito.anyLong())).thenReturn(null); + Mockito.when(appService.listAll()).thenReturn(null); + TopicMetrics topicMetrics = getTopicMetrics(); + Mockito.when(jmxService.getTopicMetrics( + Mockito.anyLong(), Mockito.anyString(), Mockito.anyInt(), Mockito.anyBoolean())). + thenReturn(topicMetrics); + + List topics = Arrays.asList(REAL_TOPIC1_IN_ZK, ZK_DEFAULT_TOPIC, INVALID_TOPIC); + List topicOverviewList = topicService.getTopicOverviewList(REAL_CLUSTER_ID_IN_MYSQL, topics); + Assert.assertFalse(topicOverviewList.isEmpty()); + Assert.assertTrue(topicOverviewList.stream().allMatch(topicOverview -> + topicOverview.getClusterId().equals(REAL_CLUSTER_ID_IN_MYSQL) && + topics.contains(topicOverview.getTopicName()) && + topicOverview.getAppId() == null && + topicOverview.getAppName() == null && + topicOverview.getByteIn() != null)); + } + + private void getTopicOverviewListWithTopicList2TopicAndApp3Test() { + Mockito.when(topicManagerService.getByClusterIdFromCache(Mockito.anyLong())).thenReturn(null); + AppDO appDO = getAppDO(); + Mockito.when(appService.listAll()).thenReturn(Arrays.asList(appDO)); + + Mockito.when(jmxService.getTopicMetrics( + Mockito.anyLong(), Mockito.anyString(), Mockito.anyInt(), Mockito.anyBoolean())). + thenReturn(null); + + List topics = Arrays.asList(REAL_TOPIC1_IN_ZK, ZK_DEFAULT_TOPIC, INVALID_TOPIC); + List topicOverviewList = topicService.getTopicOverviewList(REAL_CLUSTER_ID_IN_MYSQL, topics); + Assert.assertFalse(topicOverviewList.isEmpty()); + Assert.assertTrue(topicOverviewList.stream().allMatch(topicOverview -> + topicOverview.getClusterId().equals(REAL_CLUSTER_ID_IN_MYSQL) && + topics.contains(topicOverview.getTopicName()) && + topicOverview.getAppId() == null && + topicOverview.getAppName() == null && + topicOverview.getByteIn() == null)); + } + + private void getTopicOverviewListWithTopicList2TopicAndApp4Test() { + Mockito.when(topicManagerService.getByClusterIdFromCache(Mockito.anyLong())).thenReturn(null); + AppDO appDO = getAppDO(); + Mockito.when(appService.listAll()).thenReturn(Arrays.asList(appDO)); + + TopicMetrics topicMetrics = getTopicMetrics(); + Mockito.when(jmxService.getTopicMetrics( + Mockito.anyLong(), Mockito.anyString(), Mockito.anyInt(), Mockito.anyBoolean())). + thenReturn(topicMetrics); + + List topics = Arrays.asList(REAL_TOPIC1_IN_ZK, ZK_DEFAULT_TOPIC, INVALID_TOPIC); + List topicOverviewList = topicService.getTopicOverviewList(REAL_CLUSTER_ID_IN_MYSQL, topics); + Assert.assertFalse(topicOverviewList.isEmpty()); + Assert.assertTrue(topicOverviewList.stream().allMatch(topicOverview -> + topicOverview.getClusterId().equals(REAL_CLUSTER_ID_IN_MYSQL) && + topics.contains(topicOverview.getTopicName()) && + topicOverview.getAppId() == null && + topicOverview.getAppName() == null && + topicOverview.getByteIn() != null)); + } + + private void getTopicOverviewListWithTopicList2TopicAndApp5Test() { + TopicDO topicDO = getTopicDO(); + Mockito.when(topicManagerService.getByClusterIdFromCache(Mockito.anyLong())).thenReturn(Arrays.asList(topicDO)); + Mockito.when(appService.listAll()).thenReturn(null); + Mockito.when(jmxService.getTopicMetrics( + Mockito.anyLong(), Mockito.anyString(), Mockito.anyInt(), Mockito.anyBoolean())).thenReturn(null); + + List topics = Arrays.asList(REAL_TOPIC1_IN_ZK, ZK_DEFAULT_TOPIC, INVALID_TOPIC); + List topicOverviewList = topicService.getTopicOverviewList(REAL_CLUSTER_ID_IN_MYSQL, topics); + Assert.assertFalse(topicOverviewList.isEmpty()); + Assert.assertTrue(topicOverviewList.stream().allMatch(topicOverview -> + topicOverview.getClusterId().equals(REAL_CLUSTER_ID_IN_MYSQL) && + topics.contains(topicOverview.getTopicName()) && + topicOverview.getAppId().equals(topicDO.getAppId()) && + topicOverview.getAppName() == null && + topicOverview.getByteIn() == null)); + } + + private void getTopicOverviewListWithTopicList2TopicAndApp6Test() { + TopicDO topicDO = getTopicDO(); + Mockito.when(topicManagerService.getByClusterIdFromCache(Mockito.anyLong())).thenReturn(Arrays.asList(topicDO)); + Mockito.when(appService.listAll()).thenReturn(null); + TopicMetrics topicMetrics = getTopicMetrics(); + Mockito.when(jmxService.getTopicMetrics( + Mockito.anyLong(), Mockito.anyString(), Mockito.anyInt(), Mockito.anyBoolean())). + thenReturn(topicMetrics); + + List topics = Arrays.asList(REAL_TOPIC1_IN_ZK, ZK_DEFAULT_TOPIC, INVALID_TOPIC); + List topicOverviewList = topicService.getTopicOverviewList(REAL_CLUSTER_ID_IN_MYSQL, topics); + Assert.assertFalse(topicOverviewList.isEmpty()); + Assert.assertTrue(topicOverviewList.stream().allMatch(topicOverview -> + topicOverview.getClusterId().equals(REAL_CLUSTER_ID_IN_MYSQL) && + topics.contains(topicOverview.getTopicName()) && + topicOverview.getAppId().equals(topicDO.getAppId()) && + topicOverview.getAppName() == null && + topicOverview.getByteIn() != null)); + } + + private void getTopicOverviewListWithTopicList2TopicAndApp7Test() { + TopicDO topicDO = getTopicDO(); + Mockito.when(topicManagerService.getByClusterIdFromCache(Mockito.anyLong())).thenReturn(Arrays.asList(topicDO)); + AppDO appDO = getAppDO(); + Mockito.when(appService.listAll()).thenReturn(Arrays.asList(appDO)); + + Mockito.when(jmxService.getTopicMetrics( + Mockito.anyLong(), Mockito.anyString(), Mockito.anyInt(), Mockito.anyBoolean())). + thenReturn(null); + + List topics = Arrays.asList(REAL_TOPIC1_IN_ZK, ZK_DEFAULT_TOPIC, INVALID_TOPIC); + List topicOverviewList = topicService.getTopicOverviewList(REAL_CLUSTER_ID_IN_MYSQL, topics); + Assert.assertFalse(topicOverviewList.isEmpty()); + Assert.assertTrue(topicOverviewList.stream().allMatch(topicOverview -> + topicOverview.getClusterId().equals(REAL_CLUSTER_ID_IN_MYSQL) && + topics.contains(topicOverview.getTopicName()) && + topicOverview.getAppId().equals(topicDO.getAppId()) && + topicOverview.getAppName().equals(appDO.getName()) && + topicOverview.getByteIn() == null)); + } + + private void getTopicOverviewListWithTopicList2TopicAndApp8Test() { + TopicDO topicDO = getTopicDO(); + Mockito.when(topicManagerService.getByClusterIdFromCache(Mockito.anyLong())).thenReturn(Arrays.asList(topicDO)); + AppDO appDO = getAppDO(); + Mockito.when(appService.listAll()).thenReturn(Arrays.asList(appDO)); + + TopicMetrics topicMetrics = getTopicMetrics(); + Mockito.when(jmxService.getTopicMetrics( + Mockito.anyLong(), Mockito.anyString(), Mockito.anyInt(), Mockito.anyBoolean())). + thenReturn(topicMetrics); + + List topics = Arrays.asList(REAL_TOPIC1_IN_ZK, ZK_DEFAULT_TOPIC, INVALID_TOPIC); + List topicOverviewList = topicService.getTopicOverviewList(REAL_CLUSTER_ID_IN_MYSQL, topics); + Assert.assertFalse(topicOverviewList.isEmpty()); + Assert.assertTrue(topicOverviewList.stream().allMatch(topicOverview -> + topicOverview.getClusterId().equals(REAL_CLUSTER_ID_IN_MYSQL) && + topics.contains(topicOverview.getTopicName()) && + topicOverview.getAppId().equals(topicDO.getAppId()) && + topicOverview.getAppName().equals(appDO.getName()) && + topicOverview.getByteIn() != null)); + } + + @Test(description = "测试获取指定时间的offset信息") + public void getPartitionOffsetListTest() { + // 结果为空 + getPartitionOffsetList2EmptyTest(); + // 获取成功 + getPartitionOffsetList2SuccessTest(); + } + + private void getPartitionOffsetList2EmptyTest() { + ClusterDO clusterDO = getClusterDO(); + List list = topicService.getPartitionOffsetList(clusterDO, INVALID_TOPIC, 0L); + Assert.assertTrue(list.isEmpty()); + } + + private void getPartitionOffsetList2SuccessTest() { + ClusterDO clusterDO = getClusterDO(); + List list = topicService.getPartitionOffsetList(clusterDO, REAL_TOPIC1_IN_ZK, 0L); + Assert.assertFalse(list.isEmpty()); + } + + @Test() + public void getTopicPartitionStateTest() { + // 结果为空 + getTopicPartitionState2EmptyTest(); + + // 获取结果成功 + getTopicPartitionState2SuccessTest(); + } + + private void getTopicPartitionState2EmptyTest() { + Map> map1 = + topicService.getTopicPartitionState(null, REAL_BROKER_ID_IN_ZK); + Assert.assertTrue(map1.isEmpty()); + + Map> map2 = + topicService.getTopicPartitionState(INVALID_CLUSTER_ID, REAL_BROKER_ID_IN_ZK); + Assert.assertTrue(map2.isEmpty()); + } + + /** + * 共有三个topic, REAL_TOPIC1_IN_ZK, REAL_TOPIC2_IN_ZK, ZK_DEFAULT_TOPIC + */ + private void getTopicPartitionState2SuccessTest() { + Map> map1 = + topicService.getTopicPartitionState(REAL_CLUSTER_ID_IN_MYSQL, REAL_BROKER_ID_IN_ZK); + Assert.assertFalse(map1.isEmpty()); + } + + @Test(description = "测试数据采样") + public void fetchTopicDataTest() { + // invalid partitionId + fetchTopicData2InvalidPartitionId(); + // 指定了offset,截断 + fetchTopicData2OffsetAndTruncate(); + // 指定了offset,未截断 + fetchTopicData2OffsetAndNoTruncate(); + // 未指定offset, 返回空 + fetchTopicData2NoOffset2Empty(); + // 未指定offset,截断 + fetchTopicData2NoOffsetAndTruncate(); + // 未指定offset,未截断 + fetchTopicData2NoOffsetAndNoTruncate(); + } + + private void fetchTopicData2InvalidPartitionId() { + ClusterDO clusterDO = getClusterDO(); + TopicDataSampleDTO topicDataSampleDTO = getTopicDataSampleDTO(); + topicDataSampleDTO.setPartitionId(INVALID_PARTITION_ID); + List result = topicService.fetchTopicData(clusterDO, REAL_TOPIC1_IN_ZK, topicDataSampleDTO); + Assert.assertTrue(result.isEmpty()); + } + + private void fetchTopicData2NoOffsetAndTruncate() { + ClusterDO clusterDO = getClusterDO(); + TopicDataSampleDTO topicDataSampleDTO = getTopicDataSampleDTO(); + topicDataSampleDTO.setOffset(null); + List result = topicService.fetchTopicData(clusterDO, REAL_TOPIC1_IN_ZK, topicDataSampleDTO); + Assert.assertFalse(result.isEmpty()); + Assert.assertTrue(result.stream().allMatch( + value -> value.length() <= TopicSampleConstant.MAX_DATA_LENGTH_UNIT_BYTE)); + } + + private void fetchTopicData2NoOffsetAndNoTruncate() { + ClusterDO clusterDO = getClusterDO(); + TopicDataSampleDTO topicDataSampleDTO = getTopicDataSampleDTO(); + topicDataSampleDTO.setOffset(null); + topicDataSampleDTO.setTruncate(false); + List result = topicService.fetchTopicData(clusterDO, REAL_TOPIC1_IN_ZK, topicDataSampleDTO); + Assert.assertFalse(result.isEmpty()); + Assert.assertTrue(result.stream().allMatch( + value -> value.length() > TopicSampleConstant.MAX_DATA_LENGTH_UNIT_BYTE)); + } + + private void fetchTopicData2OffsetAndTruncate() { + ClusterDO clusterDO = getClusterDO(); + TopicDataSampleDTO topicDataSampleDTO = getTopicDataSampleDTO(); + List result = topicService.fetchTopicData(clusterDO, REAL_TOPIC1_IN_ZK, topicDataSampleDTO); + Assert.assertFalse(result.isEmpty()); + Assert.assertTrue(result.stream().allMatch( + value -> value.length() <= TopicSampleConstant.MAX_DATA_LENGTH_UNIT_BYTE)); + } + + private void fetchTopicData2OffsetAndNoTruncate() { + ClusterDO clusterDO = getClusterDO(); + TopicDataSampleDTO topicDataSampleDTO = getTopicDataSampleDTO(); + topicDataSampleDTO.setTruncate(false); + List result = topicService.fetchTopicData(clusterDO, REAL_TOPIC1_IN_ZK, topicDataSampleDTO); + Assert.assertFalse(result.isEmpty()); + Assert.assertTrue(result.stream().allMatch( + value -> value.length() > TopicSampleConstant.MAX_DATA_LENGTH_UNIT_BYTE)); + } + + private void fetchTopicData2NoOffset2Empty() { + ClusterDO clusterDO = getClusterDO(); + TopicDataSampleDTO topicDataSampleDTO = getTopicDataSampleDTO(); + topicDataSampleDTO.setOffset(null); + topicDataSampleDTO.setTimeout(-1); + List result = topicService.fetchTopicData(clusterDO, REAL_TOPIC1_IN_ZK, topicDataSampleDTO); + Assert.assertTrue(result.isEmpty()); + } + + @Test(description = "测试从数据库中获取requestMetrics指标") + public void getTopicRequestMetricsFromDBTest() { + TopicMetricsDO topicMetricsDO1 = getTopicMetricsDO(); + topicRequestMetricsDao.add(topicMetricsDO1); + + Date startTime = new Date(0L); + Date endTime = new Date(); + List result = topicService.getTopicRequestMetricsFromDB( + topicMetricsDO1.getClusterId(), topicMetricsDO1.getTopicName(), startTime, endTime); + Assert.assertFalse(result.isEmpty()); + Assert.assertTrue(result.stream().allMatch(topicMetricsDO -> + topicMetricsDO.getClusterId().equals(topicMetricsDO1.getClusterId()) && + topicMetricsDO.getTopicName().equals(topicMetricsDO1.getTopicName()) && + topicMetricsDO.getGmtCreate().after(startTime) && + topicMetricsDO.getGmtCreate().before(endTime))); + } + + @Test(description = "测试获取topic的broker列表") + public void getTopicBrokerListTest() { + List topicBrokerList = topicService.getTopicBrokerList( + REAL_CLUSTER_ID_IN_MYSQL, REAL_TOPIC2_IN_ZK); + Assert.assertFalse(topicBrokerList.isEmpty()); + } + + @Test(description = "测试topic是否有数据写入") + public void checkTopicOffsetChangedTest() { + // physicalCluster does not exist + checkTopicOffsetChanged2ClusterNotExistTest(); + // endOffsetMap is empty + checkTopicOffsetChanged2UnknownTest(); + // dtoList is not empty and result is Yes + checkTopicOffsetChanged2dtoListNotNullAndYesTest(); + // dtoList is empty and result is No + checkTopicOffsetChanged2NoTest(); + } + + private void checkTopicOffsetChanged2ClusterNotExistTest() { + Result result = + topicService.checkTopicOffsetChanged(INVALID_CLUSTER_ID, REAL_TOPIC1_IN_ZK, 0L); + Assert.assertEquals(result.getCode(), ResultStatus.CLUSTER_NOT_EXIST.getCode()); + } + + private void checkTopicOffsetChanged2UnknownTest() { + Result result = + topicService.checkTopicOffsetChanged(REAL_CLUSTER_ID_IN_MYSQL, INVALID_TOPIC, 0L); + Assert.assertEquals(result.getData().getCode(), TopicOffsetChangedEnum.UNKNOWN.getCode()); + } + + private void checkTopicOffsetChanged2dtoListNotNullAndYesTest() { + Result result = topicService.checkTopicOffsetChanged( + REAL_CLUSTER_ID_IN_MYSQL, + REAL_TOPIC1_IN_ZK, + System.currentTimeMillis()); + Assert.assertNotNull(result); + Assert.assertEquals(result.getData().getCode(), TopicOffsetChangedEnum.YES.getCode()); + } + + private void checkTopicOffsetChanged2NoTest() { + Result result = topicService.checkTopicOffsetChanged( + REAL_CLUSTER_ID_IN_MYSQL, + NO_OFFSET_CHANGE_TOPIC_IN_ZK, + System.currentTimeMillis()); + Assert.assertNotNull(result); + Assert.assertEquals(result.getData().getCode(), TopicOffsetChangedEnum.NO.getCode()); + } + +} From 41159753202a08972e9ed2522cd088b4b182d134 Mon Sep 17 00:00:00 2001 From: xuguang Date: Mon, 27 Dec 2021 10:28:08 +0800 Subject: [PATCH 10/10] =?UTF-8?q?kafka-manager-account,=20kafka-manager-bp?= =?UTF-8?q?m,=20kafka-manager-kcm,=20kafka-manager-monitor=E5=8D=95?= =?UTF-8?q?=E5=85=83=E6=B5=8B=E8=AF=95=E6=A8=A1=E5=9D=97=E6=B7=BB=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kafka-manager-account/pom.xml | 17 ++ .../src/test/java/META-INF/MANIFEST.MF | 3 + .../manager/account/AccountServiceTest.java | 8 + .../manager/account/LoginServiceTest.java | 17 ++ .../manager/account/config/BaseTest.java | 11 + .../account/config/CoreSpringBootStartUp.java | 21 ++ .../account/config/DataSourceConfig.java | 51 +++++ .../src/test/resources/application.yml | 98 ++++++++ .../kafka-manager-springboot-distribution.xml | 63 +++++ .../src/test/resources/logback-spring.xml | 215 ++++++++++++++++++ .../kafka-manager-bpm/pom.xml | 17 ++ .../kafka/manager/bpm/OrderServiceTest.java | 8 + .../kafka/manager/bpm/config/BaseTest.java | 11 + .../bpm/config/CoreSpringBootStartUp.java | 21 ++ .../manager/bpm/config/DataSourceConfig.java | 51 +++++ .../src/test/resources/application.yml | 98 ++++++++ .../kafka-manager-springboot-distribution.xml | 63 +++++ .../src/test/resources/logback-spring.xml | 215 ++++++++++++++++++ .../kafka-manager-kcm/pom.xml | 17 ++ .../manager/kcm/ClusterTaskServiceTest.java | 8 + .../kafka/manager/kcm/config/BaseTest.java | 11 + .../kcm/config/CoreSpringBootStartUp.java | 21 ++ .../manager/kcm/config/DataSourceConfig.java | 51 +++++ .../src/test/resources/application.yml | 98 ++++++++ .../kafka-manager-springboot-distribution.xml | 63 +++++ .../src/test/resources/logback-spring.xml | 215 ++++++++++++++++++ .../kafka-manager-monitor/pom.xml | 17 ++ .../manager/monitor/MonitorServiceTest.java | 8 + .../manager/monitor/config/BaseTest.java | 11 + .../monitor/config/CoreSpringBootStartUp.java | 21 ++ .../monitor/config/DataSourceConfig.java | 51 +++++ .../src/test/resources/application.yml | 98 ++++++++ .../kafka-manager-springboot-distribution.xml | 63 +++++ .../src/test/resources/logback-spring.xml | 215 ++++++++++++++++++ 34 files changed, 1956 insertions(+) create mode 100644 kafka-manager-extends/kafka-manager-account/src/test/java/META-INF/MANIFEST.MF create mode 100644 kafka-manager-extends/kafka-manager-account/src/test/java/com/xiaojukeji/kafka/manager/account/AccountServiceTest.java create mode 100644 kafka-manager-extends/kafka-manager-account/src/test/java/com/xiaojukeji/kafka/manager/account/LoginServiceTest.java create mode 100644 kafka-manager-extends/kafka-manager-account/src/test/java/com/xiaojukeji/kafka/manager/account/config/BaseTest.java create mode 100644 kafka-manager-extends/kafka-manager-account/src/test/java/com/xiaojukeji/kafka/manager/account/config/CoreSpringBootStartUp.java create mode 100644 kafka-manager-extends/kafka-manager-account/src/test/java/com/xiaojukeji/kafka/manager/account/config/DataSourceConfig.java create mode 100644 kafka-manager-extends/kafka-manager-account/src/test/resources/application.yml create mode 100755 kafka-manager-extends/kafka-manager-account/src/test/resources/distribution/kafka-manager-springboot-distribution.xml create mode 100644 kafka-manager-extends/kafka-manager-account/src/test/resources/logback-spring.xml create mode 100644 kafka-manager-extends/kafka-manager-bpm/src/test/java/com/xiaojukeji/kafka/manager/bpm/OrderServiceTest.java create mode 100644 kafka-manager-extends/kafka-manager-bpm/src/test/java/com/xiaojukeji/kafka/manager/bpm/config/BaseTest.java create mode 100644 kafka-manager-extends/kafka-manager-bpm/src/test/java/com/xiaojukeji/kafka/manager/bpm/config/CoreSpringBootStartUp.java create mode 100644 kafka-manager-extends/kafka-manager-bpm/src/test/java/com/xiaojukeji/kafka/manager/bpm/config/DataSourceConfig.java create mode 100644 kafka-manager-extends/kafka-manager-bpm/src/test/resources/application.yml create mode 100755 kafka-manager-extends/kafka-manager-bpm/src/test/resources/distribution/kafka-manager-springboot-distribution.xml create mode 100644 kafka-manager-extends/kafka-manager-bpm/src/test/resources/logback-spring.xml create mode 100644 kafka-manager-extends/kafka-manager-kcm/src/test/java/com/xiaojukeji/kafka/manager/kcm/ClusterTaskServiceTest.java create mode 100644 kafka-manager-extends/kafka-manager-kcm/src/test/java/com/xiaojukeji/kafka/manager/kcm/config/BaseTest.java create mode 100644 kafka-manager-extends/kafka-manager-kcm/src/test/java/com/xiaojukeji/kafka/manager/kcm/config/CoreSpringBootStartUp.java create mode 100644 kafka-manager-extends/kafka-manager-kcm/src/test/java/com/xiaojukeji/kafka/manager/kcm/config/DataSourceConfig.java create mode 100644 kafka-manager-extends/kafka-manager-kcm/src/test/resources/application.yml create mode 100755 kafka-manager-extends/kafka-manager-kcm/src/test/resources/distribution/kafka-manager-springboot-distribution.xml create mode 100644 kafka-manager-extends/kafka-manager-kcm/src/test/resources/logback-spring.xml create mode 100644 kafka-manager-extends/kafka-manager-monitor/src/test/java/com/xiaojukeji/kafka/manager/monitor/MonitorServiceTest.java create mode 100644 kafka-manager-extends/kafka-manager-monitor/src/test/java/com/xiaojukeji/kafka/manager/monitor/config/BaseTest.java create mode 100644 kafka-manager-extends/kafka-manager-monitor/src/test/java/com/xiaojukeji/kafka/manager/monitor/config/CoreSpringBootStartUp.java create mode 100644 kafka-manager-extends/kafka-manager-monitor/src/test/java/com/xiaojukeji/kafka/manager/monitor/config/DataSourceConfig.java create mode 100644 kafka-manager-extends/kafka-manager-monitor/src/test/resources/application.yml create mode 100755 kafka-manager-extends/kafka-manager-monitor/src/test/resources/distribution/kafka-manager-springboot-distribution.xml create mode 100644 kafka-manager-extends/kafka-manager-monitor/src/test/resources/logback-spring.xml diff --git a/kafka-manager-extends/kafka-manager-account/pom.xml b/kafka-manager-extends/kafka-manager-account/pom.xml index a3cb47fb..95b08796 100644 --- a/kafka-manager-extends/kafka-manager-account/pom.xml +++ b/kafka-manager-extends/kafka-manager-account/pom.xml @@ -39,5 +39,22 @@ com.github.ben-manes.caffeine caffeine + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.boot + spring-boot-starter-web + + + + org.testng + testng + 6.9.10 + \ No newline at end of file diff --git a/kafka-manager-extends/kafka-manager-account/src/test/java/META-INF/MANIFEST.MF b/kafka-manager-extends/kafka-manager-account/src/test/java/META-INF/MANIFEST.MF new file mode 100644 index 00000000..254272e1 --- /dev/null +++ b/kafka-manager-extends/kafka-manager-account/src/test/java/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Class-Path: + diff --git a/kafka-manager-extends/kafka-manager-account/src/test/java/com/xiaojukeji/kafka/manager/account/AccountServiceTest.java b/kafka-manager-extends/kafka-manager-account/src/test/java/com/xiaojukeji/kafka/manager/account/AccountServiceTest.java new file mode 100644 index 00000000..cb1faa37 --- /dev/null +++ b/kafka-manager-extends/kafka-manager-account/src/test/java/com/xiaojukeji/kafka/manager/account/AccountServiceTest.java @@ -0,0 +1,8 @@ +package com.xiaojukeji.kafka.manager.account; + +/** + * @author xuguang + * @Date 2021/12/25 + */ +public class AccountServiceTest { +} diff --git a/kafka-manager-extends/kafka-manager-account/src/test/java/com/xiaojukeji/kafka/manager/account/LoginServiceTest.java b/kafka-manager-extends/kafka-manager-account/src/test/java/com/xiaojukeji/kafka/manager/account/LoginServiceTest.java new file mode 100644 index 00000000..9742ad64 --- /dev/null +++ b/kafka-manager-extends/kafka-manager-account/src/test/java/com/xiaojukeji/kafka/manager/account/LoginServiceTest.java @@ -0,0 +1,17 @@ +package com.xiaojukeji.kafka.manager.account; + +import com.xiaojukeji.kafka.manager.account.config.BaseTest; +import org.testng.Assert; +import org.testng.annotations.Test; + +/** + * @author xuguang + * @Date 2021/12/25 + */ +public class LoginServiceTest extends BaseTest { + + @Test + public void test() { + Assert.assertEquals("", ""); + } +} diff --git a/kafka-manager-extends/kafka-manager-account/src/test/java/com/xiaojukeji/kafka/manager/account/config/BaseTest.java b/kafka-manager-extends/kafka-manager-account/src/test/java/com/xiaojukeji/kafka/manager/account/config/BaseTest.java new file mode 100644 index 00000000..19cb1338 --- /dev/null +++ b/kafka-manager-extends/kafka-manager-account/src/test/java/com/xiaojukeji/kafka/manager/account/config/BaseTest.java @@ -0,0 +1,11 @@ +package com.xiaojukeji.kafka.manager.account.config; + +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.testng.AbstractTransactionalTestNGSpringContextTests; + +@SpringBootTest(classes = CoreSpringBootStartUp.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@ContextConfiguration(classes = CoreSpringBootStartUp.class) +public class BaseTest extends AbstractTransactionalTestNGSpringContextTests { + +} diff --git a/kafka-manager-extends/kafka-manager-account/src/test/java/com/xiaojukeji/kafka/manager/account/config/CoreSpringBootStartUp.java b/kafka-manager-extends/kafka-manager-account/src/test/java/com/xiaojukeji/kafka/manager/account/config/CoreSpringBootStartUp.java new file mode 100644 index 00000000..b02da68b --- /dev/null +++ b/kafka-manager-extends/kafka-manager-account/src/test/java/com/xiaojukeji/kafka/manager/account/config/CoreSpringBootStartUp.java @@ -0,0 +1,21 @@ +package com.xiaojukeji.kafka.manager.account.config; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.ServletComponentScan; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.annotation.EnableScheduling; + +@EnableAsync +@EnableScheduling +@ServletComponentScan +@EnableAutoConfiguration +@SpringBootApplication(scanBasePackages = {"com.xiaojukeji.kafka.manager"}) +public class CoreSpringBootStartUp { + public static void main(String[] args) { + SpringApplication sa = new SpringApplication(CoreSpringBootStartUp.class); + sa.run(args); + } + +} diff --git a/kafka-manager-extends/kafka-manager-account/src/test/java/com/xiaojukeji/kafka/manager/account/config/DataSourceConfig.java b/kafka-manager-extends/kafka-manager-account/src/test/java/com/xiaojukeji/kafka/manager/account/config/DataSourceConfig.java new file mode 100644 index 00000000..132a309b --- /dev/null +++ b/kafka-manager-extends/kafka-manager-account/src/test/java/com/xiaojukeji/kafka/manager/account/config/DataSourceConfig.java @@ -0,0 +1,51 @@ +package com.xiaojukeji.kafka.manager.account.config; + +import org.apache.ibatis.session.SqlSessionFactory; +import org.mybatis.spring.SqlSessionFactoryBean; +import org.mybatis.spring.SqlSessionTemplate; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; + +import javax.sql.DataSource; + +/** + * @author zengqiao + * @date 20/3/17 + */ +@Configuration +public class DataSourceConfig { + @Bean(name = "dataSource") + @ConfigurationProperties(prefix = "spring.datasource.kafka-manager") + @Primary + public DataSource dataSource() { + return DataSourceBuilder.create().build(); + } + + @Bean(name = "sqlSessionFactory") + @Primary + public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSource") DataSource dataSource) throws Exception { + SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); + bean.setDataSource(dataSource); + bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml")); + bean.setConfigLocation(new PathMatchingResourcePatternResolver().getResource("classpath:mybatis-config.xml")); + return bean.getObject(); + } + + @Bean(name = "transactionManager") + @Primary + public DataSourceTransactionManager transactionManager(@Qualifier("dataSource") DataSource dataSource) { + return new DataSourceTransactionManager(dataSource); + } + + @Bean(name = "sqlSession") + @Primary + public SqlSessionTemplate sqlSessionTemplate(@Qualifier("sqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception { + return new SqlSessionTemplate(sqlSessionFactory); + } +} diff --git a/kafka-manager-extends/kafka-manager-account/src/test/resources/application.yml b/kafka-manager-extends/kafka-manager-account/src/test/resources/application.yml new file mode 100644 index 00000000..a4648a46 --- /dev/null +++ b/kafka-manager-extends/kafka-manager-account/src/test/resources/application.yml @@ -0,0 +1,98 @@ +server: + port: 8080 + tomcat: + accept-count: 1000 + max-connections: 10000 + max-threads: 800 + min-spare-threads: 100 + +spring: + application: + name: kafkamanager + profiles: + active: dev + datasource: + kafka-manager: + jdbc-url: jdbc:mysql://localhost:3306/logi_kafka_manager?characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2B8 + username: root + password: 123456 + driver-class-name: com.mysql.cj.jdbc.Driver + main: + allow-bean-definition-overriding: true + + servlet: + multipart: + max-file-size: 100MB + max-request-size: 100MB + +logging: + config: classpath:logback-spring.xml + +custom: + idc: cn + jmx: + max-conn: 10 # 2.3版本配置不在这个地方生效 + store-metrics-task: + community: + broker-metrics-enabled: true + topic-metrics-enabled: true + didi: + app-topic-metrics-enabled: false + topic-request-time-metrics-enabled: false + topic-throttled-metrics: false + save-days: 7 + +# 任务相关的开关 +task: + op: + sync-topic-enabled: false # 未落盘的Topic定期同步到DB中 + order-auto-exec: # 工单自动化审批线程的开关 + topic-enabled: false # Topic工单自动化审批开关, false:关闭自动化审批, true:开启 + app-enabled: false # App工单自动化审批开关, false:关闭自动化审批, true:开启 + +account: + ldap: + enabled: false + url: ldap://127.0.0.1:389/ + basedn: dc=tsign,dc=cn + factory: com.sun.jndi.ldap.LdapCtxFactory + filter: sAMAccountName + security: + authentication: simple + principal: cn=admin,dc=tsign,dc=cn + credentials: admin + auth-user-registration: true + auth-user-registration-role: normal + +kcm: + enabled: false + s3: + endpoint: s3.didiyunapi.com + access-key: 1234567890 + secret-key: 0987654321 + bucket: logi-kafka + n9e: + base-url: http://127.0.0.1:8004 + user-token: 12345678 + timeout: 300 + account: root + script-file: kcm_script.sh + +monitor: + enabled: false + n9e: + nid: 2 + user-token: 1234567890 + mon: + base-url: http://127.0.0.1:8000 # 夜莺v4版本,默认端口统一调整为了8000 + sink: + base-url: http://127.0.0.1:8000 # 夜莺v4版本,默认端口统一调整为了8000 + rdb: + base-url: http://127.0.0.1:8000 # 夜莺v4版本,默认端口统一调整为了8000 + +notify: + kafka: + cluster-id: 95 + topic-name: didi-kafka-notify + order: + detail-url: http://127.0.0.1 diff --git a/kafka-manager-extends/kafka-manager-account/src/test/resources/distribution/kafka-manager-springboot-distribution.xml b/kafka-manager-extends/kafka-manager-account/src/test/resources/distribution/kafka-manager-springboot-distribution.xml new file mode 100755 index 00000000..51c9a632 --- /dev/null +++ b/kafka-manager-extends/kafka-manager-account/src/test/resources/distribution/kafka-manager-springboot-distribution.xml @@ -0,0 +1,63 @@ + + assembly + + tar + zip + + + + src/main/resources/bin + bin + + control.sh + start.bat + + 0755 + + + src/main/resources + config + + *.properties + *.xml + *.yml + env/dev/* + env/qa/* + env/uat/* + env/prod/* + + + + target + lib + + + kafka-manager-web*.jar + + + + *sources.jar + + + + src/main/resources + logs + 0755 + + **/* + + + + + \ No newline at end of file diff --git a/kafka-manager-extends/kafka-manager-account/src/test/resources/logback-spring.xml b/kafka-manager-extends/kafka-manager-account/src/test/resources/logback-spring.xml new file mode 100644 index 00000000..c1c16136 --- /dev/null +++ b/kafka-manager-extends/kafka-manager-account/src/test/resources/logback-spring.xml @@ -0,0 +1,215 @@ + + + logback + + + + + + + + + + + + + + info + + + ${CONSOLE_LOG_PATTERN} + UTF-8 + + + + + + + + + ${log.path}/log_debug.log + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + UTF-8 + + + + + ${log.path}/log_debug_%d{yyyy-MM-dd}.%i.log + + 100MB + + + 7 + + + + debug + ACCEPT + DENY + + + + + + + ${log.path}/log_info.log + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + UTF-8 + + + + + ${log.path}/log_info_%d{yyyy-MM-dd}.%i.log + + 100MB + + + 7 + + + + info + ACCEPT + DENY + + + + + + + ${log.path}/log_warn.log + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + UTF-8 + + + + ${log.path}/log_warn_%d{yyyy-MM-dd}.%i.log + + 100MB + + + 7 + + + + warn + ACCEPT + DENY + + + + + + + + ${log.path}/log_error.log + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + UTF-8 + + + + ${log.path}/log_error_%d{yyyy-MM-dd}.%i.log + + 100MB + + + 7 + + + + ERROR + ACCEPT + DENY + + + + + + ${log.path}/metrics/collector_metrics.log + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + UTF-8 + + + ${log.path}/metrics/collector_metrics_%d{yyyy-MM-dd}.%i.log + + 100MB + + 3 + + + + + + ${log.path}/metrics/api_metrics.log + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + UTF-8 + + + ${log.path}/metrics/api_metrics_%d{yyyy-MM-dd}.%i.log + + 100MB + + 3 + + + + + + ${log.path}/metrics/scheduled_tasks.log + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + UTF-8 + + + ${log.path}/metrics/scheduled_tasks_%d{yyyy-MM-dd}.%i.log + + 100MB + + 5 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/kafka-manager-extends/kafka-manager-bpm/pom.xml b/kafka-manager-extends/kafka-manager-bpm/pom.xml index c8ecf459..d4da9250 100644 --- a/kafka-manager-extends/kafka-manager-bpm/pom.xml +++ b/kafka-manager-extends/kafka-manager-bpm/pom.xml @@ -35,5 +35,22 @@ kafka-manager-account ${project.parent.version} + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.boot + spring-boot-starter-web + + + + org.testng + testng + 6.9.10 + \ No newline at end of file diff --git a/kafka-manager-extends/kafka-manager-bpm/src/test/java/com/xiaojukeji/kafka/manager/bpm/OrderServiceTest.java b/kafka-manager-extends/kafka-manager-bpm/src/test/java/com/xiaojukeji/kafka/manager/bpm/OrderServiceTest.java new file mode 100644 index 00000000..5435ec2a --- /dev/null +++ b/kafka-manager-extends/kafka-manager-bpm/src/test/java/com/xiaojukeji/kafka/manager/bpm/OrderServiceTest.java @@ -0,0 +1,8 @@ +package com.xiaojukeji.kafka.manager.bpm; + +/** + * @author xuguang + * @Date 2021/12/27 + */ +public class OrderServiceTest { +} diff --git a/kafka-manager-extends/kafka-manager-bpm/src/test/java/com/xiaojukeji/kafka/manager/bpm/config/BaseTest.java b/kafka-manager-extends/kafka-manager-bpm/src/test/java/com/xiaojukeji/kafka/manager/bpm/config/BaseTest.java new file mode 100644 index 00000000..2cf7dc10 --- /dev/null +++ b/kafka-manager-extends/kafka-manager-bpm/src/test/java/com/xiaojukeji/kafka/manager/bpm/config/BaseTest.java @@ -0,0 +1,11 @@ +package com.xiaojukeji.kafka.manager.bpm.config; + +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.testng.AbstractTransactionalTestNGSpringContextTests; + +@SpringBootTest(classes = CoreSpringBootStartUp.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@ContextConfiguration(classes = CoreSpringBootStartUp.class) +public class BaseTest extends AbstractTransactionalTestNGSpringContextTests { + +} diff --git a/kafka-manager-extends/kafka-manager-bpm/src/test/java/com/xiaojukeji/kafka/manager/bpm/config/CoreSpringBootStartUp.java b/kafka-manager-extends/kafka-manager-bpm/src/test/java/com/xiaojukeji/kafka/manager/bpm/config/CoreSpringBootStartUp.java new file mode 100644 index 00000000..f60ca1fd --- /dev/null +++ b/kafka-manager-extends/kafka-manager-bpm/src/test/java/com/xiaojukeji/kafka/manager/bpm/config/CoreSpringBootStartUp.java @@ -0,0 +1,21 @@ +package com.xiaojukeji.kafka.manager.bpm.config; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.ServletComponentScan; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.annotation.EnableScheduling; + +@EnableAsync +@EnableScheduling +@ServletComponentScan +@EnableAutoConfiguration +@SpringBootApplication(scanBasePackages = {"com.xiaojukeji.kafka.manager"}) +public class CoreSpringBootStartUp { + public static void main(String[] args) { + SpringApplication sa = new SpringApplication(CoreSpringBootStartUp.class); + sa.run(args); + } + +} diff --git a/kafka-manager-extends/kafka-manager-bpm/src/test/java/com/xiaojukeji/kafka/manager/bpm/config/DataSourceConfig.java b/kafka-manager-extends/kafka-manager-bpm/src/test/java/com/xiaojukeji/kafka/manager/bpm/config/DataSourceConfig.java new file mode 100644 index 00000000..85b79eee --- /dev/null +++ b/kafka-manager-extends/kafka-manager-bpm/src/test/java/com/xiaojukeji/kafka/manager/bpm/config/DataSourceConfig.java @@ -0,0 +1,51 @@ +package com.xiaojukeji.kafka.manager.bpm.config; + +import org.apache.ibatis.session.SqlSessionFactory; +import org.mybatis.spring.SqlSessionFactoryBean; +import org.mybatis.spring.SqlSessionTemplate; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; + +import javax.sql.DataSource; + +/** + * @author zengqiao + * @date 20/3/17 + */ +@Configuration +public class DataSourceConfig { + @Bean(name = "dataSource") + @ConfigurationProperties(prefix = "spring.datasource.kafka-manager") + @Primary + public DataSource dataSource() { + return DataSourceBuilder.create().build(); + } + + @Bean(name = "sqlSessionFactory") + @Primary + public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSource") DataSource dataSource) throws Exception { + SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); + bean.setDataSource(dataSource); + bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml")); + bean.setConfigLocation(new PathMatchingResourcePatternResolver().getResource("classpath:mybatis-config.xml")); + return bean.getObject(); + } + + @Bean(name = "transactionManager") + @Primary + public DataSourceTransactionManager transactionManager(@Qualifier("dataSource") DataSource dataSource) { + return new DataSourceTransactionManager(dataSource); + } + + @Bean(name = "sqlSession") + @Primary + public SqlSessionTemplate sqlSessionTemplate(@Qualifier("sqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception { + return new SqlSessionTemplate(sqlSessionFactory); + } +} diff --git a/kafka-manager-extends/kafka-manager-bpm/src/test/resources/application.yml b/kafka-manager-extends/kafka-manager-bpm/src/test/resources/application.yml new file mode 100644 index 00000000..a4648a46 --- /dev/null +++ b/kafka-manager-extends/kafka-manager-bpm/src/test/resources/application.yml @@ -0,0 +1,98 @@ +server: + port: 8080 + tomcat: + accept-count: 1000 + max-connections: 10000 + max-threads: 800 + min-spare-threads: 100 + +spring: + application: + name: kafkamanager + profiles: + active: dev + datasource: + kafka-manager: + jdbc-url: jdbc:mysql://localhost:3306/logi_kafka_manager?characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2B8 + username: root + password: 123456 + driver-class-name: com.mysql.cj.jdbc.Driver + main: + allow-bean-definition-overriding: true + + servlet: + multipart: + max-file-size: 100MB + max-request-size: 100MB + +logging: + config: classpath:logback-spring.xml + +custom: + idc: cn + jmx: + max-conn: 10 # 2.3版本配置不在这个地方生效 + store-metrics-task: + community: + broker-metrics-enabled: true + topic-metrics-enabled: true + didi: + app-topic-metrics-enabled: false + topic-request-time-metrics-enabled: false + topic-throttled-metrics: false + save-days: 7 + +# 任务相关的开关 +task: + op: + sync-topic-enabled: false # 未落盘的Topic定期同步到DB中 + order-auto-exec: # 工单自动化审批线程的开关 + topic-enabled: false # Topic工单自动化审批开关, false:关闭自动化审批, true:开启 + app-enabled: false # App工单自动化审批开关, false:关闭自动化审批, true:开启 + +account: + ldap: + enabled: false + url: ldap://127.0.0.1:389/ + basedn: dc=tsign,dc=cn + factory: com.sun.jndi.ldap.LdapCtxFactory + filter: sAMAccountName + security: + authentication: simple + principal: cn=admin,dc=tsign,dc=cn + credentials: admin + auth-user-registration: true + auth-user-registration-role: normal + +kcm: + enabled: false + s3: + endpoint: s3.didiyunapi.com + access-key: 1234567890 + secret-key: 0987654321 + bucket: logi-kafka + n9e: + base-url: http://127.0.0.1:8004 + user-token: 12345678 + timeout: 300 + account: root + script-file: kcm_script.sh + +monitor: + enabled: false + n9e: + nid: 2 + user-token: 1234567890 + mon: + base-url: http://127.0.0.1:8000 # 夜莺v4版本,默认端口统一调整为了8000 + sink: + base-url: http://127.0.0.1:8000 # 夜莺v4版本,默认端口统一调整为了8000 + rdb: + base-url: http://127.0.0.1:8000 # 夜莺v4版本,默认端口统一调整为了8000 + +notify: + kafka: + cluster-id: 95 + topic-name: didi-kafka-notify + order: + detail-url: http://127.0.0.1 diff --git a/kafka-manager-extends/kafka-manager-bpm/src/test/resources/distribution/kafka-manager-springboot-distribution.xml b/kafka-manager-extends/kafka-manager-bpm/src/test/resources/distribution/kafka-manager-springboot-distribution.xml new file mode 100755 index 00000000..51c9a632 --- /dev/null +++ b/kafka-manager-extends/kafka-manager-bpm/src/test/resources/distribution/kafka-manager-springboot-distribution.xml @@ -0,0 +1,63 @@ + + assembly + + tar + zip + + + + src/main/resources/bin + bin + + control.sh + start.bat + + 0755 + + + src/main/resources + config + + *.properties + *.xml + *.yml + env/dev/* + env/qa/* + env/uat/* + env/prod/* + + + + target + lib + + + kafka-manager-web*.jar + + + + *sources.jar + + + + src/main/resources + logs + 0755 + + **/* + + + + + \ No newline at end of file diff --git a/kafka-manager-extends/kafka-manager-bpm/src/test/resources/logback-spring.xml b/kafka-manager-extends/kafka-manager-bpm/src/test/resources/logback-spring.xml new file mode 100644 index 00000000..c1c16136 --- /dev/null +++ b/kafka-manager-extends/kafka-manager-bpm/src/test/resources/logback-spring.xml @@ -0,0 +1,215 @@ + + + logback + + + + + + + + + + + + + + info + + + ${CONSOLE_LOG_PATTERN} + UTF-8 + + + + + + + + + ${log.path}/log_debug.log + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + UTF-8 + + + + + ${log.path}/log_debug_%d{yyyy-MM-dd}.%i.log + + 100MB + + + 7 + + + + debug + ACCEPT + DENY + + + + + + + ${log.path}/log_info.log + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + UTF-8 + + + + + ${log.path}/log_info_%d{yyyy-MM-dd}.%i.log + + 100MB + + + 7 + + + + info + ACCEPT + DENY + + + + + + + ${log.path}/log_warn.log + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + UTF-8 + + + + ${log.path}/log_warn_%d{yyyy-MM-dd}.%i.log + + 100MB + + + 7 + + + + warn + ACCEPT + DENY + + + + + + + + ${log.path}/log_error.log + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + UTF-8 + + + + ${log.path}/log_error_%d{yyyy-MM-dd}.%i.log + + 100MB + + + 7 + + + + ERROR + ACCEPT + DENY + + + + + + ${log.path}/metrics/collector_metrics.log + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + UTF-8 + + + ${log.path}/metrics/collector_metrics_%d{yyyy-MM-dd}.%i.log + + 100MB + + 3 + + + + + + ${log.path}/metrics/api_metrics.log + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + UTF-8 + + + ${log.path}/metrics/api_metrics_%d{yyyy-MM-dd}.%i.log + + 100MB + + 3 + + + + + + ${log.path}/metrics/scheduled_tasks.log + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + UTF-8 + + + ${log.path}/metrics/scheduled_tasks_%d{yyyy-MM-dd}.%i.log + + 100MB + + 5 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/kafka-manager-extends/kafka-manager-kcm/pom.xml b/kafka-manager-extends/kafka-manager-kcm/pom.xml index 7ffd00e3..9b881568 100644 --- a/kafka-manager-extends/kafka-manager-kcm/pom.xml +++ b/kafka-manager-extends/kafka-manager-kcm/pom.xml @@ -73,5 +73,22 @@ io.minio minio + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.boot + spring-boot-starter-web + + + + org.testng + testng + 6.9.10 + \ No newline at end of file diff --git a/kafka-manager-extends/kafka-manager-kcm/src/test/java/com/xiaojukeji/kafka/manager/kcm/ClusterTaskServiceTest.java b/kafka-manager-extends/kafka-manager-kcm/src/test/java/com/xiaojukeji/kafka/manager/kcm/ClusterTaskServiceTest.java new file mode 100644 index 00000000..c204a0e5 --- /dev/null +++ b/kafka-manager-extends/kafka-manager-kcm/src/test/java/com/xiaojukeji/kafka/manager/kcm/ClusterTaskServiceTest.java @@ -0,0 +1,8 @@ +package com.xiaojukeji.kafka.manager.kcm; + +/** + * @author xuguang + * @Date 2021/12/27 + */ +public class ClusterTaskServiceTest { +} diff --git a/kafka-manager-extends/kafka-manager-kcm/src/test/java/com/xiaojukeji/kafka/manager/kcm/config/BaseTest.java b/kafka-manager-extends/kafka-manager-kcm/src/test/java/com/xiaojukeji/kafka/manager/kcm/config/BaseTest.java new file mode 100644 index 00000000..9db04908 --- /dev/null +++ b/kafka-manager-extends/kafka-manager-kcm/src/test/java/com/xiaojukeji/kafka/manager/kcm/config/BaseTest.java @@ -0,0 +1,11 @@ +package com.xiaojukeji.kafka.manager.kcm.config; + +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.testng.AbstractTransactionalTestNGSpringContextTests; + +@SpringBootTest(classes = CoreSpringBootStartUp.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@ContextConfiguration(classes = CoreSpringBootStartUp.class) +public class BaseTest extends AbstractTransactionalTestNGSpringContextTests { + +} diff --git a/kafka-manager-extends/kafka-manager-kcm/src/test/java/com/xiaojukeji/kafka/manager/kcm/config/CoreSpringBootStartUp.java b/kafka-manager-extends/kafka-manager-kcm/src/test/java/com/xiaojukeji/kafka/manager/kcm/config/CoreSpringBootStartUp.java new file mode 100644 index 00000000..811a837d --- /dev/null +++ b/kafka-manager-extends/kafka-manager-kcm/src/test/java/com/xiaojukeji/kafka/manager/kcm/config/CoreSpringBootStartUp.java @@ -0,0 +1,21 @@ +package com.xiaojukeji.kafka.manager.kcm.config; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.ServletComponentScan; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.annotation.EnableScheduling; + +@EnableAsync +@EnableScheduling +@ServletComponentScan +@EnableAutoConfiguration +@SpringBootApplication(scanBasePackages = {"com.xiaojukeji.kafka.manager"}) +public class CoreSpringBootStartUp { + public static void main(String[] args) { + SpringApplication sa = new SpringApplication(CoreSpringBootStartUp.class); + sa.run(args); + } + +} diff --git a/kafka-manager-extends/kafka-manager-kcm/src/test/java/com/xiaojukeji/kafka/manager/kcm/config/DataSourceConfig.java b/kafka-manager-extends/kafka-manager-kcm/src/test/java/com/xiaojukeji/kafka/manager/kcm/config/DataSourceConfig.java new file mode 100644 index 00000000..5dd19eea --- /dev/null +++ b/kafka-manager-extends/kafka-manager-kcm/src/test/java/com/xiaojukeji/kafka/manager/kcm/config/DataSourceConfig.java @@ -0,0 +1,51 @@ +package com.xiaojukeji.kafka.manager.kcm.config; + +import org.apache.ibatis.session.SqlSessionFactory; +import org.mybatis.spring.SqlSessionFactoryBean; +import org.mybatis.spring.SqlSessionTemplate; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; + +import javax.sql.DataSource; + +/** + * @author zengqiao + * @date 20/3/17 + */ +@Configuration +public class DataSourceConfig { + @Bean(name = "dataSource") + @ConfigurationProperties(prefix = "spring.datasource.kafka-manager") + @Primary + public DataSource dataSource() { + return DataSourceBuilder.create().build(); + } + + @Bean(name = "sqlSessionFactory") + @Primary + public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSource") DataSource dataSource) throws Exception { + SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); + bean.setDataSource(dataSource); + bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml")); + bean.setConfigLocation(new PathMatchingResourcePatternResolver().getResource("classpath:mybatis-config.xml")); + return bean.getObject(); + } + + @Bean(name = "transactionManager") + @Primary + public DataSourceTransactionManager transactionManager(@Qualifier("dataSource") DataSource dataSource) { + return new DataSourceTransactionManager(dataSource); + } + + @Bean(name = "sqlSession") + @Primary + public SqlSessionTemplate sqlSessionTemplate(@Qualifier("sqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception { + return new SqlSessionTemplate(sqlSessionFactory); + } +} diff --git a/kafka-manager-extends/kafka-manager-kcm/src/test/resources/application.yml b/kafka-manager-extends/kafka-manager-kcm/src/test/resources/application.yml new file mode 100644 index 00000000..a4648a46 --- /dev/null +++ b/kafka-manager-extends/kafka-manager-kcm/src/test/resources/application.yml @@ -0,0 +1,98 @@ +server: + port: 8080 + tomcat: + accept-count: 1000 + max-connections: 10000 + max-threads: 800 + min-spare-threads: 100 + +spring: + application: + name: kafkamanager + profiles: + active: dev + datasource: + kafka-manager: + jdbc-url: jdbc:mysql://localhost:3306/logi_kafka_manager?characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2B8 + username: root + password: 123456 + driver-class-name: com.mysql.cj.jdbc.Driver + main: + allow-bean-definition-overriding: true + + servlet: + multipart: + max-file-size: 100MB + max-request-size: 100MB + +logging: + config: classpath:logback-spring.xml + +custom: + idc: cn + jmx: + max-conn: 10 # 2.3版本配置不在这个地方生效 + store-metrics-task: + community: + broker-metrics-enabled: true + topic-metrics-enabled: true + didi: + app-topic-metrics-enabled: false + topic-request-time-metrics-enabled: false + topic-throttled-metrics: false + save-days: 7 + +# 任务相关的开关 +task: + op: + sync-topic-enabled: false # 未落盘的Topic定期同步到DB中 + order-auto-exec: # 工单自动化审批线程的开关 + topic-enabled: false # Topic工单自动化审批开关, false:关闭自动化审批, true:开启 + app-enabled: false # App工单自动化审批开关, false:关闭自动化审批, true:开启 + +account: + ldap: + enabled: false + url: ldap://127.0.0.1:389/ + basedn: dc=tsign,dc=cn + factory: com.sun.jndi.ldap.LdapCtxFactory + filter: sAMAccountName + security: + authentication: simple + principal: cn=admin,dc=tsign,dc=cn + credentials: admin + auth-user-registration: true + auth-user-registration-role: normal + +kcm: + enabled: false + s3: + endpoint: s3.didiyunapi.com + access-key: 1234567890 + secret-key: 0987654321 + bucket: logi-kafka + n9e: + base-url: http://127.0.0.1:8004 + user-token: 12345678 + timeout: 300 + account: root + script-file: kcm_script.sh + +monitor: + enabled: false + n9e: + nid: 2 + user-token: 1234567890 + mon: + base-url: http://127.0.0.1:8000 # 夜莺v4版本,默认端口统一调整为了8000 + sink: + base-url: http://127.0.0.1:8000 # 夜莺v4版本,默认端口统一调整为了8000 + rdb: + base-url: http://127.0.0.1:8000 # 夜莺v4版本,默认端口统一调整为了8000 + +notify: + kafka: + cluster-id: 95 + topic-name: didi-kafka-notify + order: + detail-url: http://127.0.0.1 diff --git a/kafka-manager-extends/kafka-manager-kcm/src/test/resources/distribution/kafka-manager-springboot-distribution.xml b/kafka-manager-extends/kafka-manager-kcm/src/test/resources/distribution/kafka-manager-springboot-distribution.xml new file mode 100755 index 00000000..51c9a632 --- /dev/null +++ b/kafka-manager-extends/kafka-manager-kcm/src/test/resources/distribution/kafka-manager-springboot-distribution.xml @@ -0,0 +1,63 @@ + + assembly + + tar + zip + + + + src/main/resources/bin + bin + + control.sh + start.bat + + 0755 + + + src/main/resources + config + + *.properties + *.xml + *.yml + env/dev/* + env/qa/* + env/uat/* + env/prod/* + + + + target + lib + + + kafka-manager-web*.jar + + + + *sources.jar + + + + src/main/resources + logs + 0755 + + **/* + + + + + \ No newline at end of file diff --git a/kafka-manager-extends/kafka-manager-kcm/src/test/resources/logback-spring.xml b/kafka-manager-extends/kafka-manager-kcm/src/test/resources/logback-spring.xml new file mode 100644 index 00000000..c1c16136 --- /dev/null +++ b/kafka-manager-extends/kafka-manager-kcm/src/test/resources/logback-spring.xml @@ -0,0 +1,215 @@ + + + logback + + + + + + + + + + + + + + info + + + ${CONSOLE_LOG_PATTERN} + UTF-8 + + + + + + + + + ${log.path}/log_debug.log + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + UTF-8 + + + + + ${log.path}/log_debug_%d{yyyy-MM-dd}.%i.log + + 100MB + + + 7 + + + + debug + ACCEPT + DENY + + + + + + + ${log.path}/log_info.log + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + UTF-8 + + + + + ${log.path}/log_info_%d{yyyy-MM-dd}.%i.log + + 100MB + + + 7 + + + + info + ACCEPT + DENY + + + + + + + ${log.path}/log_warn.log + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + UTF-8 + + + + ${log.path}/log_warn_%d{yyyy-MM-dd}.%i.log + + 100MB + + + 7 + + + + warn + ACCEPT + DENY + + + + + + + + ${log.path}/log_error.log + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + UTF-8 + + + + ${log.path}/log_error_%d{yyyy-MM-dd}.%i.log + + 100MB + + + 7 + + + + ERROR + ACCEPT + DENY + + + + + + ${log.path}/metrics/collector_metrics.log + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + UTF-8 + + + ${log.path}/metrics/collector_metrics_%d{yyyy-MM-dd}.%i.log + + 100MB + + 3 + + + + + + ${log.path}/metrics/api_metrics.log + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + UTF-8 + + + ${log.path}/metrics/api_metrics_%d{yyyy-MM-dd}.%i.log + + 100MB + + 3 + + + + + + ${log.path}/metrics/scheduled_tasks.log + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + UTF-8 + + + ${log.path}/metrics/scheduled_tasks_%d{yyyy-MM-dd}.%i.log + + 100MB + + 5 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/kafka-manager-extends/kafka-manager-monitor/pom.xml b/kafka-manager-extends/kafka-manager-monitor/pom.xml index 0948a190..66c79b33 100644 --- a/kafka-manager-extends/kafka-manager-monitor/pom.xml +++ b/kafka-manager-extends/kafka-manager-monitor/pom.xml @@ -70,5 +70,22 @@ spring-context ${spring-version} + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.boot + spring-boot-starter-web + + + + org.testng + testng + 6.9.10 + \ No newline at end of file diff --git a/kafka-manager-extends/kafka-manager-monitor/src/test/java/com/xiaojukeji/kafka/manager/monitor/MonitorServiceTest.java b/kafka-manager-extends/kafka-manager-monitor/src/test/java/com/xiaojukeji/kafka/manager/monitor/MonitorServiceTest.java new file mode 100644 index 00000000..6bf90551 --- /dev/null +++ b/kafka-manager-extends/kafka-manager-monitor/src/test/java/com/xiaojukeji/kafka/manager/monitor/MonitorServiceTest.java @@ -0,0 +1,8 @@ +package com.xiaojukeji.kafka.manager.monitor; + +/** + * @author xuguang + * @Date 2021/12/27 + */ +public class MonitorServiceTest { +} diff --git a/kafka-manager-extends/kafka-manager-monitor/src/test/java/com/xiaojukeji/kafka/manager/monitor/config/BaseTest.java b/kafka-manager-extends/kafka-manager-monitor/src/test/java/com/xiaojukeji/kafka/manager/monitor/config/BaseTest.java new file mode 100644 index 00000000..368919e1 --- /dev/null +++ b/kafka-manager-extends/kafka-manager-monitor/src/test/java/com/xiaojukeji/kafka/manager/monitor/config/BaseTest.java @@ -0,0 +1,11 @@ +package com.xiaojukeji.kafka.manager.monitor.config; + +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.testng.AbstractTransactionalTestNGSpringContextTests; + +@SpringBootTest(classes = CoreSpringBootStartUp.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@ContextConfiguration(classes = CoreSpringBootStartUp.class) +public class BaseTest extends AbstractTransactionalTestNGSpringContextTests { + +} diff --git a/kafka-manager-extends/kafka-manager-monitor/src/test/java/com/xiaojukeji/kafka/manager/monitor/config/CoreSpringBootStartUp.java b/kafka-manager-extends/kafka-manager-monitor/src/test/java/com/xiaojukeji/kafka/manager/monitor/config/CoreSpringBootStartUp.java new file mode 100644 index 00000000..2bb98771 --- /dev/null +++ b/kafka-manager-extends/kafka-manager-monitor/src/test/java/com/xiaojukeji/kafka/manager/monitor/config/CoreSpringBootStartUp.java @@ -0,0 +1,21 @@ +package com.xiaojukeji.kafka.manager.monitor.config; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.ServletComponentScan; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.annotation.EnableScheduling; + +@EnableAsync +@EnableScheduling +@ServletComponentScan +@EnableAutoConfiguration +@SpringBootApplication(scanBasePackages = {"com.xiaojukeji.kafka.manager"}) +public class CoreSpringBootStartUp { + public static void main(String[] args) { + SpringApplication sa = new SpringApplication(CoreSpringBootStartUp.class); + sa.run(args); + } + +} diff --git a/kafka-manager-extends/kafka-manager-monitor/src/test/java/com/xiaojukeji/kafka/manager/monitor/config/DataSourceConfig.java b/kafka-manager-extends/kafka-manager-monitor/src/test/java/com/xiaojukeji/kafka/manager/monitor/config/DataSourceConfig.java new file mode 100644 index 00000000..5ce0aec9 --- /dev/null +++ b/kafka-manager-extends/kafka-manager-monitor/src/test/java/com/xiaojukeji/kafka/manager/monitor/config/DataSourceConfig.java @@ -0,0 +1,51 @@ +package com.xiaojukeji.kafka.manager.monitor.config; + +import org.apache.ibatis.session.SqlSessionFactory; +import org.mybatis.spring.SqlSessionFactoryBean; +import org.mybatis.spring.SqlSessionTemplate; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.core.io.support.PathMatchingResourcePatternResolver; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; + +import javax.sql.DataSource; + +/** + * @author zengqiao + * @date 20/3/17 + */ +@Configuration +public class DataSourceConfig { + @Bean(name = "dataSource") + @ConfigurationProperties(prefix = "spring.datasource.kafka-manager") + @Primary + public DataSource dataSource() { + return DataSourceBuilder.create().build(); + } + + @Bean(name = "sqlSessionFactory") + @Primary + public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSource") DataSource dataSource) throws Exception { + SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); + bean.setDataSource(dataSource); + bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml")); + bean.setConfigLocation(new PathMatchingResourcePatternResolver().getResource("classpath:mybatis-config.xml")); + return bean.getObject(); + } + + @Bean(name = "transactionManager") + @Primary + public DataSourceTransactionManager transactionManager(@Qualifier("dataSource") DataSource dataSource) { + return new DataSourceTransactionManager(dataSource); + } + + @Bean(name = "sqlSession") + @Primary + public SqlSessionTemplate sqlSessionTemplate(@Qualifier("sqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception { + return new SqlSessionTemplate(sqlSessionFactory); + } +} diff --git a/kafka-manager-extends/kafka-manager-monitor/src/test/resources/application.yml b/kafka-manager-extends/kafka-manager-monitor/src/test/resources/application.yml new file mode 100644 index 00000000..a4648a46 --- /dev/null +++ b/kafka-manager-extends/kafka-manager-monitor/src/test/resources/application.yml @@ -0,0 +1,98 @@ +server: + port: 8080 + tomcat: + accept-count: 1000 + max-connections: 10000 + max-threads: 800 + min-spare-threads: 100 + +spring: + application: + name: kafkamanager + profiles: + active: dev + datasource: + kafka-manager: + jdbc-url: jdbc:mysql://localhost:3306/logi_kafka_manager?characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2B8 + username: root + password: 123456 + driver-class-name: com.mysql.cj.jdbc.Driver + main: + allow-bean-definition-overriding: true + + servlet: + multipart: + max-file-size: 100MB + max-request-size: 100MB + +logging: + config: classpath:logback-spring.xml + +custom: + idc: cn + jmx: + max-conn: 10 # 2.3版本配置不在这个地方生效 + store-metrics-task: + community: + broker-metrics-enabled: true + topic-metrics-enabled: true + didi: + app-topic-metrics-enabled: false + topic-request-time-metrics-enabled: false + topic-throttled-metrics: false + save-days: 7 + +# 任务相关的开关 +task: + op: + sync-topic-enabled: false # 未落盘的Topic定期同步到DB中 + order-auto-exec: # 工单自动化审批线程的开关 + topic-enabled: false # Topic工单自动化审批开关, false:关闭自动化审批, true:开启 + app-enabled: false # App工单自动化审批开关, false:关闭自动化审批, true:开启 + +account: + ldap: + enabled: false + url: ldap://127.0.0.1:389/ + basedn: dc=tsign,dc=cn + factory: com.sun.jndi.ldap.LdapCtxFactory + filter: sAMAccountName + security: + authentication: simple + principal: cn=admin,dc=tsign,dc=cn + credentials: admin + auth-user-registration: true + auth-user-registration-role: normal + +kcm: + enabled: false + s3: + endpoint: s3.didiyunapi.com + access-key: 1234567890 + secret-key: 0987654321 + bucket: logi-kafka + n9e: + base-url: http://127.0.0.1:8004 + user-token: 12345678 + timeout: 300 + account: root + script-file: kcm_script.sh + +monitor: + enabled: false + n9e: + nid: 2 + user-token: 1234567890 + mon: + base-url: http://127.0.0.1:8000 # 夜莺v4版本,默认端口统一调整为了8000 + sink: + base-url: http://127.0.0.1:8000 # 夜莺v4版本,默认端口统一调整为了8000 + rdb: + base-url: http://127.0.0.1:8000 # 夜莺v4版本,默认端口统一调整为了8000 + +notify: + kafka: + cluster-id: 95 + topic-name: didi-kafka-notify + order: + detail-url: http://127.0.0.1 diff --git a/kafka-manager-extends/kafka-manager-monitor/src/test/resources/distribution/kafka-manager-springboot-distribution.xml b/kafka-manager-extends/kafka-manager-monitor/src/test/resources/distribution/kafka-manager-springboot-distribution.xml new file mode 100755 index 00000000..51c9a632 --- /dev/null +++ b/kafka-manager-extends/kafka-manager-monitor/src/test/resources/distribution/kafka-manager-springboot-distribution.xml @@ -0,0 +1,63 @@ + + assembly + + tar + zip + + + + src/main/resources/bin + bin + + control.sh + start.bat + + 0755 + + + src/main/resources + config + + *.properties + *.xml + *.yml + env/dev/* + env/qa/* + env/uat/* + env/prod/* + + + + target + lib + + + kafka-manager-web*.jar + + + + *sources.jar + + + + src/main/resources + logs + 0755 + + **/* + + + + + \ No newline at end of file diff --git a/kafka-manager-extends/kafka-manager-monitor/src/test/resources/logback-spring.xml b/kafka-manager-extends/kafka-manager-monitor/src/test/resources/logback-spring.xml new file mode 100644 index 00000000..c1c16136 --- /dev/null +++ b/kafka-manager-extends/kafka-manager-monitor/src/test/resources/logback-spring.xml @@ -0,0 +1,215 @@ + + + logback + + + + + + + + + + + + + + info + + + ${CONSOLE_LOG_PATTERN} + UTF-8 + + + + + + + + + ${log.path}/log_debug.log + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + UTF-8 + + + + + ${log.path}/log_debug_%d{yyyy-MM-dd}.%i.log + + 100MB + + + 7 + + + + debug + ACCEPT + DENY + + + + + + + ${log.path}/log_info.log + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + UTF-8 + + + + + ${log.path}/log_info_%d{yyyy-MM-dd}.%i.log + + 100MB + + + 7 + + + + info + ACCEPT + DENY + + + + + + + ${log.path}/log_warn.log + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + UTF-8 + + + + ${log.path}/log_warn_%d{yyyy-MM-dd}.%i.log + + 100MB + + + 7 + + + + warn + ACCEPT + DENY + + + + + + + + ${log.path}/log_error.log + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + UTF-8 + + + + ${log.path}/log_error_%d{yyyy-MM-dd}.%i.log + + 100MB + + + 7 + + + + ERROR + ACCEPT + DENY + + + + + + ${log.path}/metrics/collector_metrics.log + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + UTF-8 + + + ${log.path}/metrics/collector_metrics_%d{yyyy-MM-dd}.%i.log + + 100MB + + 3 + + + + + + ${log.path}/metrics/api_metrics.log + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + UTF-8 + + + ${log.path}/metrics/api_metrics_%d{yyyy-MM-dd}.%i.log + + 100MB + + 3 + + + + + + ${log.path}/metrics/scheduled_tasks.log + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n + UTF-8 + + + ${log.path}/metrics/scheduled_tasks_%d{yyyy-MM-dd}.%i.log + + 100MB + + 5 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file