diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 9ca3226e..6f868666 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -14,9 +14,10 @@ XXXX 请遵循此清单,以帮助我们快速轻松地整合您的贡献: -* [ ] 确保有针对更改提交的 Github issue(通常在您开始处理之前)。诸如拼写错误之类的琐碎更改不需要 Github issue。您的Pull Request应该只解决这个问题,而不需要进行其他更改—— 一个 PR 解决一个问题。 -* [ ] 格式化 Pull Request 标题,如[ISSUE #123] support Confluent Schema Registry。 Pull Request 中的每个提交都应该有一个有意义的主题行和正文。 -* [ ] 编写足够详细的Pull Request描述,以了解Pull Request的作用、方式和原因。 -* [ ] 编写必要的单元测试来验证您的逻辑更正。如果提交了新功能或重大更改,请记住在test 模块中添加 integration-test -* [ ] 确保编译通过,集成测试通过 +* [ ] 一个 PR(Pull Request的简写)只解决一个问题,禁止一个 PR 解决多个问题; +* [ ] 确保 PR 有对应的 Issue(通常在您开始处理之前创建),除非是书写错误之类的琐碎更改不需要 Issue ; +* [ ] 格式化 PR 及 Commit-Log 的标题及内容,例如 #861 。PS:Commit-Log 需要在 Git Commit 代码时进行填写,在 GitHub 上修改不了; +* [ ] 编写足够详细的 PR 描述,以了解 PR 的作用、方式和原因; +* [ ] 编写必要的单元测试来验证您的逻辑更正。如果提交了新功能或重大更改,请记住在 test 模块中添加 integration-test; +* [ ] 确保编译通过,集成测试通过; diff --git a/.gitignore b/.gitignore index 045ec395..cfef6e76 100644 --- a/.gitignore +++ b/.gitignore @@ -109,4 +109,8 @@ out/* dist/ dist/* km-rest/src/main/resources/templates/ -*dependency-reduced-pom* \ No newline at end of file +*dependency-reduced-pom* +#filter flattened xml +*/.flattened-pom.xml +.flattened-pom.xml +*/*/.flattened-pom.xml \ No newline at end of file diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index a70c8889..5d8023ba 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -4,7 +4,7 @@ ## Our Pledge In the interest of fostering an open and welcoming environment, we as -contributors and maintainers pledge to making participation in our project and +contributors and maintainers pledge to making participation in our project, and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, @@ -56,7 +56,7 @@ further defined and clarified by project maintainers. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported by contacting the project team at shirenchuang@didiglobal.com . All +reported by contacting the project team at https://knowstreaming.com/support-center . All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. diff --git a/README.md b/README.md index 9cc19762..8f526268 100644 --- a/README.md +++ b/README.md @@ -143,7 +143,7 @@ PS: 提问请尽量把问题一次性描述清楚,并告知环境信息情况 **`2、微信群`** -微信加群:添加`mike_zhangliang`、`PenceXie`的微信号备注KnowStreaming加群。 +微信加群:添加`mike_zhangliang`、`PenceXie` 、`szzdzhp001`的微信号备注KnowStreaming加群。
加群之前有劳点一下 star,一个小小的 star 是对KnowStreaming作者们努力建设社区的动力。 diff --git a/Releases_Notes.md b/Releases_Notes.md index ad89a3e9..a606ef72 100644 --- a/Releases_Notes.md +++ b/Releases_Notes.md @@ -1,4 +1,113 @@ +## v3.3.0 + +**问题修复** +- 修复 Connect 的 JMX-Port 配置未生效问题; +- 修复 不存在 Connector 时,OverView 页面的数据一直处于加载中的问题; +- 修复 Group 分区信息,分页时展示不全的问题; +- 修复采集副本指标时,参数传递错误的问题; +- 修复用户信息修改后,用户列表会抛出空指针异常的问题; +- 修复 Topic 详情页面,查看消息时,选择分区不生效问题; +- 修复对 ZK 客户端进行配置后不生效的问题; +- 修复 connect 模块,指标中缺少健康巡检项通过数的问题; +- 修复 connect 模块,指标获取方法存在映射错误的问题; +- 修复 connect 模块,max 纬度指标获取错误的问题; +- 修复 Topic 指标大盘 TopN 指标显示信息错误的问题; +- 修复 Broker Similar Config 显示错误的问题; +- 修复解析 ZK 四字命令时,数据类型设置错误导致空指针的问题; +- 修复新增 Topic 时,清理策略选项版本控制错误的问题; +- 修复新接入集群时 Controller-Host 信息不显示的问题; +- 修复 Connector 和 MM2 列表搜索不生效的问题; +- 修复 Zookeeper 页面,Leader 显示存在异常的问题; +- 修复前端打包失败的问题; + + +**产品优化** +- ZK Overview 页面补充默认展示的指标; +- 统一初始化 ES 索引模版的脚本为 init_es_template.sh,同时新增缺失的 connect 索引模版初始化脚本,去除多余的 replica 和 zookeper 索引模版初始化脚本; +- 指标大盘页面,优化指标筛选操作后,无指标数据的指标卡片由不显示改为显示,并增加无数据的兜底; +- 删除从 ES 读写 replica 指标的相关代码; +- 优化 Topic 健康巡检的日志,明确错误的原因; +- 优化无 ZK 模块时,巡检详情忽略对 ZK 的展示; +- 优化本地缓存大小为可配置; +- Task 模块中的返回中,补充任务的分组信息; +- FAQ 补充 Ldap 的配置说明; +- FAQ 补充接入 Kerberos 认证的 Kafka 集群的配置说明; +- ks_km_kafka_change_record 表增加时间纬度的索引,优化查询性能; +- 优化 ZK 健康巡检的日志,便于问题的排查; + +**功能新增** +- 新增基于滴滴 Kafka 的 Topic 复制功能(需使用滴滴 Kafka 才可具备该能力); +- Topic 指标大盘,新增 Topic 复制相关的指标; +- 新增基于 TestContainers 的单测; + + +**Kafka MM2 Beta版 (v3.3.0版本新增发布)** +- MM2 任务的增删改查; +- MM2 任务的指标大盘; +- MM2 任务的健康状态; + +--- + + +## v3.2.0 + +**问题修复** +- 修复健康巡检结果更新至 DB 时,出现死锁问题; +- 修复 KafkaJMXClient 类中,logger错误的问题; +- 后端修复 Topic 过期策略在 0.10.1.0 版本能多选的问题,实际应该只能二选一; +- 修复接入集群时,不填写集群配置会报错的问题; +- 升级 spring-context 至 5.3.19 版本,修复安全漏洞; +- 修复 Broker & Topic 修改配置时,多版本兼容配置的版本信息错误的问题; +- 修复 Topic 列表的健康分为健康状态; +- 修复 Broker LogSize 指标存储名称错误导致查询不到的问题; +- 修复 Prometheus 中,缺少 Group 部分指标的问题; +- 修复因缺少健康状态指标导致集群数错误的问题; +- 修复后台任务记录操作日志时,因缺少操作用户信息导致出现异常的问题; +- 修复 Replica 指标查询时,DSL 错误的问题; +- 关闭 errorLogger,修复错误日志重复输出的问题; +- 修复系统管理更新用户信息失败的问题; +- 修复因原AR信息丢失,导致迁移任务一直处于执行中的错误; +- 修复集群 Topic 列表实时数据查询时,出现失败的问题; +- 修复集群 Topic 列表,页面白屏问题; +- 修复副本变更时,因AR数据异常,导致数组访问越界的问题; + + +**产品优化** +- 优化健康巡检为按照资源维度多线程并发处理; +- 统一日志输出格式,并优化部分输出的日志; +- 优化 ZK 四字命令结果解析过程中,容易引起误解的 WARN 日志; +- 优化 Zookeeper 详情中,目录结构的搜索文案; +- 优化线程池的名称,方便第三方系统进行相关问题的分析; +- 去除 ESClient 的并发访问控制,降低 ESClient 创建数及提升利用率; +- 优化 Topic Messages 抽屉文案; +- 优化 ZK 健康巡检失败时的错误日志信息; +- 提高 Offset 信息获取的超时时间,降低并发过高时出现请求超时的概率; +- 优化 Topic & Partition 元信息的更新策略,降低对 DB 连接的占用; +- 优化 Sonar 代码扫码问题; +- 优化分区 Offset 指标的采集; +- 优化前端图表相关组件逻辑; +- 优化产品主题色; +- Consumer 列表刷新按钮新增 hover 提示; +- 优化配置 Topic 的消息大小时的测试弹框体验; +- 优化 Overview 页面 TopN 查询的流程; + + +**功能新增** +- 新增页面无数据排查文档; +- 增加 ES 索引删除的功能; +- 支持拆分API服务和Job服务部署; + + +**Kafka Connect Beta版 (v3.2.0版本新增发布)** +- Connect 集群的纳管; +- Connector 的增删改查; +- Connect 集群 & Connector 的指标大盘; + + +--- + + ## v3.1.0 **Bug修复** diff --git a/bin/init_es_template.sh b/bin/init_es_template.sh index 86fcfb66..e570d285 100644 --- a/bin/init_es_template.sh +++ b/bin/init_es_template.sh @@ -13,7 +13,7 @@ curl -s --connect-timeout 10 -o /dev/null -X POST -H 'cache-control: no-cache' - ], "settings" : { "index" : { - "number_of_shards" : "10" + "number_of_shards" : "2" } }, "mappings" : { @@ -115,7 +115,7 @@ curl -s -o /dev/null -X POST -H 'cache-control: no-cache' -H 'content-type: appl ], "settings" : { "index" : { - "number_of_shards" : "10" + "number_of_shards" : "2" } }, "mappings" : { @@ -302,7 +302,7 @@ curl -s -o /dev/null -X POST -H 'cache-control: no-cache' -H 'content-type: appl ], "settings" : { "index" : { - "number_of_shards" : "10" + "number_of_shards" : "6" } }, "mappings" : { @@ -377,7 +377,7 @@ curl -s -o /dev/null -X POST -H 'cache-control: no-cache' -H 'content-type: appl ], "settings" : { "index" : { - "number_of_shards" : "10" + "number_of_shards" : "6" } }, "mappings" : { @@ -436,72 +436,6 @@ curl -s -o /dev/null -X POST -H 'cache-control: no-cache' -H 'content-type: appl "aliases" : { } }' -curl -s -o /dev/null -X POST -H 'cache-control: no-cache' -H 'content-type: application/json' http://${esaddr}:${port}/_template/ks_kafka_replication_metric -d '{ - "order" : 10, - "index_patterns" : [ - "ks_kafka_replication_metric*" - ], - "settings" : { - "index" : { - "number_of_shards" : "10" - } - }, - "mappings" : { - "properties" : { - "brokerId" : { - "type" : "long" - }, - "partitionId" : { - "type" : "long" - }, - "routingValue" : { - "type" : "text", - "fields" : { - "keyword" : { - "ignore_above" : 256, - "type" : "keyword" - } - } - }, - "clusterPhyId" : { - "type" : "long" - }, - "topic" : { - "type" : "keyword" - }, - "metrics" : { - "properties" : { - "LogStartOffset" : { - "type" : "float" - }, - "Messages" : { - "type" : "float" - }, - "LogEndOffset" : { - "type" : "float" - } - } - }, - "key" : { - "type" : "text", - "fields" : { - "keyword" : { - "ignore_above" : 256, - "type" : "keyword" - } - } - }, - "timestamp" : { - "format" : "yyyy-MM-dd HH:mm:ss Z||yyyy-MM-dd HH:mm:ss||yyyy-MM-dd HH:mm:ss.SSS Z||yyyy-MM-dd HH:mm:ss.SSS||yyyy-MM-dd HH:mm:ss,SSS||yyyy/MM/dd HH:mm:ss||yyyy-MM-dd HH:mm:ss,SSS Z||yyyy/MM/dd HH:mm:ss,SSS Z||epoch_millis", - "index" : true, - "type" : "date", - "doc_values" : true - } - } - }, - "aliases" : { } - }' - curl -s -o /dev/null -X POST -H 'cache-control: no-cache' -H 'content-type: application/json' http://${esaddr}:${port}/_template/ks_kafka_topic_metric -d '{ "order" : 10, "index_patterns" : [ @@ -509,7 +443,7 @@ curl -s -o /dev/null -X POST -H 'cache-control: no-cache' -H 'content-type: appl ], "settings" : { "index" : { - "number_of_shards" : "10" + "number_of_shards" : "6" } }, "mappings" : { @@ -626,7 +560,7 @@ curl -s -o /dev/null -X POST -H 'cache-control: no-cache' -H 'content-type: appl ], "settings" : { "index" : { - "number_of_shards" : "10" + "number_of_shards" : "2" } }, "mappings" : { @@ -704,6 +638,388 @@ curl -s -o /dev/null -X POST -H 'cache-control: no-cache' -H 'content-type: appl "aliases" : { } }' +curl -s -o /dev/null -X POST -H 'cache-control: no-cache' -H 'content-type: application/json' http://${SERVER_ES_ADDRESS}/_template/ks_kafka_connect_cluster_metric -d '{ + "order" : 10, + "index_patterns" : [ + "ks_kafka_connect_cluster_metric*" + ], + "settings" : { + "index" : { + "number_of_shards" : "2" + } + }, + "mappings" : { + "properties" : { + "connectClusterId" : { + "type" : "long" + }, + "routingValue" : { + "type" : "text", + "fields" : { + "keyword" : { + "ignore_above" : 256, + "type" : "keyword" + } + } + }, + "clusterPhyId" : { + "type" : "long" + }, + "metrics" : { + "properties" : { + "ConnectorCount" : { + "type" : "float" + }, + "TaskCount" : { + "type" : "float" + }, + "ConnectorStartupAttemptsTotal" : { + "type" : "float" + }, + "ConnectorStartupFailurePercentage" : { + "type" : "float" + }, + "ConnectorStartupFailureTotal" : { + "type" : "float" + }, + "ConnectorStartupSuccessPercentage" : { + "type" : "float" + }, + "ConnectorStartupSuccessTotal" : { + "type" : "float" + }, + "TaskStartupAttemptsTotal" : { + "type" : "float" + }, + "TaskStartupFailurePercentage" : { + "type" : "float" + }, + "TaskStartupFailureTotal" : { + "type" : "float" + }, + "TaskStartupSuccessPercentage" : { + "type" : "float" + }, + "TaskStartupSuccessTotal" : { + "type" : "float" + } + } + }, + "key" : { + "type" : "text", + "fields" : { + "keyword" : { + "ignore_above" : 256, + "type" : "keyword" + } + } + }, + "timestamp" : { + "format" : "yyyy-MM-dd HH:mm:ss Z||yyyy-MM-dd HH:mm:ss||yyyy-MM-dd HH:mm:ss.SSS Z||yyyy-MM-dd HH:mm:ss.SSS||yyyy-MM-dd HH:mm:ss,SSS||yyyy/MM/dd HH:mm:ss||yyyy-MM-dd HH:mm:ss,SSS Z||yyyy/MM/dd HH:mm:ss,SSS Z||epoch_millis", + "index" : true, + "type" : "date", + "doc_values" : true + } + } + }, + "aliases" : { } + }' + +curl -s -o /dev/null -X POST -H 'cache-control: no-cache' -H 'content-type: application/json' http://${SERVER_ES_ADDRESS}/_template/ks_kafka_connect_connector_metric -d '{ + "order" : 10, + "index_patterns" : [ + "ks_kafka_connect_connector_metric*" + ], + "settings" : { + "index" : { + "number_of_shards" : "2" + } + }, + "mappings" : { + "properties" : { + "connectClusterId" : { + "type" : "long" + }, + "routingValue" : { + "type" : "text", + "fields" : { + "keyword" : { + "ignore_above" : 256, + "type" : "keyword" + } + } + }, + "connectorName" : { + "type" : "keyword" + }, + "connectorNameAndClusterId" : { + "type" : "keyword" + }, + "clusterPhyId" : { + "type" : "long" + }, + "metrics" : { + "properties" : { + "HealthState" : { + "type" : "float" + }, + "ConnectorTotalTaskCount" : { + "type" : "float" + }, + "HealthCheckPassed" : { + "type" : "float" + }, + "HealthCheckTotal" : { + "type" : "float" + }, + "ConnectorRunningTaskCount" : { + "type" : "float" + }, + "ConnectorPausedTaskCount" : { + "type" : "float" + }, + "ConnectorFailedTaskCount" : { + "type" : "float" + }, + "ConnectorUnassignedTaskCount" : { + "type" : "float" + }, + "BatchSizeAvg" : { + "type" : "float" + }, + "BatchSizeMax" : { + "type" : "float" + }, + "OffsetCommitAvgTimeMs" : { + "type" : "float" + }, + "OffsetCommitMaxTimeMs" : { + "type" : "float" + }, + "OffsetCommitFailurePercentage" : { + "type" : "float" + }, + "OffsetCommitSuccessPercentage" : { + "type" : "float" + }, + "PollBatchAvgTimeMs" : { + "type" : "float" + }, + "PollBatchMaxTimeMs" : { + "type" : "float" + }, + "SourceRecordActiveCount" : { + "type" : "float" + }, + "SourceRecordActiveCountAvg" : { + "type" : "float" + }, + "SourceRecordActiveCountMax" : { + "type" : "float" + }, + "SourceRecordPollRate" : { + "type" : "float" + }, + "SourceRecordPollTotal" : { + "type" : "float" + }, + "SourceRecordWriteRate" : { + "type" : "float" + }, + "SourceRecordWriteTotal" : { + "type" : "float" + }, + "OffsetCommitCompletionRate" : { + "type" : "float" + }, + "OffsetCommitCompletionTotal" : { + "type" : "float" + }, + "OffsetCommitSkipRate" : { + "type" : "float" + }, + "OffsetCommitSkipTotal" : { + "type" : "float" + }, + "PartitionCount" : { + "type" : "float" + }, + "PutBatchAvgTimeMs" : { + "type" : "float" + }, + "PutBatchMaxTimeMs" : { + "type" : "float" + }, + "SinkRecordActiveCount" : { + "type" : "float" + }, + "SinkRecordActiveCountAvg" : { + "type" : "float" + }, + "SinkRecordActiveCountMax" : { + "type" : "float" + }, + "SinkRecordLagMax" : { + "type" : "float" + }, + "SinkRecordReadRate" : { + "type" : "float" + }, + "SinkRecordReadTotal" : { + "type" : "float" + }, + "SinkRecordSendRate" : { + "type" : "float" + }, + "SinkRecordSendTotal" : { + "type" : "float" + }, + "DeadletterqueueProduceFailures" : { + "type" : "float" + }, + "DeadletterqueueProduceRequests" : { + "type" : "float" + }, + "LastErrorTimestamp" : { + "type" : "float" + }, + "TotalErrorsLogged" : { + "type" : "float" + }, + "TotalRecordErrors" : { + "type" : "float" + }, + "TotalRecordFailures" : { + "type" : "float" + }, + "TotalRecordsSkipped" : { + "type" : "float" + }, + "TotalRetries" : { + "type" : "float" + } + } + }, + "key" : { + "type" : "text", + "fields" : { + "keyword" : { + "ignore_above" : 256, + "type" : "keyword" + } + } + }, + "timestamp" : { + "format" : "yyyy-MM-dd HH:mm:ss Z||yyyy-MM-dd HH:mm:ss||yyyy-MM-dd HH:mm:ss.SSS Z||yyyy-MM-dd HH:mm:ss.SSS||yyyy-MM-dd HH:mm:ss,SSS||yyyy/MM/dd HH:mm:ss||yyyy-MM-dd HH:mm:ss,SSS Z||yyyy/MM/dd HH:mm:ss,SSS Z||epoch_millis", + "index" : true, + "type" : "date", + "doc_values" : true + } + } + }, + "aliases" : { } + }' + +curl -s -o /dev/null -X POST -H 'cache-control: no-cache' -H 'content-type: application/json' http://${SERVER_ES_ADDRESS}/_template/ks_kafka_connect_mirror_maker_metric -d '{ + "order" : 10, + "index_patterns" : [ + "ks_kafka_connect_mirror_maker_metric*" + ], + "settings" : { + "index" : { + "number_of_shards" : "2" + } + }, + "mappings" : { + "properties" : { + "connectClusterId" : { + "type" : "long" + }, + "routingValue" : { + "type" : "text", + "fields" : { + "keyword" : { + "ignore_above" : 256, + "type" : "keyword" + } + } + }, + "connectorName" : { + "type" : "keyword" + }, + "connectorNameAndClusterId" : { + "type" : "keyword" + }, + "clusterPhyId" : { + "type" : "long" + }, + "metrics" : { + "properties" : { + "HealthState" : { + "type" : "float" + }, + "HealthCheckTotal" : { + "type" : "float" + }, + "ByteCount" : { + "type" : "float" + }, + "ByteRate" : { + "type" : "float" + }, + "RecordAgeMs" : { + "type" : "float" + }, + "RecordAgeMsAvg" : { + "type" : "float" + }, + "RecordAgeMsMax" : { + "type" : "float" + }, + "RecordAgeMsMin" : { + "type" : "float" + }, + "RecordCount" : { + "type" : "float" + }, + "RecordRate" : { + "type" : "float" + }, + "ReplicationLatencyMs" : { + "type" : "float" + }, + "ReplicationLatencyMsAvg" : { + "type" : "float" + }, + "ReplicationLatencyMsMax" : { + "type" : "float" + }, + "ReplicationLatencyMsMin" : { + "type" : "float" + } + } + }, + "key" : { + "type" : "text", + "fields" : { + "keyword" : { + "ignore_above" : 256, + "type" : "keyword" + } + } + }, + "timestamp" : { + "format" : "yyyy-MM-dd HH:mm:ss Z||yyyy-MM-dd HH:mm:ss||yyyy-MM-dd HH:mm:ss.SSS Z||yyyy-MM-dd HH:mm:ss.SSS||yyyy-MM-dd HH:mm:ss,SSS||yyyy/MM/dd HH:mm:ss||yyyy-MM-dd HH:mm:ss,SSS Z||yyyy/MM/dd HH:mm:ss,SSS Z||epoch_millis", + "index" : true, + "type" : "date", + "doc_values" : true + } + } + }, + "aliases" : { } + }' + + for i in {0..6}; do logdate=_$(date -d "${i} day ago" +%Y-%m-%d) @@ -711,8 +1027,10 @@ do curl -s -o /dev/null -X PUT http://${esaddr}:${port}/ks_kafka_cluster_metric${logdate} && \ curl -s -o /dev/null -X PUT http://${esaddr}:${port}/ks_kafka_group_metric${logdate} && \ curl -s -o /dev/null -X PUT http://${esaddr}:${port}/ks_kafka_partition_metric${logdate} && \ - curl -s -o /dev/null -X PUT http://${esaddr}:${port}/ks_kafka_replication_metric${logdate} && \ curl -s -o /dev/null -X PUT http://${esaddr}:${port}/ks_kafka_zookeeper_metric${logdate} && \ + curl -s -o /dev/null -X PUT http://${esaddr}:${port}/ks_kafka_connect_cluster_metric${logdate} && \ + curl -s -o /dev/null -X PUT http://${esaddr}:${port}/ks_kafka_connect_connector_metric${logdate} && \ + curl -s -o /dev/null -X PUT http://${esaddr}:${port}/ks_kafka_connect_mirror_maker_metric${logdate} && \ curl -s -o /dev/null -X PUT http://${esaddr}:${port}/ks_kafka_topic_metric${logdate} || \ exit 2 done diff --git a/docs/contribute_guide/assets/分支管理.drawio b/docs/contribute_guide/assets/分支管理.drawio new file mode 100644 index 00000000..0e7e3d37 --- /dev/null +++ b/docs/contribute_guide/assets/分支管理.drawio @@ -0,0 +1,111 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/contribute_guide/assets/分支管理.png b/docs/contribute_guide/assets/分支管理.png new file mode 100644 index 00000000..867fecd4 Binary files /dev/null and b/docs/contribute_guide/assets/分支管理.png differ diff --git a/docs/contribute_guide/assets/环境初始化.jpg b/docs/contribute_guide/assets/环境初始化.jpg new file mode 100644 index 00000000..31ff5f28 Binary files /dev/null and b/docs/contribute_guide/assets/环境初始化.jpg differ diff --git a/docs/contribute_guide/assets/申请合并.jpg b/docs/contribute_guide/assets/申请合并.jpg new file mode 100644 index 00000000..d02a7f50 Binary files /dev/null and b/docs/contribute_guide/assets/申请合并.jpg differ diff --git a/docs/contribute_guide/assets/问题认领.jpg b/docs/contribute_guide/assets/问题认领.jpg new file mode 100644 index 00000000..62da4728 Binary files /dev/null and b/docs/contribute_guide/assets/问题认领.jpg differ diff --git a/docs/contributer_guide/代码规范.md b/docs/contribute_guide/代码规范.md similarity index 100% rename from docs/contributer_guide/代码规范.md rename to docs/contribute_guide/代码规范.md diff --git a/docs/contribute_guide/贡献名单.md b/docs/contribute_guide/贡献名单.md new file mode 100644 index 00000000..41481787 --- /dev/null +++ b/docs/contribute_guide/贡献名单.md @@ -0,0 +1,100 @@ +# 贡献名单 + +- [贡献名单](#贡献名单) + - [1、贡献者角色](#1贡献者角色) + - [1.1、Maintainer](#11maintainer) + - [1.2、Committer](#12committer) + - [1.3、Contributor](#13contributor) + - [2、贡献者名单](#2贡献者名单) + + +## 1、贡献者角色 + +KnowStreaming 开发者包含 Maintainer、Committer、Contributor 三种角色,每种角色的标准定义如下。 + +### 1.1、Maintainer + +Maintainer 是对 KnowStreaming 项目的演进和发展做出显著贡献的个人。具体包含以下的标准: + +- 完成多个关键模块或者工程的设计与开发,是项目的核心开发人员; +- 持续的投入和激情,能够积极参与社区、官网、issue、PR 等项目相关事项的维护; +- 在社区中具有有目共睹的影响力,能够代表 KnowStreaming 参加重要的社区会议和活动; +- 具有培养 Committer 和 Contributor 的意识和能力; + +### 1.2、Committer + +Committer 是具有 KnowStreaming 仓库写权限的个人,包含以下的标准: + +- 能够在长时间内做持续贡献 issue、PR 的个人; +- 参与 issue 列表的维护及重要 feature 的讨论; +- 参与 code review; + +### 1.3、Contributor + +Contributor 是对 KnowStreaming 项目有贡献的个人,标准为: + +- 提交过 PR 并被合并; + +--- + +## 2、贡献者名单 + +开源贡献者名单(不定期更新) + +在名单内,但是没有收到贡献者礼品的同学,可以联系:szzdzhp001 + +| 姓名 | Github | 角色 | 公司 | +| ------------------- | ---------------------------------------------------------- | ----------- | -------- | +| 张亮 | [@zhangliangboy](https://github.com/zhangliangboy) | Maintainer | 滴滴出行 | +| 谢鹏 | [@PenceXie](https://github.com/PenceXie) | Maintainer | 滴滴出行 | +| 赵情融 | [@zqrferrari](https://github.com/zqrferrari) | Maintainer | 滴滴出行 | +| 石臻臻 | [@shirenchuang](https://github.com/shirenchuang) | Maintainer | 滴滴出行 | +| 曾巧 | [@ZQKC](https://github.com/ZQKC) | Maintainer | 滴滴出行 | +| 孙超 | [@lucasun](https://github.com/lucasun) | Maintainer | 滴滴出行 | +| 洪华驰 | [@brodiehong](https://github.com/brodiehong) | Maintainer | 滴滴出行 | +| 许喆 | [@potaaaaaato](https://github.com/potaaaaaato) | Committer | 滴滴出行 | +| 郭宇航 | [@GraceWalk](https://github.com/GraceWalk) | Committer | 滴滴出行 | +| 李伟 | [@velee](https://github.com/velee) | Committer | 滴滴出行 | +| 张占昌 | [@zzccctv](https://github.com/zzccctv) | Committer | 滴滴出行 | +| 王东方 | [@wangdongfang-aden](https://github.com/wangdongfang-aden) | Committer | 滴滴出行 | +| 王耀波 | [@WYAOBO](https://github.com/WYAOBO) | Committer | 滴滴出行 | +| 赵寅锐 | [@ZHAOYINRUI](https://github.com/ZHAOYINRUI) | Maintainer | 字节跳动 | +| haoqi123 | [@haoqi123](https://github.com/haoqi123) | Contributor | 前程无忧 | +| chaixiaoxue | [@chaixiaoxue](https://github.com/chaixiaoxue) | Contributor | SYNNEX | +| 陆晗 | [@luhea](https://github.com/luhea) | Contributor | 竞技世界 | +| Mengqi777 | [@Mengqi777](https://github.com/Mengqi777) | Contributor | 腾讯 | +| ruanliang-hualun | [@ruanliang-hualun](https://github.com/ruanliang-hualun) | Contributor | 网易 | +| 17hao | [@17hao](https://github.com/17hao) | Contributor | | +| Huyueeer | [@Huyueeer](https://github.com/Huyueeer) | Contributor | INVENTEC | +| lomodays207 | [@lomodays207](https://github.com/lomodays207) | Contributor | 建信金科 | +| Super .Wein(星痕) | [@superspeedone](https://github.com/superspeedone) | Contributor | 韵达 | +| Hongten | [@Hongten](https://github.com/Hongten) | Contributor | Shopee | +| 徐正熙 | [@hyper-xx)](https://github.com/hyper-xx) | Contributor | 滴滴出行 | +| RichardZhengkay | [@RichardZhengkay](https://github.com/RichardZhengkay) | Contributor | 趣街 | +| 罐子里的茶 | [@gzldc](https://github.com/gzldc) | Contributor | 道富 | +| 陈忠玉 | [@paula](https://github.com/chenzhongyu11) | Contributor | 平安产险 | +| 杨光 | [@yaangvipguang](https://github.com/yangvipguang) | Contributor | +| 王亚聪 | [@wangyacongi](https://github.com/wangyacongi) | Contributor | +| Yang Jing | [@yangbajing](https://github.com/yangbajing) | Contributor | | +| 刘新元 Liu XinYuan | [@Liu-XinYuan](https://github.com/Liu-XinYuan) | Contributor | | +| Joker | [@LiubeyJokerQueue](https://github.com/JokerQueue) | Contributor | 丰巢 | +| Eason Lau | [@Liubey](https://github.com/Liubey) | Contributor | | +| hailanxin | [@hailanxin](https://github.com/hailanxin) | Contributor | | +| Qi Zhang | [@zzzhangqi](https://github.com/zzzhangqi) | Contributor | 好雨科技 | +| fengxsong | [@fengxsong](https://github.com/fengxsong) | Contributor | | +| 谢晓东 | [@Strangevy](https://github.com/Strangevy) | Contributor | 花生日记 | +| ZhaoXinlong | [@ZhaoXinlong](https://github.com/ZhaoXinlong) | Contributor | | +| xuehaipeng | [@xuehaipeng](https://github.com/xuehaipeng) | Contributor | | +| 孔令续 | [@mrazkong](https://github.com/mrazkong) | Contributor | | +| pierre xiong | [@pierre94](https://github.com/pierre94) | Contributor | | +| PengShuaixin | [@PengShuaixin](https://github.com/PengShuaixin) | Contributor | | +| 梁壮 | [@lz](https://github.com/silent-night-no-trace) | Contributor | | +| 张晓寅 | [@ahu0605](https://github.com/ahu0605) | Contributor | 电信数智 | +| 黄海婷 | [@Huanghaiting](https://github.com/Huanghaiting) | Contributor | 云徙科技 | +| 任祥德 | [@RenChauncy](https://github.com/RenChauncy) | Contributor | 探马企服 | +| 胡圣林 | [@slhu997](https://github.com/slhu997) | Contributor | | +| 史泽颖 | [@shizeying](https://github.com/shizeying) | Contributor | | +| 王玉博 | [@Wyb7290](https://github.com/Wyb7290) | Committer | | +| 伍璇 | [@Luckywustone](https://github.com/Luckywustone) | Contributor || +| 邓苑 | [@CatherineDY](https://github.com/CatherineDY) | Contributor || +| 封琼凤 | [@Luckywustone](https://github.com/fengqiongfeng) | Committer || diff --git a/docs/contribute_guide/贡献指南.md b/docs/contribute_guide/贡献指南.md new file mode 100644 index 00000000..37cf89bc --- /dev/null +++ b/docs/contribute_guide/贡献指南.md @@ -0,0 +1,167 @@ +# 贡献指南 + +- [贡献指南](#贡献指南) + - [1、行为准则](#1行为准则) + - [2、仓库规范](#2仓库规范) + - [2.1、Issue 规范](#21issue-规范) + - [2.2、Commit-Log 规范](#22commit-log-规范) + - [2.3、Pull-Request 规范](#23pull-request-规范) + - [3、操作示例](#3操作示例) + - [3.1、初始化环境](#31初始化环境) + - [3.2、认领问题](#32认领问题) + - [3.3、处理问题 \& 提交解决](#33处理问题--提交解决) + - [3.4、请求合并](#34请求合并) + - [4、常见问题](#4常见问题) + - [4.1、如何将多个 Commit-Log 合并为一个?](#41如何将多个-commit-log-合并为一个) + + +--- + + +欢迎 👏🏻 👏🏻 👏🏻 来到 `KnowStreaming`。本文档是关于如何为 `KnowStreaming` 做出贡献的指南。如果您发现不正确或遗漏的内容, 请留下您的意见/建议。 + + +--- + + +## 1、行为准则 + +请务必阅读并遵守我们的:[行为准则](https://github.com/didi/KnowStreaming/blob/master/CODE_OF_CONDUCT.md)。 + + +## 2、仓库规范 + +### 2.1、Issue 规范 + +按要求,在 [创建Issue](https://github.com/didi/KnowStreaming/issues/new/choose) 中创建ISSUE即可。 + +需要重点说明的是: +- 提供出现问题的环境信息,包括使用的系统,使用的KS版本等; +- 提供出现问题的复现方式; + + +### 2.2、Commit-Log 规范 + +`Commit-Log` 包含三部分 `Header`、`Body`、`Footer`。其中 `Header` 是必须的,格式固定,`Body` 在变更有必要详细解释时使用。 + + +**1、`Header` 规范** + +`Header` 格式为 `[Type]Message(#IssueID)`, 主要有三部分组成,分别是`Type`、`Message`、`IssueID`, + +- `Type`:说明这个提交是哪一个类型的,比如有 Bugfix、Feature、Optimize等; +- `Message`:说明提交的信息,比如修复xx问题; +- `IssueID`:该提交,关联的Issue的编号; + + +实际例子:[`[Bugfix]修复新接入的集群,Controller-Host不显示的问题(#927)`](https://github.com/didi/KnowStreaming/pull/933/commits) + + + +**2、`Body` 规范** + +一般不需要,如果解决了较复杂问题,或者代码较多,需要 `Body` 说清楚解决的问题,解决的思路等信息。 + +--- + +**3、实际例子** + +``` +[Optimize]优化 MySQL & ES 测试容器的初始化(#906) + +主要的变更 +1、knowstreaming/knowstreaming-manager 容器; +2、knowstreaming/knowstreaming-mysql 容器调整为使用 mysql:5.7 容器; +3、初始化 mysql:5.7 容器后,增加初始化 MySQL 表及数据的动作; + +被影响的变更: +1、移动 km-dist/init/sql 下的MySQL初始化脚本至 km-persistence/src/main/resource/sql 下,以便项目测试时加载到所需的初始化 SQL; +2、删除无用的 km-dist/init/template 目录; +3、因为 km-dist/init/sql 和 km-dist/init/template 目录的调整,因此也调整 ReleaseKnowStreaming.xml 内的文件内容; +``` + + +**TODO : 后续有兴趣的同学,可以考虑引入 Git 的 Hook 进行更好的 Commit-Log 的管理。** + + +### 2.3、Pull-Request 规范 + +详细见:[PULL-REQUEST 模版](../../.github/PULL_REQUEST_TEMPLATE.md) + +需要重点说明的是: + +- 任何 PR 都必须与有效 ISSUE 相关联。否则, PR 将被拒绝; +- 一个分支只修改一件事,一个 PR 只修改一件事; + +--- + + +## 3、操作示例 + +本节主要介绍对 `KnowStreaming` 进行代码贡献时,相关的操作方式及操作命令。 + +名词说明: +- 主仓库:https://github.com/didi/KnowStreaming 这个仓库为主仓库。 +- 分仓库:Fork 到自己账号下的 KnowStreaming 仓库为分仓库; + + +### 3.1、初始化环境 + +1. `Fork KnowStreaming` 主仓库至自己账号下,见 https://github.com/didi/KnowStreaming 地址右上角的 `Fork` 按钮; +2. 克隆分仓库至本地:`git clone git@github.com:xxxxxxx/KnowStreaming.git`,该仓库的简写名通常是`origin`; +3. 添加主仓库至本地:`git remote add upstream https://github.com/didi/KnowStreaming`,`upstream`是主仓库在本地的简写名,可以随意命名,前后保持一致即可; +4. 拉取主仓库代码:`git fetch upstream`; +5. 拉取分仓库代码:`git fetch origin`; +6. 将主仓库的`master`分支,拉取到本地并命名为`github_master`:`git checkout -b upstream/master`; + +最后,我们来看一下初始化完成之后的大致效果,具体如下图所示: +![环境初始化](./assets/环境初始化.jpg) + + +至此,我们的环境就初始化好了。后续,`github_master` 分支就是主仓库的`master`分支,我们可以使用`git pull`拉取该分支的最新代码,还可以使用`git checkout -b xxx`拉取我们想要的分支。 + + + +### 3.2、认领问题 + +在文末评论说明自己要处理该问题即可,具体如下图所示: + +![问题认领](./assets/问题认领.jpg) + + +### 3.3、处理问题 & 提交解决 + +本节主要介绍一下处理问题 & 提交解决过程中的分支管理,具体如下图所示: + +![分支管理](./assets/分支管理.png) + +1. 切换到主分支:`git checkout github_master`; +2. 主分支拉最新代码:`git pull`; +3. 基于主分支拉新分支:`git checkout -b fix_928`; +4. 提交代码,安装commit的规范进行提交,例如:`git commit -m "[Optimize]优化xxx问题(#928)"`; +5. 提交到自己远端仓库:`git push --set-upstream origin fix_928`; +6. `GitHub` 页面发起 `Pull Request` 请求,管理员合入主仓库。这部分详细见下一节; + + +### 3.4、请求合并 + +代码在提交到 `GitHub` 分仓库之后,就可以在 `GitHub` 的网站创建 `Pull Request`,申请将代码合入主仓库了。 `Pull Request` 具体见下图所示: + +![申请合并](./assets/申请合并.jpg) + + + +[Pull Request 创建的例子](https://github.com/didi/KnowStreaming/pull/945) + + + +--- + + +## 4、常见问题 + +### 4.1、如何将多个 Commit-Log 合并为一个? + +可以使用 `git rebase -i` 命令进行解决。 + + diff --git a/docs/contributer_guide/开发者名单.md b/docs/contributer_guide/开发者名单.md deleted file mode 100644 index 3f2c708d..00000000 --- a/docs/contributer_guide/开发者名单.md +++ /dev/null @@ -1,6 +0,0 @@ - -开源贡献者证书发放名单(定期更新) - - -贡献者名单请看:[贡献者名单](https://doc.knowstreaming.com/product/10-contribution#106-贡献者名单) - diff --git a/docs/contributer_guide/贡献流程.md b/docs/contributer_guide/贡献流程.md deleted file mode 100644 index 42679379..00000000 --- a/docs/contributer_guide/贡献流程.md +++ /dev/null @@ -1,6 +0,0 @@ - - -
-
- -请点击:[贡献流程](https://doc.knowstreaming.com/product/10-contribution#102-贡献流程) \ No newline at end of file diff --git a/docs/dev_guide/无数据排查文档.md b/docs/dev_guide/无数据排查文档.md new file mode 100644 index 00000000..fd7886bc --- /dev/null +++ b/docs/dev_guide/无数据排查文档.md @@ -0,0 +1,285 @@ +## 1、集群接入错误 + +### 1.1、异常现象 + +如下图所示,集群非空时,大概率为地址配置错误导致。 + + + + + +### 1.2、解决方案 + +接入集群时,依据提示的错误,进行相应的解决。例如: + + + +### 1.3、正常情况 + +接入集群时,页面信息都自动正常出现,没有提示错误。 + + + +## 2、JMX连接失败(需使用3.0.1及以上版本) + +### 2.1异常现象 + +Broker列表的JMX Port列出现红色感叹号,则该Broker的JMX连接异常。 + + + + + +#### 2.1.1、原因一:JMX未开启 + +##### 2.1.1.1、异常现象 + +broker列表的JMX Port值为-1,对应Broker的JMX未开启。 + + + +##### 2.1.1.2、解决方案 + +开启JMX,开启流程如下: + +1、修改kafka的bin目录下面的:`kafka-server-start.sh`文件 + +``` +# 在这个下面增加JMX端口的配置 +if [ "x$KAFKA_HEAP_OPTS" = "x" ]; then + export KAFKA_HEAP_OPTS="-Xmx1G -Xms1G" + export JMX_PORT=9999 # 增加这个配置, 这里的数值并不一定是要9999 +fi +``` + + + +2、修改kafka的bin目录下面对的:`kafka-run-class.sh`文件 + +``` +# JMX settings +if [ -z "$KAFKA_JMX_OPTS" ]; then + KAFKA_JMX_OPTS="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false + -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=${当前机器的IP}" +fi + +# JMX port to use +if [ $JMX_PORT ]; then + KAFKA_JMX_OPTS="$KAFKA_JMX_OPTS -Dcom.sun.management.jmxremote.port=$JMX_PORT - Dcom.sun.management.jmxremote.rmi.port=$JMX_PORT" +fi +``` + + + +3、重启Kafka-Broker。 + + + +#### 2.1.2、原因二:JMX配置错误 + +##### 2.1.2.1、异常现象 + +错误日志: + +``` +# 错误一: 错误提示的是真实的IP,这样的话基本就是JMX配置的有问题了。 +2021-01-27 10:06:20.730 ERROR 50901 --- [ics-Thread-1-62] c.x.k.m.c.utils.jmx.JmxConnectorWrap : JMX connect exception, host:192.168.0.1 port:9999. java.rmi.ConnectException: Connection refused to host: 192.168.0.1; nested exception is: + +# 错误二:错误提示的是127.0.0.1这个IP,这个是机器的hostname配置的可能有问题。 +2021-01-27 10:06:20.730 ERROR 50901 --- [ics-Thread-1-62] c.x.k.m.c.utils.jmx.JmxConnectorWrap : JMX connect exception, host:127.0.0.1 port:9999. java.rmi.ConnectException: Connection refused to host: 127.0.0.1;; nested exception is: +``` + + + +##### 2.1.2.2、解决方案 + +开启JMX,开启流程如下: + +1、修改kafka的bin目录下面的:`kafka-server-start.sh`文件 + +``` +# 在这个下面增加JMX端口的配置 +if [ "x$KAFKA_HEAP_OPTS" = "x" ]; then + export KAFKA_HEAP_OPTS="-Xmx1G -Xms1G" + export JMX_PORT=9999 # 增加这个配置, 这里的数值并不一定是要9999 +fi +``` + + + +2、修改kafka的bin目录下面对的:`kafka-run-class.sh`文件 + +``` +# JMX settings +if [ -z "$KAFKA_JMX_OPTS" ]; then + KAFKA_JMX_OPTS="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false + -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=${当前机器的IP}" +fi + +# JMX port to use +if [ $JMX_PORT ]; then + KAFKA_JMX_OPTS="$KAFKA_JMX_OPTS -Dcom.sun.management.jmxremote.port=$JMX_PORT - Dcom.sun.management.jmxremote.rmi.port=$JMX_PORT" +fi +``` + + + +3、重启Kafka-Broker。 + + + +#### 2.1.3、原因三:JMX开启SSL + +##### 2.1.3.1、解决方案 + + + +#### 2.1.4、原因四:连接了错误IP + +##### 2.1.4.1、异常现象 + +Broker 配置了内外网,而JMX在配置时,可能配置了内网IP或者外网IP,此时`KnowStreaming` 需要连接到特定网络的IP才可以进行访问。 + + 比如:Broker在ZK的存储结构如下所示,我们期望连接到 `endpoints` 中标记为 `INTERNAL` 的地址,但是 `KnowStreaming` 却连接了 `EXTERNAL` 的地址。 + +```json +{ + "listener_security_protocol_map": { + "EXTERNAL": "SASL_PLAINTEXT", + "INTERNAL": "SASL_PLAINTEXT" + }, + "endpoints": [ + "EXTERNAL://192.168.0.1:7092", + "INTERNAL://192.168.0.2:7093" + ], + "jmx_port": 8099, + "host": "192.168.0.1", + "timestamp": "1627289710439", + "port": -1, + "version": 4 +} +``` + +##### 2.1.4.2、解决方案 + +可以手动往`ks_km_physical_cluster`表的`jmx_properties`字段增加一个`useWhichEndpoint`字段,从而控制 `KnowStreaming` 连接到特定的JMX IP及PORT。 + +`jmx_properties`格式: + +```json +{ + "maxConn": 100, // KM对单台Broker的最大JMX连接数 + "username": "xxxxx", //用户名,可以不填写 + "password": "xxxx", // 密码,可以不填写 + "openSSL": true, //开启SSL, true表示开启ssl, false表示关闭 + "useWhichEndpoint": "EXTERNAL" //指定要连接的网络名称,填写EXTERNAL就是连接endpoints里面的EXTERNAL地址 +} +``` + + + +SQL例子: + +```sql +UPDATE ks_km_physical_cluster SET jmx_properties='{ "maxConn": 10, "username": "xxxxx", "password": "xxxx", "openSSL": false , "useWhichEndpoint": "xxx"}' where id={xxx}; +``` + +### 2.2、正常情况 + +修改完成后,如果看到 JMX PORT这一列全部为绿色,则表示JMX已正常。 + + + + + +## 3、Elasticsearch问题 + +注意:mac系统在执行curl指令时,可能报zsh错误。可参考以下操作。 + +``` +1 进入.zshrc 文件 vim ~/.zshrc +2.在.zshrc中加入 setopt no_nomatch +3.更新配置 source ~/.zshrc +``` + +### 3.1、原因一:缺少索引 + +#### 3.1.1、异常现象 + +报错信息 + +``` +com.didiglobal.logi.elasticsearch.client.model.exception.ESIndexNotFoundException: method [GET], host[http://127.0.0.1:9200], URI [/ks_kafka_broker_metric_2022-10-21,ks_kafka_broker_metric_2022-10-22/_search], status line [HTTP/1.1 404 Not Found] +``` + +curl http://{ES的IP地址}:{ES的端口号}/_cat/indices/ks_kafka* 查看KS索引列表,发现没有索引。 + +#### 3.1.2、解决方案 + +执行 [ES索引及模版初始化](https://github.com/didi/KnowStreaming/blob/master/bin/init_es_template.sh) 脚本,来创建索引及模版。 + + + +### 3.2、原因二:索引模板错误 + +#### 3.2.1、异常现象 + +多集群列表有数据,集群详情页图标无数据。查询KS索引模板列表,发现不存在。 + +``` +curl {ES的IP地址}:{ES的端口号}/_cat/templates/ks_kafka*?v&h=name +``` + +正常KS模板如下图所示。 + + + + + +#### 3.2.2、解决方案 + +删除KS索引模板和索引 + +``` +curl -XDELETE {ES的IP地址}:{ES的端口号}/ks_kafka* +curl -XDELETE {ES的IP地址}:{ES的端口号}/_template/ks_kafka* +``` + +执行 [ES索引及模版初始化](https://github.com/didi/KnowStreaming/blob/master/bin/init_es_template.sh) 脚本,来创建索引及模版。 + + +### 3.3、原因三:集群Shard满 + +#### 3.3.1、异常现象 + +报错信息 + +``` +com.didiglobal.logi.elasticsearch.client.model.exception.ESIndexNotFoundException: method [GET], host[http://127.0.0.1:9200], URI [/ks_kafka_broker_metric_2022-10-21,ks_kafka_broker_metric_2022-10-22/_search], status line [HTTP/1.1 404 Not Found] +``` + +尝试手动创建索引失败。 + +``` +#创建ks_kafka_cluster_metric_test索引的指令 +curl -s -XPUT http://{ES的IP地址}:{ES的端口号}/ks_kafka_cluster_metric_test +``` + +#### 3.3.2、解决方案 + +ES索引的默认分片数量为1000,达到数量以后,索引创建失败。 + ++ 扩大ES索引数量上限,执行指令 + +``` +curl -XPUT -H"content-type:application/json" http://{ES的IP地址}:{ES的端口号}/_cluster/settings -d ' +{ + "persistent": { + "cluster": { + "max_shards_per_node":{索引上限,默认为1000} + } + } +}' +``` + +执行 [ES索引及模版初始化](https://github.com/didi/KnowStreaming/blob/master/bin/init_es_template.sh) 脚本,来补全索引。 diff --git a/docs/install_guide/版本升级手册.md b/docs/install_guide/版本升级手册.md index 3cd580b8..061c080d 100644 --- a/docs/install_guide/版本升级手册.md +++ b/docs/install_guide/版本升级手册.md @@ -4,11 +4,180 @@ - 如果想升级至具体版本,需要将你当前版本至你期望使用版本的变更统统执行一遍,然后才能正常使用。 - 如果中间某个版本没有升级信息,则表示该版本直接替换安装包即可从前一个版本升级至当前版本。 -### 6.2.0、升级至 `master` 版本 +### 升级至 `master` 版本 -暂无 -### 6.2.1、升级至 `v3.1.0` 版本 +### 升级至 `3.3.0` 版本 + +**SQL 变更** +```sql +ALTER TABLE `logi_security_user` + CHANGE COLUMN `phone` `phone` VARCHAR(20) NOT NULL DEFAULT '' COMMENT 'mobile' ; + +ALTER TABLE ks_kc_connector ADD `heartbeat_connector_name` varchar(512) DEFAULT '' COMMENT '心跳检测connector名称'; +ALTER TABLE ks_kc_connector ADD `checkpoint_connector_name` varchar(512) DEFAULT '' COMMENT '进度确认connector名称'; + +INSERT INTO `ks_km_platform_cluster_config` (`cluster_id`, `value_group`, `value_name`, `value`, `description`, `operator`) VALUES ('-1', 'HEALTH', 'HC_MIRROR_MAKER_TOTAL_RECORD_ERRORS', '{\"value\" : 1}', 'MirrorMaker消息处理错误的次数', 'admin'); +INSERT INTO `ks_km_platform_cluster_config` (`cluster_id`, `value_group`, `value_name`, `value`, `description`, `operator`) VALUES ('-1', 'HEALTH', 'HC_MIRROR_MAKER_REPLICATION_LATENCY_MS_MAX', '{\"value\" : 6000}', 'MirrorMaker消息复制最大延迟时间', 'admin'); +INSERT INTO `ks_km_platform_cluster_config` (`cluster_id`, `value_group`, `value_name`, `value`, `description`, `operator`) VALUES ('-1', 'HEALTH', 'HC_MIRROR_MAKER_UNASSIGNED_TASK_COUNT', '{\"value\" : 20}', 'MirrorMaker未被分配的任务数量', 'admin'); +INSERT INTO `ks_km_platform_cluster_config` (`cluster_id`, `value_group`, `value_name`, `value`, `description`, `operator`) VALUES ('-1', 'HEALTH', 'HC_MIRROR_MAKER_FAILED_TASK_COUNT', '{\"value\" : 10}', 'MirrorMaker失败状态的任务数量', 'admin'); + + +-- 多集群管理权限2023-01-05新增 +INSERT INTO `logi_security_permission` (`id`, `permission_name`, `parent_id`, `leaf`, `level`, `description`, `is_delete`, `app_name`) VALUES ('2012', 'Topic-新增Topic复制', '1593', '1', '2', 'Topic-新增Topic复制', '0', 'know-streaming'); +INSERT INTO `logi_security_permission` (`id`, `permission_name`, `parent_id`, `leaf`, `level`, `description`, `is_delete`, `app_name`) VALUES ('2014', 'Topic-详情-取消Topic复制', '1593', '1', '2', 'Topic-详情-取消Topic复制', '0', 'know-streaming'); + +INSERT INTO `logi_security_role_permission` (`role_id`, `permission_id`, `is_delete`, `app_name`) VALUES ('1677', '2012', '0', 'know-streaming'); +INSERT INTO `logi_security_role_permission` (`role_id`, `permission_id`, `is_delete`, `app_name`) VALUES ('1677', '2014', '0', 'know-streaming'); + + +-- 多集群管理权限2023-01-18新增 +INSERT INTO `logi_security_permission` (`id`, `permission_name`, `parent_id`, `leaf`, `level`, `description`, `is_delete`, `app_name`) VALUES ('2016', 'MM2-新增', '1593', '1', '2', 'MM2-新增', '0', 'know-streaming'); +INSERT INTO `logi_security_permission` (`id`, `permission_name`, `parent_id`, `leaf`, `level`, `description`, `is_delete`, `app_name`) VALUES ('2018', 'MM2-编辑', '1593', '1', '2', 'MM2-编辑', '0', 'know-streaming'); +INSERT INTO `logi_security_permission` (`id`, `permission_name`, `parent_id`, `leaf`, `level`, `description`, `is_delete`, `app_name`) VALUES ('2020', 'MM2-删除', '1593', '1', '2', 'MM2-删除', '0', 'know-streaming'); +INSERT INTO `logi_security_permission` (`id`, `permission_name`, `parent_id`, `leaf`, `level`, `description`, `is_delete`, `app_name`) VALUES ('2022', 'MM2-重启', '1593', '1', '2', 'MM2-重启', '0', 'know-streaming'); +INSERT INTO `logi_security_permission` (`id`, `permission_name`, `parent_id`, `leaf`, `level`, `description`, `is_delete`, `app_name`) VALUES ('2024', 'MM2-暂停&恢复', '1593', '1', '2', 'MM2-暂停&恢复', '0', 'know-streaming'); + +INSERT INTO `logi_security_role_permission` (`role_id`, `permission_id`, `is_delete`, `app_name`) VALUES ('1677', '2016', '0', 'know-streaming'); +INSERT INTO `logi_security_role_permission` (`role_id`, `permission_id`, `is_delete`, `app_name`) VALUES ('1677', '2018', '0', 'know-streaming'); +INSERT INTO `logi_security_role_permission` (`role_id`, `permission_id`, `is_delete`, `app_name`) VALUES ('1677', '2020', '0', 'know-streaming'); +INSERT INTO `logi_security_role_permission` (`role_id`, `permission_id`, `is_delete`, `app_name`) VALUES ('1677', '2022', '0', 'know-streaming'); +INSERT INTO `logi_security_role_permission` (`role_id`, `permission_id`, `is_delete`, `app_name`) VALUES ('1677', '2024', '0', 'know-streaming'); + + +DROP TABLE IF EXISTS `ks_ha_active_standby_relation`; +CREATE TABLE `ks_ha_active_standby_relation` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', + `active_cluster_phy_id` bigint(20) NOT NULL DEFAULT '-1' COMMENT '主集群ID', + `standby_cluster_phy_id` bigint(20) NOT NULL DEFAULT '-1' COMMENT '备集群ID', + `res_name` varchar(192) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '' COMMENT '资源名称', + `res_type` int(11) NOT NULL DEFAULT '-1' COMMENT '资源类型,0:集群,1:镜像Topic,2:主备Topic', + `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `modify_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间', + `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间', + PRIMARY KEY (`id`), + UNIQUE KEY `uniq_cluster_res` (`res_type`,`active_cluster_phy_id`,`standby_cluster_phy_id`,`res_name`), + UNIQUE KEY `uniq_res_type_standby_cluster_res_name` (`res_type`,`standby_cluster_phy_id`,`res_name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='HA主备关系表'; + + +-- 删除idx_cluster_phy_id 索引并新增idx_cluster_update_time索引 +ALTER TABLE `ks_km_kafka_change_record` DROP INDEX `idx_cluster_phy_id` , +ADD INDEX `idx_cluster_update_time` (`cluster_phy_id` ASC, `update_time` ASC); +``` + +### 升级至 `3.2.0` 版本 + +**配置变更** + +```yaml +# 新增如下配置 + +spring: + logi-job: # know-streaming 依赖的 logi-job 模块的数据库的配置,默认与 know-streaming 的数据库配置保持一致即可 + enable: true # true表示开启job任务, false表关闭。KS在部署上可以考虑部署两套服务,一套处理前端请求,一套执行job任务,此时可以通过该字段进行控制 + +# 线程池大小相关配置 +thread-pool: + es: + search: # es查询线程池 + thread-num: 20 # 线程池大小 + queue-size: 10000 # 队列大小 + +# 客户端池大小相关配置 +client-pool: + kafka-admin: + client-cnt: 1 # 每个Kafka集群创建的KafkaAdminClient数 + +# ES客户端配置 +es: + index: + expire: 15 # 索引过期天数,15表示超过15天的索引会被KS过期删除 +``` + +**SQL 变更** +```sql +DROP TABLE IF EXISTS `ks_kc_connect_cluster`; +CREATE TABLE `ks_kc_connect_cluster` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Connect集群ID', + `kafka_cluster_phy_id` bigint(20) NOT NULL DEFAULT '-1' COMMENT 'Kafka集群ID', + `name` varchar(128) NOT NULL DEFAULT '' COMMENT '集群名称', + `group_name` varchar(128) NOT NULL DEFAULT '' COMMENT '集群Group名称', + `cluster_url` varchar(1024) NOT NULL DEFAULT '' COMMENT '集群地址', + `member_leader_url` varchar(1024) NOT NULL DEFAULT '' COMMENT 'URL地址', + `version` varchar(64) NOT NULL DEFAULT '' COMMENT 'connect版本', + `jmx_properties` text COMMENT 'JMX配置', + `state` tinyint(4) NOT NULL DEFAULT '1' COMMENT '集群使用的消费组状态,也表示集群状态:-1 Unknown,0 ReBalance,1 Active,2 Dead,3 Empty', + `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '接入时间', + `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间', + PRIMARY KEY (`id`), + UNIQUE KEY `uniq_id_group_name` (`id`,`group_name`), + UNIQUE KEY `uniq_name_kafka_cluster` (`name`,`kafka_cluster_phy_id`), + KEY `idx_kafka_cluster_phy_id` (`kafka_cluster_phy_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Connect集群信息表'; + + +DROP TABLE IF EXISTS `ks_kc_connector`; +CREATE TABLE `ks_kc_connector` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', + `kafka_cluster_phy_id` bigint(20) NOT NULL DEFAULT '-1' COMMENT 'Kafka集群ID', + `connect_cluster_id` bigint(20) NOT NULL DEFAULT '-1' COMMENT 'Connect集群ID', + `connector_name` varchar(512) NOT NULL DEFAULT '' COMMENT 'Connector名称', + `connector_class_name` varchar(512) NOT NULL DEFAULT '' COMMENT 'Connector类', + `connector_type` varchar(32) NOT NULL DEFAULT '' COMMENT 'Connector类型', + `state` varchar(45) NOT NULL DEFAULT '' COMMENT '状态', + `topics` text COMMENT '访问过的Topics', + `task_count` int(11) NOT NULL DEFAULT '0' COMMENT '任务数', + `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间', + PRIMARY KEY (`id`), + UNIQUE KEY `uniq_connect_cluster_id_connector_name` (`connect_cluster_id`,`connector_name`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Connector信息表'; + + +DROP TABLE IF EXISTS `ks_kc_worker`; +CREATE TABLE `ks_kc_worker` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', + `kafka_cluster_phy_id` bigint(20) NOT NULL DEFAULT '-1' COMMENT 'Kafka集群ID', + `connect_cluster_id` bigint(20) NOT NULL DEFAULT '-1' COMMENT 'Connect集群ID', + `member_id` varchar(512) NOT NULL DEFAULT '' COMMENT '成员ID', + `host` varchar(128) NOT NULL DEFAULT '' COMMENT '主机名', + `jmx_port` int(16) NOT NULL DEFAULT '-1' COMMENT 'Jmx端口', + `url` varchar(1024) NOT NULL DEFAULT '' COMMENT 'URL信息', + `leader_url` varchar(1024) NOT NULL DEFAULT '' COMMENT 'leaderURL信息', + `leader` int(16) NOT NULL DEFAULT '0' COMMENT '状态: 1是leader,0不是leader', + `worker_id` varchar(128) NOT NULL COMMENT 'worker地址', + `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间', + PRIMARY KEY (`id`), + UNIQUE KEY `uniq_cluster_id_member_id` (`connect_cluster_id`,`member_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='worker信息表'; + + +DROP TABLE IF EXISTS `ks_kc_worker_connector`; +CREATE TABLE `ks_kc_worker_connector` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', + `kafka_cluster_phy_id` bigint(20) NOT NULL DEFAULT '-1' COMMENT 'Kafka集群ID', + `connect_cluster_id` bigint(20) NOT NULL DEFAULT '-1' COMMENT 'Connect集群ID', + `connector_name` varchar(512) NOT NULL DEFAULT '' COMMENT 'Connector名称', + `worker_member_id` varchar(256) NOT NULL DEFAULT '', + `task_id` int(16) NOT NULL DEFAULT '-1' COMMENT 'Task的ID', + `state` varchar(128) DEFAULT NULL COMMENT '任务状态', + `worker_id` varchar(128) DEFAULT NULL COMMENT 'worker信息', + `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间', + PRIMARY KEY (`id`), + UNIQUE KEY `uniq_relation` (`connect_cluster_id`,`connector_name`,`task_id`,`worker_member_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Worker和Connector关系表'; + +INSERT INTO `ks_km_platform_cluster_config` (`cluster_id`, `value_group`, `value_name`, `value`, `description`, `operator`) VALUES ('-1', 'HEALTH', 'HC_CONNECTOR_FAILED_TASK_COUNT', '{\"value\" : 1}', 'connector失败状态的任务数量', 'admin'); +INSERT INTO `ks_km_platform_cluster_config` (`cluster_id`, `value_group`, `value_name`, `value`, `description`, `operator`) VALUES ('-1', 'HEALTH', 'HC_CONNECTOR_UNASSIGNED_TASK_COUNT', '{\"value\" : 1}', 'connector未被分配的任务数量', 'admin'); +INSERT INTO `ks_km_platform_cluster_config` (`cluster_id`, `value_group`, `value_name`, `value`, `description`, `operator`) VALUES ('-1', 'HEALTH', 'HC_CONNECT_CLUSTER_TASK_STARTUP_FAILURE_PERCENTAGE', '{\"value\" : 0.05}', 'Connect集群任务启动失败概率', 'admin'); +``` + +--- + +### 升级至 `v3.1.0` 版本 ```sql INSERT INTO `ks_km_platform_cluster_config` (`cluster_id`, `value_group`, `value_name`, `value`, `description`, `operator`) VALUES ('-1', 'HEALTH', 'HC_ZK_BRAIN_SPLIT', '{ \"value\": 1} ', 'ZK 脑裂', 'admin'); @@ -20,7 +189,7 @@ INSERT INTO `ks_km_platform_cluster_config` (`cluster_id`, `value_group`, `value ``` -### 6.2.2、升级至 `v3.0.1` 版本 +### 升级至 `v3.0.1` 版本 **ES 索引模版** ```bash @@ -155,7 +324,7 @@ CREATE TABLE `ks_km_group` ( ``` -### 6.2.3、升级至 `v3.0.0` 版本 +### 升级至 `v3.0.0` 版本 **SQL 变更** @@ -167,7 +336,7 @@ ADD COLUMN `zk_properties` TEXT NULL COMMENT 'ZK配置' AFTER `jmx_properties`; --- -### 6.2.4、升级至 `v3.0.0-beta.2`版本 +### 升级至 `v3.0.0-beta.2`版本 **配置变更** @@ -238,7 +407,7 @@ ALTER TABLE `logi_security_oplog` --- -### 6.2.5、升级至 `v3.0.0-beta.1`版本 +### 升级至 `v3.0.0-beta.1`版本 **SQL 变更** @@ -257,7 +426,7 @@ ALTER COLUMN `operation_methods` set default ''; --- -### 6.2.6、`2.x`版本 升级至 `v3.0.0-beta.0`版本 +### `2.x`版本 升级至 `v3.0.0-beta.0`版本 **升级步骤:** diff --git a/docs/user_guide/faq.md b/docs/user_guide/faq.md index a91cdf79..1656ec37 100644 --- a/docs/user_guide/faq.md +++ b/docs/user_guide/faq.md @@ -182,3 +182,47 @@ Node 版本: v12.22.12 + 原因:由于数据库编码和我们提供的脚本不一致,数据库里的数据发生了乱码,因此出现权限识别失败问题。 + 解决方案:清空数据库数据,将数据库字符集调整为utf8,最后重新执行[dml-logi.sql](https://github.com/didi/KnowStreaming/blob/master/km-dist/init/sql/dml-logi.sql)脚本导入数据即可。 + + +## 8.13、接入开启kerberos认证的kafka集群 + +1. 部署KnowStreaming的机器上安装krb客户端; +2. 替换/etc/krb5.conf配置文件; +3. 把kafka对应的keytab复制到改机器目录下; +4. 接入集群时认证配置,配置信息根据实际情况填写; +```json +{ + "security.protocol": "SASL_PLAINTEXT", + "sasl.mechanism": "GSSAPI", + "sasl.jaas.config": "com.sun.security.auth.module.Krb5LoginModule required useKeyTab=true keyTab=\"/etc/keytab/kafka.keytab\" storeKey=true useTicketCache=false principal=\"kafka/kafka@TEST.COM\";", + "sasl.kerberos.service.name": "kafka" +} +``` + + +## 8.14、对接Ldap的配置 + +```yaml +# 需要在application.yml中增加如下配置。相关配置的信息,按实际情况进行调整 +account: + ldap: + url: ldap://127.0.0.1:8080/ + basedn: DC=senz,DC=local + factory: com.sun.jndi.ldap.LdapCtxFactory + filter: sAMAccountName + security: + authentication: simple + principal: CN=search,DC=senz,DC=local + credentials: xxxxxxx + auth-user-registration: false # 是否注册到mysql,默认false + auth-user-registration-role: 1677 # 1677是超级管理员角色的id,如果赋予想默认赋予普通角色,可以到ks新建一个。 + +# 需要在application.yml中修改如下配置 +spring: + logi-security: + login-extend-bean-name: ksLdapLoginService # 表示使用ldap的service +``` + +## 8.15、测试时使用Testcontainers的说明 +1. 需要docker运行环境 [Testcontainers运行环境说明](https://www.testcontainers.org/supported_docker_environment/) +2. 如果本机没有docker,可以使用[远程访问docker](https://docs.docker.com/config/daemon/remote-access/) [Testcontainers配置说明](https://www.testcontainers.org/features/configuration/#customizing-docker-host-detection) \ No newline at end of file diff --git a/km-biz/pom.xml b/km-biz/pom.xml index 54399210..b8c3457b 100644 --- a/km-biz/pom.xml +++ b/km-biz/pom.xml @@ -62,10 +62,6 @@ commons-lang commons-lang - - junit - junit - commons-codec diff --git a/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/cluster/ClusterConnectorsManager.java b/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/cluster/ClusterConnectorsManager.java new file mode 100644 index 00000000..c20c5c77 --- /dev/null +++ b/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/cluster/ClusterConnectorsManager.java @@ -0,0 +1,15 @@ +package com.xiaojukeji.know.streaming.km.biz.cluster; + +import com.xiaojukeji.know.streaming.km.common.bean.dto.cluster.ClusterConnectorsOverviewDTO; +import com.xiaojukeji.know.streaming.km.common.bean.entity.result.PaginationResult; +import com.xiaojukeji.know.streaming.km.common.bean.vo.cluster.connect.ConnectStateVO; +import com.xiaojukeji.know.streaming.km.common.bean.vo.cluster.connector.ClusterConnectorOverviewVO; + +/** + * Kafka集群Connector概览 + */ +public interface ClusterConnectorsManager { + PaginationResult getClusterConnectorsOverview(Long clusterPhyId, ClusterConnectorsOverviewDTO dto); + + ConnectStateVO getClusterConnectorsState(Long clusterPhyId); +} diff --git a/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/cluster/MultiClusterPhyManager.java b/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/cluster/MultiClusterPhyManager.java index 0bd2f6e4..2d57d719 100644 --- a/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/cluster/MultiClusterPhyManager.java +++ b/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/cluster/MultiClusterPhyManager.java @@ -4,8 +4,12 @@ import com.xiaojukeji.know.streaming.km.common.bean.entity.cluster.ClusterPhysHe import com.xiaojukeji.know.streaming.km.common.bean.entity.cluster.ClusterPhysState; import com.xiaojukeji.know.streaming.km.common.bean.dto.cluster.MultiClusterDashboardDTO; import com.xiaojukeji.know.streaming.km.common.bean.entity.result.PaginationResult; +import com.xiaojukeji.know.streaming.km.common.bean.entity.result.Result; +import com.xiaojukeji.know.streaming.km.common.bean.vo.cluster.ClusterPhyBaseVO; import com.xiaojukeji.know.streaming.km.common.bean.vo.cluster.ClusterPhyDashboardVO; +import java.util.List; + /** * 多集群总体状态 */ @@ -24,4 +28,6 @@ public interface MultiClusterPhyManager { * @return */ PaginationResult getClusterPhysDashboard(MultiClusterDashboardDTO dto); + + Result> getClusterPhysBasic(); } diff --git a/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/cluster/impl/ClusterBrokersManagerImpl.java b/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/cluster/impl/ClusterBrokersManagerImpl.java index 6b180126..ab5d6a6d 100644 --- a/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/cluster/impl/ClusterBrokersManagerImpl.java +++ b/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/cluster/impl/ClusterBrokersManagerImpl.java @@ -6,6 +6,8 @@ import com.xiaojukeji.know.streaming.km.biz.cluster.ClusterBrokersManager; import com.xiaojukeji.know.streaming.km.common.bean.dto.cluster.ClusterBrokersOverviewDTO; import com.xiaojukeji.know.streaming.km.common.bean.dto.pagination.PaginationSortDTO; import com.xiaojukeji.know.streaming.km.common.bean.entity.broker.Broker; +import com.xiaojukeji.know.streaming.km.common.bean.entity.cluster.ClusterPhy; +import com.xiaojukeji.know.streaming.km.common.bean.entity.config.JmxConfig; import com.xiaojukeji.know.streaming.km.common.bean.entity.kafkacontroller.KafkaController; import com.xiaojukeji.know.streaming.km.common.bean.entity.metrics.BrokerMetrics; import com.xiaojukeji.know.streaming.km.common.bean.entity.result.PaginationResult; @@ -16,6 +18,8 @@ import com.xiaojukeji.know.streaming.km.common.bean.vo.cluster.res.ClusterBroker import com.xiaojukeji.know.streaming.km.common.bean.vo.kafkacontroller.KafkaControllerVO; import com.xiaojukeji.know.streaming.km.common.constant.KafkaConstant; import com.xiaojukeji.know.streaming.km.common.enums.SortTypeEnum; +import com.xiaojukeji.know.streaming.km.common.enums.cluster.ClusterRunStateEnum; +import com.xiaojukeji.know.streaming.km.common.utils.ConvertUtil; import com.xiaojukeji.know.streaming.km.common.utils.PaginationMetricsUtil; import com.xiaojukeji.know.streaming.km.common.utils.PaginationUtil; import com.xiaojukeji.know.streaming.km.common.utils.ValidateUtils; @@ -24,6 +28,7 @@ import com.xiaojukeji.know.streaming.km.core.service.broker.BrokerMetricService; import com.xiaojukeji.know.streaming.km.core.service.broker.BrokerService; import com.xiaojukeji.know.streaming.km.core.service.kafkacontroller.KafkaControllerService; import com.xiaojukeji.know.streaming.km.core.service.topic.TopicService; +import com.xiaojukeji.know.streaming.km.persistence.cache.LoadedClusterPhyCache; import com.xiaojukeji.know.streaming.km.persistence.kafka.KafkaJMXClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -83,9 +88,13 @@ public class ClusterBrokersManagerImpl implements ClusterBrokersManager { Map jmxConnectedMap = new HashMap<>(); brokerList.forEach(elem -> jmxConnectedMap.put(elem.getBrokerId(), kafkaJMXClient.getClientWithCheck(clusterPhyId, elem.getBrokerId()) != null)); + + ClusterPhy clusterPhy = LoadedClusterPhyCache.getByPhyId(clusterPhyId); + // 格式转换 return PaginationResult.buildSuc( this.convert2ClusterBrokersOverviewVOList( + clusterPhy, paginationResult.getData().getBizData(), brokerList, metricsResult.getData(), @@ -131,7 +140,8 @@ public class ClusterBrokersManagerImpl implements ClusterBrokersManager { clusterBrokersStateVO.setKafkaControllerAlive(true); } - clusterBrokersStateVO.setConfigSimilar(brokerConfigService.countBrokerConfigDiffsFromDB(clusterPhyId, Arrays.asList("broker.id", "listeners", "name", "value")) <= 0); + clusterBrokersStateVO.setConfigSimilar(brokerConfigService.countBrokerConfigDiffsFromDB(clusterPhyId, KafkaConstant.CONFIG_SIMILAR_IGNORED_CONFIG_KEY_LIST) <= 0 + ); return clusterBrokersStateVO; } @@ -169,7 +179,8 @@ public class ClusterBrokersManagerImpl implements ClusterBrokersManager { ); } - private List convert2ClusterBrokersOverviewVOList(List pagedBrokerIdList, + private List convert2ClusterBrokersOverviewVOList(ClusterPhy clusterPhy, + List pagedBrokerIdList, List brokerList, List metricsList, Topic groupTopic, @@ -185,9 +196,15 @@ public class ClusterBrokersManagerImpl implements ClusterBrokersManager { Broker broker = brokerMap.get(brokerId); BrokerMetrics brokerMetrics = metricsMap.get(brokerId); Boolean jmxConnected = jmxConnectedMap.get(brokerId); - voList.add(this.convert2ClusterBrokersOverviewVO(brokerId, broker, brokerMetrics, groupTopic, transactionTopic, kafkaController, jmxConnected)); } + + //补充非zk模式的JMXPort信息 + if (!clusterPhy.getRunState().equals(ClusterRunStateEnum.RUN_ZK.getRunState())) { + JmxConfig jmxConfig = ConvertUtil.str2ObjByJson(clusterPhy.getJmxProperties(), JmxConfig.class); + voList.forEach(elem -> elem.setJmxPort(jmxConfig.getJmxPort() == null ? -1 : jmxConfig.getJmxPort())); + } + return voList; } diff --git a/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/cluster/impl/ClusterConnectorsManagerImpl.java b/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/cluster/impl/ClusterConnectorsManagerImpl.java new file mode 100644 index 00000000..e982c588 --- /dev/null +++ b/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/cluster/impl/ClusterConnectorsManagerImpl.java @@ -0,0 +1,152 @@ +package com.xiaojukeji.know.streaming.km.biz.cluster.impl; + +import com.didiglobal.logi.log.ILog; +import com.didiglobal.logi.log.LogFactory; +import com.xiaojukeji.know.streaming.km.biz.cluster.ClusterConnectorsManager; +import com.xiaojukeji.know.streaming.km.common.bean.dto.cluster.ClusterConnectorsOverviewDTO; +import com.xiaojukeji.know.streaming.km.common.bean.dto.connect.ClusterConnectorDTO; +import com.xiaojukeji.know.streaming.km.common.bean.dto.metrices.MetricDTO; +import com.xiaojukeji.know.streaming.km.common.bean.dto.metrices.connect.MetricsConnectorsDTO; +import com.xiaojukeji.know.streaming.km.common.bean.entity.connect.ConnectCluster; +import com.xiaojukeji.know.streaming.km.common.bean.entity.connect.ConnectWorker; +import com.xiaojukeji.know.streaming.km.common.bean.entity.connect.WorkerConnector; +import com.xiaojukeji.know.streaming.km.common.bean.entity.metrics.connect.ConnectorMetrics; +import com.xiaojukeji.know.streaming.km.common.bean.entity.result.PaginationResult; +import com.xiaojukeji.know.streaming.km.common.bean.entity.result.Result; +import com.xiaojukeji.know.streaming.km.common.bean.po.connect.ConnectorPO; +import com.xiaojukeji.know.streaming.km.common.bean.vo.cluster.connect.ConnectStateVO; +import com.xiaojukeji.know.streaming.km.common.bean.vo.cluster.connector.ClusterConnectorOverviewVO; +import com.xiaojukeji.know.streaming.km.common.bean.vo.metrics.line.MetricMultiLinesVO; +import com.xiaojukeji.know.streaming.km.common.converter.ConnectConverter; +import com.xiaojukeji.know.streaming.km.common.utils.ConvertUtil; +import com.xiaojukeji.know.streaming.km.common.utils.PaginationMetricsUtil; +import com.xiaojukeji.know.streaming.km.common.utils.PaginationUtil; +import com.xiaojukeji.know.streaming.km.core.service.connect.cluster.ConnectClusterService; +import com.xiaojukeji.know.streaming.km.core.service.connect.connector.ConnectorMetricService; +import com.xiaojukeji.know.streaming.km.core.service.connect.connector.ConnectorService; +import com.xiaojukeji.know.streaming.km.core.service.connect.worker.WorkerConnectorService; +import com.xiaojukeji.know.streaming.km.core.service.connect.worker.WorkerService; +import org.apache.kafka.connect.runtime.AbstractStatus; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + + +@Service +public class ClusterConnectorsManagerImpl implements ClusterConnectorsManager { + private static final ILog LOGGER = LogFactory.getLog(ClusterConnectorsManagerImpl.class); + + @Autowired + private ConnectorService connectorService; + + @Autowired + private ConnectClusterService connectClusterService; + + @Autowired + private ConnectorMetricService connectorMetricService; + + @Autowired + private WorkerService workerService; + + @Autowired + private WorkerConnectorService workerConnectorService; + + @Override + public PaginationResult getClusterConnectorsOverview(Long clusterPhyId, ClusterConnectorsOverviewDTO dto) { + List clusterList = connectClusterService.listByKafkaCluster(clusterPhyId); + + List poList = connectorService.listByKafkaClusterIdFromDB(clusterPhyId); + + // 查询实时指标 + Result> latestMetricsResult = connectorMetricService.getLatestMetricsFromES( + clusterPhyId, + poList.stream().map(elem -> new ClusterConnectorDTO(elem.getConnectClusterId(), elem.getConnectorName())).collect(Collectors.toList()), + dto.getLatestMetricNames() + ); + + if (latestMetricsResult.failed()) { + LOGGER.error("method=getClusterConnectorsOverview||clusterPhyId={}||result={}||errMsg=get latest metric failed", clusterPhyId, latestMetricsResult); + return PaginationResult.buildFailure(latestMetricsResult, dto); + } + + // 转换成vo + List voList = ConnectConverter.convert2ClusterConnectorOverviewVOList(clusterList, poList,latestMetricsResult.getData()); + + // 请求分页信息 + PaginationResult voPaginationResult = this.pagingConnectorInLocal(voList, dto); + if (voPaginationResult.failed()) { + LOGGER.error("method=getClusterConnectorsOverview||clusterPhyId={}||result={}||errMsg=pagination in local failed", clusterPhyId, voPaginationResult); + + return PaginationResult.buildFailure(voPaginationResult, dto); + } + + // 查询历史指标 + Result> lineMetricsResult = connectorMetricService.listConnectClusterMetricsFromES( + clusterPhyId, + this.buildMetricsConnectorsDTO( + voPaginationResult.getData().getBizData().stream().map(elem -> new ClusterConnectorDTO(elem.getConnectClusterId(), elem.getConnectorName())).collect(Collectors.toList()), + dto.getMetricLines() + ) + ); + + + return PaginationResult.buildSuc( + ConnectConverter.supplyData2ClusterConnectorOverviewVOList( + voPaginationResult.getData().getBizData(), + lineMetricsResult.getData() + ), + voPaginationResult + ); + } + + @Override + public ConnectStateVO getClusterConnectorsState(Long clusterPhyId) { + //获取Connect集群Id列表 + List connectClusterList = connectClusterService.listByKafkaCluster(clusterPhyId); + List connectorPOList = connectorService.listByKafkaClusterIdFromDB(clusterPhyId); + List workerConnectorList = workerConnectorService.listByKafkaClusterIdFromDB(clusterPhyId); + List connectWorkerList = workerService.listByKafkaClusterIdFromDB(clusterPhyId); + + return convert2ConnectStateVO(connectClusterList, connectorPOList, workerConnectorList, connectWorkerList); + } + + /**************************************************** private method ****************************************************/ + + private MetricsConnectorsDTO buildMetricsConnectorsDTO(List connectorDTOList, MetricDTO metricDTO) { + MetricsConnectorsDTO dto = ConvertUtil.obj2Obj(metricDTO, MetricsConnectorsDTO.class); + dto.setConnectorNameList(connectorDTOList == null? new ArrayList<>(): connectorDTOList); + + return dto; + } + + private ConnectStateVO convert2ConnectStateVO(List connectClusterList, List connectorPOList, List workerConnectorList, List connectWorkerList) { + ConnectStateVO connectStateVO = new ConnectStateVO(); + connectStateVO.setConnectClusterCount(connectClusterList.size()); + connectStateVO.setTotalConnectorCount(connectorPOList.size()); + connectStateVO.setAliveConnectorCount(connectorPOList.stream().filter(elem -> elem.getState().equals(AbstractStatus.State.RUNNING.name())).collect(Collectors.toList()).size()); + connectStateVO.setWorkerCount(connectWorkerList.size()); + connectStateVO.setTotalTaskCount(workerConnectorList.size()); + connectStateVO.setAliveTaskCount(workerConnectorList.stream().filter(elem -> elem.getState().equals(AbstractStatus.State.RUNNING.name())).collect(Collectors.toList()).size()); + return connectStateVO; + } + + private PaginationResult pagingConnectorInLocal(List connectorVOList, ClusterConnectorsOverviewDTO dto) { + //模糊匹配 + connectorVOList = PaginationUtil.pageByFuzzyFilter(connectorVOList, dto.getSearchKeywords(), Arrays.asList("connectorName")); + + //排序 + if (!dto.getLatestMetricNames().isEmpty()) { + PaginationMetricsUtil.sortMetrics(connectorVOList, "latestMetrics", dto.getSortMetricNameList(), "connectorName", dto.getSortType()); + } else { + PaginationUtil.pageBySort(connectorVOList, dto.getSortField(), dto.getSortType(), "connectorName", dto.getSortType()); + } + + //分页 + return PaginationUtil.pageBySubData(connectorVOList, dto); + } + +} diff --git a/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/cluster/impl/ClusterTopicsManagerImpl.java b/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/cluster/impl/ClusterTopicsManagerImpl.java index c68f9b9a..3a2b11ef 100644 --- a/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/cluster/impl/ClusterTopicsManagerImpl.java +++ b/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/cluster/impl/ClusterTopicsManagerImpl.java @@ -14,10 +14,12 @@ import com.xiaojukeji.know.streaming.km.common.bean.vo.cluster.res.ClusterPhyTop import com.xiaojukeji.know.streaming.km.common.bean.vo.metrics.line.MetricMultiLinesVO; import com.xiaojukeji.know.streaming.km.common.constant.KafkaConstant; import com.xiaojukeji.know.streaming.km.common.converter.TopicVOConverter; +import com.xiaojukeji.know.streaming.km.common.enums.ha.HaResTypeEnum; import com.xiaojukeji.know.streaming.km.common.utils.ConvertUtil; import com.xiaojukeji.know.streaming.km.common.utils.PaginationMetricsUtil; import com.xiaojukeji.know.streaming.km.common.utils.PaginationUtil; import com.xiaojukeji.know.streaming.km.common.utils.ValidateUtils; +import com.xiaojukeji.know.streaming.km.core.service.ha.HaActiveStandbyRelationService; import com.xiaojukeji.know.streaming.km.core.service.topic.TopicMetricService; import com.xiaojukeji.know.streaming.km.core.service.topic.TopicService; import org.springframework.beans.factory.annotation.Autowired; @@ -38,16 +40,22 @@ public class ClusterTopicsManagerImpl implements ClusterTopicsManager { @Autowired private TopicMetricService topicMetricService; + @Autowired + private HaActiveStandbyRelationService haActiveStandbyRelationService; + @Override public PaginationResult getClusterPhyTopicsOverview(Long clusterPhyId, ClusterTopicsOverviewDTO dto) { // 获取集群所有的Topic信息 List topicList = topicService.listTopicsFromDB(clusterPhyId); // 获取集群所有Topic的指标 - Map metricsMap = topicMetricService.getLatestMetricsFromCacheFirst(clusterPhyId); + Map metricsMap = topicMetricService.getLatestMetricsFromCache(clusterPhyId); + + // 获取HA信息 + Set haTopicNameSet = haActiveStandbyRelationService.listByClusterAndType(clusterPhyId, HaResTypeEnum.MIRROR_TOPIC).stream().map(elem -> elem.getResName()).collect(Collectors.toSet()); // 转换成vo - List voList = TopicVOConverter.convert2ClusterPhyTopicsOverviewVOList(topicList, metricsMap); + List voList = TopicVOConverter.convert2ClusterPhyTopicsOverviewVOList(topicList, metricsMap, haTopicNameSet); // 请求分页信息 PaginationResult voPaginationResult = this.pagingTopicInLocal(voList, dto); diff --git a/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/cluster/impl/ClusterZookeepersManagerImpl.java b/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/cluster/impl/ClusterZookeepersManagerImpl.java index 7783b40b..aca30269 100644 --- a/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/cluster/impl/ClusterZookeepersManagerImpl.java +++ b/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/cluster/impl/ClusterZookeepersManagerImpl.java @@ -19,7 +19,7 @@ import com.xiaojukeji.know.streaming.km.common.enums.zookeeper.ZKRoleEnum; import com.xiaojukeji.know.streaming.km.common.utils.ConvertUtil; import com.xiaojukeji.know.streaming.km.common.utils.PaginationUtil; import com.xiaojukeji.know.streaming.km.core.service.cluster.ClusterPhyService; -import com.xiaojukeji.know.streaming.km.core.service.version.metrics.ZookeeperMetricVersionItems; +import com.xiaojukeji.know.streaming.km.core.service.version.metrics.kafka.ZookeeperMetricVersionItems; import com.xiaojukeji.know.streaming.km.core.service.zookeeper.ZnodeService; import com.xiaojukeji.know.streaming.km.core.service.zookeeper.ZookeeperMetricService; import com.xiaojukeji.know.streaming.km.core.service.zookeeper.ZookeeperService; @@ -94,7 +94,7 @@ public class ClusterZookeepersManagerImpl implements ClusterZookeepersManager { ); if (metricsResult.failed()) { LOGGER.error( - "class=ClusterZookeepersManagerImpl||method=getClusterPhyZookeepersState||clusterPhyId={}||errMsg={}", + "method=getClusterPhyZookeepersState||clusterPhyId={}||errMsg={}", clusterPhyId, metricsResult.getMessage() ); return Result.buildSuc(vo); diff --git a/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/cluster/impl/MultiClusterPhyManagerImpl.java b/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/cluster/impl/MultiClusterPhyManagerImpl.java index 68dd4ac7..7e379c99 100644 --- a/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/cluster/impl/MultiClusterPhyManagerImpl.java +++ b/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/cluster/impl/MultiClusterPhyManagerImpl.java @@ -9,13 +9,12 @@ import com.xiaojukeji.know.streaming.km.common.bean.entity.cluster.ClusterPhysHe import com.xiaojukeji.know.streaming.km.common.bean.entity.cluster.ClusterPhysState; import com.xiaojukeji.know.streaming.km.common.bean.entity.cluster.ClusterPhy; import com.xiaojukeji.know.streaming.km.common.bean.dto.cluster.MultiClusterDashboardDTO; -import com.xiaojukeji.know.streaming.km.common.bean.entity.kafkacontroller.KafkaController; import com.xiaojukeji.know.streaming.km.common.bean.entity.metrics.ClusterMetrics; import com.xiaojukeji.know.streaming.km.common.bean.entity.result.PaginationResult; import com.xiaojukeji.know.streaming.km.common.bean.entity.result.Result; +import com.xiaojukeji.know.streaming.km.common.bean.vo.cluster.ClusterPhyBaseVO; import com.xiaojukeji.know.streaming.km.common.bean.vo.cluster.ClusterPhyDashboardVO; import com.xiaojukeji.know.streaming.km.common.bean.vo.metrics.line.MetricMultiLinesVO; -import com.xiaojukeji.know.streaming.km.common.constant.Constant; import com.xiaojukeji.know.streaming.km.common.converter.ClusterVOConverter; import com.xiaojukeji.know.streaming.km.common.enums.health.HealthStateEnum; import com.xiaojukeji.know.streaming.km.common.utils.ConvertUtil; @@ -24,15 +23,11 @@ import com.xiaojukeji.know.streaming.km.common.utils.PaginationMetricsUtil; import com.xiaojukeji.know.streaming.km.common.utils.ValidateUtils; import com.xiaojukeji.know.streaming.km.core.service.cluster.ClusterMetricService; import com.xiaojukeji.know.streaming.km.core.service.cluster.ClusterPhyService; -import com.xiaojukeji.know.streaming.km.core.service.kafkacontroller.KafkaControllerService; -import com.xiaojukeji.know.streaming.km.core.service.version.metrics.ClusterMetricVersionItems; +import com.xiaojukeji.know.streaming.km.core.service.version.metrics.kafka.ClusterMetricVersionItems; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; @Service @@ -45,38 +40,26 @@ public class MultiClusterPhyManagerImpl implements MultiClusterPhyManager { @Autowired private ClusterMetricService clusterMetricService; - @Autowired - private KafkaControllerService kafkaControllerService; - @Override public ClusterPhysState getClusterPhysState() { List clusterPhyList = clusterPhyService.listAllClusters(); + ClusterPhysState physState = new ClusterPhysState(0, 0, 0, clusterPhyList.size()); - Map controllerMap = kafkaControllerService.getKafkaControllersFromDB( - clusterPhyList.stream().map(elem -> elem.getId()).collect(Collectors.toList()), - false - ); - - // TODO 后续产品上,看是否需要增加一个未知的状态,否则新接入的集群,因为新接入的集群,数据存在延迟 - ClusterPhysState physState = new ClusterPhysState(0, 0, clusterPhyList.size()); - for (ClusterPhy clusterPhy: clusterPhyList) { - KafkaController kafkaController = controllerMap.get(clusterPhy.getId()); - - if (kafkaController != null && !kafkaController.alive()) { - // 存在明确的信息表示controller挂了 - physState.setDownCount(physState.getDownCount() + 1); - } else if ((System.currentTimeMillis() - clusterPhy.getCreateTime().getTime() >= 5 * 60 * 1000) && kafkaController == null) { - // 集群接入时间是在近5分钟内,同时kafkaController信息不存在,则设置为down + for (ClusterPhy clusterPhy : clusterPhyList) { + ClusterMetrics metrics = clusterMetricService.getLatestMetricsFromCache(clusterPhy.getId()); + Float state = metrics.getMetric(ClusterMetricVersionItems.CLUSTER_METRIC_HEALTH_STATE); + if (state == null) { + physState.setUnknownCount(physState.getUnknownCount() + 1); + } else if (state.intValue() == HealthStateEnum.DEAD.getDimension()) { physState.setDownCount(physState.getDownCount() + 1); } else { - // 其他情况都设置为alive physState.setLiveCount(physState.getLiveCount() + 1); } } - return physState; } + @Override public ClusterPhysHealthState getClusterPhysHealthState() { List clusterPhyList = clusterPhyService.listAllClusters(); @@ -111,24 +94,6 @@ public class MultiClusterPhyManagerImpl implements MultiClusterPhyManager { // 转为vo格式,方便后续进行分页筛选等 List voList = ConvertUtil.list2List(clusterPhyList, ClusterPhyDashboardVO.class); - // TODO 后续产品上,看是否需要增加一个未知的状态,否则新接入的集群,因为新接入的集群,数据存在延迟 - // 获取集群controller信息并补充到vo中, - Map controllerMap = kafkaControllerService.getKafkaControllersFromDB(clusterPhyList.stream().map(elem -> elem.getId()).collect(Collectors.toList()), false); - for (ClusterPhyDashboardVO vo: voList) { - KafkaController kafkaController = controllerMap.get(vo.getId()); - - if (kafkaController != null && !kafkaController.alive()) { - // 存在明确的信息表示controller挂了 - vo.setAlive(Constant.DOWN); - } else if ((System.currentTimeMillis() - vo.getCreateTime().getTime() >= 5 * 60L * 1000L) && kafkaController == null) { - // 集群接入时间是在近5分钟内,同时kafkaController信息不存在,则设置为down - vo.setAlive(Constant.DOWN); - } else { - // 其他情况都设置为alive - vo.setAlive(Constant.ALIVE); - } - } - // 本地分页过滤 voList = this.getAndPagingDataInLocal(voList, dto); @@ -153,6 +118,15 @@ public class MultiClusterPhyManagerImpl implements MultiClusterPhyManager { ); } + @Override + public Result> getClusterPhysBasic() { + // 获取集群 + List clusterPhyList = clusterPhyService.listAllClusters(); + + // 转为vo格式,方便后续进行分页筛选等 + return Result.buildSuc(ConvertUtil.list2List(clusterPhyList, ClusterPhyBaseVO.class)); + } + /**************************************************** private method ****************************************************/ diff --git a/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/connect/connector/ConnectorManager.java b/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/connect/connector/ConnectorManager.java new file mode 100644 index 00000000..3752504d --- /dev/null +++ b/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/connect/connector/ConnectorManager.java @@ -0,0 +1,16 @@ +package com.xiaojukeji.know.streaming.km.biz.connect.connector; + +import com.xiaojukeji.know.streaming.km.common.bean.dto.connect.connector.ConnectorCreateDTO; +import com.xiaojukeji.know.streaming.km.common.bean.entity.result.Result; +import com.xiaojukeji.know.streaming.km.common.bean.vo.connect.connector.ConnectorStateVO; + +import java.util.Properties; + +public interface ConnectorManager { + Result updateConnectorConfig(Long connectClusterId, String connectorName, Properties configs, String operator); + + Result createConnector(ConnectorCreateDTO dto, String operator); + Result createConnector(ConnectorCreateDTO dto, String heartbeatName, String checkpointName, String operator); + + Result getConnectorStateVO(Long connectClusterId, String connectorName); +} diff --git a/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/connect/connector/WorkerConnectorManager.java b/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/connect/connector/WorkerConnectorManager.java new file mode 100644 index 00000000..eaf82423 --- /dev/null +++ b/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/connect/connector/WorkerConnectorManager.java @@ -0,0 +1,16 @@ +package com.xiaojukeji.know.streaming.km.biz.connect.connector; + + +import com.xiaojukeji.know.streaming.km.common.bean.entity.result.Result; +import com.xiaojukeji.know.streaming.km.common.bean.vo.connect.task.KCTaskOverviewVO; + +import java.util.List; + +/** + * @author wyb + * @date 2022/11/14 + */ +public interface WorkerConnectorManager { + Result> getTaskOverview(Long connectClusterId, String connectorName); + +} diff --git a/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/connect/connector/impl/ConnectorManagerImpl.java b/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/connect/connector/impl/ConnectorManagerImpl.java new file mode 100644 index 00000000..5800b26f --- /dev/null +++ b/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/connect/connector/impl/ConnectorManagerImpl.java @@ -0,0 +1,115 @@ +package com.xiaojukeji.know.streaming.km.biz.connect.connector.impl; + +import com.xiaojukeji.know.streaming.km.biz.connect.connector.ConnectorManager; +import com.xiaojukeji.know.streaming.km.common.bean.dto.connect.connector.ConnectorCreateDTO; +import com.xiaojukeji.know.streaming.km.common.bean.entity.connect.WorkerConnector; +import com.xiaojukeji.know.streaming.km.common.bean.entity.connect.config.ConnectConfigInfos; +import com.xiaojukeji.know.streaming.km.common.bean.entity.connect.connector.KSConnector; +import com.xiaojukeji.know.streaming.km.common.bean.entity.connect.connector.KSConnectorInfo; +import com.xiaojukeji.know.streaming.km.common.bean.entity.result.Result; +import com.xiaojukeji.know.streaming.km.common.bean.entity.result.ResultStatus; +import com.xiaojukeji.know.streaming.km.common.bean.po.connect.ConnectorPO; +import com.xiaojukeji.know.streaming.km.common.bean.vo.connect.connector.ConnectorStateVO; +import com.xiaojukeji.know.streaming.km.common.constant.connect.KafkaConnectConstant; +import com.xiaojukeji.know.streaming.km.core.service.connect.connector.ConnectorService; +import com.xiaojukeji.know.streaming.km.core.service.connect.plugin.PluginService; +import com.xiaojukeji.know.streaming.km.core.service.connect.worker.WorkerConnectorService; +import org.apache.kafka.connect.runtime.AbstractStatus; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Properties; +import java.util.stream.Collectors; + +@Service +public class ConnectorManagerImpl implements ConnectorManager { + @Autowired + private PluginService pluginService; + + @Autowired + private ConnectorService connectorService; + + @Autowired + private WorkerConnectorService workerConnectorService; + + @Override + public Result updateConnectorConfig(Long connectClusterId, String connectorName, Properties configs, String operator) { + Result infosResult = pluginService.validateConfig(connectClusterId, configs); + if (infosResult.failed()) { + return Result.buildFromIgnoreData(infosResult); + } + + if (infosResult.getData().getErrorCount() > 0) { + return Result.buildFromRSAndMsg(ResultStatus.PARAM_ILLEGAL, "Connector参数错误"); + } + + return connectorService.updateConnectorConfig(connectClusterId, connectorName, configs, operator); + } + + @Override + public Result createConnector(ConnectorCreateDTO dto, String operator) { + dto.getConfigs().put(KafkaConnectConstant.MIRROR_MAKER_NAME_FIELD_NAME, dto.getConnectorName()); + + Result createResult = connectorService.createConnector(dto.getConnectClusterId(), dto.getConnectorName(), dto.getConfigs(), operator); + if (createResult.failed()) { + return Result.buildFromIgnoreData(createResult); + } + + Result ksConnectorResult = connectorService.getAllConnectorInfoFromCluster(dto.getConnectClusterId(), dto.getConnectorName()); + if (ksConnectorResult.failed()) { + return Result.buildFromRSAndMsg(ResultStatus.SUCCESS, "创建成功,但是获取元信息失败,页面元信息会存在1分钟延迟"); + } + + connectorService.addNewToDB(ksConnectorResult.getData()); + return Result.buildSuc(); + } + + @Override + public Result createConnector(ConnectorCreateDTO dto, String heartbeatName, String checkpointName, String operator) { + dto.getConfigs().put(KafkaConnectConstant.MIRROR_MAKER_NAME_FIELD_NAME, dto.getConnectorName()); + + Result createResult = connectorService.createConnector(dto.getConnectClusterId(), dto.getConnectorName(), dto.getConfigs(), operator); + if (createResult.failed()) { + return Result.buildFromIgnoreData(createResult); + } + + Result ksConnectorResult = connectorService.getAllConnectorInfoFromCluster(dto.getConnectClusterId(), dto.getConnectorName()); + if (ksConnectorResult.failed()) { + return Result.buildFromRSAndMsg(ResultStatus.SUCCESS, "创建成功,但是获取元信息失败,页面元信息会存在1分钟延迟"); + } + + KSConnector connector = ksConnectorResult.getData(); + connector.setCheckpointConnectorName(checkpointName); + connector.setHeartbeatConnectorName(heartbeatName); + + connectorService.addNewToDB(connector); + return Result.buildSuc(); + } + + + @Override + public Result getConnectorStateVO(Long connectClusterId, String connectorName) { + ConnectorPO connectorPO = connectorService.getConnectorFromDB(connectClusterId, connectorName); + + if (connectorPO == null) { + return Result.buildFailure(ResultStatus.NOT_EXIST); + } + + List workerConnectorList = workerConnectorService.listFromDB(connectClusterId).stream().filter(elem -> elem.getConnectorName().equals(connectorName)).collect(Collectors.toList()); + + return Result.buildSuc(convert2ConnectorOverviewVO(connectorPO, workerConnectorList)); + } + + private ConnectorStateVO convert2ConnectorOverviewVO(ConnectorPO connectorPO, List workerConnectorList) { + ConnectorStateVO connectorStateVO = new ConnectorStateVO(); + connectorStateVO.setConnectClusterId(connectorPO.getConnectClusterId()); + connectorStateVO.setName(connectorPO.getConnectorName()); + connectorStateVO.setType(connectorPO.getConnectorType()); + connectorStateVO.setState(connectorPO.getState()); + connectorStateVO.setTotalTaskCount(workerConnectorList.size()); + connectorStateVO.setAliveTaskCount(workerConnectorList.stream().filter(elem -> elem.getState().equals(AbstractStatus.State.RUNNING.name())).collect(Collectors.toList()).size()); + connectorStateVO.setTotalWorkerCount(workerConnectorList.stream().map(elem -> elem.getWorkerId()).collect(Collectors.toSet()).size()); + return connectorStateVO; + } +} diff --git a/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/connect/connector/impl/WorkerConnectorManageImpl.java b/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/connect/connector/impl/WorkerConnectorManageImpl.java new file mode 100644 index 00000000..4d0cd317 --- /dev/null +++ b/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/connect/connector/impl/WorkerConnectorManageImpl.java @@ -0,0 +1,37 @@ +package com.xiaojukeji.know.streaming.km.biz.connect.connector.impl; + +import com.didiglobal.logi.log.ILog; +import com.didiglobal.logi.log.LogFactory; +import com.xiaojukeji.know.streaming.km.biz.connect.connector.WorkerConnectorManager; +import com.xiaojukeji.know.streaming.km.common.bean.entity.connect.ConnectCluster; +import com.xiaojukeji.know.streaming.km.common.bean.entity.connect.WorkerConnector; +import com.xiaojukeji.know.streaming.km.common.bean.entity.result.Result; +import com.xiaojukeji.know.streaming.km.common.bean.vo.connect.task.KCTaskOverviewVO; +import com.xiaojukeji.know.streaming.km.common.utils.ConvertUtil; +import com.xiaojukeji.know.streaming.km.core.service.connect.worker.WorkerConnectorService; +import com.xiaojukeji.know.streaming.km.persistence.connect.cache.LoadedConnectClusterCache; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @author wyb + * @date 2022/11/14 + */ +@Service +public class WorkerConnectorManageImpl implements WorkerConnectorManager { + + private static final ILog LOGGER = LogFactory.getLog(WorkerConnectorManageImpl.class); + + @Autowired + private WorkerConnectorService workerConnectorService; + + @Override + public Result> getTaskOverview(Long connectClusterId, String connectorName) { + ConnectCluster connectCluster = LoadedConnectClusterCache.getByPhyId(connectClusterId); + List workerConnectorList = workerConnectorService.getWorkerConnectorListFromCluster(connectCluster, connectorName); + + return Result.buildSuc(ConvertUtil.list2List(workerConnectorList, KCTaskOverviewVO.class)); + } +} diff --git a/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/connect/mm2/MirrorMakerManager.java b/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/connect/mm2/MirrorMakerManager.java new file mode 100644 index 00000000..6851ca5e --- /dev/null +++ b/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/connect/mm2/MirrorMakerManager.java @@ -0,0 +1,43 @@ +package com.xiaojukeji.know.streaming.km.biz.connect.mm2; + +import com.xiaojukeji.know.streaming.km.common.bean.dto.cluster.ClusterMirrorMakersOverviewDTO; +import com.xiaojukeji.know.streaming.km.common.bean.dto.connect.mm2.MirrorMakerCreateDTO; +import com.xiaojukeji.know.streaming.km.common.bean.entity.result.PaginationResult; +import com.xiaojukeji.know.streaming.km.common.bean.entity.result.Result; +import com.xiaojukeji.know.streaming.km.common.bean.vo.cluster.mm2.ClusterMirrorMakerOverviewVO; +import com.xiaojukeji.know.streaming.km.common.bean.vo.cluster.mm2.MirrorMakerBaseStateVO; +import com.xiaojukeji.know.streaming.km.common.bean.vo.cluster.mm2.MirrorMakerStateVO; +import com.xiaojukeji.know.streaming.km.common.bean.vo.connect.plugin.ConnectConfigInfosVO; +import com.xiaojukeji.know.streaming.km.common.bean.vo.connect.task.KCTaskOverviewVO; + +import java.util.List; +import java.util.Map; +import java.util.Properties; + +/** + * @author wyb + * @date 2022/12/26 + */ +public interface MirrorMakerManager { + Result createMirrorMaker(MirrorMakerCreateDTO dto, String operator); + + Result deleteMirrorMaker(Long connectClusterId, String sourceConnectorName, String operator); + + Result modifyMirrorMakerConfig(MirrorMakerCreateDTO dto, String operator); + + Result restartMirrorMaker(Long connectClusterId, String sourceConnectorName, String operator); + Result stopMirrorMaker(Long connectClusterId, String sourceConnectorName, String operator); + Result resumeMirrorMaker(Long connectClusterId, String sourceConnectorName, String operator); + + Result getMirrorMakerStateVO(Long clusterPhyId); + + PaginationResult getClusterMirrorMakersOverview(Long clusterPhyId, ClusterMirrorMakersOverviewDTO dto); + + + Result getMirrorMakerState(Long connectId, String connectName); + + Result>> getTaskOverview(Long connectClusterId, String connectorName); + Result> getMM2Configs(Long connectClusterId, String connectorName); + + Result> validateConnectors(MirrorMakerCreateDTO dto); +} diff --git a/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/connect/mm2/impl/MirrorMakerManagerImpl.java b/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/connect/mm2/impl/MirrorMakerManagerImpl.java new file mode 100644 index 00000000..803daa26 --- /dev/null +++ b/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/connect/mm2/impl/MirrorMakerManagerImpl.java @@ -0,0 +1,652 @@ +package com.xiaojukeji.know.streaming.km.biz.connect.mm2.impl; + +import com.didiglobal.logi.log.ILog; +import com.didiglobal.logi.log.LogFactory; +import com.xiaojukeji.know.streaming.km.biz.connect.connector.ConnectorManager; +import com.xiaojukeji.know.streaming.km.biz.connect.mm2.MirrorMakerManager; +import com.xiaojukeji.know.streaming.km.common.bean.dto.cluster.ClusterMirrorMakersOverviewDTO; +import com.xiaojukeji.know.streaming.km.common.bean.dto.connect.ClusterConnectorDTO; +import com.xiaojukeji.know.streaming.km.common.bean.dto.connect.connector.ConnectorCreateDTO; +import com.xiaojukeji.know.streaming.km.common.bean.dto.connect.mm2.MirrorMakerCreateDTO; +import com.xiaojukeji.know.streaming.km.common.bean.dto.metrices.MetricDTO; +import com.xiaojukeji.know.streaming.km.common.bean.dto.metrices.mm2.MetricsMirrorMakersDTO; +import com.xiaojukeji.know.streaming.km.common.bean.entity.cluster.ClusterPhy; +import com.xiaojukeji.know.streaming.km.common.bean.entity.connect.ConnectCluster; +import com.xiaojukeji.know.streaming.km.common.bean.entity.connect.ConnectWorker; +import com.xiaojukeji.know.streaming.km.common.bean.entity.connect.WorkerConnector; +import com.xiaojukeji.know.streaming.km.common.bean.entity.connect.config.ConnectConfigInfos; +import com.xiaojukeji.know.streaming.km.common.bean.entity.connect.connector.KSConnectorInfo; +import com.xiaojukeji.know.streaming.km.common.bean.entity.metrics.mm2.MirrorMakerMetrics; +import com.xiaojukeji.know.streaming.km.common.bean.entity.result.PaginationResult; +import com.xiaojukeji.know.streaming.km.common.bean.entity.result.Result; +import com.xiaojukeji.know.streaming.km.common.bean.entity.result.ResultStatus; +import com.xiaojukeji.know.streaming.km.common.bean.po.connect.ConnectorPO; +import com.xiaojukeji.know.streaming.km.common.bean.vo.cluster.mm2.ClusterMirrorMakerOverviewVO; +import com.xiaojukeji.know.streaming.km.common.bean.vo.cluster.mm2.MirrorMakerBaseStateVO; +import com.xiaojukeji.know.streaming.km.common.bean.vo.cluster.mm2.MirrorMakerStateVO; +import com.xiaojukeji.know.streaming.km.common.bean.vo.connect.plugin.ConnectConfigInfosVO; +import com.xiaojukeji.know.streaming.km.common.bean.vo.metrics.line.MetricLineVO; +import com.xiaojukeji.know.streaming.km.common.bean.vo.metrics.line.MetricMultiLinesVO; +import com.xiaojukeji.know.streaming.km.common.bean.vo.connect.task.KCTaskOverviewVO; +import com.xiaojukeji.know.streaming.km.common.constant.MsgConstant; +import com.xiaojukeji.know.streaming.km.common.utils.*; +import com.xiaojukeji.know.streaming.km.common.constant.connect.KafkaConnectConstant; +import com.xiaojukeji.know.streaming.km.common.utils.ConvertUtil; +import com.xiaojukeji.know.streaming.km.common.utils.MirrorMakerUtil; +import com.xiaojukeji.know.streaming.km.common.utils.ValidateUtils; +import com.xiaojukeji.know.streaming.km.core.service.cluster.ClusterPhyService; +import com.xiaojukeji.know.streaming.km.core.service.connect.cluster.ConnectClusterService; +import com.xiaojukeji.know.streaming.km.core.service.connect.connector.ConnectorService; +import com.xiaojukeji.know.streaming.km.core.service.connect.mm2.MirrorMakerMetricService; +import com.xiaojukeji.know.streaming.km.core.service.connect.plugin.PluginService; +import com.xiaojukeji.know.streaming.km.core.service.connect.worker.WorkerConnectorService; +import com.xiaojukeji.know.streaming.km.core.service.connect.worker.WorkerService; +import com.xiaojukeji.know.streaming.km.core.utils.ApiCallThreadPoolService; +import com.xiaojukeji.know.streaming.km.persistence.cache.LoadedClusterPhyCache; +import org.apache.commons.lang.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +import static org.apache.kafka.connect.runtime.AbstractStatus.State.RUNNING; +import static com.xiaojukeji.know.streaming.km.common.constant.connect.KafkaConnectConstant.*; + + +/** + * @author wyb + * @date 2022/12/26 + */ +@Service +public class MirrorMakerManagerImpl implements MirrorMakerManager { + private static final ILog LOGGER = LogFactory.getLog(MirrorMakerManagerImpl.class); + + @Autowired + private ConnectorService connectorService; + + @Autowired + private WorkerConnectorService workerConnectorService; + + @Autowired + private WorkerService workerService; + + @Autowired + private ConnectorManager connectorManager; + + @Autowired + private ClusterPhyService clusterPhyService; + + @Autowired + private MirrorMakerMetricService mirrorMakerMetricService; + + @Autowired + private ConnectClusterService connectClusterService; + + @Autowired + private PluginService pluginService; + + @Override + public Result createMirrorMaker(MirrorMakerCreateDTO dto, String operator) { + // 检查基本参数 + Result rv = this.checkCreateMirrorMakerParamAndUnifyData(dto); + if (rv.failed()) { + return rv; + } + + // 创建MirrorSourceConnector + Result sourceConnectResult = connectorManager.createConnector( + dto, + dto.getCheckpointConnectorConfigs() != null? MirrorMakerUtil.genCheckpointName(dto.getConnectorName()): "", + dto.getHeartbeatConnectorConfigs() != null? MirrorMakerUtil.genHeartbeatName(dto.getConnectorName()): "", + operator + ); + if (sourceConnectResult.failed()) { + // 创建失败, 直接返回 + return Result.buildFromIgnoreData(sourceConnectResult); + } + + // 创建 checkpoint 任务 + Result checkpointResult = Result.buildSuc(); + if (dto.getCheckpointConnectorConfigs() != null) { + checkpointResult = connectorManager.createConnector( + new ConnectorCreateDTO(dto.getConnectClusterId(), MirrorMakerUtil.genCheckpointName(dto.getConnectorName()), dto.getCheckpointConnectorConfigs()), + operator + ); + } + + // 创建 heartbeat 任务 + Result heartbeatResult = Result.buildSuc(); + if (dto.getHeartbeatConnectorConfigs() != null) { + heartbeatResult = connectorManager.createConnector( + new ConnectorCreateDTO(dto.getConnectClusterId(), MirrorMakerUtil.genHeartbeatName(dto.getConnectorName()), dto.getHeartbeatConnectorConfigs()), + operator + ); + } + + // 全都成功 + if (checkpointResult.successful() && checkpointResult.successful()) { + return Result.buildSuc(); + } else if (checkpointResult.failed() && checkpointResult.failed()) { + return Result.buildFromRSAndMsg( + ResultStatus.KAFKA_CONNECTOR_OPERATE_FAILED, + String.format("创建 checkpoint & heartbeat 失败.\n失败信息分别为:%s\n\n%s", checkpointResult.getMessage(), heartbeatResult.getMessage()) + ); + } else if (checkpointResult.failed()) { + return Result.buildFromRSAndMsg( + ResultStatus.KAFKA_CONNECTOR_OPERATE_FAILED, + String.format("创建 checkpoint 失败.\n失败信息分别为:%s", checkpointResult.getMessage()) + ); + } else{ + return Result.buildFromRSAndMsg( + ResultStatus.KAFKA_CONNECTOR_OPERATE_FAILED, + String.format("创建 heartbeat 失败.\n失败信息分别为:%s", heartbeatResult.getMessage()) + ); + } + } + + @Override + public Result deleteMirrorMaker(Long connectClusterId, String sourceConnectorName, String operator) { + ConnectorPO connectorPO = connectorService.getConnectorFromDB(connectClusterId, sourceConnectorName); + if (connectorPO == null) { + return Result.buildFromRSAndMsg(ResultStatus.NOT_EXIST, MsgConstant.getConnectorNotExist(connectClusterId, sourceConnectorName)); + } + + Result rv = Result.buildSuc(); + if (!ValidateUtils.isBlank(connectorPO.getCheckpointConnectorName())) { + rv = connectorService.deleteConnector(connectClusterId, connectorPO.getCheckpointConnectorName(), operator); + } + if (rv.failed()) { + return rv; + } + + if (!ValidateUtils.isBlank(connectorPO.getHeartbeatConnectorName())) { + rv = connectorService.deleteConnector(connectClusterId, connectorPO.getHeartbeatConnectorName(), operator); + } + if (rv.failed()) { + return rv; + } + + return connectorService.deleteConnector(connectClusterId, sourceConnectorName, operator); + } + + @Override + public Result modifyMirrorMakerConfig(MirrorMakerCreateDTO dto, String operator) { + ConnectorPO connectorPO = connectorService.getConnectorFromDB(dto.getConnectClusterId(), dto.getConnectorName()); + if (connectorPO == null) { + return Result.buildFromRSAndMsg(ResultStatus.NOT_EXIST, MsgConstant.getConnectorNotExist(dto.getConnectClusterId(), dto.getConnectorName())); + } + + Result rv = Result.buildSuc(); + if (!ValidateUtils.isBlank(connectorPO.getCheckpointConnectorName()) && dto.getCheckpointConnectorConfigs() != null) { + rv = connectorService.updateConnectorConfig(dto.getConnectClusterId(), connectorPO.getCheckpointConnectorName(), dto.getCheckpointConnectorConfigs(), operator); + } + if (rv.failed()) { + return rv; + } + + if (!ValidateUtils.isBlank(connectorPO.getHeartbeatConnectorName()) && dto.getHeartbeatConnectorConfigs() != null) { + rv = connectorService.updateConnectorConfig(dto.getConnectClusterId(), connectorPO.getHeartbeatConnectorName(), dto.getHeartbeatConnectorConfigs(), operator); + } + if (rv.failed()) { + return rv; + } + + return connectorService.updateConnectorConfig(dto.getConnectClusterId(), dto.getConnectorName(), dto.getConfigs(), operator); + } + + @Override + public Result restartMirrorMaker(Long connectClusterId, String sourceConnectorName, String operator) { + ConnectorPO connectorPO = connectorService.getConnectorFromDB(connectClusterId, sourceConnectorName); + if (connectorPO == null) { + return Result.buildFromRSAndMsg(ResultStatus.NOT_EXIST, MsgConstant.getConnectorNotExist(connectClusterId, sourceConnectorName)); + } + + Result rv = Result.buildSuc(); + if (!ValidateUtils.isBlank(connectorPO.getCheckpointConnectorName())) { + rv = connectorService.restartConnector(connectClusterId, connectorPO.getCheckpointConnectorName(), operator); + } + if (rv.failed()) { + return rv; + } + + if (!ValidateUtils.isBlank(connectorPO.getHeartbeatConnectorName())) { + rv = connectorService.restartConnector(connectClusterId, connectorPO.getHeartbeatConnectorName(), operator); + } + if (rv.failed()) { + return rv; + } + + return connectorService.restartConnector(connectClusterId, sourceConnectorName, operator); + } + + @Override + public Result stopMirrorMaker(Long connectClusterId, String sourceConnectorName, String operator) { + ConnectorPO connectorPO = connectorService.getConnectorFromDB(connectClusterId, sourceConnectorName); + if (connectorPO == null) { + return Result.buildFromRSAndMsg(ResultStatus.NOT_EXIST, MsgConstant.getConnectorNotExist(connectClusterId, sourceConnectorName)); + } + + Result rv = Result.buildSuc(); + if (!ValidateUtils.isBlank(connectorPO.getCheckpointConnectorName())) { + rv = connectorService.stopConnector(connectClusterId, connectorPO.getCheckpointConnectorName(), operator); + } + if (rv.failed()) { + return rv; + } + + if (!ValidateUtils.isBlank(connectorPO.getHeartbeatConnectorName())) { + rv = connectorService.stopConnector(connectClusterId, connectorPO.getHeartbeatConnectorName(), operator); + } + if (rv.failed()) { + return rv; + } + + return connectorService.stopConnector(connectClusterId, sourceConnectorName, operator); + } + + @Override + public Result resumeMirrorMaker(Long connectClusterId, String sourceConnectorName, String operator) { + ConnectorPO connectorPO = connectorService.getConnectorFromDB(connectClusterId, sourceConnectorName); + if (connectorPO == null) { + return Result.buildFromRSAndMsg(ResultStatus.NOT_EXIST, MsgConstant.getConnectorNotExist(connectClusterId, sourceConnectorName)); + } + + Result rv = Result.buildSuc(); + if (!ValidateUtils.isBlank(connectorPO.getCheckpointConnectorName())) { + rv = connectorService.resumeConnector(connectClusterId, connectorPO.getCheckpointConnectorName(), operator); + } + if (rv.failed()) { + return rv; + } + + if (!ValidateUtils.isBlank(connectorPO.getHeartbeatConnectorName())) { + rv = connectorService.resumeConnector(connectClusterId, connectorPO.getHeartbeatConnectorName(), operator); + } + if (rv.failed()) { + return rv; + } + + return connectorService.resumeConnector(connectClusterId, sourceConnectorName, operator); + } + + @Override + public Result getMirrorMakerStateVO(Long clusterPhyId) { + List connectorPOList = connectorService.listByKafkaClusterIdFromDB(clusterPhyId); + List workerConnectorList = workerConnectorService.listByKafkaClusterIdFromDB(clusterPhyId); + List workerList = workerService.listByKafkaClusterIdFromDB(clusterPhyId); + + return Result.buildSuc(convert2MirrorMakerStateVO(connectorPOList, workerConnectorList, workerList)); + } + + @Override + public PaginationResult getClusterMirrorMakersOverview(Long clusterPhyId, ClusterMirrorMakersOverviewDTO dto) { + List mirrorMakerList = connectorService.listByKafkaClusterIdFromDB(clusterPhyId).stream().filter(elem -> elem.getConnectorClassName().equals(MIRROR_MAKER_SOURCE_CONNECTOR_TYPE)).collect(Collectors.toList()); + List connectClusterList = connectClusterService.listByKafkaCluster(clusterPhyId); + + + Result> latestMetricsResult = mirrorMakerMetricService.getLatestMetricsFromES(clusterPhyId, + mirrorMakerList.stream().map(elem -> new Tuple<>(elem.getConnectClusterId(), elem.getConnectorName())).collect(Collectors.toList()), + dto.getLatestMetricNames()); + + if (latestMetricsResult.failed()) { + LOGGER.error("method=getClusterMirrorMakersOverview||clusterPhyId={}||result={}||errMsg=get latest metric failed", clusterPhyId, latestMetricsResult); + return PaginationResult.buildFailure(latestMetricsResult, dto); + } + + List mirrorMakerOverviewVOList = this.convert2ClusterMirrorMakerOverviewVO(mirrorMakerList, connectClusterList, latestMetricsResult.getData()); + + List mirrorMakerVOList = this.completeClusterInfo(mirrorMakerOverviewVOList); + + PaginationResult voPaginationResult = this.pagingMirrorMakerInLocal(mirrorMakerVOList, dto); + + if (voPaginationResult.failed()) { + LOGGER.error("method=ClusterMirrorMakerOverviewVO||clusterPhyId={}||result={}||errMsg=pagination in local failed", clusterPhyId, voPaginationResult); + + return PaginationResult.buildFailure(voPaginationResult, dto); + } + + // 查询历史指标 + Result> lineMetricsResult = mirrorMakerMetricService.listMirrorMakerClusterMetricsFromES( + clusterPhyId, + this.buildMetricsConnectorsDTO( + voPaginationResult.getData().getBizData().stream().map(elem -> new ClusterConnectorDTO(elem.getConnectClusterId(), elem.getConnectorName())).collect(Collectors.toList()), + dto.getMetricLines() + )); + + return PaginationResult.buildSuc( + this.supplyData2ClusterMirrorMakerOverviewVOList( + voPaginationResult.getData().getBizData(), + lineMetricsResult.getData() + ), + voPaginationResult + ); + } + + @Override + public Result getMirrorMakerState(Long connectClusterId, String connectName) { + //mm2任务 + ConnectorPO connectorPO = connectorService.getConnectorFromDB(connectClusterId, connectName); + if (connectorPO == null){ + return Result.buildFrom(ResultStatus.NOT_EXIST); + } + + List workerConnectorList = workerConnectorService.listFromDB(connectClusterId).stream() + .filter(workerConnector -> workerConnector.getConnectorName().equals(connectorPO.getConnectorName()) + || (!StringUtils.isBlank(connectorPO.getCheckpointConnectorName()) && workerConnector.getConnectorName().equals(connectorPO.getCheckpointConnectorName())) + || (!StringUtils.isBlank(connectorPO.getHeartbeatConnectorName()) && workerConnector.getConnectorName().equals(connectorPO.getHeartbeatConnectorName()))) + .collect(Collectors.toList()); + + MirrorMakerBaseStateVO mirrorMakerBaseStateVO = new MirrorMakerBaseStateVO(); + mirrorMakerBaseStateVO.setTotalTaskCount(workerConnectorList.size()); + mirrorMakerBaseStateVO.setAliveTaskCount(workerConnectorList.stream().filter(elem -> elem.getState().equals(RUNNING.name())).collect(Collectors.toList()).size()); + mirrorMakerBaseStateVO.setWorkerCount(workerConnectorList.stream().collect(Collectors.groupingBy(WorkerConnector::getWorkerId)).size()); + return Result.buildSuc(mirrorMakerBaseStateVO); + } + + @Override + public Result>> getTaskOverview(Long connectClusterId, String connectorName) { + ConnectorPO connectorPO = connectorService.getConnectorFromDB(connectClusterId, connectorName); + if (connectorPO == null){ + return Result.buildFrom(ResultStatus.NOT_EXIST); + } + + Map> listMap = new HashMap<>(); + List workerConnectorList = workerConnectorService.listFromDB(connectClusterId); + if (workerConnectorList.isEmpty()){ + return Result.buildSuc(listMap); + } + workerConnectorList.forEach(workerConnector -> { + if (workerConnector.getConnectorName().equals(connectorPO.getConnectorName())){ + listMap.putIfAbsent(KafkaConnectConstant.MIRROR_MAKER_SOURCE_CONNECTOR_TYPE, new ArrayList<>()); + listMap.get(MIRROR_MAKER_SOURCE_CONNECTOR_TYPE).add(ConvertUtil.obj2Obj(workerConnector, KCTaskOverviewVO.class)); + } else if (workerConnector.getConnectorName().equals(connectorPO.getCheckpointConnectorName())) { + listMap.putIfAbsent(KafkaConnectConstant.MIRROR_MAKER_HEARTBEAT_CONNECTOR_TYPE, new ArrayList<>()); + listMap.get(MIRROR_MAKER_HEARTBEAT_CONNECTOR_TYPE).add(ConvertUtil.obj2Obj(workerConnector, KCTaskOverviewVO.class)); + } else if (workerConnector.getConnectorName().equals(connectorPO.getHeartbeatConnectorName())) { + listMap.putIfAbsent(KafkaConnectConstant.MIRROR_MAKER_CHECKPOINT_CONNECTOR_TYPE, new ArrayList<>()); + listMap.get(MIRROR_MAKER_CHECKPOINT_CONNECTOR_TYPE).add(ConvertUtil.obj2Obj(workerConnector, KCTaskOverviewVO.class)); + } + + }); + + return Result.buildSuc(listMap); + } + + @Override + public Result> getMM2Configs(Long connectClusterId, String connectorName) { + ConnectorPO connectorPO = connectorService.getConnectorFromDB(connectClusterId, connectorName); + if (connectorPO == null){ + return Result.buildFrom(ResultStatus.NOT_EXIST); + } + + List propList = new ArrayList<>(); + + // source + Result connectorResult = connectorService.getConnectorInfoFromCluster(connectClusterId, connectorPO.getConnectorName()); + if (connectorResult.failed()) { + return Result.buildFromIgnoreData(connectorResult); + } + + Properties props = new Properties(); + props.putAll(connectorResult.getData().getConfig()); + propList.add(props); + + // checkpoint + if (!ValidateUtils.isBlank(connectorPO.getCheckpointConnectorName())) { + connectorResult = connectorService.getConnectorInfoFromCluster(connectClusterId, connectorPO.getCheckpointConnectorName()); + if (connectorResult.failed()) { + return Result.buildFromIgnoreData(connectorResult); + } + + props = new Properties(); + props.putAll(connectorResult.getData().getConfig()); + propList.add(props); + } + + + // heartbeat + if (!ValidateUtils.isBlank(connectorPO.getHeartbeatConnectorName())) { + connectorResult = connectorService.getConnectorInfoFromCluster(connectClusterId, connectorPO.getHeartbeatConnectorName()); + if (connectorResult.failed()) { + return Result.buildFromIgnoreData(connectorResult); + } + + props = new Properties(); + props.putAll(connectorResult.getData().getConfig()); + propList.add(props); + } + + return Result.buildSuc(propList); + } + + @Override + public Result> validateConnectors(MirrorMakerCreateDTO dto) { + List voList = new ArrayList<>(); + + Result infoResult = pluginService.validateConfig(dto.getConnectClusterId(), dto.getConfigs()); + if (infoResult.failed()) { + return Result.buildFromIgnoreData(infoResult); + } + + voList.add(ConvertUtil.obj2Obj(infoResult.getData(), ConnectConfigInfosVO.class)); + + if (dto.getHeartbeatConnectorConfigs() != null) { + infoResult = pluginService.validateConfig(dto.getConnectClusterId(), dto.getHeartbeatConnectorConfigs()); + if (infoResult.failed()) { + return Result.buildFromIgnoreData(infoResult); + } + + voList.add(ConvertUtil.obj2Obj(infoResult.getData(), ConnectConfigInfosVO.class)); + } + + if (dto.getCheckpointConnectorConfigs() != null) { + infoResult = pluginService.validateConfig(dto.getConnectClusterId(), dto.getCheckpointConnectorConfigs()); + if (infoResult.failed()) { + return Result.buildFromIgnoreData(infoResult); + } + + voList.add(ConvertUtil.obj2Obj(infoResult.getData(), ConnectConfigInfosVO.class)); + } + + return Result.buildSuc(voList); + } + + + /**************************************************** private method ****************************************************/ + + private MetricsMirrorMakersDTO buildMetricsConnectorsDTO(List connectorDTOList, MetricDTO metricDTO) { + MetricsMirrorMakersDTO dto = ConvertUtil.obj2Obj(metricDTO, MetricsMirrorMakersDTO.class); + dto.setConnectorNameList(connectorDTOList == null? new ArrayList<>(): connectorDTOList); + + return dto; + } + + public Result checkCreateMirrorMakerParamAndUnifyData(MirrorMakerCreateDTO dto) { + ClusterPhy sourceClusterPhy = clusterPhyService.getClusterByCluster(dto.getSourceKafkaClusterId()); + if (sourceClusterPhy == null) { + return Result.buildFromRSAndMsg(ResultStatus.CLUSTER_NOT_EXIST, MsgConstant.getClusterPhyNotExist(dto.getSourceKafkaClusterId())); + } + + ConnectCluster connectCluster = connectClusterService.getById(dto.getConnectClusterId()); + if (connectCluster == null) { + return Result.buildFromRSAndMsg(ResultStatus.CLUSTER_NOT_EXIST, MsgConstant.getConnectClusterNotExist(dto.getConnectClusterId())); + } + + ClusterPhy targetClusterPhy = clusterPhyService.getClusterByCluster(connectCluster.getKafkaClusterPhyId()); + if (targetClusterPhy == null) { + return Result.buildFromRSAndMsg(ResultStatus.CLUSTER_NOT_EXIST, MsgConstant.getClusterPhyNotExist(connectCluster.getKafkaClusterPhyId())); + } + + if (!dto.getConfigs().containsKey(CONNECTOR_CLASS_FILED_NAME)) { + return Result.buildFromRSAndMsg(ResultStatus.PARAM_ILLEGAL, "SourceConnector缺少connector.class"); + } + + if (!MIRROR_MAKER_SOURCE_CONNECTOR_TYPE.equals(dto.getConfigs().getProperty(CONNECTOR_CLASS_FILED_NAME))) { + return Result.buildFromRSAndMsg(ResultStatus.PARAM_ILLEGAL, "SourceConnector的connector.class类型错误"); + } + + if (dto.getCheckpointConnectorConfigs() != null) { + if (!dto.getCheckpointConnectorConfigs().containsKey(CONNECTOR_CLASS_FILED_NAME)) { + return Result.buildFromRSAndMsg(ResultStatus.PARAM_ILLEGAL, "CheckpointConnector缺少connector.class"); + } + + if (!MIRROR_MAKER_CHECKPOINT_CONNECTOR_TYPE.equals(dto.getCheckpointConnectorConfigs().getProperty(CONNECTOR_CLASS_FILED_NAME))) { + return Result.buildFromRSAndMsg(ResultStatus.PARAM_ILLEGAL, "Checkpoint的connector.class类型错误"); + } + } + + if (dto.getHeartbeatConnectorConfigs() != null) { + if (!dto.getHeartbeatConnectorConfigs().containsKey(CONNECTOR_CLASS_FILED_NAME)) { + return Result.buildFromRSAndMsg(ResultStatus.PARAM_ILLEGAL, "HeartbeatConnector缺少connector.class"); + } + + if (!MIRROR_MAKER_HEARTBEAT_CONNECTOR_TYPE.equals(dto.getHeartbeatConnectorConfigs().getProperty(CONNECTOR_CLASS_FILED_NAME))) { + return Result.buildFromRSAndMsg(ResultStatus.PARAM_ILLEGAL, "Heartbeat的connector.class类型错误"); + } + } + + dto.unifyData( + sourceClusterPhy.getId(), sourceClusterPhy.getBootstrapServers(), ConvertUtil.str2ObjByJson(sourceClusterPhy.getClientProperties(), Properties.class), + targetClusterPhy.getId(), targetClusterPhy.getBootstrapServers(), ConvertUtil.str2ObjByJson(targetClusterPhy.getClientProperties(), Properties.class) + ); + + return Result.buildSuc(); + } + + private MirrorMakerStateVO convert2MirrorMakerStateVO(List connectorPOList,List workerConnectorList,List workerList){ + MirrorMakerStateVO mirrorMakerStateVO = new MirrorMakerStateVO(); + + List sourceSet = connectorPOList.stream().filter(elem -> elem.getConnectorClassName().equals(MIRROR_MAKER_SOURCE_CONNECTOR_TYPE)).collect(Collectors.toList()); + mirrorMakerStateVO.setMirrorMakerCount(sourceSet.size()); + + Set connectClusterIdSet = sourceSet.stream().map(ConnectorPO::getConnectClusterId).collect(Collectors.toSet()); + mirrorMakerStateVO.setWorkerCount(workerList.stream().filter(elem -> connectClusterIdSet.contains(elem.getConnectClusterId())).collect(Collectors.toList()).size()); + + List mirrorMakerConnectorList = new ArrayList<>(); + mirrorMakerConnectorList.addAll(sourceSet); + mirrorMakerConnectorList.addAll(connectorPOList.stream().filter(elem -> elem.getConnectorClassName().equals(MIRROR_MAKER_CHECKPOINT_CONNECTOR_TYPE)).collect(Collectors.toList())); + mirrorMakerConnectorList.addAll(connectorPOList.stream().filter(elem -> elem.getConnectorClassName().equals(MIRROR_MAKER_HEARTBEAT_CONNECTOR_TYPE)).collect(Collectors.toList())); + mirrorMakerStateVO.setTotalConnectorCount(mirrorMakerConnectorList.size()); + mirrorMakerStateVO.setAliveConnectorCount(mirrorMakerConnectorList.stream().filter(elem -> elem.getState().equals(RUNNING.name())).collect(Collectors.toList()).size()); + + Set connectorNameSet = mirrorMakerConnectorList.stream().map(elem -> elem.getConnectorName()).collect(Collectors.toSet()); + List taskList = workerConnectorList.stream().filter(elem -> connectorNameSet.contains(elem.getConnectorName())).collect(Collectors.toList()); + mirrorMakerStateVO.setTotalTaskCount(taskList.size()); + mirrorMakerStateVO.setAliveTaskCount(taskList.stream().filter(elem -> elem.getState().equals(RUNNING.name())).collect(Collectors.toList()).size()); + + return mirrorMakerStateVO; + } + + private List convert2ClusterMirrorMakerOverviewVO(List mirrorMakerList, List connectClusterList, List latestMetric) { + List clusterMirrorMakerOverviewVOList = new ArrayList<>(); + Map metricsMap = latestMetric.stream().collect(Collectors.toMap(elem -> elem.getConnectClusterId() + "@" + elem.getConnectorName(), Function.identity())); + Map connectClusterMap = connectClusterList.stream().collect(Collectors.toMap(elem -> elem.getId(), Function.identity())); + + for (ConnectorPO mirrorMaker : mirrorMakerList) { + ClusterMirrorMakerOverviewVO clusterMirrorMakerOverviewVO = new ClusterMirrorMakerOverviewVO(); + clusterMirrorMakerOverviewVO.setConnectClusterId(mirrorMaker.getConnectClusterId()); + clusterMirrorMakerOverviewVO.setConnectClusterName(connectClusterMap.get(mirrorMaker.getConnectClusterId()).getName()); + clusterMirrorMakerOverviewVO.setConnectorName(mirrorMaker.getConnectorName()); + clusterMirrorMakerOverviewVO.setState(mirrorMaker.getState()); + clusterMirrorMakerOverviewVO.setCheckpointConnector(mirrorMaker.getCheckpointConnectorName()); + clusterMirrorMakerOverviewVO.setTaskCount(mirrorMaker.getTaskCount()); + clusterMirrorMakerOverviewVO.setHeartbeatConnector(mirrorMaker.getHeartbeatConnectorName()); + clusterMirrorMakerOverviewVO.setLatestMetrics(metricsMap.getOrDefault(mirrorMaker.getConnectClusterId() + "@" + mirrorMaker.getConnectorName(), new MirrorMakerMetrics(mirrorMaker.getConnectClusterId(), mirrorMaker.getConnectorName()))); + clusterMirrorMakerOverviewVOList.add(clusterMirrorMakerOverviewVO); + } + return clusterMirrorMakerOverviewVOList; + } + + PaginationResult pagingMirrorMakerInLocal(List mirrorMakerOverviewVOList, ClusterMirrorMakersOverviewDTO dto) { + List mirrorMakerVOList = PaginationUtil.pageByFuzzyFilter(mirrorMakerOverviewVOList, dto.getSearchKeywords(), Arrays.asList("connectorName")); + + //排序 + if (!dto.getLatestMetricNames().isEmpty()) { + PaginationMetricsUtil.sortMetrics(mirrorMakerVOList, "latestMetrics", dto.getSortMetricNameList(), "connectorName", dto.getSortType()); + } else { + PaginationUtil.pageBySort(mirrorMakerVOList, dto.getSortField(), dto.getSortType(), "connectorName", dto.getSortType()); + } + + //分页 + return PaginationUtil.pageBySubData(mirrorMakerVOList, dto); + } + + public static List supplyData2ClusterMirrorMakerOverviewVOList(List voList, + List metricLineVOList) { + Map> metricLineMap = new HashMap<>(); + if (metricLineVOList != null) { + for (MetricMultiLinesVO metricMultiLinesVO : metricLineVOList) { + metricMultiLinesVO.getMetricLines() + .forEach(metricLineVO -> { + String key = metricLineVO.getName(); + List metricLineVOS = metricLineMap.getOrDefault(key, new ArrayList<>()); + metricLineVOS.add(metricLineVO); + metricLineMap.put(key, metricLineVOS); + }); + } + } + + voList.forEach(elem -> { + elem.setMetricLines(metricLineMap.get(elem.getConnectClusterId() + "#" + elem.getConnectorName())); + }); + + return voList; + } + + private List completeClusterInfo(List mirrorMakerVOList) { + + Map connectorInfoMap = new HashMap<>(); + + for (ClusterMirrorMakerOverviewVO mirrorMakerVO : mirrorMakerVOList) { + ApiCallThreadPoolService.runnableTask(String.format("method=completeClusterInfo||connectClusterId=%d||connectorName=%s||getMirrorMakerInfo", mirrorMakerVO.getConnectClusterId(), mirrorMakerVO.getConnectorName()), + 3000 + , () -> { + Result connectorInfoRet = connectorService.getConnectorInfoFromCluster(mirrorMakerVO.getConnectClusterId(), mirrorMakerVO.getConnectorName()); + if (connectorInfoRet.hasData()) { + connectorInfoMap.put(mirrorMakerVO.getConnectClusterId() + mirrorMakerVO.getConnectorName(), connectorInfoRet.getData()); + } + + return connectorInfoRet.getData(); + }); + } + + ApiCallThreadPoolService.waitResult(1000); + + List newMirrorMakerVOList = new ArrayList<>(); + for (ClusterMirrorMakerOverviewVO mirrorMakerVO : mirrorMakerVOList) { + KSConnectorInfo connectorInfo = connectorInfoMap.get(mirrorMakerVO.getConnectClusterId() + mirrorMakerVO.getConnectorName()); + if (connectorInfo == null) { + continue; + } + + String sourceClusterAlias = connectorInfo.getConfig().get(MIRROR_MAKER_SOURCE_CLUSTER_ALIAS_FIELD_NAME); + String targetClusterAlias = connectorInfo.getConfig().get(MIRROR_MAKER_TARGET_CLUSTER_ALIAS_FIELD_NAME); + //先默认设置为集群别名 + mirrorMakerVO.setSourceKafkaClusterName(sourceClusterAlias); + mirrorMakerVO.setDestKafkaClusterName(targetClusterAlias); + + if (!ValidateUtils.isBlank(sourceClusterAlias) && CommonUtils.isNumeric(sourceClusterAlias)) { + ClusterPhy clusterPhy = LoadedClusterPhyCache.getByPhyId(Long.valueOf(sourceClusterAlias)); + if (clusterPhy != null) { + mirrorMakerVO.setSourceKafkaClusterId(clusterPhy.getId()); + mirrorMakerVO.setSourceKafkaClusterName(clusterPhy.getName()); + } + } + + if (!ValidateUtils.isBlank(targetClusterAlias) && CommonUtils.isNumeric(targetClusterAlias)) { + ClusterPhy clusterPhy = LoadedClusterPhyCache.getByPhyId(Long.valueOf(targetClusterAlias)); + if (clusterPhy != null) { + mirrorMakerVO.setDestKafkaClusterId(clusterPhy.getId()); + mirrorMakerVO.setDestKafkaClusterName(clusterPhy.getName()); + } + } + + newMirrorMakerVOList.add(mirrorMakerVO); + + } + + return newMirrorMakerVOList; + } +} diff --git a/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/group/GroupManager.java b/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/group/GroupManager.java index a3686c03..5a6d3ac6 100644 --- a/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/group/GroupManager.java +++ b/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/group/GroupManager.java @@ -39,5 +39,5 @@ public interface GroupManager { Result resetGroupOffsets(GroupOffsetResetDTO dto, String operator) throws Exception; - List getGroupTopicOverviewVOList (Long clusterPhyId, List groupMemberPOList); + List getGroupTopicOverviewVOList(Long clusterPhyId, List groupMemberPOList); } diff --git a/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/group/impl/GroupManagerImpl.java b/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/group/impl/GroupManagerImpl.java index 77095cc0..17216793 100644 --- a/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/group/impl/GroupManagerImpl.java +++ b/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/group/impl/GroupManagerImpl.java @@ -8,10 +8,15 @@ import com.xiaojukeji.know.streaming.km.common.bean.dto.group.GroupOffsetResetDT import com.xiaojukeji.know.streaming.km.common.bean.dto.pagination.PaginationBaseDTO; import com.xiaojukeji.know.streaming.km.common.bean.dto.pagination.PaginationSortDTO; import com.xiaojukeji.know.streaming.km.common.bean.dto.partition.PartitionOffsetDTO; +import com.xiaojukeji.know.streaming.km.common.bean.entity.cluster.ClusterPhy; import com.xiaojukeji.know.streaming.km.common.bean.entity.group.Group; import com.xiaojukeji.know.streaming.km.common.bean.entity.group.GroupTopic; import com.xiaojukeji.know.streaming.km.common.bean.entity.group.GroupTopicMember; +import com.xiaojukeji.know.streaming.km.common.bean.entity.kafka.KSGroupDescription; +import com.xiaojukeji.know.streaming.km.common.bean.entity.kafka.KSMemberConsumerAssignment; +import com.xiaojukeji.know.streaming.km.common.bean.entity.kafka.KSMemberDescription; import com.xiaojukeji.know.streaming.km.common.bean.entity.metrics.GroupMetrics; +import com.xiaojukeji.know.streaming.km.common.bean.entity.offset.KSOffsetSpec; import com.xiaojukeji.know.streaming.km.common.bean.entity.result.PaginationResult; import com.xiaojukeji.know.streaming.km.common.bean.entity.result.Result; import com.xiaojukeji.know.streaming.km.common.bean.entity.topic.Topic; @@ -34,15 +39,13 @@ import com.xiaojukeji.know.streaming.km.common.utils.ConvertUtil; import com.xiaojukeji.know.streaming.km.common.utils.PaginationMetricsUtil; import com.xiaojukeji.know.streaming.km.common.utils.PaginationUtil; import com.xiaojukeji.know.streaming.km.common.utils.ValidateUtils; +import com.xiaojukeji.know.streaming.km.core.service.cluster.ClusterPhyService; import com.xiaojukeji.know.streaming.km.core.service.group.GroupMetricService; import com.xiaojukeji.know.streaming.km.core.service.group.GroupService; import com.xiaojukeji.know.streaming.km.core.service.partition.PartitionService; import com.xiaojukeji.know.streaming.km.core.service.topic.TopicService; -import com.xiaojukeji.know.streaming.km.core.service.version.metrics.GroupMetricVersionItems; +import com.xiaojukeji.know.streaming.km.core.service.version.metrics.kafka.GroupMetricVersionItems; import com.xiaojukeji.know.streaming.km.persistence.es.dao.GroupMetricESDAO; -import org.apache.kafka.clients.admin.ConsumerGroupDescription; -import org.apache.kafka.clients.admin.MemberDescription; -import org.apache.kafka.clients.admin.OffsetSpec; import org.apache.kafka.common.ConsumerGroupState; import org.apache.kafka.common.TopicPartition; import org.springframework.beans.factory.annotation.Autowired; @@ -51,6 +54,8 @@ import org.springframework.stereotype.Component; import java.util.*; import java.util.stream.Collectors; +import static com.xiaojukeji.know.streaming.km.common.enums.group.GroupTypeEnum.CONNECT_CLUSTER_PROTOCOL_TYPE; + @Component public class GroupManagerImpl implements GroupManager { private static final ILog log = LogFactory.getLog(GroupManagerImpl.class); @@ -70,6 +75,9 @@ public class GroupManagerImpl implements GroupManager { @Autowired private GroupMetricESDAO groupMetricESDAO; + @Autowired + private ClusterPhyService clusterPhyService; + @Override public PaginationResult pagingGroupMembers(Long clusterPhyId, String topicName, @@ -140,6 +148,11 @@ public class GroupManagerImpl implements GroupManager { String groupName, List latestMetricNames, PaginationSortDTO dto) throws NotExistException, AdminOperateException { + ClusterPhy clusterPhy = clusterPhyService.getClusterByCluster(clusterPhyId); + if (clusterPhy == null) { + return PaginationResult.buildFailure(MsgConstant.getClusterPhyNotExist(clusterPhyId), dto); + } + // 获取消费组消费的TopicPartition列表 Map consumedOffsetMap = groupService.getGroupOffsetFromKafka(clusterPhyId, groupName); List partitionList = consumedOffsetMap.keySet() @@ -150,13 +163,18 @@ public class GroupManagerImpl implements GroupManager { Collections.sort(partitionList); // 获取消费组当前运行信息 - ConsumerGroupDescription groupDescription = groupService.getGroupDescriptionFromKafka(clusterPhyId, groupName); + KSGroupDescription groupDescription = groupService.getGroupDescriptionFromKafka(clusterPhy, groupName); // 转换存储格式 - Map tpMemberMap = new HashMap<>(); - for (MemberDescription description: groupDescription.members()) { - for (TopicPartition tp: description.assignment().topicPartitions()) { - tpMemberMap.put(tp, description); + Map tpMemberMap = new HashMap<>(); + + //如果不是connect集群 + if (!groupDescription.protocolType().equals(CONNECT_CLUSTER_PROTOCOL_TYPE)) { + for (KSMemberDescription description : groupDescription.members()) { + KSMemberConsumerAssignment assignment = (KSMemberConsumerAssignment) description.assignment(); + for (TopicPartition tp : assignment.topicPartitions()) { + tpMemberMap.put(tp, description); + } } } @@ -173,11 +191,11 @@ public class GroupManagerImpl implements GroupManager { vo.setTopicName(topicName); vo.setPartitionId(groupMetrics.getPartitionId()); - MemberDescription memberDescription = tpMemberMap.get(new TopicPartition(topicName, groupMetrics.getPartitionId())); - if (memberDescription != null) { - vo.setMemberId(memberDescription.consumerId()); - vo.setHost(memberDescription.host()); - vo.setClientId(memberDescription.clientId()); + KSMemberDescription ksMemberDescription = tpMemberMap.get(new TopicPartition(topicName, groupMetrics.getPartitionId())); + if (ksMemberDescription != null) { + vo.setMemberId(ksMemberDescription.consumerId()); + vo.setHost(ksMemberDescription.host()); + vo.setClientId(ksMemberDescription.clientId()); } vo.setLatestMetrics(groupMetrics); @@ -203,7 +221,12 @@ public class GroupManagerImpl implements GroupManager { return rv; } - ConsumerGroupDescription description = groupService.getGroupDescriptionFromKafka(dto.getClusterId(), dto.getGroupName()); + ClusterPhy clusterPhy = clusterPhyService.getClusterByCluster(dto.getClusterId()); + if (clusterPhy == null) { + return Result.buildFromRSAndMsg(ResultStatus.CLUSTER_NOT_EXIST, MsgConstant.getClusterPhyNotExist(dto.getClusterId())); + } + + KSGroupDescription description = groupService.getGroupDescriptionFromKafka(clusterPhy, dto.getGroupName()); if (ConsumerGroupState.DEAD.equals(description.state()) && !dto.isCreateIfNotExist()) { return Result.buildFromRSAndMsg(ResultStatus.KAFKA_OPERATE_FAILED, "group不存在, 重置失败"); } @@ -274,16 +297,16 @@ public class GroupManagerImpl implements GroupManager { ))); } - OffsetSpec offsetSpec = null; + KSOffsetSpec offsetSpec = null; if (OffsetTypeEnum.PRECISE_TIMESTAMP.getResetType() == dto.getResetType()) { - offsetSpec = OffsetSpec.forTimestamp(dto.getTimestamp()); + offsetSpec = KSOffsetSpec.forTimestamp(dto.getTimestamp()); } else if (OffsetTypeEnum.EARLIEST.getResetType() == dto.getResetType()) { - offsetSpec = OffsetSpec.earliest(); + offsetSpec = KSOffsetSpec.earliest(); } else { - offsetSpec = OffsetSpec.latest(); + offsetSpec = KSOffsetSpec.latest(); } - return partitionService.getPartitionOffsetFromKafka(dto.getClusterId(), dto.getTopicName(), offsetSpec, dto.getTimestamp()); + return partitionService.getPartitionOffsetFromKafka(dto.getClusterId(), dto.getTopicName(), offsetSpec); } private List convert2GroupTopicOverviewVOList(List poList, List metricsList) { @@ -345,32 +368,4 @@ public class GroupManagerImpl implements GroupManager { dto ); } - - private List convert2GroupTopicOverviewVOList(String groupName, String state, List groupTopicList, List metricsList) { - if (metricsList == null) { - metricsList = new ArrayList<>(); - } - - // - Map metricsMap = new HashMap<>(); - for (GroupMetrics metrics : metricsList) { - if (!groupName.equals(metrics.getGroup())) continue; - metricsMap.put(metrics.getTopic(), metrics); - } - - List voList = new ArrayList<>(); - for (GroupTopicMember po : groupTopicList) { - GroupTopicOverviewVO vo = ConvertUtil.obj2Obj(po, GroupTopicOverviewVO.class); - vo.setGroupName(groupName); - vo.setState(state); - GroupMetrics metrics = metricsMap.get(po.getTopicName()); - if (metrics != null) { - vo.setMaxLag(ConvertUtil.Float2Long(metrics.getMetrics().get(GroupMetricVersionItems.GROUP_METRIC_LAG))); - } - - voList.add(vo); - } - return voList; - } - } diff --git a/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/reassign/impl/ReassignManagerImpl.java b/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/reassign/impl/ReassignManagerImpl.java index 557974ee..4909ee60 100644 --- a/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/reassign/impl/ReassignManagerImpl.java +++ b/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/reassign/impl/ReassignManagerImpl.java @@ -22,7 +22,7 @@ import com.xiaojukeji.know.streaming.km.common.utils.ValidateUtils; import com.xiaojukeji.know.streaming.km.core.service.reassign.ReassignService; import com.xiaojukeji.know.streaming.km.core.service.topic.TopicMetricService; import com.xiaojukeji.know.streaming.km.core.service.topic.TopicService; -import com.xiaojukeji.know.streaming.km.core.service.version.metrics.TopicMetricVersionItems; +import com.xiaojukeji.know.streaming.km.core.service.version.metrics.kafka.TopicMetricVersionItems; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; diff --git a/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/topic/impl/TopicConfigManagerImpl.java b/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/topic/impl/TopicConfigManagerImpl.java index d52ad657..ccb02cf6 100644 --- a/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/topic/impl/TopicConfigManagerImpl.java +++ b/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/topic/impl/TopicConfigManagerImpl.java @@ -16,7 +16,7 @@ import com.xiaojukeji.know.streaming.km.common.utils.ValidateUtils; import com.xiaojukeji.know.streaming.km.core.service.broker.BrokerConfigService; import com.xiaojukeji.know.streaming.km.core.service.broker.BrokerService; import com.xiaojukeji.know.streaming.km.core.service.topic.TopicConfigService; -import com.xiaojukeji.know.streaming.km.core.service.version.BaseVersionControlService; +import com.xiaojukeji.know.streaming.km.core.service.version.BaseKafkaVersionControlService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -27,7 +27,7 @@ import java.util.stream.Collectors; import static com.xiaojukeji.know.streaming.km.common.enums.version.VersionEnum.*; @Component -public class TopicConfigManagerImpl extends BaseVersionControlService implements TopicConfigManager { +public class TopicConfigManagerImpl extends BaseKafkaVersionControlService implements TopicConfigManager { private static final ILog log = LogFactory.getLog(TopicConfigManagerImpl.class); private static final String GET_DEFAULT_TOPIC_CONFIG = "getDefaultTopicConfig"; diff --git a/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/topic/impl/TopicStateManagerImpl.java b/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/topic/impl/TopicStateManagerImpl.java index afc907da..cd970528 100644 --- a/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/topic/impl/TopicStateManagerImpl.java +++ b/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/topic/impl/TopicStateManagerImpl.java @@ -10,6 +10,7 @@ import com.xiaojukeji.know.streaming.km.common.bean.entity.broker.Broker; import com.xiaojukeji.know.streaming.km.common.bean.entity.cluster.ClusterPhy; import com.xiaojukeji.know.streaming.km.common.bean.entity.metrics.PartitionMetrics; import com.xiaojukeji.know.streaming.km.common.bean.entity.metrics.TopicMetrics; +import com.xiaojukeji.know.streaming.km.common.bean.entity.offset.KSOffsetSpec; import com.xiaojukeji.know.streaming.km.common.bean.entity.partition.Partition; import com.xiaojukeji.know.streaming.km.common.bean.entity.result.PaginationResult; import com.xiaojukeji.know.streaming.km.common.bean.entity.result.Result; @@ -43,10 +44,9 @@ import com.xiaojukeji.know.streaming.km.core.service.partition.PartitionService; import com.xiaojukeji.know.streaming.km.core.service.topic.TopicConfigService; import com.xiaojukeji.know.streaming.km.core.service.topic.TopicMetricService; import com.xiaojukeji.know.streaming.km.core.service.topic.TopicService; -import com.xiaojukeji.know.streaming.km.core.service.version.metrics.TopicMetricVersionItems; +import com.xiaojukeji.know.streaming.km.core.service.version.metrics.kafka.TopicMetricVersionItems; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; -import org.apache.kafka.clients.admin.OffsetSpec; import org.apache.kafka.clients.consumer.*; import org.apache.kafka.common.TopicPartition; import org.apache.kafka.common.config.TopicConfig; @@ -143,12 +143,12 @@ public class TopicStateManagerImpl implements TopicStateManager { } // 获取分区beginOffset - Result> beginOffsetsMapResult = partitionService.getPartitionOffsetFromKafka(clusterPhyId, topicName, dto.getFilterPartitionId(), OffsetSpec.earliest(), null); + Result> beginOffsetsMapResult = partitionService.getPartitionOffsetFromKafka(clusterPhyId, topicName, dto.getFilterPartitionId(), KSOffsetSpec.earliest()); if (beginOffsetsMapResult.failed()) { return Result.buildFromIgnoreData(beginOffsetsMapResult); } // 获取分区endOffset - Result> endOffsetsMapResult = partitionService.getPartitionOffsetFromKafka(clusterPhyId, topicName, dto.getFilterPartitionId(), OffsetSpec.latest(), null); + Result> endOffsetsMapResult = partitionService.getPartitionOffsetFromKafka(clusterPhyId, topicName, dto.getFilterPartitionId(), KSOffsetSpec.latest()); if (endOffsetsMapResult.failed()) { return Result.buildFromIgnoreData(endOffsetsMapResult); } @@ -307,7 +307,7 @@ public class TopicStateManagerImpl implements TopicStateManager { if (metricsResult.failed()) { // 仅打印错误日志,但是不直接返回错误 log.error( - "class=TopicStateManagerImpl||method=getTopicPartitions||clusterPhyId={}||topicName={}||result={}||msg=get metrics from es failed", + "method=getTopicPartitions||clusterPhyId={}||topicName={}||result={}||msg=get metrics from es failed", clusterPhyId, topicName, metricsResult ); } diff --git a/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/version/VersionControlManager.java b/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/version/VersionControlManager.java index 575a26d3..ea4a9dc2 100644 --- a/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/version/VersionControlManager.java +++ b/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/version/VersionControlManager.java @@ -20,7 +20,7 @@ public interface VersionControlManager { * 获取当前ks所有支持的kafka版本 * @return */ - Result> listAllVersions(); + Result> listAllKafkaVersions(); /** * 获取全部集群 clusterId 中类型为 type 的指标,不论支持不支持 @@ -28,7 +28,7 @@ public interface VersionControlManager { * @param type * @return */ - Result> listClusterVersionControlItem(Long clusterId, Integer type); + Result> listKafkaClusterVersionControlItem(Long clusterId, Integer type); /** * 获取当前用户设置的用于展示的指标配置 diff --git a/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/version/impl/VersionControlManagerImpl.java b/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/version/impl/VersionControlManagerImpl.java index 501e4822..740974d7 100644 --- a/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/version/impl/VersionControlManagerImpl.java +++ b/km-biz/src/main/java/com/xiaojukeji/know/streaming/km/biz/version/impl/VersionControlManagerImpl.java @@ -17,6 +17,7 @@ import com.xiaojukeji.know.streaming.km.common.bean.vo.version.VersionItemVO; import com.xiaojukeji.know.streaming.km.common.enums.version.VersionEnum; import com.xiaojukeji.know.streaming.km.common.utils.ConvertUtil; import com.xiaojukeji.know.streaming.km.common.utils.VersionUtil; +import com.xiaojukeji.know.streaming.km.core.service.cluster.ClusterPhyService; import com.xiaojukeji.know.streaming.km.core.service.version.VersionControlService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -29,10 +30,12 @@ import java.util.stream.Collectors; import static com.xiaojukeji.know.streaming.km.common.enums.version.VersionEnum.V_MAX; import static com.xiaojukeji.know.streaming.km.common.enums.version.VersionItemTypeEnum.*; -import static com.xiaojukeji.know.streaming.km.core.service.version.metrics.BrokerMetricVersionItems.*; -import static com.xiaojukeji.know.streaming.km.core.service.version.metrics.ClusterMetricVersionItems.*; -import static com.xiaojukeji.know.streaming.km.core.service.version.metrics.GroupMetricVersionItems.*; -import static com.xiaojukeji.know.streaming.km.core.service.version.metrics.TopicMetricVersionItems.*; +import static com.xiaojukeji.know.streaming.km.core.service.version.metrics.kafka.BrokerMetricVersionItems.*; +import static com.xiaojukeji.know.streaming.km.core.service.version.metrics.kafka.ClusterMetricVersionItems.*; +import static com.xiaojukeji.know.streaming.km.core.service.version.metrics.kafka.GroupMetricVersionItems.*; +import static com.xiaojukeji.know.streaming.km.core.service.version.metrics.kafka.TopicMetricVersionItems.*; +import static com.xiaojukeji.know.streaming.km.core.service.version.metrics.connect.MirrorMakerMetricVersionItems.*; +import static com.xiaojukeji.know.streaming.km.core.service.version.metrics.kafka.ZookeeperMetricVersionItems.*; @Service public class VersionControlManagerImpl implements VersionControlManager { @@ -47,6 +50,7 @@ public class VersionControlManagerImpl implements VersionControlManager { @PostConstruct public void init(){ + // topic defaultMetrics.add(new UserMetricConfig(METRIC_TOPIC.getCode(), TOPIC_METRIC_HEALTH_STATE, true)); defaultMetrics.add(new UserMetricConfig(METRIC_TOPIC.getCode(), TOPIC_METRIC_FAILED_FETCH_REQ, true)); defaultMetrics.add(new UserMetricConfig(METRIC_TOPIC.getCode(), TOPIC_METRIC_FAILED_PRODUCE_REQ, true)); @@ -57,6 +61,7 @@ public class VersionControlManagerImpl implements VersionControlManager { defaultMetrics.add(new UserMetricConfig(METRIC_TOPIC.getCode(), TOPIC_METRIC_BYTES_REJECTED, true)); defaultMetrics.add(new UserMetricConfig(METRIC_TOPIC.getCode(), TOPIC_METRIC_MESSAGE_IN, true)); + // cluster defaultMetrics.add(new UserMetricConfig(METRIC_CLUSTER.getCode(), CLUSTER_METRIC_HEALTH_STATE, true)); defaultMetrics.add(new UserMetricConfig(METRIC_CLUSTER.getCode(), CLUSTER_METRIC_ACTIVE_CONTROLLER_COUNT, true)); defaultMetrics.add(new UserMetricConfig(METRIC_CLUSTER.getCode(), CLUSTER_METRIC_BYTES_IN, true)); @@ -72,11 +77,13 @@ public class VersionControlManagerImpl implements VersionControlManager { defaultMetrics.add(new UserMetricConfig(METRIC_CLUSTER.getCode(), CLUSTER_METRIC_GROUP_REBALANCES, true)); defaultMetrics.add(new UserMetricConfig(METRIC_CLUSTER.getCode(), CLUSTER_METRIC_JOB_RUNNING, true)); + // group defaultMetrics.add(new UserMetricConfig(METRIC_GROUP.getCode(), GROUP_METRIC_OFFSET_CONSUMED, true)); defaultMetrics.add(new UserMetricConfig(METRIC_GROUP.getCode(), GROUP_METRIC_LAG, true)); defaultMetrics.add(new UserMetricConfig(METRIC_GROUP.getCode(), GROUP_METRIC_STATE, true)); defaultMetrics.add(new UserMetricConfig(METRIC_GROUP.getCode(), GROUP_METRIC_HEALTH_STATE, true)); + // broker defaultMetrics.add(new UserMetricConfig(METRIC_BROKER.getCode(), BROKER_METRIC_HEALTH_STATE, true)); defaultMetrics.add(new UserMetricConfig(METRIC_BROKER.getCode(), BROKER_METRIC_CONNECTION_COUNT, true)); defaultMetrics.add(new UserMetricConfig(METRIC_BROKER.getCode(), BROKER_METRIC_MESSAGE_IN, true)); @@ -90,8 +97,37 @@ public class VersionControlManagerImpl implements VersionControlManager { defaultMetrics.add(new UserMetricConfig(METRIC_BROKER.getCode(), BROKER_METRIC_PARTITIONS_SKEW, true)); defaultMetrics.add(new UserMetricConfig(METRIC_BROKER.getCode(), BROKER_METRIC_BYTES_IN, true)); defaultMetrics.add(new UserMetricConfig(METRIC_BROKER.getCode(), BROKER_METRIC_BYTES_OUT, true)); + + // zookeeper + defaultMetrics.add(new UserMetricConfig(METRIC_ZOOKEEPER.getCode(), ZOOKEEPER_METRIC_HEALTH_STATE, true)); + defaultMetrics.add(new UserMetricConfig(METRIC_ZOOKEEPER.getCode(), ZOOKEEPER_METRIC_HEALTH_CHECK_PASSED, true)); + defaultMetrics.add(new UserMetricConfig(METRIC_ZOOKEEPER.getCode(), ZOOKEEPER_METRIC_HEALTH_CHECK_TOTAL, true)); + defaultMetrics.add(new UserMetricConfig(METRIC_ZOOKEEPER.getCode(), ZOOKEEPER_METRIC_MAX_REQUEST_LATENCY, true)); + defaultMetrics.add(new UserMetricConfig(METRIC_ZOOKEEPER.getCode(), ZOOKEEPER_METRIC_OUTSTANDING_REQUESTS, true)); + defaultMetrics.add(new UserMetricConfig(METRIC_ZOOKEEPER.getCode(), ZOOKEEPER_METRIC_NODE_COUNT, true)); + defaultMetrics.add(new UserMetricConfig(METRIC_ZOOKEEPER.getCode(), ZOOKEEPER_METRIC_WATCH_COUNT, true)); + defaultMetrics.add(new UserMetricConfig(METRIC_ZOOKEEPER.getCode(), ZOOKEEPER_METRIC_NUM_ALIVE_CONNECTIONS, true)); + defaultMetrics.add(new UserMetricConfig(METRIC_ZOOKEEPER.getCode(), ZOOKEEPER_METRIC_PACKETS_RECEIVED, true)); + defaultMetrics.add(new UserMetricConfig(METRIC_ZOOKEEPER.getCode(), ZOOKEEPER_METRIC_PACKETS_SENT, true)); + defaultMetrics.add(new UserMetricConfig(METRIC_ZOOKEEPER.getCode(), ZOOKEEPER_METRIC_EPHEMERALS_COUNT, true)); + defaultMetrics.add(new UserMetricConfig(METRIC_ZOOKEEPER.getCode(), ZOOKEEPER_METRIC_APPROXIMATE_DATA_SIZE, true)); + defaultMetrics.add(new UserMetricConfig(METRIC_ZOOKEEPER.getCode(), ZOOKEEPER_METRIC_OPEN_FILE_DESCRIPTOR_COUNT, true)); + defaultMetrics.add(new UserMetricConfig(METRIC_ZOOKEEPER.getCode(), ZOOKEEPER_METRIC_KAFKA_ZK_DISCONNECTS_PER_SEC, true)); + defaultMetrics.add(new UserMetricConfig(METRIC_ZOOKEEPER.getCode(), ZOOKEEPER_METRIC_KAFKA_ZK_SYNC_CONNECTS_PER_SEC, true)); + defaultMetrics.add(new UserMetricConfig(METRIC_ZOOKEEPER.getCode(), ZOOKEEPER_METRIC_KAFKA_ZK_REQUEST_LATENCY_99TH, true)); + + // mm2 + defaultMetrics.add(new UserMetricConfig(METRIC_CONNECT_MIRROR_MAKER.getCode(), MIRROR_MAKER_METRIC_BYTE_COUNT, true)); + defaultMetrics.add(new UserMetricConfig(METRIC_CONNECT_MIRROR_MAKER.getCode(), MIRROR_MAKER_METRIC_BYTE_RATE, true)); + defaultMetrics.add(new UserMetricConfig(METRIC_CONNECT_MIRROR_MAKER.getCode(), MIRROR_MAKER_METRIC_RECORD_AGE_MS_MAX, true)); + defaultMetrics.add(new UserMetricConfig(METRIC_CONNECT_MIRROR_MAKER.getCode(), MIRROR_MAKER_METRIC_RECORD_COUNT, true)); + defaultMetrics.add(new UserMetricConfig(METRIC_CONNECT_MIRROR_MAKER.getCode(), MIRROR_MAKER_METRIC_RECORD_RATE, true)); + defaultMetrics.add(new UserMetricConfig(METRIC_CONNECT_MIRROR_MAKER.getCode(), MIRROR_MAKER_METRIC_REPLICATION_LATENCY_MS_MAX, true)); } + @Autowired + private ClusterPhyService clusterPhyService; + @Autowired private VersionControlService versionControlService; @@ -107,7 +143,13 @@ public class VersionControlManagerImpl implements VersionControlManager { allVersionItemVO.addAll(ConvertUtil.list2List(versionControlService.listVersionControlItem(METRIC_BROKER.getCode()), VersionItemVO.class)); allVersionItemVO.addAll(ConvertUtil.list2List(versionControlService.listVersionControlItem(METRIC_PARTITION.getCode()), VersionItemVO.class)); allVersionItemVO.addAll(ConvertUtil.list2List(versionControlService.listVersionControlItem(METRIC_REPLICATION.getCode()), VersionItemVO.class)); + allVersionItemVO.addAll(ConvertUtil.list2List(versionControlService.listVersionControlItem(METRIC_ZOOKEEPER.getCode()), VersionItemVO.class)); + + allVersionItemVO.addAll(ConvertUtil.list2List(versionControlService.listVersionControlItem(METRIC_CONNECT_CLUSTER.getCode()), VersionItemVO.class)); + allVersionItemVO.addAll(ConvertUtil.list2List(versionControlService.listVersionControlItem(METRIC_CONNECT_CONNECTOR.getCode()), VersionItemVO.class)); + allVersionItemVO.addAll(ConvertUtil.list2List(versionControlService.listVersionControlItem(METRIC_CONNECT_MIRROR_MAKER.getCode()), VersionItemVO.class)); + allVersionItemVO.addAll(ConvertUtil.list2List(versionControlService.listVersionControlItem(WEB_OP.getCode()), VersionItemVO.class)); Map map = allVersionItemVO.stream().collect( @@ -121,18 +163,20 @@ public class VersionControlManagerImpl implements VersionControlManager { } @Override - public Result> listAllVersions() { + public Result> listAllKafkaVersions() { return Result.buildSuc(VersionEnum.allVersionsWithOutMax()); } @Override - public Result> listClusterVersionControlItem(Long clusterId, Integer type) { + public Result> listKafkaClusterVersionControlItem(Long clusterId, Integer type) { List allItem = versionControlService.listVersionControlItem(type); List versionItemVOS = new ArrayList<>(); + String versionStr = clusterPhyService.getVersionFromCacheFirst(clusterId); + for (VersionControlItem item : allItem){ VersionItemVO itemVO = ConvertUtil.obj2Obj(item, VersionItemVO.class); - boolean support = versionControlService.isClusterSupport(clusterId, item); + boolean support = versionControlService.isClusterSupport(versionStr, item); itemVO.setSupport(support); itemVO.setDesc(itemSupportDesc(item, support)); @@ -145,7 +189,7 @@ public class VersionControlManagerImpl implements VersionControlManager { @Override public Result> listUserMetricItem(Long clusterId, Integer type, String operator) { - Result> ret = listClusterVersionControlItem(clusterId, type); + Result> ret = listKafkaClusterVersionControlItem(clusterId, type); if(null == ret || ret.failed()){ return Result.buildFail(); } diff --git a/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/metric/AbstractMetricCollector.java b/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/metric/AbstractMetricCollector.java index 7d0e85f6..ceb1fbff 100644 --- a/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/metric/AbstractMetricCollector.java +++ b/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/metric/AbstractMetricCollector.java @@ -1,7 +1,6 @@ package com.xiaojukeji.know.streaming.km.collector.metric; import com.xiaojukeji.know.streaming.km.collector.service.CollectThreadPoolService; -import com.xiaojukeji.know.streaming.km.common.bean.entity.cluster.ClusterPhy; import com.xiaojukeji.know.streaming.km.common.bean.event.metric.BaseMetricEvent; import com.xiaojukeji.know.streaming.km.common.component.SpringTool; import com.xiaojukeji.know.streaming.km.common.enums.version.VersionItemTypeEnum; @@ -9,17 +8,20 @@ import com.xiaojukeji.know.streaming.km.common.utils.FutureWaitUtil; import org.springframework.beans.factory.annotation.Autowired; + /** * @author didi */ -public abstract class AbstractMetricCollector { - public abstract void collectMetrics(ClusterPhy clusterPhy); +public abstract class AbstractMetricCollector { + public abstract String getClusterVersion(C c); public abstract VersionItemTypeEnum collectorType(); @Autowired private CollectThreadPoolService collectThreadPoolService; + public abstract void collectMetrics(C c); + protected FutureWaitUtil getFutureUtilByClusterPhyId(Long clusterPhyId) { return collectThreadPoolService.selectSuitableFutureUtil(clusterPhyId * 1000L + this.collectorType().getCode()); } diff --git a/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/metric/ReplicaMetricCollector.java b/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/metric/ReplicaMetricCollector.java deleted file mode 100644 index 3f9e0035..00000000 --- a/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/metric/ReplicaMetricCollector.java +++ /dev/null @@ -1,124 +0,0 @@ -package com.xiaojukeji.know.streaming.km.collector.metric; - -import com.alibaba.fastjson.JSON; -import com.didiglobal.logi.log.ILog; -import com.didiglobal.logi.log.LogFactory; -import com.xiaojukeji.know.streaming.km.common.bean.entity.cluster.ClusterPhy; -import com.xiaojukeji.know.streaming.km.common.bean.entity.metrics.ReplicationMetrics; -import com.xiaojukeji.know.streaming.km.common.bean.entity.partition.Partition; -import com.xiaojukeji.know.streaming.km.common.bean.entity.result.Result; -import com.xiaojukeji.know.streaming.km.common.bean.entity.version.VersionControlItem; -import com.xiaojukeji.know.streaming.km.common.bean.event.metric.ReplicaMetricEvent; -import com.xiaojukeji.know.streaming.km.common.constant.Constant; -import com.xiaojukeji.know.streaming.km.common.enums.version.VersionItemTypeEnum; -import com.xiaojukeji.know.streaming.km.common.utils.EnvUtil; -import com.xiaojukeji.know.streaming.km.common.utils.FutureWaitUtil; -import com.xiaojukeji.know.streaming.km.core.service.partition.PartitionService; -import com.xiaojukeji.know.streaming.km.core.service.replica.ReplicaMetricService; -import com.xiaojukeji.know.streaming.km.core.service.version.VersionControlService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import java.util.ArrayList; -import java.util.List; - -import static com.xiaojukeji.know.streaming.km.common.enums.version.VersionItemTypeEnum.METRIC_REPLICATION; - -/** - * @author didi - */ -@Component -public class ReplicaMetricCollector extends AbstractMetricCollector { - protected static final ILog LOGGER = LogFactory.getLog("METRIC_LOGGER"); - - @Autowired - private VersionControlService versionControlService; - - @Autowired - private ReplicaMetricService replicaMetricService; - - @Autowired - private PartitionService partitionService; - - @Override - public void collectMetrics(ClusterPhy clusterPhy) { - Long startTime = System.currentTimeMillis(); - Long clusterPhyId = clusterPhy.getId(); - List items = versionControlService.listVersionControlItem(clusterPhyId, collectorType().getCode()); - - List partitions = partitionService.listPartitionByCluster(clusterPhyId); - - FutureWaitUtil future = this.getFutureUtilByClusterPhyId(clusterPhyId); - - List metricsList = new ArrayList<>(); - for(Partition partition : partitions) { - for (Integer brokerId: partition.getAssignReplicaList()) { - ReplicationMetrics metrics = new ReplicationMetrics(clusterPhyId, partition.getTopicName(), brokerId, partition.getPartitionId()); - metricsList.add(metrics); - - future.runnableTask( - String.format("method=ReplicaMetricCollector||clusterPhyId=%d||brokerId=%d||topicName=%s||partitionId=%d", - clusterPhyId, brokerId, partition.getTopicName(), partition.getPartitionId()), - 30000, - () -> collectMetrics(clusterPhyId, metrics, items) - ); - } - } - - future.waitExecute(30000); - - publishMetric(new ReplicaMetricEvent(this, metricsList)); - - LOGGER.info("method=ReplicaMetricCollector||clusterPhyId={}||startTime={}||costTime={}||msg=collect finished.", - clusterPhyId, startTime, System.currentTimeMillis() - startTime); - } - - @Override - public VersionItemTypeEnum collectorType() { - return METRIC_REPLICATION; - } - - /**************************************************** private method ****************************************************/ - - private ReplicationMetrics collectMetrics(Long clusterPhyId, ReplicationMetrics metrics, List items) { - long startTime = System.currentTimeMillis(); - - metrics.putMetric(Constant.COLLECT_METRICS_COST_TIME_METRICS_NAME, Constant.COLLECT_METRICS_ERROR_COST_TIME); - - for(VersionControlItem v : items) { - try { - if (metrics.getMetrics().containsKey(v.getName())) { - continue; - } - - Result ret = replicaMetricService.collectReplicaMetricsFromKafka( - clusterPhyId, - metrics.getTopic(), - metrics.getBrokerId(), - metrics.getPartitionId(), - v.getName() - ); - - if (null == ret || ret.failed() || null == ret.getData()) { - continue; - } - - metrics.putMetric(ret.getData().getMetrics()); - - if (!EnvUtil.isOnline()) { - LOGGER.info("method=ReplicaMetricCollector||clusterPhyId={}||topicName={}||partitionId={}||metricName={}||metricValue={}", - clusterPhyId, metrics.getTopic(), metrics.getPartitionId(), v.getName(), JSON.toJSONString(ret.getData().getMetrics())); - } - - } catch (Exception e) { - LOGGER.error("method=ReplicaMetricCollector||clusterPhyId={}||topicName={}||partition={}||metricName={}||errMsg=exception!", - clusterPhyId, metrics.getTopic(), metrics.getPartitionId(), v.getName(), e); - } - } - - // 记录采集性能 - metrics.putMetric(Constant.COLLECT_METRICS_COST_TIME_METRICS_NAME, (System.currentTimeMillis() - startTime) / 1000.0f); - - return metrics; - } -} diff --git a/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/metric/connect/AbstractConnectMetricCollector.java b/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/metric/connect/AbstractConnectMetricCollector.java new file mode 100644 index 00000000..78ca717c --- /dev/null +++ b/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/metric/connect/AbstractConnectMetricCollector.java @@ -0,0 +1,50 @@ +package com.xiaojukeji.know.streaming.km.collector.metric.connect; + +import com.didiglobal.logi.log.ILog; +import com.didiglobal.logi.log.LogFactory; +import com.xiaojukeji.know.streaming.km.collector.metric.AbstractMetricCollector; +import com.xiaojukeji.know.streaming.km.common.bean.entity.connect.ConnectCluster; +import com.xiaojukeji.know.streaming.km.common.utils.ConvertUtil; +import com.xiaojukeji.know.streaming.km.common.utils.LoggerUtil; +import com.xiaojukeji.know.streaming.km.core.service.connect.cluster.ConnectClusterService; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.List; + +/** + * @author didi + */ +public abstract class AbstractConnectMetricCollector extends AbstractMetricCollector { + private static final ILog LOGGER = LogFactory.getLog(AbstractConnectMetricCollector.class); + + protected static final ILog METRIC_COLLECTED_LOGGER = LoggerUtil.getMetricCollectedLogger(); + + @Autowired + private ConnectClusterService connectClusterService; + + public abstract List collectConnectMetrics(ConnectCluster connectCluster); + + @Override + public String getClusterVersion(ConnectCluster connectCluster){ + return connectClusterService.getClusterVersion(connectCluster.getId()); + } + + @Override + public void collectMetrics(ConnectCluster connectCluster) { + long startTime = System.currentTimeMillis(); + + // 采集指标 + List metricsList = this.collectConnectMetrics(connectCluster); + + // 输出耗时信息 + LOGGER.info( + "metricType={}||connectClusterId={}||costTimeUnitMs={}", + this.collectorType().getMessage(), connectCluster.getId(), System.currentTimeMillis() - startTime + ); + + // 输出采集到的指标信息 + METRIC_COLLECTED_LOGGER.debug("metricType={}||connectClusterId={}||metrics={}!", + this.collectorType().getMessage(), connectCluster.getId(), ConvertUtil.obj2Json(metricsList) + ); + } +} diff --git a/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/metric/connect/ConnectClusterMetricCollector.java b/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/metric/connect/ConnectClusterMetricCollector.java new file mode 100644 index 00000000..df463ea1 --- /dev/null +++ b/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/metric/connect/ConnectClusterMetricCollector.java @@ -0,0 +1,83 @@ +package com.xiaojukeji.know.streaming.km.collector.metric.connect; + +import com.didiglobal.logi.log.ILog; +import com.didiglobal.logi.log.LogFactory; +import com.xiaojukeji.know.streaming.km.common.bean.entity.connect.ConnectCluster; +import com.xiaojukeji.know.streaming.km.common.bean.entity.metrics.connect.ConnectClusterMetrics; +import com.xiaojukeji.know.streaming.km.common.bean.entity.result.Result; +import com.xiaojukeji.know.streaming.km.common.bean.entity.version.VersionControlItem; +import com.xiaojukeji.know.streaming.km.common.bean.event.metric.connect.ConnectClusterMetricEvent; +import com.xiaojukeji.know.streaming.km.common.constant.Constant; +import com.xiaojukeji.know.streaming.km.common.enums.version.VersionItemTypeEnum; +import com.xiaojukeji.know.streaming.km.common.utils.FutureWaitUtil; +import com.xiaojukeji.know.streaming.km.core.service.connect.cluster.ConnectClusterMetricService; +import com.xiaojukeji.know.streaming.km.core.service.version.VersionControlService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Collections; +import java.util.List; + +import static com.xiaojukeji.know.streaming.km.common.enums.version.VersionItemTypeEnum.METRIC_CONNECT_CLUSTER; + +/** + * @author didi + */ +@Component +public class ConnectClusterMetricCollector extends AbstractConnectMetricCollector { + protected static final ILog LOGGER = LogFactory.getLog(ConnectClusterMetricCollector.class); + + @Autowired + private VersionControlService versionControlService; + + @Autowired + private ConnectClusterMetricService connectClusterMetricService; + + @Override + public List collectConnectMetrics(ConnectCluster connectCluster) { + Long startTime = System.currentTimeMillis(); + Long clusterPhyId = connectCluster.getKafkaClusterPhyId(); + Long connectClusterId = connectCluster.getId(); + + ConnectClusterMetrics metrics = new ConnectClusterMetrics(clusterPhyId, connectClusterId); + metrics.putMetric(Constant.COLLECT_METRICS_COST_TIME_METRICS_NAME, Constant.COLLECT_METRICS_ERROR_COST_TIME); + List items = versionControlService.listVersionControlItem(getClusterVersion(connectCluster), collectorType().getCode()); + FutureWaitUtil future = this.getFutureUtilByClusterPhyId(connectClusterId); + + for (VersionControlItem item : items) { + future.runnableTask( + String.format("class=ConnectClusterMetricCollector||connectClusterId=%d||metricName=%s", connectClusterId, item.getName()), + 30000, + () -> { + try { + Result ret = connectClusterMetricService.collectConnectClusterMetricsFromKafka(connectClusterId, item.getName()); + if (null == ret || !ret.hasData()) { + return null; + } + metrics.putMetric(ret.getData().getMetrics()); + + } catch (Exception e) { + LOGGER.error( + "method=collectConnectMetrics||connectClusterId={}||metricName={}||errMsg=exception!", + connectClusterId, item.getName(), e + ); + } + return null; + } + ); + } + + future.waitExecute(30000); + + metrics.putMetric(Constant.COLLECT_METRICS_COST_TIME_METRICS_NAME, (System.currentTimeMillis() - startTime) / 1000.0f); + + this.publishMetric(new ConnectClusterMetricEvent(this, Collections.singletonList(metrics))); + + return Collections.singletonList(metrics); + } + + @Override + public VersionItemTypeEnum collectorType() { + return METRIC_CONNECT_CLUSTER; + } +} diff --git a/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/metric/connect/ConnectConnectorMetricCollector.java b/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/metric/connect/ConnectConnectorMetricCollector.java new file mode 100644 index 00000000..4da6d8fd --- /dev/null +++ b/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/metric/connect/ConnectConnectorMetricCollector.java @@ -0,0 +1,107 @@ +package com.xiaojukeji.know.streaming.km.collector.metric.connect; + +import com.didiglobal.logi.log.ILog; +import com.didiglobal.logi.log.LogFactory; +import com.xiaojukeji.know.streaming.km.common.bean.entity.connect.ConnectCluster; +import com.xiaojukeji.know.streaming.km.common.bean.entity.metrics.connect.ConnectorMetrics; +import com.xiaojukeji.know.streaming.km.common.bean.entity.result.Result; +import com.xiaojukeji.know.streaming.km.common.bean.entity.version.VersionControlItem; +import com.xiaojukeji.know.streaming.km.common.bean.event.metric.connect.ConnectorMetricEvent; +import com.xiaojukeji.know.streaming.km.common.constant.Constant; +import com.xiaojukeji.know.streaming.km.common.enums.connect.ConnectorTypeEnum; +import com.xiaojukeji.know.streaming.km.common.enums.version.VersionItemTypeEnum; +import com.xiaojukeji.know.streaming.km.common.utils.FutureWaitUtil; +import com.xiaojukeji.know.streaming.km.core.service.connect.connector.ConnectorMetricService; +import com.xiaojukeji.know.streaming.km.core.service.connect.connector.ConnectorService; +import com.xiaojukeji.know.streaming.km.core.service.version.VersionControlService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; + +import static com.xiaojukeji.know.streaming.km.common.enums.version.VersionItemTypeEnum.METRIC_CONNECT_CONNECTOR; + +/** + * @author didi + */ +@Component +public class ConnectConnectorMetricCollector extends AbstractConnectMetricCollector { + protected static final ILog LOGGER = LogFactory.getLog(ConnectConnectorMetricCollector.class); + + @Autowired + private VersionControlService versionControlService; + + @Autowired + private ConnectorService connectorService; + + @Autowired + private ConnectorMetricService connectorMetricService; + + @Override + public List collectConnectMetrics(ConnectCluster connectCluster) { + Long clusterPhyId = connectCluster.getKafkaClusterPhyId(); + Long connectClusterId = connectCluster.getId(); + + List items = versionControlService.listVersionControlItem(this.getClusterVersion(connectCluster), collectorType().getCode()); + Result> connectorList = connectorService.listConnectorsFromCluster(connectClusterId); + + FutureWaitUtil future = this.getFutureUtilByClusterPhyId(connectClusterId); + + List metricsList = new ArrayList<>(); + for (String connectorName : connectorList.getData()) { + ConnectorMetrics metrics = new ConnectorMetrics(connectClusterId, connectorName); + metrics.setClusterPhyId(clusterPhyId); + + metricsList.add(metrics); + future.runnableTask( + String.format("class=ConnectConnectorMetricCollector||connectClusterId=%d||connectorName=%s", connectClusterId, connectorName), + 30000, + () -> collectMetrics(connectClusterId, connectorName, metrics, items) + ); + } + future.waitResult(30000); + + this.publishMetric(new ConnectorMetricEvent(this, metricsList)); + + return metricsList; + } + + @Override + public VersionItemTypeEnum collectorType() { + return METRIC_CONNECT_CONNECTOR; + } + + /**************************************************** private method ****************************************************/ + + private void collectMetrics(Long connectClusterId, String connectorName, ConnectorMetrics metrics, List items) { + long startTime = System.currentTimeMillis(); + ConnectorTypeEnum connectorType = connectorService.getConnectorType(connectClusterId, connectorName); + + metrics.putMetric(Constant.COLLECT_METRICS_COST_TIME_METRICS_NAME, Constant.COLLECT_METRICS_ERROR_COST_TIME); + + for (VersionControlItem v : items) { + try { + //过滤已测得指标 + if (metrics.getMetrics().get(v.getName()) != null) { + continue; + } + + Result ret = connectorMetricService.collectConnectClusterMetricsFromKafka(connectClusterId, connectorName, v.getName(), connectorType); + if (null == ret || ret.failed() || null == ret.getData()) { + continue; + } + + metrics.putMetric(ret.getData().getMetrics()); + } catch (Exception e) { + LOGGER.error( + "method=collectMetrics||connectClusterId={}||connectorName={}||metric={}||errMsg=exception!", + connectClusterId, connectorName, v.getName(), e + ); + } + } + + // 记录采集性能 + metrics.putMetric(Constant.COLLECT_METRICS_COST_TIME_METRICS_NAME, (System.currentTimeMillis() - startTime) / 1000.0f); + } +} diff --git a/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/metric/connect/mm2/MirrorMakerMetricCollector.java b/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/metric/connect/mm2/MirrorMakerMetricCollector.java new file mode 100644 index 00000000..36436fba --- /dev/null +++ b/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/metric/connect/mm2/MirrorMakerMetricCollector.java @@ -0,0 +1,117 @@ +package com.xiaojukeji.know.streaming.km.collector.metric.connect.mm2; + +import com.didiglobal.logi.log.ILog; +import com.didiglobal.logi.log.LogFactory; +import com.xiaojukeji.know.streaming.km.collector.metric.connect.AbstractConnectMetricCollector; +import com.xiaojukeji.know.streaming.km.common.bean.entity.connect.ConnectCluster; +import com.xiaojukeji.know.streaming.km.common.bean.entity.connect.mm2.MirrorMakerTopic; +import com.xiaojukeji.know.streaming.km.common.bean.entity.metrics.mm2.MirrorMakerMetrics; +import com.xiaojukeji.know.streaming.km.common.bean.entity.result.Result; +import com.xiaojukeji.know.streaming.km.common.bean.entity.version.VersionControlItem; +import com.xiaojukeji.know.streaming.km.common.bean.event.metric.mm2.MirrorMakerMetricEvent; +import com.xiaojukeji.know.streaming.km.common.bean.po.connect.ConnectorPO; +import com.xiaojukeji.know.streaming.km.common.constant.Constant; +import com.xiaojukeji.know.streaming.km.common.enums.version.VersionItemTypeEnum; +import com.xiaojukeji.know.streaming.km.common.utils.FutureWaitUtil; +import com.xiaojukeji.know.streaming.km.core.service.connect.connector.ConnectorService; +import com.xiaojukeji.know.streaming.km.core.service.connect.mm2.MirrorMakerMetricService; +import com.xiaojukeji.know.streaming.km.core.service.connect.mm2.MirrorMakerService; +import com.xiaojukeji.know.streaming.km.core.service.version.VersionControlService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import static com.xiaojukeji.know.streaming.km.common.constant.connect.KafkaConnectConstant.MIRROR_MAKER_SOURCE_CONNECTOR_TYPE; +import static com.xiaojukeji.know.streaming.km.common.enums.version.VersionItemTypeEnum.METRIC_CONNECT_MIRROR_MAKER; + +/** + * @author wyb + * @date 2022/12/15 + */ +@Component +public class MirrorMakerMetricCollector extends AbstractConnectMetricCollector { + protected static final ILog LOGGER = LogFactory.getLog(MirrorMakerMetricCollector.class); + + @Autowired + private VersionControlService versionControlService; + + @Autowired + private MirrorMakerService mirrorMakerService; + + @Autowired + private ConnectorService connectorService; + + @Autowired + private MirrorMakerMetricService mirrorMakerMetricService; + + @Override + public VersionItemTypeEnum collectorType() { + return METRIC_CONNECT_MIRROR_MAKER; + } + + @Override + public List collectConnectMetrics(ConnectCluster connectCluster) { + Long clusterPhyId = connectCluster.getKafkaClusterPhyId(); + Long connectClusterId = connectCluster.getId(); + + List mirrorMakerList = connectorService.listByConnectClusterIdFromDB(connectClusterId).stream().filter(elem -> elem.getConnectorClassName().equals(MIRROR_MAKER_SOURCE_CONNECTOR_TYPE)).collect(Collectors.toList()); + Map mirrorMakerTopicMap = mirrorMakerService.getMirrorMakerTopicMap(connectClusterId).getData(); + + List items = versionControlService.listVersionControlItem(this.getClusterVersion(connectCluster), collectorType().getCode()); + FutureWaitUtil future = this.getFutureUtilByClusterPhyId(clusterPhyId); + + List metricsList = new ArrayList<>(); + + for (ConnectorPO mirrorMaker : mirrorMakerList) { + MirrorMakerMetrics metrics = new MirrorMakerMetrics(clusterPhyId, connectClusterId, mirrorMaker.getConnectorName()); + metricsList.add(metrics); + + List mirrorMakerTopicList = mirrorMakerService.getMirrorMakerTopicList(mirrorMaker, mirrorMakerTopicMap); + future.runnableTask(String.format("class=MirrorMakerMetricCollector||connectClusterId=%d||mirrorMakerName=%s", connectClusterId, mirrorMaker.getConnectorName()), + 30000, + () -> collectMetrics(connectClusterId, mirrorMaker.getConnectorName(), metrics, items, mirrorMakerTopicList)); + } + future.waitResult(30000); + + this.publishMetric(new MirrorMakerMetricEvent(this,metricsList)); + + return metricsList; + } + + /**************************************************** private method ****************************************************/ + private void collectMetrics(Long connectClusterId, String mirrorMakerName, MirrorMakerMetrics metrics, List items, List mirrorMakerTopicList) { + long startTime = System.currentTimeMillis(); + metrics.putMetric(Constant.COLLECT_METRICS_COST_TIME_METRICS_NAME, Constant.COLLECT_METRICS_ERROR_COST_TIME); + + for (VersionControlItem v : items) { + try { + //已测量指标过滤 + if (metrics.getMetrics().get(v.getName()) != null) { + continue; + } + + Result ret = mirrorMakerMetricService.collectMirrorMakerMetricsFromKafka(connectClusterId, mirrorMakerName, mirrorMakerTopicList, v.getName()); + if (ret == null || !ret.hasData()) { + continue; + } + metrics.putMetric(ret.getData().getMetrics()); + + } catch (Exception e) { + LOGGER.error( + "method=collectMetrics||connectClusterId={}||mirrorMakerName={}||metric={}||errMsg=exception!", + connectClusterId, mirrorMakerName, v.getName(), e + ); + + } + } + metrics.putMetric(Constant.COLLECT_METRICS_COST_TIME_METRICS_NAME, (System.currentTimeMillis() - startTime) / 1000.0f); + + } +} + + + diff --git a/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/metric/kafka/AbstractKafkaMetricCollector.java b/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/metric/kafka/AbstractKafkaMetricCollector.java new file mode 100644 index 00000000..4c995cfb --- /dev/null +++ b/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/metric/kafka/AbstractKafkaMetricCollector.java @@ -0,0 +1,50 @@ +package com.xiaojukeji.know.streaming.km.collector.metric.kafka; + +import com.didiglobal.logi.log.ILog; +import com.didiglobal.logi.log.LogFactory; +import com.xiaojukeji.know.streaming.km.collector.metric.AbstractMetricCollector; +import com.xiaojukeji.know.streaming.km.common.bean.entity.cluster.ClusterPhy; +import com.xiaojukeji.know.streaming.km.common.utils.ConvertUtil; +import com.xiaojukeji.know.streaming.km.common.utils.LoggerUtil; +import com.xiaojukeji.know.streaming.km.core.service.cluster.ClusterPhyService; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.List; + +/** + * @author didi + */ +public abstract class AbstractKafkaMetricCollector extends AbstractMetricCollector { + private static final ILog LOGGER = LogFactory.getLog(AbstractMetricCollector.class); + + protected static final ILog METRIC_COLLECTED_LOGGER = LoggerUtil.getMetricCollectedLogger(); + + @Autowired + private ClusterPhyService clusterPhyService; + + public abstract List collectKafkaMetrics(ClusterPhy clusterPhy); + + @Override + public String getClusterVersion(ClusterPhy clusterPhy){ + return clusterPhyService.getVersionFromCacheFirst(clusterPhy.getId()); + } + + @Override + public void collectMetrics(ClusterPhy clusterPhy) { + long startTime = System.currentTimeMillis(); + + // 采集指标 + List metricsList = this.collectKafkaMetrics(clusterPhy); + + // 输出耗时信息 + LOGGER.info( + "metricType={}||clusterPhyId={}||costTimeUnitMs={}", + this.collectorType().getMessage(), clusterPhy.getId(), System.currentTimeMillis() - startTime + ); + + // 输出采集到的指标信息 + METRIC_COLLECTED_LOGGER.debug("metricType={}||clusterPhyId={}||metrics={}!", + this.collectorType().getMessage(), clusterPhy.getId(), ConvertUtil.obj2Json(metricsList) + ); + } +} diff --git a/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/metric/BrokerMetricCollector.java b/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/metric/kafka/BrokerMetricCollector.java similarity index 68% rename from km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/metric/BrokerMetricCollector.java rename to km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/metric/kafka/BrokerMetricCollector.java index e60372a4..6ae2a063 100644 --- a/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/metric/BrokerMetricCollector.java +++ b/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/metric/kafka/BrokerMetricCollector.java @@ -1,6 +1,5 @@ -package com.xiaojukeji.know.streaming.km.collector.metric; +package com.xiaojukeji.know.streaming.km.collector.metric.kafka; -import com.alibaba.fastjson.JSON; import com.didiglobal.logi.log.ILog; import com.didiglobal.logi.log.LogFactory; import com.xiaojukeji.know.streaming.km.common.bean.entity.broker.Broker; @@ -11,7 +10,6 @@ import com.xiaojukeji.know.streaming.km.common.bean.entity.version.VersionContro import com.xiaojukeji.know.streaming.km.common.bean.event.metric.BrokerMetricEvent; import com.xiaojukeji.know.streaming.km.common.constant.Constant; import com.xiaojukeji.know.streaming.km.common.enums.version.VersionItemTypeEnum; -import com.xiaojukeji.know.streaming.km.common.utils.EnvUtil; import com.xiaojukeji.know.streaming.km.common.utils.FutureWaitUtil; import com.xiaojukeji.know.streaming.km.core.service.broker.BrokerMetricService; import com.xiaojukeji.know.streaming.km.core.service.broker.BrokerService; @@ -28,8 +26,8 @@ import static com.xiaojukeji.know.streaming.km.common.enums.version.VersionItemT * @author didi */ @Component -public class BrokerMetricCollector extends AbstractMetricCollector { - protected static final ILog LOGGER = LogFactory.getLog("METRIC_LOGGER"); +public class BrokerMetricCollector extends AbstractKafkaMetricCollector { + private static final ILog LOGGER = LogFactory.getLog(BrokerMetricCollector.class); @Autowired private VersionControlService versionControlService; @@ -41,32 +39,31 @@ public class BrokerMetricCollector extends AbstractMetricCollector collectKafkaMetrics(ClusterPhy clusterPhy) { Long clusterPhyId = clusterPhy.getId(); List brokers = brokerService.listAliveBrokersFromDB(clusterPhy.getId()); - List items = versionControlService.listVersionControlItem(clusterPhyId, collectorType().getCode()); + List items = versionControlService.listVersionControlItem(this.getClusterVersion(clusterPhy), collectorType().getCode()); FutureWaitUtil future = this.getFutureUtilByClusterPhyId(clusterPhyId); - List brokerMetrics = new ArrayList<>(); + List metricsList = new ArrayList<>(); for(Broker broker : brokers) { BrokerMetrics metrics = new BrokerMetrics(clusterPhyId, broker.getBrokerId(), broker.getHost(), broker.getPort()); - brokerMetrics.add(metrics); + metrics.putMetric(Constant.COLLECT_METRICS_COST_TIME_METRICS_NAME, Constant.COLLECT_METRICS_ERROR_COST_TIME); + metricsList.add(metrics); future.runnableTask( - String.format("method=BrokerMetricCollector||clusterPhyId=%d||brokerId=%d", clusterPhyId, broker.getBrokerId()), + String.format("class=BrokerMetricCollector||clusterPhyId=%d||brokerId=%d", clusterPhyId, broker.getBrokerId()), 30000, () -> collectMetrics(clusterPhyId, metrics, items) ); } future.waitExecute(30000); - this.publishMetric(new BrokerMetricEvent(this, brokerMetrics)); + this.publishMetric(new BrokerMetricEvent(this, metricsList)); - LOGGER.info("method=BrokerMetricCollector||clusterPhyId={}||startTime={}||costTime={}||msg=collect finished.", - clusterPhyId, startTime, System.currentTimeMillis() - startTime); + return metricsList; } @Override @@ -78,7 +75,6 @@ public class BrokerMetricCollector extends AbstractMetricCollector items) { long startTime = System.currentTimeMillis(); - metrics.putMetric(Constant.COLLECT_METRICS_COST_TIME_METRICS_NAME, Constant.COLLECT_METRICS_ERROR_COST_TIME); for(VersionControlItem v : items) { try { @@ -92,14 +88,11 @@ public class BrokerMetricCollector extends AbstractMetricCollector { - protected static final ILog LOGGER = LogFactory.getLog("METRIC_LOGGER"); +public class ClusterMetricCollector extends AbstractKafkaMetricCollector { + protected static final ILog LOGGER = LogFactory.getLog(ClusterMetricCollector.class); @Autowired private VersionControlService versionControlService; @@ -37,35 +34,37 @@ public class ClusterMetricCollector extends AbstractMetricCollector collectKafkaMetrics(ClusterPhy clusterPhy) { Long startTime = System.currentTimeMillis(); Long clusterPhyId = clusterPhy.getId(); - List items = versionControlService.listVersionControlItem(clusterPhyId, collectorType().getCode()); + List items = versionControlService.listVersionControlItem(this.getClusterVersion(clusterPhy), collectorType().getCode()); ClusterMetrics metrics = new ClusterMetrics(clusterPhyId, clusterPhy.getKafkaVersion()); + metrics.putMetric(Constant.COLLECT_METRICS_COST_TIME_METRICS_NAME, Constant.COLLECT_METRICS_ERROR_COST_TIME); FutureWaitUtil future = this.getFutureUtilByClusterPhyId(clusterPhyId); for(VersionControlItem v : items) { future.runnableTask( - String.format("method=ClusterMetricCollector||clusterPhyId=%d||metricName=%s", clusterPhyId, v.getName()), + String.format("class=ClusterMetricCollector||clusterPhyId=%d||metricName=%s", clusterPhyId, v.getName()), 30000, () -> { try { - if(null != metrics.getMetrics().get(v.getName())){return null;} + if(null != metrics.getMetrics().get(v.getName())){ + return null; + } Result ret = clusterMetricService.collectClusterMetricsFromKafka(clusterPhyId, v.getName()); - if(null == ret || ret.failed() || null == ret.getData()){return null;} + if(null == ret || ret.failed() || null == ret.getData()){ + return null; + } metrics.putMetric(ret.getData().getMetrics()); - - if(!EnvUtil.isOnline()){ - LOGGER.info("method=ClusterMetricCollector||clusterPhyId={}||metricName={}||metricValue={}", - clusterPhyId, v.getName(), ConvertUtil.obj2Json(ret.getData().getMetrics())); - } } catch (Exception e){ - LOGGER.error("method=ClusterMetricCollector||clusterPhyId={}||metricName={}||errMsg=exception!", - clusterPhyId, v.getName(), e); + LOGGER.error( + "method=collectKafkaMetrics||clusterPhyId={}||metricName={}||errMsg=exception!", + clusterPhyId, v.getName(), e + ); } return null; @@ -76,10 +75,9 @@ public class ClusterMetricCollector extends AbstractMetricCollector> { - protected static final ILog LOGGER = LogFactory.getLog("METRIC_LOGGER"); +public class GroupMetricCollector extends AbstractKafkaMetricCollector { + protected static final ILog LOGGER = LogFactory.getLog(GroupMetricCollector.class); @Autowired private VersionControlService versionControlService; @@ -45,40 +40,38 @@ public class GroupMetricCollector extends AbstractMetricCollector collectKafkaMetrics(ClusterPhy clusterPhy) { Long clusterPhyId = clusterPhy.getId(); - List groups = new ArrayList<>(); + List groupNameList = new ArrayList<>(); try { - groups = groupService.listGroupsFromKafka(clusterPhyId); + groupNameList = groupService.listGroupsFromKafka(clusterPhy); } catch (Exception e) { - LOGGER.error("method=GroupMetricCollector||clusterPhyId={}||msg=exception!", clusterPhyId, e); + LOGGER.error("method=collectKafkaMetrics||clusterPhyId={}||msg=exception!", clusterPhyId, e); } - if(CollectionUtils.isEmpty(groups)){return;} + if(ValidateUtils.isEmptyList(groupNameList)) { + return Collections.emptyList(); + } - List items = versionControlService.listVersionControlItem(clusterPhyId, collectorType().getCode()); + List items = versionControlService.listVersionControlItem(this.getClusterVersion(clusterPhy), collectorType().getCode()); - FutureWaitUtil future = getFutureUtilByClusterPhyId(clusterPhyId); + FutureWaitUtil future = this.getFutureUtilByClusterPhyId(clusterPhyId); Map> metricsMap = new ConcurrentHashMap<>(); - for(String groupName : groups) { + for(String groupName : groupNameList) { future.runnableTask( - String.format("method=GroupMetricCollector||clusterPhyId=%d||groupName=%s", clusterPhyId, groupName), + String.format("class=GroupMetricCollector||clusterPhyId=%d||groupName=%s", clusterPhyId, groupName), 30000, () -> collectMetrics(clusterPhyId, groupName, metricsMap, items)); } future.waitResult(30000); - List metricsList = new ArrayList<>(); - metricsMap.values().forEach(elem -> metricsList.addAll(elem)); + List metricsList = metricsMap.values().stream().collect(ArrayList::new, ArrayList::addAll, ArrayList::addAll); publishMetric(new GroupMetricEvent(this, metricsList)); - - LOGGER.info("method=GroupMetricCollector||clusterPhyId={}||startTime={}||cost={}||msg=collect finished.", - clusterPhyId, startTime, System.currentTimeMillis() - startTime); + return metricsList; } @Override @@ -91,9 +84,7 @@ public class GroupMetricCollector extends AbstractMetricCollector> metricsMap, List items) { long startTime = System.currentTimeMillis(); - List groupMetricsList = new ArrayList<>(); - - Map tpGroupPOMap = new HashMap<>(); + Map subMetricMap = new HashMap<>(); GroupMetrics groupMetrics = new GroupMetrics(clusterPhyId, groupName, true); groupMetrics.putMetric(Constant.COLLECT_METRICS_COST_TIME_METRICS_NAME, Constant.COLLECT_METRICS_ERROR_COST_TIME); @@ -107,38 +98,31 @@ public class GroupMetricCollector extends AbstractMetricCollector { + ret.getData().forEach(metrics -> { if (metrics.isBGroupMetric()) { groupMetrics.putMetric(metrics.getMetrics()); - } else { - String topicName = metrics.getTopic(); - Integer partitionId = metrics.getPartitionId(); - String tpGroupKey = genTopicPartitionGroupKey(topicName, partitionId); - - tpGroupPOMap.putIfAbsent(tpGroupKey, new GroupMetrics(clusterPhyId, partitionId, topicName, groupName, false)); - tpGroupPOMap.get(tpGroupKey).putMetric(metrics.getMetrics()); + return; } - }); - if(!EnvUtil.isOnline()){ - LOGGER.info("method=GroupMetricCollector||clusterPhyId={}||groupName={}||metricName={}||metricValue={}", - clusterPhyId, groupName, metricName, JSON.toJSONString(ret.getData())); - } - }catch (Exception e){ - LOGGER.error("method=GroupMetricCollector||clusterPhyId={}||groupName={}||errMsg=exception!", clusterPhyId, groupName, e); + TopicPartition tp = new TopicPartition(metrics.getTopic(), metrics.getPartitionId()); + subMetricMap.putIfAbsent(tp, new GroupMetrics(clusterPhyId, metrics.getPartitionId(), metrics.getTopic(), groupName, false)); + subMetricMap.get(tp).putMetric(metrics.getMetrics()); + }); + } catch (Exception e) { + LOGGER.error( + "method=collectMetrics||clusterPhyId={}||groupName={}||errMsg=exception!", + clusterPhyId, groupName, e + ); } } - groupMetricsList.add(groupMetrics); - groupMetricsList.addAll(tpGroupPOMap.values()); + List metricsList = new ArrayList<>(); + metricsList.add(groupMetrics); + metricsList.addAll(subMetricMap.values()); // 记录采集性能 groupMetrics.putMetric(Constant.COLLECT_METRICS_COST_TIME_METRICS_NAME, (System.currentTimeMillis() - startTime) / 1000.0f); - metricsMap.put(groupName, groupMetricsList); - } - - private String genTopicPartitionGroupKey(String topic, Integer partitionId){ - return topic + "@" + partitionId; + metricsMap.put(groupName, metricsList); } } diff --git a/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/metric/PartitionMetricCollector.java b/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/metric/kafka/PartitionMetricCollector.java similarity index 72% rename from km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/metric/PartitionMetricCollector.java rename to km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/metric/kafka/PartitionMetricCollector.java index 89363652..30d2cf4b 100644 --- a/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/metric/PartitionMetricCollector.java +++ b/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/metric/kafka/PartitionMetricCollector.java @@ -1,4 +1,4 @@ -package com.xiaojukeji.know.streaming.km.collector.metric; +package com.xiaojukeji.know.streaming.km.collector.metric.kafka; import com.didiglobal.logi.log.ILog; import com.didiglobal.logi.log.LogFactory; @@ -9,8 +9,6 @@ import com.xiaojukeji.know.streaming.km.common.bean.entity.topic.Topic; import com.xiaojukeji.know.streaming.km.common.bean.entity.version.VersionControlItem; import com.xiaojukeji.know.streaming.km.common.bean.event.metric.PartitionMetricEvent; import com.xiaojukeji.know.streaming.km.common.enums.version.VersionItemTypeEnum; -import com.xiaojukeji.know.streaming.km.common.utils.ConvertUtil; -import com.xiaojukeji.know.streaming.km.common.utils.EnvUtil; import com.xiaojukeji.know.streaming.km.common.utils.FutureWaitUtil; import com.xiaojukeji.know.streaming.km.core.service.partition.PartitionMetricService; import com.xiaojukeji.know.streaming.km.core.service.topic.TopicService; @@ -27,8 +25,8 @@ import static com.xiaojukeji.know.streaming.km.common.enums.version.VersionItemT * @author didi */ @Component -public class PartitionMetricCollector extends AbstractMetricCollector { - protected static final ILog LOGGER = LogFactory.getLog("METRIC_LOGGER"); +public class PartitionMetricCollector extends AbstractKafkaMetricCollector { + protected static final ILog LOGGER = LogFactory.getLog(PartitionMetricCollector.class); @Autowired private VersionControlService versionControlService; @@ -40,13 +38,10 @@ public class PartitionMetricCollector extends AbstractMetricCollector collectKafkaMetrics(ClusterPhy clusterPhy) { Long clusterPhyId = clusterPhy.getId(); List topicList = topicService.listTopicsFromCacheFirst(clusterPhyId); - List items = versionControlService.listVersionControlItem(clusterPhyId, collectorType().getCode()); - - // 获取集群所有分区 + List items = versionControlService.listVersionControlItem(this.getClusterVersion(clusterPhy), collectorType().getCode()); FutureWaitUtil future = this.getFutureUtilByClusterPhyId(clusterPhyId); @@ -55,9 +50,9 @@ public class PartitionMetricCollector extends AbstractMetricCollector()); future.runnableTask( - String.format("method=PartitionMetricCollector||clusterPhyId=%d||topicName=%s", clusterPhyId, topic.getTopicName()), + String.format("class=PartitionMetricCollector||clusterPhyId=%d||topicName=%s", clusterPhyId, topic.getTopicName()), 30000, - () -> collectMetrics(clusterPhyId, topic.getTopicName(), metricsMap.get(topic.getTopicName()), items) + () -> this.collectMetrics(clusterPhyId, topic.getTopicName(), metricsMap.get(topic.getTopicName()), items) ); } @@ -68,10 +63,7 @@ public class PartitionMetricCollector extends AbstractMetricCollector> { - protected static final ILog LOGGER = LogFactory.getLog("METRIC_LOGGER"); +public class TopicMetricCollector extends AbstractKafkaMetricCollector { + protected static final ILog LOGGER = LogFactory.getLog(TopicMetricCollector.class); @Autowired private VersionControlService versionControlService; @@ -46,11 +44,10 @@ public class TopicMetricCollector extends AbstractMetricCollector collectKafkaMetrics(ClusterPhy clusterPhy) { Long clusterPhyId = clusterPhy.getId(); List topics = topicService.listTopicsFromCacheFirst(clusterPhyId); - List items = versionControlService.listVersionControlItem(clusterPhyId, collectorType().getCode()); + List items = versionControlService.listVersionControlItem(this.getClusterVersion(clusterPhy), collectorType().getCode()); FutureWaitUtil future = this.getFutureUtilByClusterPhyId(clusterPhyId); @@ -64,7 +61,7 @@ public class TopicMetricCollector extends AbstractMetricCollector collectMetrics(clusterPhyId, topic.getTopicName(), metricsMap, items) ); @@ -77,8 +74,7 @@ public class TopicMetricCollector extends AbstractMetricCollector { - protected static final ILog LOGGER = LogFactory.getLog("METRIC_LOGGER"); +public class ZookeeperMetricCollector extends AbstractKafkaMetricCollector { + protected static final ILog LOGGER = LogFactory.getLog(ZookeeperMetricCollector.class); @Autowired private VersionControlService versionControlService; @@ -51,21 +49,21 @@ public class ZookeeperMetricCollector extends AbstractMetricCollector collectKafkaMetrics(ClusterPhy clusterPhy) { Long startTime = System.currentTimeMillis(); Long clusterPhyId = clusterPhy.getId(); - List items = versionControlService.listVersionControlItem(clusterPhyId, collectorType().getCode()); + List items = versionControlService.listVersionControlItem(this.getClusterVersion(clusterPhy), collectorType().getCode()); List aliveZKList = zookeeperService.listFromDBByCluster(clusterPhyId) .stream() .filter(elem -> Constant.ALIVE.equals(elem.getStatus())) .collect(Collectors.toList()); KafkaController kafkaController = kafkaControllerService.getKafkaControllerFromDB(clusterPhyId); - ZookeeperMetrics metrics = ZookeeperMetrics.initWithMetric(clusterPhyId, Constant.COLLECT_METRICS_COST_TIME_METRICS_NAME, (float)Constant.INVALID_CODE); + ZookeeperMetrics metrics = ZookeeperMetrics.initWithMetric(clusterPhyId, Constant.COLLECT_METRICS_COST_TIME_METRICS_NAME, Constant.COLLECT_METRICS_ERROR_COST_TIME); if (ValidateUtils.isEmptyList(aliveZKList)) { // 没有存活的ZK时,发布事件,然后直接返回 - publishMetric(new ZookeeperMetricEvent(this, Arrays.asList(metrics))); - return; + publishMetric(new ZookeeperMetricEvent(this, Collections.singletonList(metrics))); + return Collections.singletonList(metrics); } // 构造参数 @@ -82,6 +80,7 @@ public class ZookeeperMetricCollector extends AbstractMetricCollector ret = zookeeperMetricService.collectMetricsFromZookeeper(param); @@ -90,16 +89,9 @@ public class ZookeeperMetricCollector extends AbstractMetricCollector closeOldAndCreateNew(Long shardId) { // 新的 FutureWaitUtil newFutureUtil = FutureWaitUtil.init( - "CollectorMetricsFutureUtil-Shard-" + shardId, + "MetricCollect-Shard-" + shardId, this.futureUtilThreadNum, this.futureUtilThreadNum, this.futureUtilQueueSize diff --git a/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/AbstractMetricESSender.java b/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/AbstractMetricESSender.java index d3192f1f..c8756491 100644 --- a/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/AbstractMetricESSender.java +++ b/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/AbstractMetricESSender.java @@ -3,67 +3,47 @@ package com.xiaojukeji.know.streaming.km.collector.sink; import com.didiglobal.logi.log.ILog; import com.didiglobal.logi.log.LogFactory; import com.xiaojukeji.know.streaming.km.common.bean.po.BaseESPO; -import com.xiaojukeji.know.streaming.km.common.utils.EnvUtil; -import com.xiaojukeji.know.streaming.km.common.utils.NamedThreadFactory; +import com.xiaojukeji.know.streaming.km.common.utils.FutureUtil; import com.xiaojukeji.know.streaming.km.persistence.es.dao.BaseMetricESDAO; import org.apache.commons.collections.CollectionUtils; import java.util.List; import java.util.Objects; -import java.util.concurrent.LinkedBlockingDeque; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; public abstract class AbstractMetricESSender { - protected static final ILog LOGGER = LogFactory.getLog("METRIC_LOGGER"); + private static final ILog LOGGER = LogFactory.getLog(AbstractMetricESSender.class); - private static final int THRESHOLD = 100; + private static final int THRESHOLD = 100; - private static final ThreadPoolExecutor esExecutor = new ThreadPoolExecutor( + private static final FutureUtil esExecutor = FutureUtil.init( + "MetricsESSender", 10, 20, - 6000, - TimeUnit.MILLISECONDS, - new LinkedBlockingDeque<>(1000), - new NamedThreadFactory("KM-Collect-MetricESSender-ES"), - (r, e) -> LOGGER.warn("class=MetricESSender||msg=KM-Collect-MetricESSender-ES Deque is blocked, taskCount:{}" + e.getTaskCount()) + 10000 ); /** * 根据不同监控维度来发送 */ - protected boolean send2es(String index, List statsList){ + protected boolean send2es(String index, List statsList) { + LOGGER.info("method=send2es||indexName={}||metricsSize={}||msg=send metrics to es", index, statsList.size()); + if (CollectionUtils.isEmpty(statsList)) { return true; } - if (!EnvUtil.isOnline()) { - LOGGER.info("class=MetricESSender||method=send2es||ariusStats={}||size={}", - index, statsList.size()); - } - BaseMetricESDAO baseMetricESDao = BaseMetricESDAO.getByStatsType(index); - if (Objects.isNull( baseMetricESDao )) { - LOGGER.error("class=MetricESSender||method=send2es||errMsg=fail to find {}", index); + if (Objects.isNull(baseMetricESDao)) { + LOGGER.error("method=send2es||indexName={}||errMsg=find dao failed", index); return false; } - int size = statsList.size(); - int num = (size) % THRESHOLD == 0 ? (size / THRESHOLD) : (size / THRESHOLD + 1); + for (int i = 0; i < statsList.size(); i += THRESHOLD) { + final int idxStart = i; - if (size < THRESHOLD) { - esExecutor.execute( - () -> baseMetricESDao.batchInsertStats(statsList) - ); - return true; - } - - for (int i = 1; i < num + 1; i++) { - int end = (i * THRESHOLD) > size ? size : (i * THRESHOLD); - int start = (i - 1) * THRESHOLD; - - esExecutor.execute( - () -> baseMetricESDao.batchInsertStats(statsList.subList(start, end)) + // 异步发送 + esExecutor.submitTask( + () -> baseMetricESDao.batchInsertStats(statsList.subList(idxStart, Math.min(idxStart + THRESHOLD, statsList.size()))) ); } diff --git a/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/ReplicaMetricESSender.java b/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/ReplicaMetricESSender.java deleted file mode 100644 index 76b2aa2a..00000000 --- a/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/ReplicaMetricESSender.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.xiaojukeji.know.streaming.km.collector.sink; - -import com.didiglobal.logi.log.ILog; -import com.didiglobal.logi.log.LogFactory; -import com.xiaojukeji.know.streaming.km.common.bean.event.metric.ReplicaMetricEvent; -import com.xiaojukeji.know.streaming.km.common.bean.po.metrice.ReplicationMetricPO; -import com.xiaojukeji.know.streaming.km.common.utils.ConvertUtil; -import org.springframework.context.ApplicationListener; -import org.springframework.stereotype.Component; - -import javax.annotation.PostConstruct; - -import static com.xiaojukeji.know.streaming.km.common.constant.ESIndexConstant.REPLICATION_INDEX; - -@Component -public class ReplicaMetricESSender extends AbstractMetricESSender implements ApplicationListener { - protected static final ILog LOGGER = LogFactory.getLog("METRIC_LOGGER"); - - @PostConstruct - public void init(){ - LOGGER.info("class=GroupMetricESSender||method=init||msg=init finished"); - } - - @Override - public void onApplicationEvent(ReplicaMetricEvent event) { - send2es(REPLICATION_INDEX, ConvertUtil.list2List(event.getReplicationMetrics(), ReplicationMetricPO.class)); - } -} diff --git a/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/connect/ConnectClusterMetricESSender.java b/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/connect/ConnectClusterMetricESSender.java new file mode 100644 index 00000000..25bd7a3a --- /dev/null +++ b/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/connect/ConnectClusterMetricESSender.java @@ -0,0 +1,33 @@ +package com.xiaojukeji.know.streaming.km.collector.sink.connect; + +import com.didiglobal.logi.log.ILog; +import com.didiglobal.logi.log.LogFactory; +import com.xiaojukeji.know.streaming.km.collector.sink.AbstractMetricESSender; +import com.xiaojukeji.know.streaming.km.common.bean.event.metric.connect.ConnectClusterMetricEvent; +import com.xiaojukeji.know.streaming.km.common.bean.po.metrice.connect.ConnectClusterMetricPO; +import com.xiaojukeji.know.streaming.km.common.utils.ConvertUtil; +import org.springframework.context.ApplicationListener; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; + +import static com.xiaojukeji.know.streaming.km.persistence.es.template.TemplateConstant.CONNECT_CLUSTER_INDEX; + +/** + * @author wyb + * @date 2022/11/7 + */ +@Component +public class ConnectClusterMetricESSender extends AbstractMetricESSender implements ApplicationListener { + protected static final ILog LOGGER = LogFactory.getLog(ConnectClusterMetricESSender.class); + + @PostConstruct + public void init(){ + LOGGER.info("class=ConnectClusterMetricESSender||method=init||msg=init finished"); + } + + @Override + public void onApplicationEvent(ConnectClusterMetricEvent event) { + send2es(CONNECT_CLUSTER_INDEX, ConvertUtil.list2List(event.getConnectClusterMetrics(), ConnectClusterMetricPO.class)); + } +} diff --git a/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/connect/ConnectorMetricESSender.java b/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/connect/ConnectorMetricESSender.java new file mode 100644 index 00000000..4234c974 --- /dev/null +++ b/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/connect/ConnectorMetricESSender.java @@ -0,0 +1,33 @@ +package com.xiaojukeji.know.streaming.km.collector.sink.connect; + +import com.didiglobal.logi.log.ILog; +import com.didiglobal.logi.log.LogFactory; +import com.xiaojukeji.know.streaming.km.collector.sink.AbstractMetricESSender; +import com.xiaojukeji.know.streaming.km.common.bean.event.metric.connect.ConnectorMetricEvent; +import com.xiaojukeji.know.streaming.km.common.bean.po.metrice.connect.ConnectorMetricPO; +import com.xiaojukeji.know.streaming.km.common.utils.ConvertUtil; +import org.springframework.context.ApplicationListener; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; + +import static com.xiaojukeji.know.streaming.km.persistence.es.template.TemplateConstant.CONNECT_CONNECTOR_INDEX; + +/** + * @author wyb + * @date 2022/11/7 + */ +@Component +public class ConnectorMetricESSender extends AbstractMetricESSender implements ApplicationListener { + protected static final ILog LOGGER = LogFactory.getLog(ConnectorMetricESSender.class); + + @PostConstruct + public void init(){ + LOGGER.info("class=ConnectorMetricESSender||method=init||msg=init finished"); + } + + @Override + public void onApplicationEvent(ConnectorMetricEvent event) { + send2es(CONNECT_CONNECTOR_INDEX, ConvertUtil.list2List(event.getConnectorMetricsList(), ConnectorMetricPO.class)); + } +} diff --git a/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/BrokerMetricESSender.java b/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/kafka/BrokerMetricESSender.java similarity index 68% rename from km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/BrokerMetricESSender.java rename to km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/kafka/BrokerMetricESSender.java index 6708ba38..1c074df5 100644 --- a/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/BrokerMetricESSender.java +++ b/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/kafka/BrokerMetricESSender.java @@ -1,7 +1,8 @@ -package com.xiaojukeji.know.streaming.km.collector.sink; +package com.xiaojukeji.know.streaming.km.collector.sink.kafka; import com.didiglobal.logi.log.ILog; import com.didiglobal.logi.log.LogFactory; +import com.xiaojukeji.know.streaming.km.collector.sink.AbstractMetricESSender; import com.xiaojukeji.know.streaming.km.common.bean.event.metric.BrokerMetricEvent; import com.xiaojukeji.know.streaming.km.common.bean.po.metrice.BrokerMetricPO; import com.xiaojukeji.know.streaming.km.common.utils.ConvertUtil; @@ -10,15 +11,15 @@ import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; -import static com.xiaojukeji.know.streaming.km.common.constant.ESIndexConstant.BROKER_INDEX; +import static com.xiaojukeji.know.streaming.km.persistence.es.template.TemplateConstant.BROKER_INDEX; @Component public class BrokerMetricESSender extends AbstractMetricESSender implements ApplicationListener { - protected static final ILog LOGGER = LogFactory.getLog("METRIC_LOGGER"); + private static final ILog LOGGER = LogFactory.getLog(BrokerMetricESSender.class); @PostConstruct public void init(){ - LOGGER.info("class=BrokerMetricESSender||method=init||msg=init finished"); + LOGGER.info("method=init||msg=init finished"); } @Override diff --git a/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/ClusterMetricESSender.java b/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/kafka/ClusterMetricESSender.java similarity index 68% rename from km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/ClusterMetricESSender.java rename to km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/kafka/ClusterMetricESSender.java index 94091748..70ee3d89 100644 --- a/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/ClusterMetricESSender.java +++ b/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/kafka/ClusterMetricESSender.java @@ -1,7 +1,8 @@ -package com.xiaojukeji.know.streaming.km.collector.sink; +package com.xiaojukeji.know.streaming.km.collector.sink.kafka; import com.didiglobal.logi.log.ILog; import com.didiglobal.logi.log.LogFactory; +import com.xiaojukeji.know.streaming.km.collector.sink.AbstractMetricESSender; import com.xiaojukeji.know.streaming.km.common.bean.event.metric.ClusterMetricEvent; import com.xiaojukeji.know.streaming.km.common.bean.po.metrice.ClusterMetricPO; import com.xiaojukeji.know.streaming.km.common.utils.ConvertUtil; @@ -10,16 +11,15 @@ import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; - -import static com.xiaojukeji.know.streaming.km.common.constant.ESIndexConstant.CLUSTER_INDEX; +import static com.xiaojukeji.know.streaming.km.persistence.es.template.TemplateConstant.CLUSTER_INDEX; @Component public class ClusterMetricESSender extends AbstractMetricESSender implements ApplicationListener { - protected static final ILog LOGGER = LogFactory.getLog("METRIC_LOGGER"); + private static final ILog LOGGER = LogFactory.getLog(ClusterMetricESSender.class); @PostConstruct public void init(){ - LOGGER.info("class=ClusterMetricESSender||method=init||msg=init finished"); + LOGGER.info("method=init||msg=init finished"); } @Override diff --git a/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/GroupMetricESSender.java b/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/kafka/GroupMetricESSender.java similarity index 67% rename from km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/GroupMetricESSender.java rename to km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/kafka/GroupMetricESSender.java index cd7a2242..2192ad90 100644 --- a/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/GroupMetricESSender.java +++ b/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/kafka/GroupMetricESSender.java @@ -1,7 +1,8 @@ -package com.xiaojukeji.know.streaming.km.collector.sink; +package com.xiaojukeji.know.streaming.km.collector.sink.kafka; import com.didiglobal.logi.log.ILog; import com.didiglobal.logi.log.LogFactory; +import com.xiaojukeji.know.streaming.km.collector.sink.AbstractMetricESSender; import com.xiaojukeji.know.streaming.km.common.bean.event.metric.GroupMetricEvent; import com.xiaojukeji.know.streaming.km.common.bean.po.metrice.GroupMetricPO; import com.xiaojukeji.know.streaming.km.common.utils.ConvertUtil; @@ -10,16 +11,15 @@ import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; - -import static com.xiaojukeji.know.streaming.km.common.constant.ESIndexConstant.GROUP_INDEX; +import static com.xiaojukeji.know.streaming.km.persistence.es.template.TemplateConstant.GROUP_INDEX; @Component public class GroupMetricESSender extends AbstractMetricESSender implements ApplicationListener { - protected static final ILog LOGGER = LogFactory.getLog("METRIC_LOGGER"); + private static final ILog LOGGER = LogFactory.getLog(GroupMetricESSender.class); @PostConstruct public void init(){ - LOGGER.info("class=GroupMetricESSender||method=init||msg=init finished"); + LOGGER.info("method=init||msg=init finished"); } @Override diff --git a/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/PartitionMetricESSender.java b/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/kafka/PartitionMetricESSender.java similarity index 68% rename from km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/PartitionMetricESSender.java rename to km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/kafka/PartitionMetricESSender.java index ce108835..40087e28 100644 --- a/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/PartitionMetricESSender.java +++ b/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/kafka/PartitionMetricESSender.java @@ -1,7 +1,8 @@ -package com.xiaojukeji.know.streaming.km.collector.sink; +package com.xiaojukeji.know.streaming.km.collector.sink.kafka; import com.didiglobal.logi.log.ILog; import com.didiglobal.logi.log.LogFactory; +import com.xiaojukeji.know.streaming.km.collector.sink.AbstractMetricESSender; import com.xiaojukeji.know.streaming.km.common.bean.event.metric.PartitionMetricEvent; import com.xiaojukeji.know.streaming.km.common.bean.po.metrice.PartitionMetricPO; import com.xiaojukeji.know.streaming.km.common.utils.ConvertUtil; @@ -10,15 +11,15 @@ import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; -import static com.xiaojukeji.know.streaming.km.common.constant.ESIndexConstant.PARTITION_INDEX; +import static com.xiaojukeji.know.streaming.km.persistence.es.template.TemplateConstant.PARTITION_INDEX; @Component public class PartitionMetricESSender extends AbstractMetricESSender implements ApplicationListener { - protected static final ILog LOGGER = LogFactory.getLog("METRIC_LOGGER"); + private static final ILog LOGGER = LogFactory.getLog(PartitionMetricESSender.class); @PostConstruct public void init(){ - LOGGER.info("class=PartitionMetricESSender||method=init||msg=init finished"); + LOGGER.info("method=init||msg=init finished"); } @Override diff --git a/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/TopicMetricESSender.java b/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/kafka/TopicMetricESSender.java similarity index 67% rename from km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/TopicMetricESSender.java rename to km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/kafka/TopicMetricESSender.java index eebd82aa..fb3cff7d 100644 --- a/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/TopicMetricESSender.java +++ b/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/kafka/TopicMetricESSender.java @@ -1,7 +1,8 @@ -package com.xiaojukeji.know.streaming.km.collector.sink; +package com.xiaojukeji.know.streaming.km.collector.sink.kafka; import com.didiglobal.logi.log.ILog; import com.didiglobal.logi.log.LogFactory; +import com.xiaojukeji.know.streaming.km.collector.sink.AbstractMetricESSender; import com.xiaojukeji.know.streaming.km.common.bean.event.metric.*; import com.xiaojukeji.know.streaming.km.common.bean.po.metrice.*; import com.xiaojukeji.know.streaming.km.common.utils.ConvertUtil; @@ -10,16 +11,15 @@ import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; - -import static com.xiaojukeji.know.streaming.km.common.constant.ESIndexConstant.TOPIC_INDEX; +import static com.xiaojukeji.know.streaming.km.persistence.es.template.TemplateConstant.TOPIC_INDEX; @Component public class TopicMetricESSender extends AbstractMetricESSender implements ApplicationListener { - protected static final ILog LOGGER = LogFactory.getLog("METRIC_LOGGER"); + private static final ILog LOGGER = LogFactory.getLog(TopicMetricESSender.class); @PostConstruct public void init(){ - LOGGER.info("class=TopicMetricESSender||method=init||msg=init finished"); + LOGGER.info("method=init||msg=init finished"); } @Override diff --git a/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/ZookeeperMetricESSender.java b/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/kafka/ZookeeperMetricESSender.java similarity index 68% rename from km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/ZookeeperMetricESSender.java rename to km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/kafka/ZookeeperMetricESSender.java index 4f9dad53..c93f4860 100644 --- a/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/ZookeeperMetricESSender.java +++ b/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/kafka/ZookeeperMetricESSender.java @@ -1,7 +1,8 @@ -package com.xiaojukeji.know.streaming.km.collector.sink; +package com.xiaojukeji.know.streaming.km.collector.sink.kafka; import com.didiglobal.logi.log.ILog; import com.didiglobal.logi.log.LogFactory; +import com.xiaojukeji.know.streaming.km.collector.sink.AbstractMetricESSender; import com.xiaojukeji.know.streaming.km.common.utils.ConvertUtil; import com.xiaojukeji.know.streaming.km.common.bean.event.metric.ZookeeperMetricEvent; import com.xiaojukeji.know.streaming.km.common.bean.po.metrice.ZookeeperMetricPO; @@ -10,15 +11,15 @@ import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; -import static com.xiaojukeji.know.streaming.km.common.constant.ESIndexConstant.ZOOKEEPER_INDEX; +import static com.xiaojukeji.know.streaming.km.persistence.es.template.TemplateConstant.ZOOKEEPER_INDEX; @Component public class ZookeeperMetricESSender extends AbstractMetricESSender implements ApplicationListener { - protected static final ILog LOGGER = LogFactory.getLog("METRIC_LOGGER"); + private static final ILog LOGGER = LogFactory.getLog(ZookeeperMetricESSender.class); @PostConstruct public void init(){ - LOGGER.info("class=ZookeeperMetricESSender||method=init||msg=init finished"); + LOGGER.info("method=init||msg=init finished"); } @Override diff --git a/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/mm2/MirrorMakerMetricESSender.java b/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/mm2/MirrorMakerMetricESSender.java new file mode 100644 index 00000000..3089a995 --- /dev/null +++ b/km-collector/src/main/java/com/xiaojukeji/know/streaming/km/collector/sink/mm2/MirrorMakerMetricESSender.java @@ -0,0 +1,33 @@ +package com.xiaojukeji.know.streaming.km.collector.sink.mm2; + +import com.didiglobal.logi.log.ILog; +import com.didiglobal.logi.log.LogFactory; +import com.xiaojukeji.know.streaming.km.collector.sink.AbstractMetricESSender; +import com.xiaojukeji.know.streaming.km.common.bean.event.metric.mm2.MirrorMakerMetricEvent; +import com.xiaojukeji.know.streaming.km.common.bean.po.metrice.mm2.MirrorMakerMetricPO; +import com.xiaojukeji.know.streaming.km.common.utils.ConvertUtil; +import org.springframework.context.ApplicationListener; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; + +import static com.xiaojukeji.know.streaming.km.persistence.es.template.TemplateConstant.CONNECT_MM2_INDEX; + +/** + * @author zengqiao + * @date 2022/12/20 + */ +@Component +public class MirrorMakerMetricESSender extends AbstractMetricESSender implements ApplicationListener { + protected static final ILog LOGGER = LogFactory.getLog(MirrorMakerMetricESSender.class); + + @PostConstruct + public void init(){ + LOGGER.info("method=init||msg=init finished"); + } + + @Override + public void onApplicationEvent(MirrorMakerMetricEvent event) { + send2es(CONNECT_MM2_INDEX, ConvertUtil.list2List(event.getMetricsList(), MirrorMakerMetricPO.class)); + } +} diff --git a/km-common/pom.xml b/km-common/pom.xml index 2e1edb75..b1dc65a7 100644 --- a/km-common/pom.xml +++ b/km-common/pom.xml @@ -87,10 +87,6 @@ 3.0.2 - - junit - junit - org.projectlombok lombok @@ -133,5 +129,9 @@ org.apache.kafka kafka_2.13 + + org.apache.kafka + connect-runtime + \ No newline at end of file diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/cluster/ClusterConnectorsOverviewDTO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/cluster/ClusterConnectorsOverviewDTO.java new file mode 100644 index 00000000..75970724 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/cluster/ClusterConnectorsOverviewDTO.java @@ -0,0 +1,28 @@ +package com.xiaojukeji.know.streaming.km.common.bean.dto.cluster; + +import com.xiaojukeji.know.streaming.km.common.bean.dto.metrices.MetricDTO; +import com.xiaojukeji.know.streaming.km.common.bean.dto.pagination.PaginationSortDTO; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; +import java.util.List; + + +/** + * @author zengqiao + * @date 22/02/24 + */ +@Data +public class ClusterConnectorsOverviewDTO extends PaginationSortDTO { + @NotNull(message = "latestMetricNames不允许为空") + @ApiModelProperty("需要指标点的信息") + private List latestMetricNames; + + @NotNull(message = "metricLines不允许为空") + @ApiModelProperty("需要指标曲线的信息") + private MetricDTO metricLines; + + @ApiModelProperty("需要排序的指标名称列表,比较第一个不为空的metric") + private List sortMetricNameList; +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/cluster/ClusterGroupsOverviewDTO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/cluster/ClusterGroupsOverviewDTO.java deleted file mode 100644 index 13d13b52..00000000 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/cluster/ClusterGroupsOverviewDTO.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.xiaojukeji.know.streaming.km.common.bean.dto.cluster; - -import com.xiaojukeji.know.streaming.km.common.bean.dto.pagination.PaginationMulFuzzySearchDTO; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; - - -/** - * @author zengqiao - * @date 22/02/24 - */ -@Data -public class ClusterGroupsOverviewDTO extends PaginationMulFuzzySearchDTO { - @ApiModelProperty("查找该Topic") - private String topicName; - - @ApiModelProperty("查找该Group") - private String groupName; -} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/cluster/ClusterMirrorMakersOverviewDTO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/cluster/ClusterMirrorMakersOverviewDTO.java new file mode 100644 index 00000000..c109ebba --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/cluster/ClusterMirrorMakersOverviewDTO.java @@ -0,0 +1,12 @@ +package com.xiaojukeji.know.streaming.km.common.bean.dto.cluster; + +import lombok.Data; + + +/** + * @author zengqiao + * @date 22/12/12 + */ +@Data +public class ClusterMirrorMakersOverviewDTO extends ClusterConnectorsOverviewDTO { +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/connect/ClusterConnectorDTO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/connect/ClusterConnectorDTO.java new file mode 100644 index 00000000..bbc84ccf --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/connect/ClusterConnectorDTO.java @@ -0,0 +1,32 @@ +package com.xiaojukeji.know.streaming.km.common.bean.dto.connect; + +import com.xiaojukeji.know.streaming.km.common.bean.dto.BaseDTO; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * @author zengqiao + * @date 2022-10-17 + */ +@Data +@NoArgsConstructor +@ApiModel(description = "集群Connector") +public class ClusterConnectorDTO extends BaseDTO { + @NotNull(message = "connectClusterId不允许为空") + @ApiModelProperty(value = "Connector集群ID", example = "1") + protected Long connectClusterId; + + @NotBlank(message = "name不允许为空串") + @ApiModelProperty(value = "Connector名称", example = "know-streaming-connector") + protected String connectorName; + + public ClusterConnectorDTO(Long connectClusterId, String connectorName) { + this.connectClusterId = connectClusterId; + this.connectorName = connectorName; + } +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/connect/cluster/ConnectClusterDTO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/connect/cluster/ConnectClusterDTO.java new file mode 100644 index 00000000..a8ca1ab2 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/connect/cluster/ConnectClusterDTO.java @@ -0,0 +1,29 @@ +package com.xiaojukeji.know.streaming.km.common.bean.dto.connect.cluster; + +import com.xiaojukeji.know.streaming.km.common.bean.dto.BaseDTO; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @author zengqiao + * @date 2022-10-17 + */ +@Data +@ApiModel(description = "集群Connector") +public class ConnectClusterDTO extends BaseDTO { + @ApiModelProperty(value = "Connect集群ID", example = "1") + private Long id; + + @ApiModelProperty(value = "Connect集群名称", example = "know-streaming") + private String name; + + @ApiModelProperty(value = "Connect集群URL", example = "http://127.0.0.1:8080") + private String clusterUrl; + + @ApiModelProperty(value = "Connect集群版本", example = "2.5.1") + private String version; + + @ApiModelProperty(value = "JMX配置", example = "") + private String jmxProperties; +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/connect/connector/ConnectorActionDTO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/connect/connector/ConnectorActionDTO.java new file mode 100644 index 00000000..f4294d68 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/connect/connector/ConnectorActionDTO.java @@ -0,0 +1,20 @@ +package com.xiaojukeji.know.streaming.km.common.bean.dto.connect.connector; + +import com.xiaojukeji.know.streaming.km.common.bean.dto.connect.ClusterConnectorDTO; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +/** + * @author zengqiao + * @date 2022-10-17 + */ +@Data +@ApiModel(description = "操作Connector") +public class ConnectorActionDTO extends ClusterConnectorDTO { + @NotBlank(message = "action不允许为空串") + @ApiModelProperty(value = "Connector名称", example = "stop|restart|resume") + private String action; +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/connect/connector/ConnectorCreateDTO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/connect/connector/ConnectorCreateDTO.java new file mode 100644 index 00000000..46639f0e --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/connect/connector/ConnectorCreateDTO.java @@ -0,0 +1,28 @@ +package com.xiaojukeji.know.streaming.km.common.bean.dto.connect.connector; + +import com.xiaojukeji.know.streaming.km.common.bean.dto.connect.ClusterConnectorDTO; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotNull; +import java.util.Properties; + +/** + * @author zengqiao + * @date 2022-10-17 + */ +@Data +@NoArgsConstructor +@ApiModel(description = "创建Connector") +public class ConnectorCreateDTO extends ClusterConnectorDTO { + @NotNull(message = "configs不允许为空") + @ApiModelProperty(value = "配置", example = "") + protected Properties configs; + + public ConnectorCreateDTO(Long connectClusterId, String connectorName, Properties configs) { + super(connectClusterId, connectorName); + this.configs = configs; + } +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/connect/connector/ConnectorDeleteDTO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/connect/connector/ConnectorDeleteDTO.java new file mode 100644 index 00000000..55dce017 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/connect/connector/ConnectorDeleteDTO.java @@ -0,0 +1,14 @@ +package com.xiaojukeji.know.streaming.km.common.bean.dto.connect.connector; + +import com.xiaojukeji.know.streaming.km.common.bean.dto.connect.ClusterConnectorDTO; +import io.swagger.annotations.ApiModel; +import lombok.Data; + +/** + * @author zengqiao + * @date 2022-10-17 + */ +@Data +@ApiModel(description = "删除Connector") +public class ConnectorDeleteDTO extends ClusterConnectorDTO { +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/connect/mm2/MirrorMaker2ActionDTO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/connect/mm2/MirrorMaker2ActionDTO.java new file mode 100644 index 00000000..1d06c6af --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/connect/mm2/MirrorMaker2ActionDTO.java @@ -0,0 +1,15 @@ +package com.xiaojukeji.know.streaming.km.common.bean.dto.connect.mm2; + +import com.xiaojukeji.know.streaming.km.common.bean.dto.connect.connector.ConnectorActionDTO; +import io.swagger.annotations.ApiModel; +import lombok.Data; + + +/** + * @author zengqiao + * @date 2022-12-12 + */ +@Data +@ApiModel(description = "操作MM2") +public class MirrorMaker2ActionDTO extends ConnectorActionDTO { +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/connect/mm2/MirrorMaker2DeleteDTO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/connect/mm2/MirrorMaker2DeleteDTO.java new file mode 100644 index 00000000..9b219cfc --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/connect/mm2/MirrorMaker2DeleteDTO.java @@ -0,0 +1,14 @@ +package com.xiaojukeji.know.streaming.km.common.bean.dto.connect.mm2; + +import com.xiaojukeji.know.streaming.km.common.bean.dto.connect.connector.ConnectorDeleteDTO; +import io.swagger.annotations.ApiModel; +import lombok.Data; + +/** + * @author zengqiao + * @date 2022-12-12 + */ +@Data +@ApiModel(description = "删除MM2") +public class MirrorMaker2DeleteDTO extends ConnectorDeleteDTO { +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/connect/mm2/MirrorMakerCreateDTO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/connect/mm2/MirrorMakerCreateDTO.java new file mode 100644 index 00000000..fa9867ec --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/connect/mm2/MirrorMakerCreateDTO.java @@ -0,0 +1,69 @@ +package com.xiaojukeji.know.streaming.km.common.bean.dto.connect.mm2; + +import com.xiaojukeji.know.streaming.km.common.bean.dto.connect.connector.ConnectorCreateDTO; +import com.xiaojukeji.know.streaming.km.common.constant.connect.KafkaConnectConstant; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.apache.kafka.clients.CommonClientConfigs; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import java.util.Properties; + +/** + * @author zengqiao + * @date 2022-12-12 + */ +@Data +@ApiModel(description = "创建MM2") +public class MirrorMakerCreateDTO extends ConnectorCreateDTO { + @NotNull(message = "sourceKafkaClusterId不允许为空") + @ApiModelProperty(value = "源Kafka集群ID", example = "") + private Long sourceKafkaClusterId; + + @Valid + @ApiModelProperty(value = "heartbeat-connector的信息", example = "") + private Properties heartbeatConnectorConfigs; + + @Valid + @ApiModelProperty(value = "checkpoint-connector的信息", example = "") + private Properties checkpointConnectorConfigs; + + public void unifyData(Long sourceKafkaClusterId, String sourceBootstrapServers, Properties sourceKafkaProps, + Long targetKafkaClusterId, String targetBootstrapServers, Properties targetKafkaProps) { + if (sourceKafkaProps == null) { + sourceKafkaProps = new Properties(); + } + + if (targetKafkaProps == null) { + targetKafkaProps = new Properties(); + } + + this.unifyData(this.configs, sourceKafkaClusterId, sourceBootstrapServers, sourceKafkaProps, targetKafkaClusterId, targetBootstrapServers, targetKafkaProps); + + if (heartbeatConnectorConfigs != null) { + this.unifyData(this.heartbeatConnectorConfigs, sourceKafkaClusterId, sourceBootstrapServers, sourceKafkaProps, targetKafkaClusterId, targetBootstrapServers, targetKafkaProps); + } + + if (checkpointConnectorConfigs != null) { + this.unifyData(this.checkpointConnectorConfigs, sourceKafkaClusterId, sourceBootstrapServers, sourceKafkaProps, targetKafkaClusterId, targetBootstrapServers, targetKafkaProps); + } + } + + private void unifyData(Properties dataConfig, + Long sourceKafkaClusterId, String sourceBootstrapServers, Properties sourceKafkaProps, + Long targetKafkaClusterId, String targetBootstrapServers, Properties targetKafkaProps) { + dataConfig.put(KafkaConnectConstant.MIRROR_MAKER_SOURCE_CLUSTER_ALIAS_FIELD_NAME, sourceKafkaClusterId); + dataConfig.put(KafkaConnectConstant.MIRROR_MAKER_SOURCE_CLUSTER_FIELD_NAME + "." + CommonClientConfigs.BOOTSTRAP_SERVERS_CONFIG, sourceBootstrapServers); + for (Object configKey: sourceKafkaProps.keySet()) { + dataConfig.put(KafkaConnectConstant.MIRROR_MAKER_SOURCE_CLUSTER_FIELD_NAME + "." + configKey, sourceKafkaProps.getProperty((String) configKey)); + } + + dataConfig.put(KafkaConnectConstant.MIRROR_MAKER_TARGET_CLUSTER_ALIAS_FIELD_NAME, targetKafkaClusterId); + dataConfig.put(KafkaConnectConstant.MIRROR_MAKER_TARGET_CLUSTER_FIELD_NAME + "." + CommonClientConfigs.BOOTSTRAP_SERVERS_CONFIG, targetBootstrapServers); + for (Object configKey: targetKafkaProps.keySet()) { + dataConfig.put(KafkaConnectConstant.MIRROR_MAKER_TARGET_CLUSTER_FIELD_NAME + "." + configKey, targetKafkaProps.getProperty((String) configKey)); + } + } +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/connect/task/TaskActionDTO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/connect/task/TaskActionDTO.java new file mode 100644 index 00000000..a5d99188 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/connect/task/TaskActionDTO.java @@ -0,0 +1,20 @@ +package com.xiaojukeji.know.streaming.km.common.bean.dto.connect.task; + +import com.xiaojukeji.know.streaming.km.common.bean.dto.connect.connector.ConnectorActionDTO; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * @author zengqiao + * @date 2022-10-17 + */ +@Data +@ApiModel(description = "操作Task") +public class TaskActionDTO extends ConnectorActionDTO { + @NotNull(message = "taskId不允许为NULL") + @ApiModelProperty(value = "taskId", example = "123") + private Long taskId; +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/ha/mirror/MirrorTopicCreateDTO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/ha/mirror/MirrorTopicCreateDTO.java new file mode 100644 index 00000000..58182670 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/ha/mirror/MirrorTopicCreateDTO.java @@ -0,0 +1,38 @@ +package com.xiaojukeji.know.streaming.km.common.bean.dto.ha.mirror; + +import com.xiaojukeji.know.streaming.km.common.bean.dto.BaseDTO; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * @author zengqiao + * @date 20/4/23 + */ +@Data +@ApiModel(description="Topic镜像信息") +public class MirrorTopicCreateDTO extends BaseDTO { + @Min(value = 0, message = "sourceClusterPhyId不允许为空,且最小值为0") + @ApiModelProperty(value = "源集群ID", example = "3") + private Long sourceClusterPhyId; + + @Min(value = 0, message = "destClusterPhyId不允许为空,且最小值为0") + @ApiModelProperty(value = "目标集群ID", example = "3") + private Long destClusterPhyId; + + @NotBlank(message = "topicName不允许为空串") + @ApiModelProperty(value = "Topic名称", example = "mirrorTopic") + private String topicName; + + @NotNull(message = "syncData不允许为空") + @ApiModelProperty(value = "同步数据", example = "true") + private Boolean syncData; + + @NotNull(message = "syncConfig不允许为空") + @ApiModelProperty(value = "同步配置", example = "false") + private Boolean syncConfig; +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/ha/mirror/MirrorTopicDeleteDTO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/ha/mirror/MirrorTopicDeleteDTO.java new file mode 100644 index 00000000..8b7d0095 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/ha/mirror/MirrorTopicDeleteDTO.java @@ -0,0 +1,29 @@ +package com.xiaojukeji.know.streaming.km.common.bean.dto.ha.mirror; + +import com.xiaojukeji.know.streaming.km.common.bean.dto.BaseDTO; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotBlank; + +/** + * @author zengqiao + * @date 20/4/23 + */ +@Data +@ApiModel(description="Topic镜像信息") +public class MirrorTopicDeleteDTO extends BaseDTO { + @Min(value = 0, message = "sourceClusterPhyId不允许为空,且最小值为0") + @ApiModelProperty(value = "源集群ID", example = "3") + private Long sourceClusterPhyId; + + @Min(value = 0, message = "destClusterPhyId不允许为空,且最小值为0") + @ApiModelProperty(value = "目标集群ID", example = "3") + private Long destClusterPhyId; + + @NotBlank(message = "topicName不允许为空串") + @ApiModelProperty(value = "Topic名称", example = "mirrorTopic") + private String topicName; +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/metrices/connect/MetricsConnectClustersDTO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/metrices/connect/MetricsConnectClustersDTO.java new file mode 100644 index 00000000..7986553c --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/metrices/connect/MetricsConnectClustersDTO.java @@ -0,0 +1,22 @@ +package com.xiaojukeji.know.streaming.km.common.bean.dto.metrices.connect; + +import com.xiaojukeji.know.streaming.km.common.bean.dto.metrices.MetricDTO; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @author didi + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel(description = "Connect集群指标查询信息") +public class MetricsConnectClustersDTO extends MetricDTO { + @ApiModelProperty("Connect集群ID") + private List connectClusterIdList; +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/metrices/connect/MetricsConnectorsDTO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/metrices/connect/MetricsConnectorsDTO.java new file mode 100644 index 00000000..a51700f1 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/metrices/connect/MetricsConnectorsDTO.java @@ -0,0 +1,23 @@ +package com.xiaojukeji.know.streaming.km.common.bean.dto.metrices.connect; + +import com.xiaojukeji.know.streaming.km.common.bean.dto.connect.ClusterConnectorDTO; +import com.xiaojukeji.know.streaming.km.common.bean.dto.metrices.MetricDTO; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @author didi + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel(description = "Connector指标查询信息") +public class MetricsConnectorsDTO extends MetricDTO { + @ApiModelProperty("Connector列表") + private List connectorNameList; +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/metrices/mm2/MetricsMirrorMakersDTO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/metrices/mm2/MetricsMirrorMakersDTO.java new file mode 100644 index 00000000..512832f9 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/dto/metrices/mm2/MetricsMirrorMakersDTO.java @@ -0,0 +1,23 @@ +package com.xiaojukeji.know.streaming.km.common.bean.dto.metrices.mm2; + +import com.xiaojukeji.know.streaming.km.common.bean.dto.connect.ClusterConnectorDTO; +import com.xiaojukeji.know.streaming.km.common.bean.dto.metrices.MetricDTO; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @author didi + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@ApiModel(description = "MirrorMaker指标查询信息") +public class MetricsMirrorMakersDTO extends MetricDTO { + @ApiModelProperty("MirrorMaker的SourceConnect列表") + private List connectorNameList; +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/EntifyIdInterface.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/EntityIdInterface.java similarity index 80% rename from km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/EntifyIdInterface.java rename to km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/EntityIdInterface.java index c6b42615..2f40f39c 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/EntifyIdInterface.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/EntityIdInterface.java @@ -3,7 +3,7 @@ package com.xiaojukeji.know.streaming.km.common.bean.entity; /** * @author didi */ -public interface EntifyIdInterface { +public interface EntityIdInterface { /** * 获取id * @return diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/broker/Broker.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/broker/Broker.java index 513e926e..752aade0 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/broker/Broker.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/broker/Broker.java @@ -3,7 +3,6 @@ package com.xiaojukeji.know.streaming.km.common.bean.entity.broker; import com.alibaba.fastjson.TypeReference; import com.xiaojukeji.know.streaming.km.common.bean.entity.common.IpPortData; -import com.xiaojukeji.know.streaming.km.common.bean.entity.config.JmxConfig; import com.xiaojukeji.know.streaming.km.common.bean.po.broker.BrokerPO; import com.xiaojukeji.know.streaming.km.common.utils.ConvertUtil; import lombok.AllArgsConstructor; @@ -66,13 +65,13 @@ public class Broker implements Serializable { */ private Map endpointMap; - public static Broker buildFrom(Long clusterPhyId, Node node, Long startTimestamp, JmxConfig jmxConfig) { + public static Broker buildFrom(Long clusterPhyId, Node node, Long startTimestamp) { Broker metadata = new Broker(); metadata.setClusterPhyId(clusterPhyId); metadata.setBrokerId(node.id()); metadata.setHost(node.host()); metadata.setPort(node.port()); - metadata.setJmxPort(jmxConfig != null ? jmxConfig.getJmxPort() : -1); + metadata.setJmxPort(-1); metadata.setStartTimestamp(startTimestamp); metadata.setRack(node.rack()); metadata.setStatus(1); diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/cluster/ClusterPhy.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/cluster/ClusterPhy.java index 823ec67d..a534a015 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/cluster/ClusterPhy.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/cluster/ClusterPhy.java @@ -1,6 +1,6 @@ package com.xiaojukeji.know.streaming.km.common.bean.entity.cluster; -import com.xiaojukeji.know.streaming.km.common.bean.entity.EntifyIdInterface; +import com.xiaojukeji.know.streaming.km.common.bean.entity.EntityIdInterface; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -10,7 +10,7 @@ import java.util.Date; @Data @NoArgsConstructor @AllArgsConstructor -public class ClusterPhy implements Comparable, EntifyIdInterface { +public class ClusterPhy implements Comparable, EntityIdInterface { /** * 主键 */ diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/cluster/ClusterPhysState.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/cluster/ClusterPhysState.java index 38daaebc..2f1abc29 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/cluster/ClusterPhysState.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/cluster/ClusterPhysState.java @@ -18,5 +18,7 @@ public class ClusterPhysState { private Integer downCount; + private Integer unknownCount; + private Integer total; } diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/config/ZKConfig.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/config/ZKConfig.java index 66a727e5..f0fe41d0 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/config/ZKConfig.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/config/ZKConfig.java @@ -13,9 +13,6 @@ import java.util.Properties; */ @ApiModel(description = "ZK配置") public class ZKConfig implements Serializable { - @ApiModelProperty(value="ZK的jmx配置") - private JmxConfig jmxConfig; - @ApiModelProperty(value="ZK是否开启secure", example = "false") private Boolean openSecure = false; @@ -28,14 +25,6 @@ public class ZKConfig implements Serializable { @ApiModelProperty(value="ZK的Request超时时间") private Properties otherProps = new Properties(); - public JmxConfig getJmxConfig() { - return jmxConfig == null? new JmxConfig(): jmxConfig; - } - - public void setJmxConfig(JmxConfig jmxConfig) { - this.jmxConfig = jmxConfig; - } - public Boolean getOpenSecure() { return openSecure != null && openSecure; } @@ -53,7 +42,7 @@ public class ZKConfig implements Serializable { } public Integer getRequestTimeoutUnitMs() { - return requestTimeoutUnitMs == null? Constant.DEFAULT_REQUEST_TIMEOUT_UNIT_MS: requestTimeoutUnitMs; + return requestTimeoutUnitMs == null? Constant.DEFAULT_SESSION_TIMEOUT_UNIT_MS: requestTimeoutUnitMs; } public void setRequestTimeoutUnitMs(Integer requestTimeoutUnitMs) { diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/config/metric/UserMetricConfig.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/config/metric/UserMetricConfig.java index e244181a..171cd68f 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/config/metric/UserMetricConfig.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/config/metric/UserMetricConfig.java @@ -1,7 +1,5 @@ package com.xiaojukeji.know.streaming.km.common.bean.entity.config.metric; -import com.xiaojukeji.know.streaming.km.common.constant.Constant; -import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/ConnectCluster.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/ConnectCluster.java new file mode 100644 index 00000000..a4c67bbc --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/ConnectCluster.java @@ -0,0 +1,61 @@ +package com.xiaojukeji.know.streaming.km.common.bean.entity.connect; + +import com.xiaojukeji.know.streaming.km.common.bean.entity.EntityIdInterface; +import lombok.Data; + +import java.io.Serializable; + +@Data +public class ConnectCluster implements Serializable, Comparable, EntityIdInterface { + /** + * 集群ID + */ + private Long id; + + /** + * 集群名字 + */ + private String name; + + /** + * 集群使用的消费组 + */ + private String groupName; + + /** + * 集群使用的消费组状态,也表示集群状态 + * @see com.xiaojukeji.know.streaming.km.common.enums.group.GroupStateEnum + */ + private Integer state; + + /** + * worker中显示的leader url信息 + */ + private String memberLeaderUrl; + + /** + * 版本信息 + */ + private String version; + + /** + * jmx配置 + * @see com.xiaojukeji.know.streaming.km.common.bean.entity.config.JmxConfig + */ + private String jmxProperties; + + /** + * Kafka集群ID + */ + private Long kafkaClusterPhyId; + + /** + * 集群地址 + */ + private String clusterUrl; + + @Override + public int compareTo(ConnectCluster connectCluster) { + return this.id.compareTo(connectCluster.getId()); + } +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/ConnectClusterMetadata.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/ConnectClusterMetadata.java new file mode 100644 index 00000000..b3243756 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/ConnectClusterMetadata.java @@ -0,0 +1,38 @@ +package com.xiaojukeji.know.streaming.km.common.bean.entity.connect; + +import com.xiaojukeji.know.streaming.km.common.enums.group.GroupStateEnum; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +@Data +@NoArgsConstructor +public class ConnectClusterMetadata implements Serializable { + /** + * Kafka集群名字 + */ + private Long kafkaClusterPhyId; + + /** + * 集群使用的消费组 + */ + private String groupName; + + /** + * 集群使用的消费组状态,也表示集群状态 + */ + private GroupStateEnum state; + + /** + * worker中显示的leader url信息 + */ + private String memberLeaderUrl; + + public ConnectClusterMetadata(Long kafkaClusterPhyId, String groupName, GroupStateEnum state, String memberLeaderUrl) { + this.kafkaClusterPhyId = kafkaClusterPhyId; + this.groupName = groupName; + this.state = state; + this.memberLeaderUrl = memberLeaderUrl; + } +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/ConnectWorker.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/ConnectWorker.java new file mode 100644 index 00000000..703a7bc7 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/ConnectWorker.java @@ -0,0 +1,86 @@ +package com.xiaojukeji.know.streaming.km.common.bean.entity.connect; + +import com.didiglobal.logi.log.ILog; +import com.didiglobal.logi.log.LogFactory; +import com.xiaojukeji.know.streaming.km.common.utils.CommonUtils; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +@Data +@NoArgsConstructor +public class ConnectWorker implements Serializable { + + protected static final ILog LOGGER = LogFactory.getLog(ConnectWorker.class); + + /** + * Kafka集群ID + */ + private Long kafkaClusterPhyId; + + /** + * 集群ID + */ + private Long connectClusterId; + + /** + * 成员ID + */ + private String memberId; + + /** + * 主机 + */ + private String host; + + /** + * Jmx端口 + */ + private Integer jmxPort; + + /** + * URL + */ + private String url; + + /** + * leader的URL + */ + private String leaderUrl; + + /** + * 1:是leader,0:不是leader + */ + private Integer leader; + + /** + * worker地址 + */ + private String workerId; + + public ConnectWorker(Long kafkaClusterPhyId, + Long connectClusterId, + String memberId, + String host, + Integer jmxPort, + String url, + String leaderUrl, + Integer leader) { + this.kafkaClusterPhyId = kafkaClusterPhyId; + this.connectClusterId = connectClusterId; + this.memberId = memberId; + this.host = host; + this.jmxPort = jmxPort; + this.url = url; + this.leaderUrl = leaderUrl; + this.leader = leader; + String workerId = CommonUtils.getWorkerId(url); + if (workerId == null) { + workerId = memberId; + LOGGER.error("class=ConnectWorker||connectClusterId={}||memberId={}||url={}||msg=analysis url fail" + , connectClusterId, memberId, url); + } + this.workerId = workerId; + } +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/WorkerConnector.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/WorkerConnector.java new file mode 100644 index 00000000..423e21ce --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/WorkerConnector.java @@ -0,0 +1,58 @@ +package com.xiaojukeji.know.streaming.km.common.bean.entity.connect; + +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +@Data +@NoArgsConstructor +public class WorkerConnector implements Serializable { + /** + * connect集群ID + */ + private Long connectClusterId; + + /** + * kafka集群ID + */ + private Long kafkaClusterPhyId; + + /** + * connector名称 + */ + private String connectorName; + + private String workerMemberId; + + /** + * 任务状态 + */ + private String state; + + /** + * 任务ID + */ + private Integer taskId; + + /** + * worker信息 + */ + private String workerId; + + /** + * 错误原因 + */ + private String trace; + + public WorkerConnector(Long kafkaClusterPhyId, Long connectClusterId, String connectorName, String workerMemberId, Integer taskId, String state, String workerId, String trace) { + this.kafkaClusterPhyId = kafkaClusterPhyId; + this.connectClusterId = connectClusterId; + this.connectorName = connectorName; + this.workerMemberId = workerMemberId; + this.taskId = taskId; + this.state = state; + this.workerId = workerId; + this.trace = trace; + } +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/config/ConnectConfigInfo.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/config/ConnectConfigInfo.java new file mode 100644 index 00000000..ffe8c332 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/config/ConnectConfigInfo.java @@ -0,0 +1,19 @@ +package com.xiaojukeji.know.streaming.km.common.bean.entity.connect.config; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.apache.kafka.connect.runtime.rest.entities.ConfigInfo; + + +/** + * @see ConfigInfo + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ConnectConfigInfo { + private ConnectConfigKeyInfo definition; + + private ConnectConfigValueInfo value; +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/config/ConnectConfigInfos.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/config/ConnectConfigInfos.java new file mode 100644 index 00000000..f58adbe0 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/config/ConnectConfigInfos.java @@ -0,0 +1,71 @@ +package com.xiaojukeji.know.streaming.km.common.bean.entity.connect.config; + + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.apache.kafka.connect.runtime.rest.entities.ConfigInfo; +import org.apache.kafka.connect.runtime.rest.entities.ConfigInfos; + +import java.util.*; + +import static com.xiaojukeji.know.streaming.km.common.constant.Constant.CONNECTOR_CONFIG_ACTION_RELOAD_NAME; +import static com.xiaojukeji.know.streaming.km.common.constant.Constant.CONNECTOR_CONFIG_ERRORS_TOLERANCE_NAME; + +/** + * @see ConfigInfos + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ConnectConfigInfos { + + private static final Map> recommendValuesMap = new HashMap<>(); + + static { + recommendValuesMap.put(CONNECTOR_CONFIG_ACTION_RELOAD_NAME, Arrays.asList("none", "restart")); + recommendValuesMap.put(CONNECTOR_CONFIG_ERRORS_TOLERANCE_NAME, Arrays.asList("none", "all")); + } + private String name; + + private int errorCount; + + private List groups; + + private List configs; + + public ConnectConfigInfos(ConfigInfos configInfos) { + this.name = configInfos.name(); + this.errorCount = configInfos.errorCount(); + this.groups = configInfos.groups(); + + this.configs = new ArrayList<>(); + for (ConfigInfo configInfo: configInfos.values()) { + ConnectConfigKeyInfo definition = new ConnectConfigKeyInfo(); + definition.setName(configInfo.configKey().name()); + definition.setType(configInfo.configKey().type()); + definition.setRequired(configInfo.configKey().required()); + definition.setDefaultValue(configInfo.configKey().defaultValue()); + definition.setImportance(configInfo.configKey().importance()); + definition.setDocumentation(configInfo.configKey().documentation()); + definition.setGroup(configInfo.configKey().group()); + definition.setOrderInGroup(configInfo.configKey().orderInGroup()); + definition.setWidth(configInfo.configKey().width()); + definition.setDisplayName(configInfo.configKey().displayName()); + definition.setDependents(configInfo.configKey().dependents()); + + ConnectConfigValueInfo value = new ConnectConfigValueInfo(); + value.setName(configInfo.configValue().name()); + value.setValue(configInfo.configValue().value()); + value.setRecommendedValues(recommendValuesMap.getOrDefault(configInfo.configValue().name(), configInfo.configValue().recommendedValues())); + value.setErrors(configInfo.configValue().errors()); + value.setVisible(configInfo.configValue().visible()); + + ConnectConfigInfo connectConfigInfo = new ConnectConfigInfo(); + connectConfigInfo.setDefinition(definition); + connectConfigInfo.setValue(value); + + this.configs.add(connectConfigInfo); + } + } +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/config/ConnectConfigKeyInfo.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/config/ConnectConfigKeyInfo.java new file mode 100644 index 00000000..13ada833 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/config/ConnectConfigKeyInfo.java @@ -0,0 +1,38 @@ +package com.xiaojukeji.know.streaming.km.common.bean.entity.connect.config; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.apache.kafka.connect.runtime.rest.entities.ConfigKeyInfo; + +import java.util.List; + +/** + * @see ConfigKeyInfo + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ConnectConfigKeyInfo { + private String name; + + private String type; + + private boolean required; + + private String defaultValue; + + private String importance; + + private String documentation; + + private String group; + + private int orderInGroup; + + private String width; + + private String displayName; + + private List dependents; +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/config/ConnectConfigValueInfo.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/config/ConnectConfigValueInfo.java new file mode 100644 index 00000000..af2aecf5 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/config/ConnectConfigValueInfo.java @@ -0,0 +1,27 @@ +package com.xiaojukeji.know.streaming.km.common.bean.entity.connect.config; + + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.apache.kafka.connect.runtime.rest.entities.ConfigValueInfo; + +import java.util.List; + +/** + * @see ConfigValueInfo + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ConnectConfigValueInfo { + private String name; + + private String value; + + private List recommendedValues; + + private List errors; + + private boolean visible; +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/connector/KSAbstractConnectState.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/connector/KSAbstractConnectState.java new file mode 100644 index 00000000..a5525768 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/connector/KSAbstractConnectState.java @@ -0,0 +1,20 @@ +package com.xiaojukeji.know.streaming.km.common.bean.entity.connect.connector; + +import com.alibaba.fastjson.annotation.JSONField; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import org.apache.kafka.connect.runtime.rest.entities.ConnectorStateInfo; + +/** + * @see ConnectorStateInfo.AbstractState + */ +@Data +public abstract class KSAbstractConnectState { + private String state; + + private String trace; + + @JSONField(name="worker_id") + @JsonProperty("worker_id") + private String workerId; +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/connector/KSConnector.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/connector/KSConnector.java new file mode 100644 index 00000000..6b3f7b57 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/connector/KSConnector.java @@ -0,0 +1,58 @@ +package com.xiaojukeji.know.streaming.km.common.bean.entity.connect.connector; + +import lombok.Data; + +import java.io.Serializable; + +@Data +public class KSConnector implements Serializable { + /** + * Kafka集群ID + */ + private Long kafkaClusterPhyId; + + /** + * connect集群ID + */ + private Long connectClusterId; + + /** + * connector名称 + */ + private String connectorName; + + /** + * connector类名 + */ + private String connectorClassName; + + /** + * connector类型 + */ + private String connectorType; + + /** + * 访问过的Topic列表 + */ + private String topics; + + /** + * task数 + */ + private Integer taskCount; + + /** + * 状态 + */ + private String state; + + /** + * 心跳检测connector名称 + */ + private String heartbeatConnectorName; + + /** + * 进度确认connector名称 + */ + private String checkpointConnectorName; +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/connector/KSConnectorInfo.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/connector/KSConnectorInfo.java new file mode 100644 index 00000000..f1c3ed31 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/connector/KSConnectorInfo.java @@ -0,0 +1,26 @@ +package com.xiaojukeji.know.streaming.km.common.bean.entity.connect.connector; + +import lombok.Data; +import org.apache.kafka.connect.runtime.rest.entities.ConnectorType; +import org.apache.kafka.connect.util.ConnectorTaskId; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +/** + * copy from: + * @see org.apache.kafka.connect.runtime.rest.entities.ConnectorInfo + */ +@Data +public class KSConnectorInfo implements Serializable { + private Long connectClusterId; + + private String name; + + private Map config; + + private List tasks; + + private ConnectorType type; +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/connector/KSConnectorState.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/connector/KSConnectorState.java new file mode 100644 index 00000000..9cd9ea74 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/connector/KSConnectorState.java @@ -0,0 +1,11 @@ +package com.xiaojukeji.know.streaming.km.common.bean.entity.connect.connector; + +import lombok.Data; +import org.apache.kafka.connect.runtime.rest.entities.ConnectorStateInfo; + +/** + * @see ConnectorStateInfo.ConnectorState + */ +@Data +public class KSConnectorState extends KSAbstractConnectState { +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/connector/KSConnectorStateInfo.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/connector/KSConnectorStateInfo.java new file mode 100644 index 00000000..31d6657b --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/connector/KSConnectorStateInfo.java @@ -0,0 +1,21 @@ +package com.xiaojukeji.know.streaming.km.common.bean.entity.connect.connector; + +import lombok.Data; +import org.apache.kafka.connect.runtime.rest.entities.ConnectorStateInfo; +import org.apache.kafka.connect.runtime.rest.entities.ConnectorType; + +import java.util.List; + +/** + * @see ConnectorStateInfo + */ +@Data +public class KSConnectorStateInfo { + private String name; + + private KSConnectorState connector; + + private List tasks; + + private ConnectorType type; +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/connector/KSTaskState.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/connector/KSTaskState.java new file mode 100644 index 00000000..323291b0 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/connector/KSTaskState.java @@ -0,0 +1,12 @@ +package com.xiaojukeji.know.streaming.km.common.bean.entity.connect.connector; + +import lombok.Data; +import org.apache.kafka.connect.runtime.rest.entities.ConnectorStateInfo; + +/** + * @see ConnectorStateInfo.TaskState + */ +@Data +public class KSTaskState extends KSAbstractConnectState { + private int id; +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/mm2/MirrorMakerTopic.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/mm2/MirrorMakerTopic.java new file mode 100644 index 00000000..aea8a33c --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/mm2/MirrorMakerTopic.java @@ -0,0 +1,33 @@ +package com.xiaojukeji.know.streaming.km.common.bean.entity.connect.mm2; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Map; + +/** + * @author wyb + * @date 2022/12/14 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class MirrorMakerTopic { + + /** + * mm2集群别名 + */ + private String clusterAlias; + + /** + * topic名称 + */ + private String topicName; + + /** + * partition在connect上的分布 Map + */ + private Map partitionMap; + +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/plugin/ConnectPluginBasic.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/plugin/ConnectPluginBasic.java new file mode 100644 index 00000000..82c2ad84 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/connect/plugin/ConnectPluginBasic.java @@ -0,0 +1,38 @@ +package com.xiaojukeji.know.streaming.km.common.bean.entity.connect.plugin; + +import com.alibaba.fastjson.annotation.JSONField; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModel; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * @author zengqiao + * @date 22/10/17 + */ +@Data +@ApiModel(description = "Connect插件信息") +@NoArgsConstructor +public class ConnectPluginBasic implements Serializable { + /** + * Json序列化时对应的字段 + */ + @JSONField(name="class") + @JsonProperty("class") + private String className; + + private String type; + + private String version; + + private String helpDocLink; + + public ConnectPluginBasic(String className, String type, String version, String helpDocLink) { + this.className = className; + this.type = type; + this.version = version; + this.helpDocLink = helpDocLink; + } +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/group/Group.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/group/Group.java index 3b2e22e9..656924b7 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/group/Group.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/group/Group.java @@ -1,12 +1,12 @@ package com.xiaojukeji.know.streaming.km.common.bean.entity.group; +import com.xiaojukeji.know.streaming.km.common.bean.entity.kafka.KSGroupDescription; import com.xiaojukeji.know.streaming.km.common.constant.Constant; import com.xiaojukeji.know.streaming.km.common.enums.group.GroupStateEnum; import com.xiaojukeji.know.streaming.km.common.enums.group.GroupTypeEnum; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; -import org.apache.kafka.clients.admin.ConsumerGroupDescription; import java.util.ArrayList; import java.util.List; @@ -61,14 +61,14 @@ public class Group { */ private int coordinatorId; - public Group(Long clusterPhyId, String groupName, ConsumerGroupDescription groupDescription) { + public Group(Long clusterPhyId, String groupName, KSGroupDescription groupDescription) { this.clusterPhyId = clusterPhyId; - this.type = groupDescription.isSimpleConsumerGroup()? GroupTypeEnum.CONSUMER: GroupTypeEnum.CONNECTOR; + this.type = GroupTypeEnum.getTypeByProtocolType(groupDescription.protocolType()); this.name = groupName; this.state = GroupStateEnum.getByRawState(groupDescription.state()); - this.memberCount = groupDescription.members() == null? 0: groupDescription.members().size(); + this.memberCount = groupDescription.members() == null ? 0 : groupDescription.members().size(); this.topicMembers = new ArrayList<>(); this.partitionAssignor = groupDescription.partitionAssignor(); - this.coordinatorId = groupDescription.coordinator() == null? Constant.INVALID_CODE: groupDescription.coordinator().id(); + this.coordinatorId = groupDescription.coordinator() == null ? Constant.INVALID_CODE : groupDescription.coordinator().id(); } } diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/ha/HaActiveStandbyRelation.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/ha/HaActiveStandbyRelation.java new file mode 100644 index 00000000..db306641 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/ha/HaActiveStandbyRelation.java @@ -0,0 +1,23 @@ +package com.xiaojukeji.know.streaming.km.common.bean.entity.ha; + +import com.xiaojukeji.know.streaming.km.common.bean.po.BasePO; +import com.xiaojukeji.know.streaming.km.common.enums.ha.HaResTypeEnum; +import lombok.Data; + +@Data +public class HaActiveStandbyRelation extends BasePO { + private Long activeClusterPhyId; + + private Long standbyClusterPhyId; + + /** + * 资源名称 + */ + private String resName; + + /** + * 资源类型,0:集群,1:镜像Topic,2:主备Topic + * @see HaResTypeEnum + */ + private Integer resType; +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/health/HealthCheckAggResult.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/health/HealthCheckAggResult.java index 69d65a20..afd42120 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/health/HealthCheckAggResult.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/health/HealthCheckAggResult.java @@ -14,16 +14,16 @@ import java.util.stream.Collectors; @Data @NoArgsConstructor public class HealthCheckAggResult { - private HealthCheckNameEnum checkNameEnum; + protected HealthCheckNameEnum checkNameEnum; - private List poList; + protected List poList; - private Boolean passed; + protected Boolean passed; public HealthCheckAggResult(HealthCheckNameEnum checkNameEnum, List poList) { this.checkNameEnum = checkNameEnum; this.poList = poList; - if (!ValidateUtils.isEmptyList(poList) && poList.stream().filter(elem -> elem.getPassed() <= 0).count() <= 0) { + if (ValidateUtils.isEmptyList(poList) || poList.stream().filter(elem -> elem.getPassed() <= 0).count() <= 0) { passed = true; } else { passed = false; @@ -45,24 +45,12 @@ public class HealthCheckAggResult { return (int) (poList.stream().filter(elem -> elem.getPassed() > 0).count()); } - /** - * 计算当前检查的健康分 - * 比如:计算集群Broker健康检查中的某一项的健康分 - */ - public Integer calRawHealthScore() { - if (poList == null || poList.isEmpty()) { - return 100; - } - - return 100 * this.getPassedCount() / this.getTotalCount(); - } - public List getNotPassedResNameList() { if (poList == null) { return new ArrayList<>(); } - return poList.stream().filter(elem -> elem.getPassed() <= 0).map(elem -> elem.getResName()).collect(Collectors.toList()); + return poList.stream().filter(elem -> elem.getPassed() <= 0 && !ValidateUtils.isBlank(elem.getResName())).map(elem -> elem.getResName()).collect(Collectors.toList()); } public Date getCreateTime() { diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/health/HealthScoreResult.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/health/HealthScoreResult.java index c503c129..302feb5b 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/health/HealthScoreResult.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/health/HealthScoreResult.java @@ -3,87 +3,20 @@ package com.xiaojukeji.know.streaming.km.common.bean.entity.health; import com.xiaojukeji.know.streaming.km.common.bean.entity.config.healthcheck.BaseClusterHealthConfig; import com.xiaojukeji.know.streaming.km.common.bean.po.health.HealthCheckResultPO; import com.xiaojukeji.know.streaming.km.common.enums.health.HealthCheckNameEnum; -import com.xiaojukeji.know.streaming.km.common.utils.ValidateUtils; import lombok.Data; import lombok.NoArgsConstructor; -import java.util.ArrayList; -import java.util.Date; import java.util.List; -import java.util.stream.Collectors; @Data @NoArgsConstructor -public class HealthScoreResult { - private HealthCheckNameEnum checkNameEnum; - +public class HealthScoreResult extends HealthCheckAggResult { private BaseClusterHealthConfig baseConfig; - private List poList; - - private Boolean passed; - public HealthScoreResult(HealthCheckNameEnum checkNameEnum, BaseClusterHealthConfig baseConfig, List poList) { - this.checkNameEnum = checkNameEnum; + super(checkNameEnum, poList); this.baseConfig = baseConfig; - this.poList = poList; - if (!ValidateUtils.isEmptyList(poList) && poList.stream().filter(elem -> elem.getPassed() <= 0).count() <= 0) { - passed = true; - } else { - passed = false; - } - } - - public Integer getTotalCount() { - if (poList == null) { - return 0; - } - - return poList.size(); - } - - public Integer getPassedCount() { - if (poList == null) { - return 0; - } - return (int) (poList.stream().filter(elem -> elem.getPassed() > 0).count()); - } - - /** - * 计算当前检查的健康分 - * 比如:计算集群Broker健康检查中的某一项的健康分 - */ - public Integer calRawHealthScore() { - if (poList == null || poList.isEmpty()) { - return 100; - } - - return 100 * this.getPassedCount() / this.getTotalCount(); - } - - public List getNotPassedResNameList() { - if (poList == null) { - return new ArrayList<>(); - } - - return poList.stream().filter(elem -> elem.getPassed() <= 0 && !ValidateUtils.isBlank(elem.getResName())).map(elem -> elem.getResName()).collect(Collectors.toList()); - } - - public Date getCreateTime() { - if (ValidateUtils.isEmptyList(poList)) { - return null; - } - - return poList.get(0).getCreateTime(); - } - - public Date getUpdateTime() { - if (ValidateUtils.isEmptyList(poList)) { - return null; - } - - return poList.get(0).getUpdateTime(); } } diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/kafka/KSDescribeGroupsResult.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/kafka/KSDescribeGroupsResult.java new file mode 100644 index 00000000..9630703c --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/kafka/KSDescribeGroupsResult.java @@ -0,0 +1,45 @@ +package com.xiaojukeji.know.streaming.km.common.bean.entity.kafka; + +import org.apache.kafka.common.KafkaFuture; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ExecutionException; + +public class KSDescribeGroupsResult { + private final Map> futures; + + public KSDescribeGroupsResult(final Map> futures) { + this.futures = futures; + } + + /** + * Return a map from group id to futures which yield group descriptions. + */ + public Map> describedGroups() { + return futures; + } + + /** + * Return a future which yields all ConsumerGroupDescription objects, if all the describes succeed. + */ + public KafkaFuture> all() { + return KafkaFuture.allOf(futures.values().toArray(new KafkaFuture[0])).thenApply( + new KafkaFuture.BaseFunction>() { + @Override + public Map apply(Void v) { + try { + Map descriptions = new HashMap<>(futures.size()); + for (Map.Entry> entry : futures.entrySet()) { + descriptions.put(entry.getKey(), entry.getValue().get()); + } + return descriptions; + } catch (InterruptedException | ExecutionException e) { + // This should be unreachable, since the KafkaFuture#allOf already ensured + // that all of the futures completed successfully. + throw new RuntimeException(e); + } + } + }); + } +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/kafka/KSGroupDescription.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/kafka/KSGroupDescription.java new file mode 100644 index 00000000..c58f89d2 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/kafka/KSGroupDescription.java @@ -0,0 +1,124 @@ +package com.xiaojukeji.know.streaming.km.common.bean.entity.kafka; + +import org.apache.kafka.common.ConsumerGroupState; +import org.apache.kafka.common.Node; +import org.apache.kafka.common.acl.AclOperation; +import org.apache.kafka.common.utils.Utils; + +import java.util.*; + +public class KSGroupDescription { + private final String groupId; + private final String protocolType; + private final Collection members; + private final String partitionAssignor; + private final ConsumerGroupState state; + private final Node coordinator; + private final Set authorizedOperations; + + public KSGroupDescription(String groupId, + String protocolType, + Collection members, + String partitionAssignor, + ConsumerGroupState state, + Node coordinator) { + this(groupId, protocolType, members, partitionAssignor, state, coordinator, Collections.emptySet()); + } + + public KSGroupDescription(String groupId, + String protocolType, + Collection members, + String partitionAssignor, + ConsumerGroupState state, + Node coordinator, + Set authorizedOperations) { + this.groupId = groupId == null ? "" : groupId; + this.protocolType = protocolType; + this.members = members == null ? Collections.emptyList() : + Collections.unmodifiableList(new ArrayList<>(members)); + this.partitionAssignor = partitionAssignor == null ? "" : partitionAssignor; + this.state = state; + this.coordinator = coordinator; + this.authorizedOperations = authorizedOperations; + } + + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + final KSGroupDescription that = (KSGroupDescription) o; + return protocolType == that.protocolType && + Objects.equals(groupId, that.groupId) && + Objects.equals(members, that.members) && + Objects.equals(partitionAssignor, that.partitionAssignor) && + state == that.state && + Objects.equals(coordinator, that.coordinator) && + Objects.equals(authorizedOperations, that.authorizedOperations); + } + + @Override + public int hashCode() { + return Objects.hash(groupId, protocolType, members, partitionAssignor, state, coordinator, authorizedOperations); + } + + /** + * The id of the consumer group. + */ + public String groupId() { + return groupId; + } + + /** + * If consumer group is simple or not. + */ + public String protocolType() { + return protocolType; + } + + /** + * A list of the members of the consumer group. + */ + public Collection members() { + return members; + } + + /** + * The consumer group partition assignor. + */ + public String partitionAssignor() { + return partitionAssignor; + } + + /** + * The consumer group state, or UNKNOWN if the state is too new for us to parse. + */ + public ConsumerGroupState state() { + return state; + } + + /** + * The consumer group coordinator, or null if the coordinator is not known. + */ + public Node coordinator() { + return coordinator; + } + + /** + * authorizedOperations for this group, or null if that information is not known. + */ + public Set authorizedOperations() { + return authorizedOperations; + } + + @Override + public String toString() { + return "(groupId=" + groupId + + ", protocolType=" + protocolType + + ", members=" + Utils.join(members, ",") + + ", partitionAssignor=" + partitionAssignor + + ", state=" + state + + ", coordinator=" + coordinator + + ", authorizedOperations=" + authorizedOperations + + ")"; + } +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/kafka/KSListGroupsResult.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/kafka/KSListGroupsResult.java new file mode 100644 index 00000000..9f07138b --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/kafka/KSListGroupsResult.java @@ -0,0 +1,79 @@ +package com.xiaojukeji.know.streaming.km.common.bean.entity.kafka; + +import org.apache.kafka.clients.admin.ConsumerGroupListing; +import org.apache.kafka.common.KafkaFuture; +import org.apache.kafka.common.internals.KafkaFutureImpl; + +import java.util.ArrayList; +import java.util.Collection; + +public class KSListGroupsResult { + private final KafkaFutureImpl> all; + private final KafkaFutureImpl> valid; + private final KafkaFutureImpl> errors; + + public KSListGroupsResult(KafkaFutureImpl> future) { + this.all = new KafkaFutureImpl<>(); + this.valid = new KafkaFutureImpl<>(); + this.errors = new KafkaFutureImpl<>(); + future.thenApply(new KafkaFuture.BaseFunction, Void>() { + @Override + public Void apply(Collection results) { + ArrayList curErrors = new ArrayList<>(); + ArrayList curValid = new ArrayList<>(); + for (Object resultObject : results) { + if (resultObject instanceof Throwable) { + curErrors.add((Throwable) resultObject); + } else { + curValid.add((ConsumerGroupListing) resultObject); + } + } + if (!curErrors.isEmpty()) { + all.completeExceptionally(curErrors.get(0)); + } else { + all.complete(curValid); + } + valid.complete(curValid); + errors.complete(curErrors); + return null; + } + }); + } + + /** + * Returns a future that yields either an exception, or the full set of consumer group + * listings. + * + * In the event of a failure, the future yields nothing but the first exception which + * occurred. + */ + public KafkaFuture> all() { + return all; + } + + /** + * Returns a future which yields just the valid listings. + * + * This future never fails with an error, no matter what happens. Errors are completely + * ignored. If nothing can be fetched, an empty collection is yielded. + * If there is an error, but some results can be returned, this future will yield + * those partial results. When using this future, it is a good idea to also check + * the errors future so that errors can be displayed and handled. + */ + public KafkaFuture> valid() { + return valid; + } + + /** + * Returns a future which yields just the errors which occurred. + * + * If this future yields a non-empty collection, it is very likely that elements are + * missing from the valid() set. + * + * This future itself never fails with an error. In the event of an error, this future + * will successfully yield a collection containing at least one exception. + */ + public KafkaFuture> errors() { + return errors; + } +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/kafka/KSMemberBaseAssignment.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/kafka/KSMemberBaseAssignment.java new file mode 100644 index 00000000..3c38e4e5 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/kafka/KSMemberBaseAssignment.java @@ -0,0 +1,4 @@ +package com.xiaojukeji.know.streaming.km.common.bean.entity.kafka; + +public class KSMemberBaseAssignment { +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/kafka/KSMemberConnectAssignment.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/kafka/KSMemberConnectAssignment.java new file mode 100644 index 00000000..ba6bf638 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/kafka/KSMemberConnectAssignment.java @@ -0,0 +1,25 @@ +package com.xiaojukeji.know.streaming.km.common.bean.entity.kafka; + +import lombok.Getter; +import org.apache.kafka.connect.runtime.distributed.ConnectProtocol; + + +@Getter +public class KSMemberConnectAssignment extends KSMemberBaseAssignment { + private final ConnectProtocol.Assignment assignment; + + private final ConnectProtocol.WorkerState workerState; + + public KSMemberConnectAssignment(ConnectProtocol.Assignment assignment, ConnectProtocol.WorkerState workerState) { + this.assignment = assignment; + this.workerState = workerState; + } + + @Override + public String toString() { + return "KSMemberConnectAssignment{" + + "assignment=" + assignment + + ", workerState=" + workerState + + '}'; + } +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/kafka/KSMemberConsumerAssignment.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/kafka/KSMemberConsumerAssignment.java new file mode 100644 index 00000000..0a9950c3 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/kafka/KSMemberConsumerAssignment.java @@ -0,0 +1,50 @@ +package com.xiaojukeji.know.streaming.km.common.bean.entity.kafka; + +import org.apache.kafka.common.TopicPartition; +import org.apache.kafka.common.utils.Utils; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; + +public class KSMemberConsumerAssignment extends KSMemberBaseAssignment { + private final Set topicPartitions; + + /** + * Creates an instance with the specified parameters. + * + * @param topicPartitions List of topic partitions + */ + public KSMemberConsumerAssignment(Set topicPartitions) { + this.topicPartitions = topicPartitions == null ? Collections.emptySet() : + Collections.unmodifiableSet(new HashSet<>(topicPartitions)); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + KSMemberConsumerAssignment that = (KSMemberConsumerAssignment) o; + + return Objects.equals(topicPartitions, that.topicPartitions); + } + + @Override + public int hashCode() { + return topicPartitions != null ? topicPartitions.hashCode() : 0; + } + + /** + * The topic partitions assigned to a group member. + */ + public Set topicPartitions() { + return topicPartitions; + } + + @Override + public String toString() { + return "(topicPartitions=" + Utils.join(topicPartitions, ",") + ")"; + } +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/kafka/KSMemberDescription.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/kafka/KSMemberDescription.java new file mode 100644 index 00000000..2690ba77 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/kafka/KSMemberDescription.java @@ -0,0 +1,93 @@ +package com.xiaojukeji.know.streaming.km.common.bean.entity.kafka; + +import java.util.Objects; +import java.util.Optional; + +public class KSMemberDescription { + private final String memberId; + private final Optional groupInstanceId; + private final String clientId; + private final String host; + private final KSMemberBaseAssignment assignment; + + public KSMemberDescription(String memberId, + Optional groupInstanceId, + String clientId, + String host, + KSMemberBaseAssignment assignment) { + this.memberId = memberId == null ? "" : memberId; + this.groupInstanceId = groupInstanceId; + this.clientId = clientId == null ? "" : clientId; + this.host = host == null ? "" : host; + this.assignment = assignment == null ? + new KSMemberBaseAssignment() : assignment; + } + + public KSMemberDescription(String memberId, + String clientId, + String host, + KSMemberBaseAssignment assignment) { + this(memberId, Optional.empty(), clientId, host, assignment); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + KSMemberDescription that = (KSMemberDescription) o; + return memberId.equals(that.memberId) && + groupInstanceId.equals(that.groupInstanceId) && + clientId.equals(that.clientId) && + host.equals(that.host) && + assignment.equals(that.assignment); + } + + @Override + public int hashCode() { + return Objects.hash(memberId, groupInstanceId, clientId, host, assignment); + } + + /** + * The consumer id of the group member. + */ + public String consumerId() { + return memberId; + } + + /** + * The instance id of the group member. + */ + public Optional groupInstanceId() { + return groupInstanceId; + } + + /** + * The client id of the group member. + */ + public String clientId() { + return clientId; + } + + /** + * The host where the group member is running. + */ + public String host() { + return host; + } + + /** + * The assignment of the group member. + */ + public KSMemberBaseAssignment assignment() { + return assignment; + } + + @Override + public String toString() { + return "(memberId=" + memberId + + ", groupInstanceId=" + groupInstanceId.orElse("null") + + ", clientId=" + clientId + + ", host=" + host + + ", assignment=" + assignment + ")"; + } +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/metrics/BaseMetrics.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/metrics/BaseMetrics.java index 2ab9af97..c6ce6351 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/metrics/BaseMetrics.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/metrics/BaseMetrics.java @@ -36,7 +36,7 @@ public abstract class BaseMetrics implements Serializable { return metrics.get(key); } - public BaseMetrics(Long clusterPhyId){ + protected BaseMetrics(Long clusterPhyId) { this.clusterPhyId = clusterPhyId; } diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/metrics/connect/ConnectClusterMetrics.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/metrics/connect/ConnectClusterMetrics.java new file mode 100644 index 00000000..fe710391 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/metrics/connect/ConnectClusterMetrics.java @@ -0,0 +1,35 @@ +package com.xiaojukeji.know.streaming.km.common.bean.entity.metrics.connect; + +import com.xiaojukeji.know.streaming.km.common.bean.entity.metrics.BaseMetrics; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.ToString; + +/** + * @author zengqiao + * @date 20/6/17 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@ToString +public class ConnectClusterMetrics extends BaseMetrics { + private Long connectClusterId; + + public ConnectClusterMetrics(Long clusterPhyId, Long connectClusterId){ + super(clusterPhyId); + this.connectClusterId = connectClusterId; + } + + public static ConnectClusterMetrics initWithMetric(Long connectClusterId, String metric, Float value) { + ConnectClusterMetrics brokerMetrics = new ConnectClusterMetrics(connectClusterId, connectClusterId); + brokerMetrics.putMetric(metric, value); + return brokerMetrics; + } + + @Override + public String unique() { + return "KCC@" + clusterPhyId + "@" + connectClusterId; + } +} \ No newline at end of file diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/metrics/connect/ConnectWorkerMetrics.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/metrics/connect/ConnectWorkerMetrics.java new file mode 100644 index 00000000..78d9fe06 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/metrics/connect/ConnectWorkerMetrics.java @@ -0,0 +1,35 @@ +package com.xiaojukeji.know.streaming.km.common.bean.entity.metrics.connect; + +import com.xiaojukeji.know.streaming.km.common.bean.entity.metrics.BaseMetrics; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.ToString; + +/** + * @author wyb + * @date 2022/11/2 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@ToString +public class ConnectWorkerMetrics extends BaseMetrics { + + private Long connectClusterId; + + private String workerId; + + public static ConnectWorkerMetrics initWithMetric(Long connectClusterId, String workerId, String metric, Float value) { + ConnectWorkerMetrics connectWorkerMetrics = new ConnectWorkerMetrics(); + connectWorkerMetrics.setConnectClusterId(connectClusterId); + connectWorkerMetrics.setWorkerId(workerId); + connectWorkerMetrics.putMetric(metric, value); + return connectWorkerMetrics; + } + + @Override + public String unique() { + return "KCC@" + clusterPhyId + "@" + connectClusterId + "@" + workerId; + } +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/metrics/connect/ConnectorMetrics.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/metrics/connect/ConnectorMetrics.java new file mode 100644 index 00000000..08540ed5 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/metrics/connect/ConnectorMetrics.java @@ -0,0 +1,39 @@ +package com.xiaojukeji.know.streaming.km.common.bean.entity.metrics.connect; + +import com.xiaojukeji.know.streaming.km.common.bean.entity.metrics.BaseMetrics; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.ToString; + +/** + * @author zengqiao + * @date 20/6/17 + */ +@Data +@NoArgsConstructor +@ToString +public class ConnectorMetrics extends BaseMetrics { + private Long connectClusterId; + + private String connectorName; + + private String connectorNameAndClusterId; + + public ConnectorMetrics(Long connectClusterId, String connectorName) { + super(null); + this.connectClusterId = connectClusterId; + this.connectorName = connectorName; + this.connectorNameAndClusterId = connectorName + "#" + connectClusterId; + } + + public static ConnectorMetrics initWithMetric(Long connectClusterId, String connectorName, String metricName, Float value) { + ConnectorMetrics metrics = new ConnectorMetrics(connectClusterId, connectorName); + metrics.putMetric(metricName, value); + return metrics; + } + + @Override + public String unique() { + return "KCOR@" + connectClusterId + "@" + connectorName; + } +} \ No newline at end of file diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/metrics/connect/ConnectorTaskMetrics.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/metrics/connect/ConnectorTaskMetrics.java new file mode 100644 index 00000000..eb0dc42d --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/metrics/connect/ConnectorTaskMetrics.java @@ -0,0 +1,38 @@ +package com.xiaojukeji.know.streaming.km.common.bean.entity.metrics.connect; + +import com.xiaojukeji.know.streaming.km.common.bean.entity.metrics.BaseMetrics; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.ToString; + +/** + * @author wyb + * @date 2022/11/4 + */ +@Data +@NoArgsConstructor +@ToString +public class ConnectorTaskMetrics extends BaseMetrics { + private Long connectClusterId; + + private String connectorName; + + private Integer taskId; + + public ConnectorTaskMetrics(Long connectClusterId, String connectorName, Integer taskId) { + this.connectClusterId = connectClusterId; + this.connectorName = connectorName; + this.taskId = taskId; + } + + public static ConnectorTaskMetrics initWithMetric(Long connectClusterId, String connectorName, Integer taskId, String metricName, Float value) { + ConnectorTaskMetrics metrics = new ConnectorTaskMetrics(connectClusterId, connectorName, taskId); + metrics.putMetric(metricName,value); + return metrics; + } + + @Override + public String unique() { + return "KCOR@" + connectClusterId + "@" + connectorName + "@" + taskId; + } +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/metrics/mm2/MirrorMakerMetrics.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/metrics/mm2/MirrorMakerMetrics.java new file mode 100644 index 00000000..b44324ea --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/metrics/mm2/MirrorMakerMetrics.java @@ -0,0 +1,46 @@ +package com.xiaojukeji.know.streaming.km.common.bean.entity.metrics.mm2; + +import com.xiaojukeji.know.streaming.km.common.bean.entity.metrics.BaseMetrics; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.ToString; + +/** + * @author zengqiao + * @date 20/6/17 + */ +@Data +@NoArgsConstructor +@ToString +public class MirrorMakerMetrics extends BaseMetrics { + private Long connectClusterId; + + private String connectorName; + + private String connectorNameAndClusterId; + + public MirrorMakerMetrics(Long connectClusterId, String connectorName) { + super(null); + this.connectClusterId = connectClusterId; + this.connectorName = connectorName; + this.connectorNameAndClusterId = connectorName + "#" + connectClusterId; + } + + public MirrorMakerMetrics(Long clusterPhyId, Long connectClusterId, String connectorName) { + super(clusterPhyId); + this.connectClusterId = connectClusterId; + this.connectorName = connectorName; + this.connectorNameAndClusterId = connectorName + "#" + connectClusterId; + } + + public static MirrorMakerMetrics initWithMetric(Long connectClusterId, String connectorName, String metricName, Float value) { + MirrorMakerMetrics metrics = new MirrorMakerMetrics(connectClusterId, connectorName); + metrics.putMetric(metricName, value); + return metrics; + } + + @Override + public String unique() { + return "KCOR@" + connectClusterId + "@" + connectorName; + } +} \ No newline at end of file diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/metrics/mm2/MirrorMakerTopicPartitionMetrics.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/metrics/mm2/MirrorMakerTopicPartitionMetrics.java new file mode 100644 index 00000000..ef17adc9 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/metrics/mm2/MirrorMakerTopicPartitionMetrics.java @@ -0,0 +1,38 @@ +package com.xiaojukeji.know.streaming.km.common.bean.entity.metrics.mm2; + +import com.xiaojukeji.know.streaming.km.common.bean.entity.metrics.BaseMetrics; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author wyb + * @date 2022/12/16 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class MirrorMakerTopicPartitionMetrics extends BaseMetrics { + private Long connectClusterId; + + private String mirrorMakerName; + + private String clusterAlias; + + private String topicName; + + private Integer partitionId; + + private String workerId; + + @Override + public String unique() { + return "KCOR@" + connectClusterId + "@" + mirrorMakerName + "@" + clusterAlias + "@" + workerId + "@" + topicName + "@" + partitionId; + } + + public static MirrorMakerTopicPartitionMetrics initWithMetric(Long connectClusterId, String mirrorMakerName, String clusterAlias, String topicName, Integer partitionId, String workerId, String metricName, Float value) { + MirrorMakerTopicPartitionMetrics metrics = new MirrorMakerTopicPartitionMetrics(connectClusterId, mirrorMakerName, clusterAlias, topicName, partitionId, workerId); + metrics.putMetric(metricName, value); + return metrics; + } +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/offset/KSOffsetSpec.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/offset/KSOffsetSpec.java new file mode 100644 index 00000000..580e2f6f --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/offset/KSOffsetSpec.java @@ -0,0 +1,50 @@ +package com.xiaojukeji.know.streaming.km.common.bean.entity.offset; + +import org.apache.kafka.clients.admin.OffsetSpec; + +/** + * @see OffsetSpec + */ +public class KSOffsetSpec { + public static class KSEarliestSpec extends KSOffsetSpec { } + + public static class KSLatestSpec extends KSOffsetSpec { } + + public static class KSTimestampSpec extends KSOffsetSpec { + private final long timestamp; + + public KSTimestampSpec(long timestamp) { + this.timestamp = timestamp; + } + + public long timestamp() { + return timestamp; + } + } + + /** + * Used to retrieve the latest offset of a partition + */ + public static KSOffsetSpec latest() { + return new KSOffsetSpec.KSLatestSpec(); + } + + /** + * Used to retrieve the earliest offset of a partition + */ + public static KSOffsetSpec earliest() { + return new KSOffsetSpec.KSEarliestSpec(); + } + + /** + * Used to retrieve the earliest offset whose timestamp is greater than + * or equal to the given timestamp in the corresponding partition + * @param timestamp in milliseconds + */ + public static KSOffsetSpec forTimestamp(long timestamp) { + return new KSOffsetSpec.KSTimestampSpec(timestamp); + } + + private KSOffsetSpec() { + } +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/param/cluster/ClusterParam.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/param/cluster/ClusterParam.java new file mode 100644 index 00000000..95269065 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/param/cluster/ClusterParam.java @@ -0,0 +1,10 @@ +package com.xiaojukeji.know.streaming.km.common.bean.entity.param.cluster; + +import com.xiaojukeji.know.streaming.km.common.bean.entity.param.VersionItemParam; + +/** + * @author wyc + * @date 2022/11/9 + */ +public class ClusterParam extends VersionItemParam { +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/param/cluster/ClusterPhyParam.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/param/cluster/ClusterPhyParam.java index d55ceab5..203efcdb 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/param/cluster/ClusterPhyParam.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/param/cluster/ClusterPhyParam.java @@ -1,6 +1,5 @@ package com.xiaojukeji.know.streaming.km.common.bean.entity.param.cluster; -import com.xiaojukeji.know.streaming.km.common.bean.entity.param.VersionItemParam; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -8,6 +7,6 @@ import lombok.NoArgsConstructor; @Data @NoArgsConstructor @AllArgsConstructor -public class ClusterPhyParam extends VersionItemParam { +public class ClusterPhyParam extends ClusterParam { protected Long clusterPhyId; } diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/param/cluster/ConnectClusterParam.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/param/cluster/ConnectClusterParam.java new file mode 100644 index 00000000..2f830c55 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/param/cluster/ConnectClusterParam.java @@ -0,0 +1,16 @@ +package com.xiaojukeji.know.streaming.km.common.bean.entity.param.cluster; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author wyb + * @date 2022/11/9 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ConnectClusterParam extends ClusterParam{ + protected Long connectClusterId; +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/param/connect/ConnectorParam.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/param/connect/ConnectorParam.java new file mode 100644 index 00000000..fb923a0c --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/param/connect/ConnectorParam.java @@ -0,0 +1,27 @@ +package com.xiaojukeji.know.streaming.km.common.bean.entity.param.connect; + +import com.xiaojukeji.know.streaming.km.common.bean.entity.param.cluster.ConnectClusterParam; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author wyb + * @date 2022/11/8 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ConnectorParam extends ConnectClusterParam { + + private String connectorName; + + private String connectorType; + + public ConnectorParam(Long connectClusterId, String connectorName, String connectorType) { + super(connectClusterId); + this.connectorName = connectorName; + this.connectorType = connectorType; + } + +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/param/connect/mm2/MirrorMakerParam.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/param/connect/mm2/MirrorMakerParam.java new file mode 100644 index 00000000..357559c6 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/param/connect/mm2/MirrorMakerParam.java @@ -0,0 +1,32 @@ +package com.xiaojukeji.know.streaming.km.common.bean.entity.param.connect.mm2; + +import com.xiaojukeji.know.streaming.km.common.bean.entity.connect.mm2.MirrorMakerTopic; +import com.xiaojukeji.know.streaming.km.common.bean.entity.param.cluster.ConnectClusterParam; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @author wyb + * @date 2022/12/21 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class MirrorMakerParam extends ConnectClusterParam { + + private String mirrorMakerName; + + private String connectorType; + + List mirrorMakerTopicList; + + public MirrorMakerParam(Long connectClusterId, String connectorType, String mirrorMakerName, List mirrorMakerTopicList) { + super(connectClusterId); + this.mirrorMakerName = mirrorMakerName; + this.connectorType = connectorType; + this.mirrorMakerTopicList = mirrorMakerTopicList; + } +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/param/metric/connect/ConnectClusterMetricParam.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/param/metric/connect/ConnectClusterMetricParam.java new file mode 100644 index 00000000..92946c5c --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/param/metric/connect/ConnectClusterMetricParam.java @@ -0,0 +1,21 @@ +package com.xiaojukeji.know.streaming.km.common.bean.entity.param.metric.connect; + +import com.xiaojukeji.know.streaming.km.common.bean.entity.param.metric.MetricParam; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author wyb + * @date 2022/11/1 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ConnectClusterMetricParam extends MetricParam { + + private Long connectClusterId; + + private String metric; + +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/param/metric/connect/ConnectorMetricParam.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/param/metric/connect/ConnectorMetricParam.java new file mode 100644 index 00000000..6cad85eb --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/param/metric/connect/ConnectorMetricParam.java @@ -0,0 +1,29 @@ +package com.xiaojukeji.know.streaming.km.common.bean.entity.param.metric.connect; + +import com.xiaojukeji.know.streaming.km.common.bean.entity.param.metric.MetricParam; +import com.xiaojukeji.know.streaming.km.common.enums.connect.ConnectorTypeEnum; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author wyb + * @date 2022/11/2 + */ +@Data +@NoArgsConstructor +public class ConnectorMetricParam extends MetricParam { + private Long connectClusterId; + + private String connectorName; + + private String metricName; + + private ConnectorTypeEnum connectorType; + + public ConnectorMetricParam(Long connectClusterId, String connectorName, String metricName, ConnectorTypeEnum connectorType) { + this.connectClusterId = connectClusterId; + this.connectorName = connectorName; + this.metricName = metricName; + this.connectorType = connectorType; + } +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/param/metric/connect/mm2/MirrorMakerMetricParam.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/param/metric/connect/mm2/MirrorMakerMetricParam.java new file mode 100644 index 00000000..c67f3128 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/param/metric/connect/mm2/MirrorMakerMetricParam.java @@ -0,0 +1,26 @@ +package com.xiaojukeji.know.streaming.km.common.bean.entity.param.metric.connect.mm2; + +import com.xiaojukeji.know.streaming.km.common.bean.entity.connect.mm2.MirrorMakerTopic; +import com.xiaojukeji.know.streaming.km.common.bean.entity.param.metric.MetricParam; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @author wyb + * @date 2022/12/15 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class MirrorMakerMetricParam extends MetricParam { + private Long connectClusterId; + + private String mirrorMakerName; + + private List mirrorMakerTopicList; + + private String metric; +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/param/partition/PartitionOffsetParam.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/param/partition/PartitionOffsetParam.java index 02907a6c..09f81812 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/param/partition/PartitionOffsetParam.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/param/partition/PartitionOffsetParam.java @@ -1,23 +1,39 @@ package com.xiaojukeji.know.streaming.km.common.bean.entity.param.partition; -import com.xiaojukeji.know.streaming.km.common.bean.entity.param.topic.TopicParam; -import lombok.Data; +import com.xiaojukeji.know.streaming.km.common.bean.entity.offset.KSOffsetSpec; +import com.xiaojukeji.know.streaming.km.common.bean.entity.param.cluster.ClusterPhyParam; +import com.xiaojukeji.know.streaming.km.common.utils.Triple; +import lombok.Getter; import lombok.NoArgsConstructor; -import org.apache.kafka.clients.admin.OffsetSpec; import org.apache.kafka.common.TopicPartition; -import java.util.Map; +import java.util.*; +import java.util.stream.Collectors; -@Data +@Getter @NoArgsConstructor -public class PartitionOffsetParam extends TopicParam { - private Map topicPartitionOffsets; +public class PartitionOffsetParam extends ClusterPhyParam { + private List>> offsetSpecList; - private Long timestamp; + public PartitionOffsetParam(Long clusterPhyId, String topicName, KSOffsetSpec ksOffsetSpec, List partitionList) { + super(clusterPhyId); + this.offsetSpecList = Collections.singletonList(new Triple<>(topicName, ksOffsetSpec, partitionList)); + } - public PartitionOffsetParam(Long clusterPhyId, String topicName, Map topicPartitionOffsets, Long timestamp) { - super(clusterPhyId, topicName); - this.topicPartitionOffsets = topicPartitionOffsets; - this.timestamp = timestamp; + public PartitionOffsetParam(Long clusterPhyId, String topicName, List specList, List partitionList) { + super(clusterPhyId); + this.offsetSpecList = new ArrayList<>(); + specList.forEach(elem -> offsetSpecList.add(new Triple<>(topicName, elem, partitionList))); + } + + public PartitionOffsetParam(Long clusterPhyId, KSOffsetSpec offsetSpec, List partitionList) { + super(clusterPhyId); + Map> tpMap = new HashMap<>(); + partitionList.forEach(elem -> { + tpMap.putIfAbsent(elem.topic(), new ArrayList<>()); + tpMap.get(elem.topic()).add(elem); + }); + + this.offsetSpecList = tpMap.entrySet().stream().map(elem -> new Triple<>(elem.getKey(), offsetSpec, elem.getValue())).collect(Collectors.toList()); } } diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/reassign/ReassignResult.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/reassign/ReassignResult.java index 92dbe77d..8a734b1e 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/reassign/ReassignResult.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/reassign/ReassignResult.java @@ -1,6 +1,5 @@ package com.xiaojukeji.know.streaming.km.common.bean.entity.reassign; -import com.xiaojukeji.know.streaming.km.common.utils.CommonUtils; import lombok.Data; import org.apache.kafka.common.TopicPartition; @@ -20,10 +19,4 @@ public class ReassignResult { return state.isDone(); } - - public boolean checkPreferredReplicaElectionUnNeed(String reassignBrokerIds, String originalBrokerIds) { - Integer targetLeader = CommonUtils.string2IntList(reassignBrokerIds).get(0); - Integer originalLeader = CommonUtils.string2IntList(originalBrokerIds).get(0); - return originalLeader.equals(targetLeader); - } } diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/result/Result.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/result/Result.java index bd3b8cc8..54281b40 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/result/Result.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/result/Result.java @@ -100,6 +100,13 @@ public class Result extends BaseResult { return result; } + public static Result buildFrom(Result ret) { + Result result = new Result<>(); + result.setCode(ret.getCode()); + result.setMessage(ret.getMessage()); + return result; + } + public static Result buildFrom(ValidateKafkaAddressErrorEnum errorEnum, String msg) { Result result = new Result<>(); result.setCode(errorEnum.getCode()); diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/result/ResultStatus.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/result/ResultStatus.java index 252146c9..444a7940 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/result/ResultStatus.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/result/ResultStatus.java @@ -54,6 +54,8 @@ public enum ResultStatus { * 调用错误, [8000, 9000) */ KAFKA_OPERATE_FAILED(8010, "Kafka操作失败"), + KAFKA_CONNECTOR_OPERATE_FAILED(8011, "KafkaConnect操作失败"), + KAFKA_CONNECTOR_READ_FAILED(8012, "KafkaConnect读失败"), MYSQL_OPERATE_FAILED(8020, "MySQL操作失败"), ZK_OPERATE_FAILED(8030, "ZK操作失败"), ZK_FOUR_LETTER_CMD_FORBIDDEN(8031, "ZK四字命令被禁止"), diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/topic/TopicConfig.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/topic/TopicConfig.java index 162f5bcf..5fde198a 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/topic/TopicConfig.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/topic/TopicConfig.java @@ -14,6 +14,11 @@ import java.io.Serializable; @NoArgsConstructor @AllArgsConstructor public class TopicConfig implements Serializable { + /** + * 表主键ID + */ + private Long id; + /** * 物理集群ID */ diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/version/VersionConnectJmxInfo.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/version/VersionConnectJmxInfo.java new file mode 100644 index 00000000..7c4e257a --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/version/VersionConnectJmxInfo.java @@ -0,0 +1,13 @@ +package com.xiaojukeji.know.streaming.km.common.bean.entity.version; + +import com.xiaojukeji.know.streaming.km.common.enums.connect.ConnectorTypeEnum; +import lombok.Data; + +/** + * @author wyb + * @date 2022/11/24 + */ +@Data +public class VersionConnectJmxInfo extends VersionJmxInfo{ + private ConnectorTypeEnum type; +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/version/VersionControlItem.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/version/VersionControlItem.java index f0af86df..56b9169c 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/version/VersionControlItem.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/version/VersionControlItem.java @@ -2,7 +2,6 @@ package com.xiaojukeji.know.streaming.km.common.bean.entity.version; import com.xiaojukeji.know.streaming.km.common.enums.version.VersionEnum; import lombok.AllArgsConstructor; -import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/zookeeper/Znode.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/zookeeper/Znode.java index fd25df57..24868a93 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/zookeeper/Znode.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/zookeeper/Znode.java @@ -1,7 +1,5 @@ package com.xiaojukeji.know.streaming.km.common.bean.entity.zookeeper; - -import com.xiaojukeji.know.streaming.km.common.utils.Tuple; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import org.apache.zookeeper.data.Stat; diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/zookeeper/fourletterword/MonitorCmdData.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/zookeeper/fourletterword/MonitorCmdData.java index 2fb3c9da..7e2a10f4 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/zookeeper/fourletterword/MonitorCmdData.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/zookeeper/fourletterword/MonitorCmdData.java @@ -23,8 +23,8 @@ import lombok.Data; public class MonitorCmdData extends BaseFourLetterWordCmdData { private String zkVersion; private Float zkAvgLatency; - private Long zkMaxLatency; - private Long zkMinLatency; + private Float zkMaxLatency; + private Float zkMinLatency; private Long zkPacketsReceived; private Long zkPacketsSent; private Long zkNumAliveConnections; diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/zookeeper/fourletterword/ServerCmdData.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/zookeeper/fourletterword/ServerCmdData.java index 883231d6..0bd9e0a4 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/zookeeper/fourletterword/ServerCmdData.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/zookeeper/fourletterword/ServerCmdData.java @@ -18,8 +18,8 @@ import lombok.Data; public class ServerCmdData extends BaseFourLetterWordCmdData { private String zkVersion; private Float zkAvgLatency; - private Long zkMaxLatency; - private Long zkMinLatency; + private Float zkMaxLatency; + private Float zkMinLatency; private Long zkPacketsReceived; private Long zkPacketsSent; private Long zkNumAliveConnections; diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/zookeeper/fourletterword/parser/ConfigCmdDataParser.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/zookeeper/fourletterword/parser/ConfigCmdDataParser.java index 35ec153b..7f27073c 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/zookeeper/fourletterword/parser/ConfigCmdDataParser.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/entity/zookeeper/fourletterword/parser/ConfigCmdDataParser.java @@ -99,13 +99,13 @@ public class ConfigCmdDataParser implements FourLetterWordDataParser brokerMetrics; + private final List brokerMetrics; public BrokerMetricEvent(Object source, List brokerMetrics) { super( source ); diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/event/metric/ClusterMetricEvent.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/event/metric/ClusterMetricEvent.java index e4a16c99..aaf38896 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/event/metric/ClusterMetricEvent.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/event/metric/ClusterMetricEvent.java @@ -11,7 +11,7 @@ import java.util.List; @Getter public class ClusterMetricEvent extends BaseMetricEvent{ - private List clusterMetrics; + private final List clusterMetrics; public ClusterMetricEvent(Object source, List clusterMetrics) { super( source ); diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/event/metric/GroupMetricEvent.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/event/metric/GroupMetricEvent.java index 600daa46..24ce93ca 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/event/metric/GroupMetricEvent.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/event/metric/GroupMetricEvent.java @@ -11,7 +11,7 @@ import java.util.List; @Getter public class GroupMetricEvent extends BaseMetricEvent{ - private List groupMetrics; + private final List groupMetrics; public GroupMetricEvent(Object source, List groupMetrics) { super( source ); diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/event/metric/PartitionMetricEvent.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/event/metric/PartitionMetricEvent.java index a2654ea5..0bc09b38 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/event/metric/PartitionMetricEvent.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/event/metric/PartitionMetricEvent.java @@ -11,7 +11,7 @@ import java.util.List; @Getter public class PartitionMetricEvent extends BaseMetricEvent{ - private List partitionMetrics; + private final List partitionMetrics; public PartitionMetricEvent(Object source, List partitionMetrics) { super( source ); diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/event/metric/ReplicaMetricEvent.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/event/metric/ReplicaMetricEvent.java deleted file mode 100644 index bc4f0c10..00000000 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/event/metric/ReplicaMetricEvent.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.xiaojukeji.know.streaming.km.common.bean.event.metric; - -import com.xiaojukeji.know.streaming.km.common.bean.entity.metrics.ReplicationMetrics; -import lombok.Getter; - -import java.util.List; - -/** - * @author didi - */ -@Getter -public class ReplicaMetricEvent extends BaseMetricEvent{ - - private List replicationMetrics; - - public ReplicaMetricEvent(Object source, List replicationMetrics) { - super( source ); - this.replicationMetrics = replicationMetrics; - } -} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/event/metric/TopicMetricEvent.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/event/metric/TopicMetricEvent.java index 299afe01..359ef2a0 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/event/metric/TopicMetricEvent.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/event/metric/TopicMetricEvent.java @@ -11,7 +11,7 @@ import java.util.List; @Getter public class TopicMetricEvent extends BaseMetricEvent{ - private List topicMetrics; + private final List topicMetrics; public TopicMetricEvent(Object source, List topicMetrics) { super( source ); diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/event/metric/ZookeeperMetricEvent.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/event/metric/ZookeeperMetricEvent.java index 19279d53..261440d6 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/event/metric/ZookeeperMetricEvent.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/event/metric/ZookeeperMetricEvent.java @@ -11,7 +11,7 @@ import java.util.List; @Getter public class ZookeeperMetricEvent extends BaseMetricEvent { - private List zookeeperMetrics; + private final List zookeeperMetrics; public ZookeeperMetricEvent(Object source, List zookeeperMetrics) { super( source ); diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/event/metric/connect/ConnectClusterMetricEvent.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/event/metric/connect/ConnectClusterMetricEvent.java new file mode 100644 index 00000000..2e6101d1 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/event/metric/connect/ConnectClusterMetricEvent.java @@ -0,0 +1,21 @@ +package com.xiaojukeji.know.streaming.km.common.bean.event.metric.connect; + +import com.xiaojukeji.know.streaming.km.common.bean.entity.metrics.connect.ConnectClusterMetrics; +import com.xiaojukeji.know.streaming.km.common.bean.event.metric.BaseMetricEvent; +import lombok.Getter; + +import java.util.List; + +/** + * @author wyb + * @date 2022/11/7 + */ +@Getter +public class ConnectClusterMetricEvent extends BaseMetricEvent { + private List connectClusterMetrics; + + public ConnectClusterMetricEvent(Object source, List connectClusterMetrics) { + super(source); + this.connectClusterMetrics = connectClusterMetrics; + } +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/event/metric/connect/ConnectorMetricEvent.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/event/metric/connect/ConnectorMetricEvent.java new file mode 100644 index 00000000..23de77c0 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/event/metric/connect/ConnectorMetricEvent.java @@ -0,0 +1,21 @@ +package com.xiaojukeji.know.streaming.km.common.bean.event.metric.connect; + +import com.xiaojukeji.know.streaming.km.common.bean.entity.metrics.connect.ConnectorMetrics; +import com.xiaojukeji.know.streaming.km.common.bean.event.metric.BaseMetricEvent; +import lombok.Getter; + +import java.util.List; + +/** + * @author wyb + * @date 2022/11/7 + */ +@Getter +public class ConnectorMetricEvent extends BaseMetricEvent { + private List connectorMetricsList; + + public ConnectorMetricEvent(Object source, List connectorMetricsList) { + super(source); + this.connectorMetricsList = connectorMetricsList; + } +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/event/metric/mm2/MirrorMakerMetricEvent.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/event/metric/mm2/MirrorMakerMetricEvent.java new file mode 100644 index 00000000..42e98ce7 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/event/metric/mm2/MirrorMakerMetricEvent.java @@ -0,0 +1,21 @@ +package com.xiaojukeji.know.streaming.km.common.bean.event.metric.mm2; + +import com.xiaojukeji.know.streaming.km.common.bean.entity.metrics.mm2.MirrorMakerMetrics; +import com.xiaojukeji.know.streaming.km.common.bean.event.metric.BaseMetricEvent; +import lombok.Getter; + +import java.util.List; + +/** + * @author zengqiao + * @date 2022/12/20 + */ +@Getter +public class MirrorMakerMetricEvent extends BaseMetricEvent { + private final List metricsList; + + public MirrorMakerMetricEvent(Object source, List metricsList) { + super(source); + this.metricsList = metricsList; + } +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/po/connect/ConnectClusterPO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/po/connect/ConnectClusterPO.java new file mode 100644 index 00000000..f0a364e6 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/po/connect/ConnectClusterPO.java @@ -0,0 +1,51 @@ +package com.xiaojukeji.know.streaming.km.common.bean.po.connect; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.xiaojukeji.know.streaming.km.common.bean.po.BasePO; +import com.xiaojukeji.know.streaming.km.common.constant.Constant; +import lombok.Data; + +@Data +@TableName(Constant.MYSQL_KC_TABLE_NAME_PREFIX + "connect_cluster") +public class ConnectClusterPO extends BasePO { + /** + * Kafka集群ID + */ + private Long kafkaClusterPhyId; + + /** + * 集群名字 + */ + private String name; + + /** + * 集群使用的消费组 + */ + private String groupName; + + /** + * 集群使用的消费组状态,也表示集群状态 + */ + private Integer state; + + /** + * 集群地址 + */ + private String clusterUrl; + + /** + * worker中显示的leader url信息 + */ + private String memberLeaderUrl; + + /** + * 版本信息 + */ + private String version; + + /** + * jmx配置 + * @see com.xiaojukeji.know.streaming.km.common.bean.entity.config.JmxConfig + */ + private String jmxProperties; +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/po/connect/ConnectWorkerPO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/po/connect/ConnectWorkerPO.java new file mode 100644 index 00000000..5eb9a9ef --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/po/connect/ConnectWorkerPO.java @@ -0,0 +1,55 @@ +package com.xiaojukeji.know.streaming.km.common.bean.po.connect; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.xiaojukeji.know.streaming.km.common.bean.po.BasePO; +import com.xiaojukeji.know.streaming.km.common.constant.Constant; +import lombok.Data; + +@Data +@TableName(Constant.MYSQL_KC_TABLE_NAME_PREFIX + "worker") +public class ConnectWorkerPO extends BasePO { + /** + * Kafka集群ID + */ + private Long kafkaClusterPhyId; + + /** + * 集群ID + */ + private Long connectClusterId; + + /** + * 成员ID + */ + private String memberId; + + /** + * 主机 + */ + private String host; + + /** + * Jmx端口 + */ + private Integer jmxPort; + + /** + * URL + */ + private String url; + + /** + * leader的URL + */ + private String leaderUrl; + + /** + * 1:是leader,0:不是leader + */ + private Integer leader; + + /** + * worker地址 + */ + private String workerId; +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/po/connect/ConnectorPO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/po/connect/ConnectorPO.java new file mode 100644 index 00000000..1d82a9e1 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/po/connect/ConnectorPO.java @@ -0,0 +1,60 @@ +package com.xiaojukeji.know.streaming.km.common.bean.po.connect; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.xiaojukeji.know.streaming.km.common.bean.po.BasePO; +import com.xiaojukeji.know.streaming.km.common.constant.Constant; +import lombok.Data; + +@Data +@TableName(Constant.MYSQL_KC_TABLE_NAME_PREFIX + "connector") +public class ConnectorPO extends BasePO { + /** + * Kafka集群ID + */ + private Long kafkaClusterPhyId; + + /** + * connect集群ID + */ + private Long connectClusterId; + + /** + * connector名称 + */ + private String connectorName; + + /** + * connector类名 + */ + private String connectorClassName; + + /** + * connector类型 + */ + private String connectorType; + + /** + * 访问过的Topic列表 + */ + private String topics; + + /** + * task数 + */ + private Integer taskCount; + + /** + * 状态 + */ + private String state; + + /** + * 心跳检测connector + */ + private String heartbeatConnectorName; + + /** + * 进度确认connector + */ + private String checkpointConnectorName; +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/po/connect/WorkerConnectorPO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/po/connect/WorkerConnectorPO.java new file mode 100644 index 00000000..f30d0ab6 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/po/connect/WorkerConnectorPO.java @@ -0,0 +1,45 @@ +package com.xiaojukeji.know.streaming.km.common.bean.po.connect; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.xiaojukeji.know.streaming.km.common.bean.po.BasePO; +import com.xiaojukeji.know.streaming.km.common.constant.Constant; +import lombok.Data; + +@Data +@TableName(Constant.MYSQL_KC_TABLE_NAME_PREFIX + "worker_connector") +public class WorkerConnectorPO extends BasePO { + /** + * connect集群ID + */ + private Long connectClusterId; + + /** + * kafka集群ID + */ + private Long kafkaClusterPhyId; + + /** + * connector名称 + */ + private String connectorName; + + /** + * worker成员ID + */ + private String workerMemberId; + + /** + * 任务ID + */ + private Integer taskId; + + /** + * task状态 + */ + private String state; + + /** + * worker信息 + */ + private String workerId; +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/po/ha/HaActiveStandbyRelationPO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/po/ha/HaActiveStandbyRelationPO.java new file mode 100644 index 00000000..e019a4f0 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/po/ha/HaActiveStandbyRelationPO.java @@ -0,0 +1,33 @@ +package com.xiaojukeji.know.streaming.km.common.bean.po.ha; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.xiaojukeji.know.streaming.km.common.bean.po.BasePO; +import com.xiaojukeji.know.streaming.km.common.constant.Constant; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@TableName(Constant.MYSQL_HA_TABLE_NAME_PREFIX + "active_standby_relation") +public class HaActiveStandbyRelationPO extends BasePO { + private Long activeClusterPhyId; + + private Long standbyClusterPhyId; + + /** + * 资源名称 + */ + private String resName; + + /** + * 资源类型,0:集群,1:镜像Topic,2:主备Topic + */ + private Integer resType; + + public HaActiveStandbyRelationPO(Long activeClusterPhyId, Long standbyClusterPhyId, String resName, Integer resType) { + this.activeClusterPhyId = activeClusterPhyId; + this.standbyClusterPhyId = standbyClusterPhyId; + this.resName = resName; + this.resType = resType; + } +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/po/metrice/connect/ConnectClusterMetricPO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/po/metrice/connect/ConnectClusterMetricPO.java new file mode 100644 index 00000000..462c7763 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/po/metrice/connect/ConnectClusterMetricPO.java @@ -0,0 +1,30 @@ +package com.xiaojukeji.know.streaming.km.common.bean.po.metrice.connect; + +import com.xiaojukeji.know.streaming.km.common.bean.po.metrice.BaseMetricESPO; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import static com.xiaojukeji.know.streaming.km.common.utils.CommonUtils.monitorTimestamp2min; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ConnectClusterMetricPO extends BaseMetricESPO { + private Long connectClusterId; + + public ConnectClusterMetricPO(Long kafkaClusterPhyId, Long connectClusterId){ + super(kafkaClusterPhyId); + this.connectClusterId = connectClusterId; + } + + @Override + public String getKey() { + return "KCC@" + clusterPhyId + "@" + connectClusterId + "@" + monitorTimestamp2min(timestamp); + } + + @Override + public String getRoutingValue() { + return String.valueOf(connectClusterId); + } +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/po/metrice/connect/ConnectorMetricPO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/po/metrice/connect/ConnectorMetricPO.java new file mode 100644 index 00000000..7f3f7d71 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/po/metrice/connect/ConnectorMetricPO.java @@ -0,0 +1,39 @@ +package com.xiaojukeji.know.streaming.km.common.bean.po.metrice.connect; + +import com.xiaojukeji.know.streaming.km.common.bean.po.metrice.BaseMetricESPO; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import static com.xiaojukeji.know.streaming.km.common.utils.CommonUtils.monitorTimestamp2min; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ConnectorMetricPO extends BaseMetricESPO { + private Long connectClusterId; + + private String connectorName; + + /** + * 用于es内部排序 + */ + private String connectorNameAndClusterId; + + public ConnectorMetricPO(Long kafkaClusterPhyId, Long connectClusterId, String connectorName){ + super(kafkaClusterPhyId); + this.connectClusterId = connectClusterId; + this.connectorName = connectorName; + this.connectorNameAndClusterId = connectorName + "#" + connectClusterId; + } + + @Override + public String getKey() { + return "KCOR@" + clusterPhyId + "@" + connectClusterId + "@" + connectorName + "@" + monitorTimestamp2min(timestamp); + } + + @Override + public String getRoutingValue() { + return String.valueOf(connectClusterId); + } +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/po/metrice/mm2/MirrorMakerMetricPO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/po/metrice/mm2/MirrorMakerMetricPO.java new file mode 100644 index 00000000..5a823024 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/po/metrice/mm2/MirrorMakerMetricPO.java @@ -0,0 +1,39 @@ +package com.xiaojukeji.know.streaming.km.common.bean.po.metrice.mm2; + +import com.xiaojukeji.know.streaming.km.common.bean.po.metrice.BaseMetricESPO; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import static com.xiaojukeji.know.streaming.km.common.utils.CommonUtils.monitorTimestamp2min; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class MirrorMakerMetricPO extends BaseMetricESPO { + private Long connectClusterId; + + private String connectorName; + + /** + * 用于es内部排序 + */ + private String connectorNameAndClusterId; + + public MirrorMakerMetricPO(Long kafkaClusterPhyId, Long connectClusterId, String connectorName){ + super(kafkaClusterPhyId); + this.connectClusterId = connectClusterId; + this.connectorName = connectorName; + this.connectorNameAndClusterId = connectorName + "#" + connectClusterId; + } + + @Override + public String getKey() { + return "KCOR@" + clusterPhyId + "@" + connectClusterId + "@" + connectorName + "@" + monitorTimestamp2min(timestamp); + } + + @Override + public String getRoutingValue() { + return String.valueOf(connectClusterId); + } +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/po/partition/PartitionPO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/po/partition/PartitionPO.java index c54ea851..8740668c 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/po/partition/PartitionPO.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/po/partition/PartitionPO.java @@ -5,6 +5,8 @@ import com.xiaojukeji.know.streaming.km.common.bean.po.BasePO; import com.xiaojukeji.know.streaming.km.common.constant.Constant; import lombok.Data; +import java.util.Objects; + @Data @TableName(Constant.MYSQL_TABLE_NAME_PREFIX + "partition") public class PartitionPO extends BasePO { @@ -37,4 +39,31 @@ public class PartitionPO extends BasePO { * AR */ private String assignReplicas; + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + + if (o == null || getClass() != o.getClass()) { + return false; + } + if (!super.equals(o)) { + return false; + } + + PartitionPO po = (PartitionPO) o; + return Objects.equals(clusterPhyId, po.clusterPhyId) + && Objects.equals(topicName, po.topicName) + && Objects.equals(partitionId, po.partitionId) + && Objects.equals(leaderBrokerId, po.leaderBrokerId) + && Objects.equals(inSyncReplicas, po.inSyncReplicas) + && Objects.equals(assignReplicas, po.assignReplicas); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), clusterPhyId, topicName, partitionId, leaderBrokerId, inSyncReplicas, assignReplicas); + } } diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/po/topic/TopicPO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/po/topic/TopicPO.java index 09ccbc16..8e14a313 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/po/topic/TopicPO.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/po/topic/TopicPO.java @@ -5,6 +5,8 @@ import com.xiaojukeji.know.streaming.km.common.bean.po.BasePO; import com.xiaojukeji.know.streaming.km.common.constant.Constant; import lombok.Data; +import java.util.Objects; + @Data @TableName(Constant.MYSQL_TABLE_NAME_PREFIX + "topic") public class TopicPO extends BasePO { @@ -52,4 +54,35 @@ public class TopicPO extends BasePO { * 备注信息 */ private String description; + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + + if (o == null || getClass() != o.getClass()) { + return false; + } + + if (!super.equals(o)) { + return false; + } + + TopicPO topicPO = (TopicPO) o; + return Objects.equals(clusterPhyId, topicPO.clusterPhyId) + && Objects.equals(topicName, topicPO.topicName) + && Objects.equals(replicaNum, topicPO.replicaNum) + && Objects.equals(partitionNum, topicPO.partitionNum) + && Objects.equals(brokerIds, topicPO.brokerIds) + && Objects.equals(partitionMap, topicPO.partitionMap) + && Objects.equals(retentionMs, topicPO.retentionMs) + && Objects.equals(type, topicPO.type) + && Objects.equals(description, topicPO.description); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), clusterPhyId, topicName, replicaNum, partitionNum, brokerIds, partitionMap, retentionMs, type, description); + } } \ No newline at end of file diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/cluster/ClusterPhysStateVO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/cluster/ClusterPhysStateVO.java index fdd814c0..b8a7c8dd 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/cluster/ClusterPhysStateVO.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/cluster/ClusterPhysStateVO.java @@ -18,6 +18,9 @@ public class ClusterPhysStateVO { @ApiModelProperty(value = "挂掉集群数", example = "10") private Integer downCount; + @ApiModelProperty(value = "未知状态集群数", example = "10") + private Integer unknownCount; + @ApiModelProperty(value = "集群总数", example = "40") private Integer total; } diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/cluster/connect/ConnectClusterBasicCombineExistVO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/cluster/connect/ConnectClusterBasicCombineExistVO.java new file mode 100644 index 00000000..4cb919a7 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/cluster/connect/ConnectClusterBasicCombineExistVO.java @@ -0,0 +1,18 @@ +package com.xiaojukeji.know.streaming.km.common.bean.vo.cluster.connect; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + + +/** + * 集群的Connect集群信息 + * @author zengqiao + * @date 22/02/23 + */ +@Data +@ApiModel(description = "Connect集群基本信息") +public class ConnectClusterBasicCombineExistVO extends ConnectClusterBasicVO { + @ApiModelProperty(value="是否存在", example = "true") + protected Boolean exist; +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/cluster/connect/ConnectClusterBasicVO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/cluster/connect/ConnectClusterBasicVO.java new file mode 100644 index 00000000..53bdc0ed --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/cluster/connect/ConnectClusterBasicVO.java @@ -0,0 +1,44 @@ +package com.xiaojukeji.know.streaming.km.common.bean.vo.cluster.connect; + +import com.xiaojukeji.know.streaming.km.common.bean.vo.BaseVO; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + + +/** + * 集群的Connect集群信息 + * @author zengqiao + * @date 22/02/23 + */ +@Data +@ApiModel(description = "Connect集群基本信息") +public class ConnectClusterBasicVO extends BaseVO { + @ApiModelProperty(value = "Connect集群ID", example = "1") + private Long id; + + @ApiModelProperty(value = "Connect集群名称", example = "know-streaming") + private String name; + + @ApiModelProperty(value = "Connect集群使用的Group", example = "know-streaming") + private String groupName; + + @ApiModelProperty(value = "Connect集群URL", example = "http://127.0.0.1:8080") + private String clusterUrl; + + @ApiModelProperty(value = "Connect集群获取到的URL", example = "http://127.0.0.1:8080") + private String memberLeaderUrl; + + @ApiModelProperty(value = "Connect集群版本", example = "2.5.1") + private String version; + + @ApiModelProperty(value = "JMX配置", example = "") + private String jmxProperties; + + /** + * 集群使用的消费组状态,也表示集群状态 + * @see com.xiaojukeji.know.streaming.km.common.enums.group.GroupStateEnum + */ + @ApiModelProperty(value = "状态,2表示Dead,只有Dead才可以删除", example = "") + private Integer state; +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/cluster/connect/ConnectStateVO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/cluster/connect/ConnectStateVO.java new file mode 100644 index 00000000..e94b0b28 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/cluster/connect/ConnectStateVO.java @@ -0,0 +1,42 @@ +package com.xiaojukeji.know.streaming.km.common.bean.vo.cluster.connect; + +import com.xiaojukeji.know.streaming.km.common.bean.vo.BaseVO; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 集群Connectors状态信息 + * @author zengqiao + * @date 22/10/17 + */ +@Data +@ApiModel(description = "集群Connects状态信息") +public class ConnectStateVO extends BaseVO { + @ApiModelProperty(value = "健康检查状态", example = "1") + private Integer healthState; + + @ApiModelProperty(value = "健康检查通过数", example = "1") + private Integer healthCheckPassed; + + @ApiModelProperty(value = "健康检查总数", example = "1") + private Integer healthCheckTotal; + + @ApiModelProperty(value = "connect集群数", example = "1") + private Integer connectClusterCount; + + @ApiModelProperty(value = "worker数", example = "1") + private Integer workerCount; + + @ApiModelProperty(value = "总Connector数", example = "1") + private Integer totalConnectorCount; + + @ApiModelProperty(value = "存活Connector数", example = "1") + private Integer aliveConnectorCount; + + @ApiModelProperty(value = "总Task数", example = "1") + private Integer totalTaskCount; + + @ApiModelProperty(value = "存活Task数", example = "1") + private Integer aliveTaskCount; +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/cluster/connector/ClusterConnectorOverviewVO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/cluster/connector/ClusterConnectorOverviewVO.java new file mode 100644 index 00000000..8533eec1 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/cluster/connector/ClusterConnectorOverviewVO.java @@ -0,0 +1,42 @@ +package com.xiaojukeji.know.streaming.km.common.bean.vo.cluster.connector; + +import com.xiaojukeji.know.streaming.km.common.bean.entity.metrics.BaseMetrics; +import com.xiaojukeji.know.streaming.km.common.bean.vo.metrics.line.MetricLineVO; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +/** + * 集群Connector信息 + * @author zengqiao + * @date 22/02/23 + */ +@Data +@ApiModel(description = "Connector概览信息") +public class ClusterConnectorOverviewVO extends ConnectorBasicVO { + @ApiModelProperty(value = "Connector插件名称", example = "know-streaming") + private String connectorClassName; + + @ApiModelProperty(value = "Connector类型", example = "source") + private String connectorType; + + /** + * @see org.apache.kafka.connect.runtime.AbstractStatus.State + */ + @ApiModelProperty(value = "状态", example = "RUNNING") + private String state; + + @ApiModelProperty(value = "Task数", example = "100") + private Integer taskCount; + + @ApiModelProperty(value = "访问的Topic列表", example = "") + private List topicNameList; + + @ApiModelProperty(value = "多个指标的当前值, 包括健康分/LogSize等") + private BaseMetrics latestMetrics; + + @ApiModelProperty(value = "多个指标的历史曲线值,包括LogSize/BytesIn等") + private List metricLines; +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/cluster/connector/ClusterWorkerOverviewVO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/cluster/connector/ClusterWorkerOverviewVO.java new file mode 100644 index 00000000..c14eb4e2 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/cluster/connector/ClusterWorkerOverviewVO.java @@ -0,0 +1,31 @@ +package com.xiaojukeji.know.streaming.km.common.bean.vo.cluster.connector; + +import com.xiaojukeji.know.streaming.km.common.bean.vo.BaseVO; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + + +/** + * 集群Worker信息 + * @author zengqiao + * @date 22/02/23 + */ +@Data +@ApiModel(description = "Worker概览信息") +public class ClusterWorkerOverviewVO extends BaseVO { + @ApiModelProperty(value = "Connect集群ID", example = "1") + private Long connectClusterId; + + @ApiModelProperty(value = "Connect集群名称", example = "know-streaming") + private String connectClusterName; + + @ApiModelProperty(value = "worker主机", example = "know-streaming") + private String workerHost; + + @ApiModelProperty(value = "Connector数", example = "10") + private Integer connectorCount; + + @ApiModelProperty(value = "Task数", example = "10") + private Integer taskCount; +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/cluster/connector/ConnectorBasicCombineExistVO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/cluster/connector/ConnectorBasicCombineExistVO.java new file mode 100644 index 00000000..0bf6042f --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/cluster/connector/ConnectorBasicCombineExistVO.java @@ -0,0 +1,18 @@ +package com.xiaojukeji.know.streaming.km.common.bean.vo.cluster.connector; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + + +/** + * 集群Connector信息 + * @author zengqiao + * @date 22/02/23 + */ +@Data +@ApiModel(description = "Connector基本信息") +public class ConnectorBasicCombineExistVO extends ConnectorBasicVO { + @ApiModelProperty(value="是否存在", example = "true") + protected Boolean exist; +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/cluster/connector/ConnectorBasicVO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/cluster/connector/ConnectorBasicVO.java new file mode 100644 index 00000000..19217668 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/cluster/connector/ConnectorBasicVO.java @@ -0,0 +1,25 @@ +package com.xiaojukeji.know.streaming.km.common.bean.vo.cluster.connector; + +import com.xiaojukeji.know.streaming.km.common.bean.vo.BaseVO; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + + +/** + * 集群Connector信息 + * @author zengqiao + * @date 22/02/23 + */ +@Data +@ApiModel(description = "Connector基本信息") +public class ConnectorBasicVO extends BaseVO { + @ApiModelProperty(value = "Connect集群ID", example = "1") + private Long connectClusterId; + + @ApiModelProperty(value = "Connect集群名称", example = "know-streaming") + private String connectClusterName; + + @ApiModelProperty(value = "Connector名称", example = "know-streaming") + private String connectorName; +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/cluster/mm2/ClusterMirrorMakerOverviewVO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/cluster/mm2/ClusterMirrorMakerOverviewVO.java new file mode 100644 index 00000000..27a3bd94 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/cluster/mm2/ClusterMirrorMakerOverviewVO.java @@ -0,0 +1,52 @@ +package com.xiaojukeji.know.streaming.km.common.bean.vo.cluster.mm2; + +import com.xiaojukeji.know.streaming.km.common.bean.entity.metrics.BaseMetrics; +import com.xiaojukeji.know.streaming.km.common.bean.vo.metrics.line.MetricLineVO; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +/** + * 集群MM2信息 + * @author zengqiao + * @date 22/02/23 + */ +@Data +@ApiModel(description = "MM2概览信息") +public class ClusterMirrorMakerOverviewVO extends MirrorMakerBasicVO { + @ApiModelProperty(value = "源Kafka集群Id", example = "1") + private Long sourceKafkaClusterId; + + @ApiModelProperty(value = "源Kafka集群名称", example = "aaa") + private String sourceKafkaClusterName; + + @ApiModelProperty(value = "目标Kafka集群Id", example = "1") + private Long destKafkaClusterId; + + @ApiModelProperty(value = "目标Kafka集群名称", example = "aaa") + private String destKafkaClusterName; + + /** + * @see org.apache.kafka.connect.runtime.AbstractStatus.State + */ + @ApiModelProperty(value = "状态", example = "RUNNING") + private String state; + + @ApiModelProperty(value = "Task数", example = "100") + private Integer taskCount; + + @ApiModelProperty(value = "心跳检测connector", example = "heartbeatConnector") + private String heartbeatConnector; + + @ApiModelProperty(value = "进度确认connector", example = "checkpointConnector") + private String checkpointConnector; + + + @ApiModelProperty(value = "多个指标的当前值, 包括健康分/LogSize等") + private BaseMetrics latestMetrics; + + @ApiModelProperty(value = "多个指标的历史曲线值,包括LogSize/BytesIn等") + private List metricLines; +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/cluster/mm2/MirrorMakerBaseStateVO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/cluster/mm2/MirrorMakerBaseStateVO.java new file mode 100644 index 00000000..04aed035 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/cluster/mm2/MirrorMakerBaseStateVO.java @@ -0,0 +1,25 @@ +package com.xiaojukeji.know.streaming.km.common.bean.vo.cluster.mm2; + +import com.xiaojukeji.know.streaming.km.common.bean.vo.BaseVO; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 集群MM2状态信息 + * @author fengqiongfeng + * @date 22/12/29 + */ +@Data +@ApiModel(description = "集群MM2状态信息") +public class MirrorMakerBaseStateVO extends BaseVO { + + @ApiModelProperty(value = "worker数", example = "1") + private Integer workerCount; + + @ApiModelProperty(value = "总Task数", example = "1") + private Integer totalTaskCount; + + @ApiModelProperty(value = "存活Task数", example = "1") + private Integer aliveTaskCount; +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/cluster/mm2/MirrorMakerBasicVO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/cluster/mm2/MirrorMakerBasicVO.java new file mode 100644 index 00000000..177d76eb --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/cluster/mm2/MirrorMakerBasicVO.java @@ -0,0 +1,16 @@ +package com.xiaojukeji.know.streaming.km.common.bean.vo.cluster.mm2; + +import com.xiaojukeji.know.streaming.km.common.bean.vo.cluster.connector.ConnectorBasicVO; +import io.swagger.annotations.ApiModel; +import lombok.Data; + + +/** + * 集群MM2信息 + * @author zengqiao + * @date 22/02/23 + */ +@Data +@ApiModel(description = "MM2基本信息") +public class MirrorMakerBasicVO extends ConnectorBasicVO { +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/cluster/mm2/MirrorMakerStateVO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/cluster/mm2/MirrorMakerStateVO.java new file mode 100644 index 00000000..e0a1782d --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/cluster/mm2/MirrorMakerStateVO.java @@ -0,0 +1,34 @@ +package com.xiaojukeji.know.streaming.km.common.bean.vo.cluster.mm2; + +import com.xiaojukeji.know.streaming.km.common.bean.vo.BaseVO; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * 集群MM2状态信息 + * @author zengqiao + * @date 22/12/12 + */ +@Data +@ApiModel(description = "集群MM2状态信息") +public class MirrorMakerStateVO extends BaseVO { + + @ApiModelProperty(value = "MM2数", example = "1") + private Integer mirrorMakerCount; + + @ApiModelProperty(value = "worker数", example = "1") + private Integer workerCount; + + @ApiModelProperty(value = "总Connector数", example = "1") + private Integer totalConnectorCount; + + @ApiModelProperty(value = "存活Connector数", example = "1") + private Integer aliveConnectorCount; + + @ApiModelProperty(value = "总Task数", example = "1") + private Integer totalTaskCount; + + @ApiModelProperty(value = "存活Task数", example = "1") + private Integer aliveTaskCount; +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/cluster/res/ClusterPhyTopicsOverviewVO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/cluster/res/ClusterPhyTopicsOverviewVO.java index a767b9f2..10258bf1 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/cluster/res/ClusterPhyTopicsOverviewVO.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/cluster/res/ClusterPhyTopicsOverviewVO.java @@ -32,6 +32,9 @@ public class ClusterPhyTopicsOverviewVO extends BaseTimeVO { @ApiModelProperty(value = "副本数", example = "2") private Integer replicaNum; + @ApiModelProperty(value = "处于镜像复制中", example = "true") + private Boolean inMirror; + @ApiModelProperty(value = "多个指标的当前值, 包括健康分/LogSize等") private BaseMetrics latestMetrics; diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/connect/connector/ConnectorStateVO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/connect/connector/ConnectorStateVO.java new file mode 100644 index 00000000..7176efd2 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/connect/connector/ConnectorStateVO.java @@ -0,0 +1,32 @@ +package com.xiaojukeji.know.streaming.km.common.bean.vo.connect.connector; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @author wyb + * @date 2022/11/15 + */ +@Data +public class ConnectorStateVO { + @ApiModelProperty(value = "connect集群ID", example = "1") + private Long connectClusterId; + + @ApiModelProperty(value = "connector名称", example = "input1") + private String name; + + @ApiModelProperty(value = "connector类型", example = "source") + private String type; + + @ApiModelProperty(value = "connector状态", example = "running") + private String state; + + @ApiModelProperty(value = "总Task数", example = "1") + private Integer totalTaskCount; + + @ApiModelProperty(value = "存活Task数", example = "1") + private Integer aliveTaskCount; + + @ApiModelProperty(value = "总Worker数", example = "1") + private Integer totalWorkerCount; +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/connect/plugin/ConnectConfigInfoVO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/connect/plugin/ConnectConfigInfoVO.java new file mode 100644 index 00000000..172ecdc3 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/connect/plugin/ConnectConfigInfoVO.java @@ -0,0 +1,19 @@ +package com.xiaojukeji.know.streaming.km.common.bean.vo.connect.plugin; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.apache.kafka.connect.runtime.rest.entities.ConfigInfo; + + +/** + * @see ConfigInfo + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ConnectConfigInfoVO { + private ConnectConfigKeyInfoVO definition; + + private ConnectConfigValueInfoVO value; +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/connect/plugin/ConnectConfigInfosVO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/connect/plugin/ConnectConfigInfosVO.java new file mode 100644 index 00000000..200a32fd --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/connect/plugin/ConnectConfigInfosVO.java @@ -0,0 +1,25 @@ +package com.xiaojukeji.know.streaming.km.common.bean.vo.connect.plugin; + + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.apache.kafka.connect.runtime.rest.entities.ConfigInfos; + +import java.util.List; + +/** + * @see ConfigInfos + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ConnectConfigInfosVO { + private String name; + + private int errorCount; + + private List groups; + + private List configs; +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/connect/plugin/ConnectConfigKeyInfoVO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/connect/plugin/ConnectConfigKeyInfoVO.java new file mode 100644 index 00000000..424cb344 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/connect/plugin/ConnectConfigKeyInfoVO.java @@ -0,0 +1,38 @@ +package com.xiaojukeji.know.streaming.km.common.bean.vo.connect.plugin; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.apache.kafka.connect.runtime.rest.entities.ConfigKeyInfo; + +import java.util.List; + +/** + * @see ConfigKeyInfo + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ConnectConfigKeyInfoVO { + private String name; + + private String type; + + private boolean required; + + private String defaultValue; + + private String importance; + + private String documentation; + + private String group; + + private int orderInGroup; + + private String width; + + private String displayName; + + private List dependents; +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/connect/plugin/ConnectConfigValueInfoVO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/connect/plugin/ConnectConfigValueInfoVO.java new file mode 100644 index 00000000..6363cca0 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/connect/plugin/ConnectConfigValueInfoVO.java @@ -0,0 +1,27 @@ +package com.xiaojukeji.know.streaming.km.common.bean.vo.connect.plugin; + + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.apache.kafka.connect.runtime.rest.entities.ConfigValueInfo; + +import java.util.List; + +/** + * @see ConfigValueInfo + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ConnectConfigValueInfoVO { + private String name; + + private String value; + + private List recommendedValues; + + private List errors; + + private boolean visible; +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/connect/plugin/ConnectPluginBasicVO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/connect/plugin/ConnectPluginBasicVO.java new file mode 100644 index 00000000..1b9c811b --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/connect/plugin/ConnectPluginBasicVO.java @@ -0,0 +1,26 @@ +package com.xiaojukeji.know.streaming.km.common.bean.vo.connect.plugin; + +import com.xiaojukeji.know.streaming.km.common.bean.vo.BaseVO; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @author zengqiao + * @date 22/10/17 + */ +@Data +@ApiModel(description = "Connect插件信息") +public class ConnectPluginBasicVO extends BaseVO { + @ApiModelProperty(value = "指标或操作项名称", example = "org.apache.kafka.connect.file.FileStreamSinkConnector") + private String className; + + @ApiModelProperty(value = "类型", example = "source|sink") + private String type; + + @ApiModelProperty(value = "版本", example = "2.5.1") + private String version; + + @ApiModelProperty(value = "帮助文档地址", example = "") + private String helpDocLink; +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/connect/task/KCTaskOverviewVO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/connect/task/KCTaskOverviewVO.java new file mode 100644 index 00000000..c82b0ed4 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/connect/task/KCTaskOverviewVO.java @@ -0,0 +1,32 @@ +package com.xiaojukeji.know.streaming.km.common.bean.vo.connect.task; + +import com.xiaojukeji.know.streaming.km.common.bean.vo.BaseVO; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + + +/** + * Task信息概览 + * @author zengqiao + * @date 22/02/23 + */ +@Data +@ApiModel(description = "Task信息概览") +public class KCTaskOverviewVO extends BaseVO { + + @ApiModelProperty(value = "connect集群ID", example = "1") + private Long connectClusterId; + + @ApiModelProperty(value = "taskId", example = "1") + private Integer taskId; + + @ApiModelProperty(value = "worker地址", example = "127.0.0.1:8080") + private String workerId; + + @ApiModelProperty(value = "task状态", example = "RUNNING") + private String state; + + @ApiModelProperty(value = "错误原因", example = "asx") + private String trace; +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/ha/mirror/TopicMirrorInfoVO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/ha/mirror/TopicMirrorInfoVO.java new file mode 100644 index 00000000..b1f748c0 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/ha/mirror/TopicMirrorInfoVO.java @@ -0,0 +1,37 @@ +package com.xiaojukeji.know.streaming.km.common.bean.vo.ha.mirror; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @author zengqiao + * @date 20/4/29 + */ +@Data +@ApiModel(description="Topic复制信息") +public class TopicMirrorInfoVO { + @ApiModelProperty(value="源集群ID", example = "1") + private Long sourceClusterId; + + @ApiModelProperty(value="源集群名称", example = "know-streaming-1") + private String sourceClusterName; + + @ApiModelProperty(value="目标集群ID", example = "2") + private Long destClusterId; + + @ApiModelProperty(value="目标集群名称", example = "know-streaming-2") + private String destClusterName; + + @ApiModelProperty(value="Topic名称", example = "know-streaming") + private String topicName; + + @ApiModelProperty(value="写入速率(bytes/s)", example = "100") + private Double bytesIn; + + @ApiModelProperty(value="复制速率(bytes/s)", example = "100") + private Double replicationBytesIn; + + @ApiModelProperty(value="延迟消息数", example = "100") + private Long lag; +} \ No newline at end of file diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/health/HealthCheckConfigVO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/health/HealthCheckConfigVO.java index c9857c56..cb889444 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/health/HealthCheckConfigVO.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/health/HealthCheckConfigVO.java @@ -20,6 +20,9 @@ public class HealthCheckConfigVO { @ApiModelProperty(value="检查维度名称", example = "Broker") private String dimensionName; + @ApiModelProperty(value="检查维度前端展示名称", example = "Connector") + private String dimensionDisplayName; + @ApiModelProperty(value="配置组", example = "HEALTH") private String configGroup; diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/health/HealthScoreBaseResultVO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/health/HealthScoreBaseResultVO.java index c9abc528..5da85481 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/health/HealthScoreBaseResultVO.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/health/HealthScoreBaseResultVO.java @@ -21,6 +21,9 @@ public class HealthScoreBaseResultVO extends BaseTimeVO { @ApiModelProperty(value="检查维度名称", example = "cluster") private String dimensionName; + @ApiModelProperty(value="检查维度前端显示名称", example = "cluster") + private String dimensionDisplayName; + @ApiModelProperty(value="检查名称", example = "Group延迟") private String configName; @@ -30,9 +33,6 @@ public class HealthScoreBaseResultVO extends BaseTimeVO { @ApiModelProperty(value="检查说明", example = "Group延迟") private String configDesc; - @ApiModelProperty(value="得分", example = "100") - private Integer score; - @ApiModelProperty(value="结果", example = "true") private Boolean passed; diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/metrics/point/MetricPointVO.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/metrics/point/MetricPointVO.java index c647b222..72b5b31e 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/metrics/point/MetricPointVO.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/bean/vo/metrics/point/MetricPointVO.java @@ -2,7 +2,6 @@ package com.xiaojukeji.know.streaming.km.common.bean.vo.metrics.point; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; -import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -11,7 +10,6 @@ import lombok.NoArgsConstructor; */ @Data @NoArgsConstructor -@AllArgsConstructor @ApiModel(description = "指标点") public class MetricPointVO implements Comparable { @ApiModelProperty(value = "指标名", example = "HealthScore") @@ -26,6 +24,13 @@ public class MetricPointVO implements Comparable { @ApiModelProperty(value = "指标值聚合方式:avg、max、min、sum") private String aggType; + public MetricPointVO(String name, Long timeStamp, String value, String aggType) { + this.name = name; + this.timeStamp = timeStamp; + this.value = value; + this.aggType = aggType; + } + @Override public int compareTo(MetricPointVO o) { if(null == o){return 0;} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/component/BaseExtendFactory.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/component/BaseExtendFactory.java index aa9861e0..0da610d3 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/component/BaseExtendFactory.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/component/BaseExtendFactory.java @@ -24,7 +24,7 @@ public abstract class BaseExtendFactory { try { handler = doGet(classNamePre, clazz); } catch (NotFindSubclassException e) { - LOGGER.error("class=BaseExtendFactory||method=getByClassNamePer||handleNamePre={}||msg={}", classNamePre, + LOGGER.error("method=getByClassNamePer||handleNamePre={}||msg={}", classNamePre, e.getMessage()); } @@ -36,7 +36,7 @@ public abstract class BaseExtendFactory { try { beans = SpringTool.getBeansOfType(clazz); } catch (BeansException e) { - LOGGER.error("class=BaseExtendFactory||method=findFromSpringContext||handleNamePre={}||msg={}", + LOGGER.error("method=findFromSpringContext||handleNamePre={}||msg={}", classNamePre, e.getMessage()); } diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/component/RestTemplateConfig.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/component/RestTemplateConfig.java index 8676828a..332b6776 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/component/RestTemplateConfig.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/component/RestTemplateConfig.java @@ -90,7 +90,7 @@ public class RestTemplateConfig { try { traceResponse(request, response, exe, subFlag, beginNano); } catch (Exception e) { - SYSTEM_LOGGER.warn("class=LogHttpRequestInterceptor||method=intercept||msg={}", e.getMessage()); + SYSTEM_LOGGER.warn("method=intercept||msg={}", e.getMessage()); } throw new ThirdPartRemoteException("rest-template: " + exe.getMessage(), exe, ResultStatus.HTTP_REQ_ERROR); @@ -98,7 +98,7 @@ public class RestTemplateConfig { } private void traceRequest(HttpRequest request, String subFlag, byte[] body) throws IOException { - REQ_LOGGER.info("class=LogHttpRequestInterceptor||method=traceRequest||remoteRequest||url={}||method={}||headers={}||body={}||subFlag={}", + REQ_LOGGER.info("method=traceRequest||remoteRequest||url={}||method={}||headers={}||body={}||subFlag={}", request.getURI(), request.getMethod(), JSON.toJSONString(request.getHeaders()), new String(body, "UTF-8"), subFlag); } @@ -108,7 +108,7 @@ public class RestTemplateConfig { StringBuilder inputStringBuilder = new StringBuilder(); if (response == null) { RESP_LOGGER.warn( - "class=LogHttpRequestInterceptor||method=traceResponse||remoteResponse||code=-1||url={}||text={}||headers={}||body={}||timeCost={}||subFlag={}", + "method=traceResponse||remoteResponse||code=-1||url={}||text={}||headers={}||body={}||timeCost={}||subFlag={}", url, null, null, null, (System.nanoTime() - nanoTime) / 1000 / 1000, subFlag); return; } @@ -131,25 +131,34 @@ public class RestTemplateConfig { } } catch (Exception e) { RESP_LOGGER.warn( - "class=remoteResponse||code={}||url={}||text={}||headers={}||body={}||error={}||timeCost={}||subFlag={}", - response.getStatusCode(), url, response.getStatusText(), response.getHeaders(), - inputStringBuilder.toString(), e, (System.nanoTime() - nanoTime) / 1000 / 1000, subFlag); + "method=traceResponse||remoteResponse||code={}||url={}||text={}||headers={}||body={}||error={}||timeCost={}||subFlag={}", + response.getStatusCode(), + url, + response.getStatusText(), + response.getHeaders(), + inputStringBuilder.toString(), + e, + (System.nanoTime() - nanoTime) / 1000 / 1000, + subFlag + ); + if (!response.getStatusCode().is2xxSuccessful()) { - throw new ThirdPartRemoteException(e.getMessage(), e, ResultStatus.HTTP_REQ_ERROR); + throw new ThirdPartRemoteException(getResponseBodyAndIgnoreException(response), e, ResultStatus.HTTP_REQ_ERROR); } } + String responseString = inputStringBuilder.toString().replace("\n", ""); responseString = responseString.substring(0, Math.min(responseString.length(), 5000)); if (!response.getStatusCode().is2xxSuccessful()) { if (exception == null) { RESP_LOGGER.warn( - "class=LogHttpRequestInterceptor||method=traceResponse||remoteResponse||code={}||url={}||text={}||headers={}||body={}||timeCost={}||subFlag={}", + "method=traceResponse||remoteResponse||code={}||url={}||text={}||headers={}||body={}||timeCost={}||subFlag={}", response.getStatusCode(), url, response.getStatusText(), response.getHeaders(), responseString, (System.nanoTime() - nanoTime) / 1000 / 1000, subFlag); } else { RESP_LOGGER.warn( - "remoteResponse||code={}||url={}||text={}||headers={}||body={}||error={}||timeCost={}||subFlag={}", + "method=traceResponse||remoteResponse||code={}||url={}||text={}||headers={}||body={}||error={}||timeCost={}||subFlag={}", response.getStatusCode(), url, response.getStatusText(), response.getHeaders(), responseString, exception, (System.nanoTime() - nanoTime) / 1000 / 1000, subFlag); } @@ -158,12 +167,12 @@ public class RestTemplateConfig { if (exception == null) { RESP_LOGGER.info( - "class=LogHttpRequestInterceptor||method=traceResponse||remoteResponse||code={}||url={}||text={}||headers={}||responseBody={}||timeCost={}||subFlag={}", + "method=traceResponse||remoteResponse||code={}||url={}||text={}||headers={}||responseBody={}||timeCost={}||subFlag={}", response.getStatusCode(), url, response.getStatusText(), response.getHeaders(), responseString, (System.nanoTime() - nanoTime) / 1000 / 1000, subFlag); } else { RESP_LOGGER.warn( - "class=LogHttpRequestInterceptor||method=traceResponse||remoteResponse||code={}||url={}||text={}||headers={}||responseBody={}||error={}||timeCost={}||subFlag={}", + "method=traceResponse||remoteResponse||code={}||url={}||text={}||headers={}||responseBody={}||error={}||timeCost={}||subFlag={}", response.getStatusCode(), url, response.getStatusText(), response.getHeaders(), responseString, exception, (System.nanoTime() - nanoTime) / 1000 / 1000, subFlag); } @@ -172,6 +181,19 @@ public class RestTemplateConfig { } + private String getResponseBodyAndIgnoreException(ClientHttpResponse response) { + try { + byte[] bytes = new byte[response.getBody().available()]; + response.getBody().read(bytes); + + return new String(bytes); + } catch (Exception e) { + // ignore + } + + return ""; + } + private static String simpleUrl(HttpRequest request) { String url = request.getURI().toString(); int index = url.indexOf("?"); diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/component/RestTool.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/component/RestTool.java index 614ffdf9..058e4540 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/component/RestTool.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/component/RestTool.java @@ -13,6 +13,7 @@ import org.springframework.web.client.RestTemplate; import org.springframework.web.util.UriComponentsBuilder; import java.lang.reflect.Type; +import java.util.List; import java.util.Map; /** @@ -22,7 +23,6 @@ import java.util.Map; */ @Component public class RestTool { - private static final ILog LOGGER = LogFactory.getLog(RestTool.class); @Autowired @@ -38,39 +38,38 @@ public class RestTool { * @return */ public T postObjectWithRawContent(String url, Object postBody, HttpHeaders headers, Class resultType) { - ResponseEntity result = restTemplate.exchange(url, HttpMethod.POST, new HttpEntity<>(postBody, headers), - String.class); + ResponseEntity result = restTemplate.exchange( + url, + HttpMethod.POST, + new HttpEntity<>(postBody, headers), + String.class + ); + return ConvertUtil.toObj(result.getBody(), resultType); } /** * POST请求 * @param url 请求地址 - * @param request 请求内容 - * @param responseType 期望返回的类型 + * @param postBody 请求内容 + * @param resultType 期望返回的类型 * @param 泛型T * @return T */ - public T postObjectWithJsonContent(String url, Object request, Type responseType) { - HttpHeaders jsonHead = getJsonContentHeaders(); - ResponseEntity result = restTemplate.exchange(url, HttpMethod.POST, - new HttpEntity( ConvertUtil.obj2Json(request), jsonHead), String.class); - return ConvertUtil.toObj(result.getBody(), responseType); + public T postObjectWithJsonContent(String url, Object postBody, Class resultType) { + return this.postObjectWithRawContent(url, postBody, this.getJsonContentHeaders(), resultType); } /** * POST请求 * @param url 请求地址 - * @param request 请求内容 - * @param responseType 期望返回的类型 + * @param postBody 请求内容 + * @param resultType 期望返回的类型 * @param 泛型T * @return T */ - public T postObjectWithJsonContentAndHeader(String url, Map headers, Object request, - Type responseType) { - ResponseEntity result = restTemplate.exchange(url, HttpMethod.POST, - new HttpEntity(ConvertUtil.obj2Json(request), getJsonContentHeaders(headers)), String.class); - return ConvertUtil.toObj(result.getBody(), responseType); + public T postObjectWithJsonContentAndHeader(String url, Map headers, Object postBody, Class resultType) { + return this.postObjectWithRawContent(url, postBody, this.getJsonContentHeaders(headers), resultType); } /** @@ -81,8 +80,15 @@ public class RestTool { * @param 泛型T * @return T */ - public T getObjectWithJsonContent(String url, Map params, Type resultType) { - ResponseEntity result = restTemplate.exchange(url, HttpMethod.GET, null, String.class, params); + public T getObjectWithJsonContent(String url, Map params, Class resultType) { + ResponseEntity result = restTemplate.exchange( + url, + HttpMethod.GET, + null, + String.class, + params + ); + return ConvertUtil.toObj(result.getBody(), resultType); } @@ -95,8 +101,13 @@ public class RestTool { * @return T */ public T getForObject(String url, HttpHeaders headers, Type resultType) { - ResponseEntity result = restTemplate.exchange(url, HttpMethod.GET, new HttpEntity<>(null, headers), - String.class); + ResponseEntity result = restTemplate.exchange( + url, + HttpMethod.GET, + new HttpEntity<>(null, headers), + String.class + ); + return ConvertUtil.toObj(result.getBody(), resultType); } @@ -131,7 +142,7 @@ public class RestTool { new HttpEntity<>(null, getJsonContentHeaders(headers)), String.class); return JSON.parseObject(result.getBody(), resultType); } catch (Exception e){ - LOGGER.error("class=RestTool||method=getForObject||url={}||msg=exception!", url, e); + LOGGER.error("method=getForObject||url={}||msg=exception!", url, e); } return null; @@ -151,7 +162,7 @@ public class RestTool { new HttpEntity<>(null, headers), String.class); return JSON.parseObject(result.getBody(), resultType); } catch (Exception e){ - LOGGER.error("class=RestTool||method=getForObject||url={}||msg=exception!", url, e); + LOGGER.error("method=getForObject||url={}||msg=exception!", url, e); } return null; @@ -169,6 +180,26 @@ public class RestTool { return result.getBody(); } + /** + * GET请求 + * @param url 请求地址 + * @param params 请求参数 + * @param resultType 返回类型 + * @param 泛型T + * @return T + */ + public List getArrayObjectWithJsonContent(String url, Map params, Class resultType) { + ResponseEntity result = restTemplate.exchange( + url, + HttpMethod.GET, + null, + String.class, + params + ); + + return ConvertUtil.str2ObjArrayByJson(result.getBody(), resultType); + } + /** * 根据map中的参数构建url+queryString * @param url 请求地址 @@ -181,7 +212,6 @@ public class RestTool { } UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url); - return builder.toUriString(); } diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/constant/ApiPrefix.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/constant/ApiPrefix.java index 4b514998..c7c1803b 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/constant/ApiPrefix.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/constant/ApiPrefix.java @@ -12,6 +12,12 @@ public class ApiPrefix { public static final String API_V3_PREFIX = API_PREFIX + "v3/"; + public static final String API_V3_CONNECT_PREFIX = API_V3_PREFIX + "kafka-connect/"; + + public static final String API_V3_MM2_PREFIX = API_V3_PREFIX + "kafka-mm2/"; + + public static final String API_V3_HA_MIRROR_PREFIX = API_V3_PREFIX + "ha-mirror/"; + public static final String API_V3_OPEN_PREFIX = API_V3_PREFIX + "open/"; private ApiPrefix() { diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/constant/Constant.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/constant/Constant.java index 59a52c1c..5ba73baa 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/constant/Constant.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/constant/Constant.java @@ -45,6 +45,8 @@ public class Constant { public static final int INVALID_CODE = -1; public static final String MYSQL_TABLE_NAME_PREFIX = "ks_km_"; + public static final String MYSQL_KC_TABLE_NAME_PREFIX = "ks_kc_"; + public static final String MYSQL_HA_TABLE_NAME_PREFIX = "ks_ha_"; public static final String SWAGGER_API_TAG_PREFIX = "KS-KM-"; @@ -59,9 +61,14 @@ public class Constant { * 采集指标的花费时间 */ public static final String COLLECT_METRICS_COST_TIME_METRICS_NAME = "CollectMetricsCostTimeUnitSec"; - public static final Float COLLECT_METRICS_ERROR_COST_TIME = -1.0F; + public static final Float COLLECT_METRICS_ERROR_COST_TIME = 100.001F; public static final Integer DEFAULT_RETRY_TIME = 3; public static final Integer ZK_ALIVE_BUT_4_LETTER_FORBIDDEN = 11; + + public static final String CONNECTOR_CONFIG_ACTION_RELOAD_NAME = "config.action.reload"; + + public static final String CONNECTOR_CONFIG_ERRORS_TOLERANCE_NAME = "errors.tolerance"; + } diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/constant/ESConstant.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/constant/ESConstant.java index 1b8a7740..07cef36f 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/constant/ESConstant.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/constant/ESConstant.java @@ -36,6 +36,13 @@ public class ESConstant { public static final Integer DEFAULT_RETRY_TIME = 3; + public static final String PARTITION_INDEX = "ks_kafka_partition_metric"; + + /** + * 获取Topic-Latest指标时,单次允许的Topic数 + */ + public static final int SEARCH_LATEST_TOPIC_METRIC_CNT_PER_REQUEST = 500; + private ESConstant() { } } diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/constant/ESIndexConstant.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/constant/ESIndexConstant.java deleted file mode 100644 index 1f5654d0..00000000 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/constant/ESIndexConstant.java +++ /dev/null @@ -1,709 +0,0 @@ -package com.xiaojukeji.know.streaming.km.common.constant; - -public class ESIndexConstant { - - public final static String TOPIC_INDEX = "ks_kafka_topic_metric"; - public final static String TOPIC_TEMPLATE = "{\n" + - " \"order\" : 10,\n" + - " \"index_patterns\" : [\n" + - " \"ks_kafka_topic_metric*\"\n" + - " ],\n" + - " \"settings\" : {\n" + - " \"index\" : {\n" + - " \"number_of_shards\" : \"10\"\n" + - " }\n" + - " },\n" + - " \"mappings\" : {\n" + - " \"properties\" : {\n" + - " \"brokerId\" : {\n" + - " \"type\" : \"long\"\n" + - " },\n" + - " \"routingValue\" : {\n" + - " \"type\" : \"text\",\n" + - " \"fields\" : {\n" + - " \"keyword\" : {\n" + - " \"ignore_above\" : 256,\n" + - " \"type\" : \"keyword\"\n" + - " }\n" + - " }\n" + - " },\n" + - " \"topic\" : {\n" + - " \"type\" : \"keyword\"\n" + - " },\n" + - " \"clusterPhyId\" : {\n" + - " \"type\" : \"long\"\n" + - " },\n" + - " \"metrics\" : {\n" + - " \"properties\" : {\n" + - " \"BytesIn_min_15\" : {\n" + - " \"type\" : \"float\"\n" + - " },\n" + - " \"Messages\" : {\n" + - " \"type\" : \"float\"\n" + - " },\n" + - " \"BytesRejected\" : {\n" + - " \"type\" : \"float\"\n" + - " },\n" + - " \"PartitionURP\" : {\n" + - " \"type\" : \"float\"\n" + - " },\n" + - " \"HealthCheckTotal\" : {\n" + - " \"type\" : \"float\"\n" + - " },\n" + - " \"ReplicationCount\" : {\n" + - " \"type\" : \"float\"\n" + - " },\n" + - " \"ReplicationBytesOut\" : {\n" + - " \"type\" : \"float\"\n" + - " },\n" + - " \"ReplicationBytesIn\" : {\n" + - " \"type\" : \"float\"\n" + - " },\n" + - " \"FailedFetchRequests\" : {\n" + - " \"type\" : \"float\"\n" + - " },\n" + - " \"BytesIn_min_5\" : {\n" + - " \"type\" : \"float\"\n" + - " },\n" + - " \"HealthScore\" : {\n" + - " \"type\" : \"float\"\n" + - " },\n" + - " \"LogSize\" : {\n" + - " \"type\" : \"float\"\n" + - " },\n" + - " \"BytesOut\" : {\n" + - " \"type\" : \"float\"\n" + - " },\n" + - " \"BytesOut_min_15\" : {\n" + - " \"type\" : \"float\"\n" + - " },\n" + - " \"FailedProduceRequests\" : {\n" + - " \"type\" : \"float\"\n" + - " },\n" + - " \"BytesIn\" : {\n" + - " \"type\" : \"float\"\n" + - " },\n" + - " \"BytesOut_min_5\" : {\n" + - " \"type\" : \"float\"\n" + - " },\n" + - " \"MessagesIn\" : {\n" + - " \"type\" : \"float\"\n" + - " },\n" + - " \"TotalProduceRequests\" : {\n" + - " \"type\" : \"float\"\n" + - " },\n" + - " \"HealthCheckPassed\" : {\n" + - " \"type\" : \"float\"\n" + - " }\n" + - " }\n" + - " },\n" + - " \"brokerAgg\" : {\n" + - " \"type\" : \"keyword\"\n" + - " },\n" + - " \"key\" : {\n" + - " \"type\" : \"text\",\n" + - " \"fields\" : {\n" + - " \"keyword\" : {\n" + - " \"ignore_above\" : 256,\n" + - " \"type\" : \"keyword\"\n" + - " }\n" + - " }\n" + - " },\n" + - " \"timestamp\" : {\n" + - " \"format\" : \"yyyy-MM-dd HH:mm:ss Z||yyyy-MM-dd HH:mm:ss||yyyy-MM-dd HH:mm:ss.SSS Z||yyyy-MM-dd HH:mm:ss.SSS||yyyy-MM-dd HH:mm:ss,SSS||yyyy/MM/dd HH:mm:ss||yyyy-MM-dd HH:mm:ss,SSS Z||yyyy/MM/dd HH:mm:ss,SSS Z||epoch_millis\",\n" + - " \"index\" : true,\n" + - " \"type\" : \"date\",\n" + - " \"doc_values\" : true\n" + - " }\n" + - " }\n" + - " },\n" + - " \"aliases\" : { }\n" + - " }"; - - public final static String CLUSTER_INDEX = "ks_kafka_cluster_metric"; - public final static String CLUSTER_TEMPLATE = "{\n" + - " \"order\" : 10,\n" + - " \"index_patterns\" : [\n" + - " \"ks_kafka_cluster_metric*\"\n" + - " ],\n" + - " \"settings\" : {\n" + - " \"index\" : {\n" + - " \"number_of_shards\" : \"10\"\n" + - " }\n" + - " },\n" + - " \"mappings\" : {\n" + - " \"properties\" : {\n" + - " \"routingValue\" : {\n" + - " \"type\" : \"text\",\n" + - " \"fields\" : {\n" + - " \"keyword\" : {\n" + - " \"ignore_above\" : 256,\n" + - " \"type\" : \"keyword\"\n" + - " }\n" + - " }\n" + - " },\n" + - " \"clusterPhyId\" : {\n" + - " \"type\" : \"long\"\n" + - " },\n" + - " \"metrics\" : {\n" + - " \"properties\" : {\n" + - " \"Connections\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"BytesIn_min_15\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"PartitionURP\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"HealthScore_Topics\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"EventQueueSize\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"ActiveControllerCount\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"GroupDeads\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"BytesIn_min_5\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"HealthCheckTotal_Topics\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"Partitions\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"BytesOut\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"Groups\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"BytesOut_min_15\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"TotalRequestQueueSize\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"HealthCheckPassed_Groups\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"TotalProduceRequests\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"HealthCheckPassed\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"TotalLogSize\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"GroupEmptys\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"PartitionNoLeader\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"HealthScore_Brokers\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"Messages\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"Topics\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"PartitionMinISR_E\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"HealthCheckTotal\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"Brokers\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"Replicas\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"HealthCheckTotal_Groups\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"GroupRebalances\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"MessageIn\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"HealthScore\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"HealthCheckPassed_Topics\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"HealthCheckTotal_Brokers\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"PartitionMinISR_S\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"BytesIn\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"BytesOut_min_5\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"GroupActives\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"MessagesIn\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"GroupReBalances\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"HealthCheckPassed_Brokers\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"HealthScore_Groups\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"TotalResponseQueueSize\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"Zookeepers\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"LeaderMessages\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"HealthScore_Cluster\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"HealthCheckPassed_Cluster\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"HealthCheckTotal_Cluster\" : {\n" + - " \"type\" : \"double\"\n" + - " }\n" + - " }\n" + - " },\n" + - " \"key\" : {\n" + - " \"type\" : \"text\",\n" + - " \"fields\" : {\n" + - " \"keyword\" : {\n" + - " \"ignore_above\" : 256,\n" + - " \"type\" : \"keyword\"\n" + - " }\n" + - " }\n" + - " },\n" + - " \"timestamp\" : {\n" + - " \"format\" : \"yyyy-MM-dd HH:mm:ss Z||yyyy-MM-dd HH:mm:ss||yyyy-MM-dd HH:mm:ss.SSS Z||yyyy-MM-dd HH:mm:ss.SSS||yyyy-MM-dd HH:mm:ss,SSS||yyyy/MM/dd HH:mm:ss||yyyy-MM-dd HH:mm:ss,SSS Z||yyyy/MM/dd HH:mm:ss,SSS Z||epoch_millis\",\n" + - " \"type\" : \"date\"\n" + - " }\n" + - " }\n" + - " },\n" + - " \"aliases\" : { }\n" + - " }"; - - public final static String BROKER_INDEX = "ks_kafka_broker_metric"; - public final static String BROKER_TEMPLATE = "{\n" + - " \"order\" : 10,\n" + - " \"index_patterns\" : [\n" + - " \"ks_kafka_broker_metric*\"\n" + - " ],\n" + - " \"settings\" : {\n" + - " \"index\" : {\n" + - " \"number_of_shards\" : \"10\"\n" + - " }\n" + - " },\n" + - " \"mappings\" : {\n" + - " \"properties\" : {\n" + - " \"brokerId\" : {\n" + - " \"type\" : \"long\"\n" + - " },\n" + - " \"routingValue\" : {\n" + - " \"type\" : \"text\",\n" + - " \"fields\" : {\n" + - " \"keyword\" : {\n" + - " \"ignore_above\" : 256,\n" + - " \"type\" : \"keyword\"\n" + - " }\n" + - " }\n" + - " },\n" + - " \"clusterPhyId\" : {\n" + - " \"type\" : \"long\"\n" + - " },\n" + - " \"metrics\" : {\n" + - " \"properties\" : {\n" + - " \"NetworkProcessorAvgIdle\" : {\n" + - " \"type\" : \"float\"\n" + - " },\n" + - " \"UnderReplicatedPartitions\" : {\n" + - " \"type\" : \"float\"\n" + - " },\n" + - " \"BytesIn_min_15\" : {\n" + - " \"type\" : \"float\"\n" + - " },\n" + - " \"HealthCheckTotal\" : {\n" + - " \"type\" : \"float\"\n" + - " },\n" + - " \"RequestHandlerAvgIdle\" : {\n" + - " \"type\" : \"float\"\n" + - " },\n" + - " \"connectionsCount\" : {\n" + - " \"type\" : \"float\"\n" + - " },\n" + - " \"BytesIn_min_5\" : {\n" + - " \"type\" : \"float\"\n" + - " },\n" + - " \"HealthScore\" : {\n" + - " \"type\" : \"float\"\n" + - " },\n" + - " \"BytesOut\" : {\n" + - " \"type\" : \"float\"\n" + - " },\n" + - " \"BytesOut_min_15\" : {\n" + - " \"type\" : \"float\"\n" + - " },\n" + - " \"BytesIn\" : {\n" + - " \"type\" : \"float\"\n" + - " },\n" + - " \"BytesOut_min_5\" : {\n" + - " \"type\" : \"float\"\n" + - " },\n" + - " \"TotalRequestQueueSize\" : {\n" + - " \"type\" : \"float\"\n" + - " },\n" + - " \"MessagesIn\" : {\n" + - " \"type\" : \"float\"\n" + - " },\n" + - " \"TotalProduceRequests\" : {\n" + - " \"type\" : \"float\"\n" + - " },\n" + - " \"HealthCheckPassed\" : {\n" + - " \"type\" : \"float\"\n" + - " },\n" + - " \"TotalResponseQueueSize\" : {\n" + - " \"type\" : \"float\"\n" + - " }\n" + - " }\n" + - " },\n" + - " \"key\" : {\n" + - " \"type\" : \"text\",\n" + - " \"fields\" : {\n" + - " \"keyword\" : {\n" + - " \"ignore_above\" : 256,\n" + - " \"type\" : \"keyword\"\n" + - " }\n" + - " }\n" + - " },\n" + - " \"timestamp\" : {\n" + - " \"format\" : \"yyyy-MM-dd HH:mm:ss Z||yyyy-MM-dd HH:mm:ss||yyyy-MM-dd HH:mm:ss.SSS Z||yyyy-MM-dd HH:mm:ss.SSS||yyyy-MM-dd HH:mm:ss,SSS||yyyy/MM/dd HH:mm:ss||yyyy-MM-dd HH:mm:ss,SSS Z||yyyy/MM/dd HH:mm:ss,SSS Z||epoch_millis\",\n" + - " \"index\" : true,\n" + - " \"type\" : \"date\",\n" + - " \"doc_values\" : true\n" + - " }\n" + - " }\n" + - " },\n" + - " \"aliases\" : { }\n" + - " }"; - - public final static String PARTITION_INDEX = "ks_kafka_partition_metric"; - public final static String PARTITION_TEMPLATE = "{\n" + - " \"order\" : 10,\n" + - " \"index_patterns\" : [\n" + - " \"ks_kafka_partition_metric*\"\n" + - " ],\n" + - " \"settings\" : {\n" + - " \"index\" : {\n" + - " \"number_of_shards\" : \"10\"\n" + - " }\n" + - " },\n" + - " \"mappings\" : {\n" + - " \"properties\" : {\n" + - " \"brokerId\" : {\n" + - " \"type\" : \"long\"\n" + - " },\n" + - " \"partitionId\" : {\n" + - " \"type\" : \"long\"\n" + - " },\n" + - " \"routingValue\" : {\n" + - " \"type\" : \"text\",\n" + - " \"fields\" : {\n" + - " \"keyword\" : {\n" + - " \"ignore_above\" : 256,\n" + - " \"type\" : \"keyword\"\n" + - " }\n" + - " }\n" + - " },\n" + - " \"clusterPhyId\" : {\n" + - " \"type\" : \"long\"\n" + - " },\n" + - " \"topic\" : {\n" + - " \"type\" : \"keyword\"\n" + - " },\n" + - " \"metrics\" : {\n" + - " \"properties\" : {\n" + - " \"LogStartOffset\" : {\n" + - " \"type\" : \"float\"\n" + - " },\n" + - " \"Messages\" : {\n" + - " \"type\" : \"float\"\n" + - " },\n" + - " \"LogEndOffset\" : {\n" + - " \"type\" : \"float\"\n" + - " }\n" + - " }\n" + - " },\n" + - " \"key\" : {\n" + - " \"type\" : \"text\",\n" + - " \"fields\" : {\n" + - " \"keyword\" : {\n" + - " \"ignore_above\" : 256,\n" + - " \"type\" : \"keyword\"\n" + - " }\n" + - " }\n" + - " },\n" + - " \"timestamp\" : {\n" + - " \"format\" : \"yyyy-MM-dd HH:mm:ss Z||yyyy-MM-dd HH:mm:ss||yyyy-MM-dd HH:mm:ss.SSS Z||yyyy-MM-dd HH:mm:ss.SSS||yyyy-MM-dd HH:mm:ss,SSS||yyyy/MM/dd HH:mm:ss||yyyy-MM-dd HH:mm:ss,SSS Z||yyyy/MM/dd HH:mm:ss,SSS Z||epoch_millis\",\n" + - " \"index\" : true,\n" + - " \"type\" : \"date\",\n" + - " \"doc_values\" : true\n" + - " }\n" + - " }\n" + - " },\n" + - " \"aliases\" : { }\n" + - " }"; - - public final static String GROUP_INDEX = "ks_kafka_group_metric"; - public final static String GROUP_TEMPLATE = "{\n" + - " \"order\" : 10,\n" + - " \"index_patterns\" : [\n" + - " \"ks_kafka_group_metric*\"\n" + - " ],\n" + - " \"settings\" : {\n" + - " \"index\" : {\n" + - " \"number_of_shards\" : \"10\"\n" + - " }\n" + - " },\n" + - " \"mappings\" : {\n" + - " \"properties\" : {\n" + - " \"group\" : {\n" + - " \"type\" : \"keyword\"\n" + - " },\n" + - " \"partitionId\" : {\n" + - " \"type\" : \"long\"\n" + - " },\n" + - " \"routingValue\" : {\n" + - " \"type\" : \"text\",\n" + - " \"fields\" : {\n" + - " \"keyword\" : {\n" + - " \"ignore_above\" : 256,\n" + - " \"type\" : \"keyword\"\n" + - " }\n" + - " }\n" + - " },\n" + - " \"clusterPhyId\" : {\n" + - " \"type\" : \"long\"\n" + - " },\n" + - " \"topic\" : {\n" + - " \"type\" : \"keyword\"\n" + - " },\n" + - " \"metrics\" : {\n" + - " \"properties\" : {\n" + - " \"HealthScore\" : {\n" + - " \"type\" : \"float\"\n" + - " },\n" + - " \"Lag\" : {\n" + - " \"type\" : \"float\"\n" + - " },\n" + - " \"OffsetConsumed\" : {\n" + - " \"type\" : \"float\"\n" + - " },\n" + - " \"HealthCheckTotal\" : {\n" + - " \"type\" : \"float\"\n" + - " },\n" + - " \"HealthCheckPassed\" : {\n" + - " \"type\" : \"float\"\n" + - " }\n" + - " }\n" + - " },\n" + - " \"groupMetric\" : {\n" + - " \"type\" : \"keyword\"\n" + - " },\n" + - " \"key\" : {\n" + - " \"type\" : \"text\",\n" + - " \"fields\" : {\n" + - " \"keyword\" : {\n" + - " \"ignore_above\" : 256,\n" + - " \"type\" : \"keyword\"\n" + - " }\n" + - " }\n" + - " },\n" + - " \"timestamp\" : {\n" + - " \"format\" : \"yyyy-MM-dd HH:mm:ss Z||yyyy-MM-dd HH:mm:ss||yyyy-MM-dd HH:mm:ss.SSS Z||yyyy-MM-dd HH:mm:ss.SSS||yyyy-MM-dd HH:mm:ss,SSS||yyyy/MM/dd HH:mm:ss||yyyy-MM-dd HH:mm:ss,SSS Z||yyyy/MM/dd HH:mm:ss,SSS Z||epoch_millis\",\n" + - " \"index\" : true,\n" + - " \"type\" : \"date\",\n" + - " \"doc_values\" : true\n" + - " }\n" + - " }\n" + - " },\n" + - " \"aliases\" : { }\n" + - " }"; - - public final static String REPLICATION_INDEX = "ks_kafka_replication_metric"; - public final static String REPLICATION_TEMPLATE = "{\n" + - " \"order\" : 10,\n" + - " \"index_patterns\" : [\n" + - " \"ks_kafka_replication_metric*\"\n" + - " ],\n" + - " \"settings\" : {\n" + - " \"index\" : {\n" + - " \"number_of_shards\" : \"10\"\n" + - " }\n" + - " },\n" + - " \"mappings\" : {\n" + - " \"properties\" : {\n" + - " \"brokerId\" : {\n" + - " \"type\" : \"long\"\n" + - " },\n" + - " \"partitionId\" : {\n" + - " \"type\" : \"long\"\n" + - " },\n" + - " \"routingValue\" : {\n" + - " \"type\" : \"text\",\n" + - " \"fields\" : {\n" + - " \"keyword\" : {\n" + - " \"ignore_above\" : 256,\n" + - " \"type\" : \"keyword\"\n" + - " }\n" + - " }\n" + - " },\n" + - " \"clusterPhyId\" : {\n" + - " \"type\" : \"long\"\n" + - " },\n" + - " \"topic\" : {\n" + - " \"type\" : \"keyword\"\n" + - " },\n" + - " \"metrics\" : {\n" + - " \"properties\" : {\n" + - " \"LogStartOffset\" : {\n" + - " \"type\" : \"float\"\n" + - " },\n" + - " \"Messages\" : {\n" + - " \"type\" : \"float\"\n" + - " },\n" + - " \"LogEndOffset\" : {\n" + - " \"type\" : \"float\"\n" + - " }\n" + - " }\n" + - " },\n" + - " \"key\" : {\n" + - " \"type\" : \"text\",\n" + - " \"fields\" : {\n" + - " \"keyword\" : {\n" + - " \"ignore_above\" : 256,\n" + - " \"type\" : \"keyword\"\n" + - " }\n" + - " }\n" + - " },\n" + - " \"timestamp\" : {\n" + - " \"format\" : \"yyyy-MM-dd HH:mm:ss Z||yyyy-MM-dd HH:mm:ss||yyyy-MM-dd HH:mm:ss.SSS Z||yyyy-MM-dd HH:mm:ss.SSS||yyyy-MM-dd HH:mm:ss,SSS||yyyy/MM/dd HH:mm:ss||yyyy-MM-dd HH:mm:ss,SSS Z||yyyy/MM/dd HH:mm:ss,SSS Z||epoch_millis\",\n" + - " \"index\" : true,\n" + - " \"type\" : \"date\",\n" + - " \"doc_values\" : true\n" + - " }\n" + - " }\n" + - " },\n" + - " \"aliases\" : { }\n" + - " }"; - - public final static String ZOOKEEPER_INDEX = "ks_kafka_zookeeper_metric"; - public final static String ZOOKEEPER_TEMPLATE = "{\n" + - " \"order\" : 10,\n" + - " \"index_patterns\" : [\n" + - " \"ks_kafka_zookeeper_metric*\"\n" + - " ],\n" + - " \"settings\" : {\n" + - " \"index\" : {\n" + - " \"number_of_shards\" : \"10\"\n" + - " }\n" + - " },\n" + - " \"mappings\" : {\n" + - " \"properties\" : {\n" + - " \"routingValue\" : {\n" + - " \"type\" : \"text\",\n" + - " \"fields\" : {\n" + - " \"keyword\" : {\n" + - " \"ignore_above\" : 256,\n" + - " \"type\" : \"keyword\"\n" + - " }\n" + - " }\n" + - " },\n" + - " \"clusterPhyId\" : {\n" + - " \"type\" : \"long\"\n" + - " },\n" + - " \"metrics\" : {\n" + - " \"properties\" : {\n" + - " \"AvgRequestLatency\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"MinRequestLatency\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"MaxRequestLatency\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"OutstandingRequests\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"NodeCount\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"WatchCount\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"NumAliveConnections\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"PacketsReceived\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"PacketsSent\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"EphemeralsCount\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"ApproximateDataSize\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"OpenFileDescriptorCount\" : {\n" + - " \"type\" : \"double\"\n" + - " },\n" + - " \"MaxFileDescriptorCount\" : {\n" + - " \"type\" : \"double\"\n" + - " }\n" + - " }\n" + - " },\n" + - " \"key\" : {\n" + - " \"type\" : \"text\",\n" + - " \"fields\" : {\n" + - " \"keyword\" : {\n" + - " \"ignore_above\" : 256,\n" + - " \"type\" : \"keyword\"\n" + - " }\n" + - " }\n" + - " },\n" + - " \"timestamp\" : {\n" + - " \"format\" : \"yyyy-MM-dd HH:mm:ss Z||yyyy-MM-dd HH:mm:ss||yyyy-MM-dd HH:mm:ss.SSS Z||yyyy-MM-dd HH:mm:ss.SSS||yyyy-MM-dd HH:mm:ss,SSS||yyyy/MM/dd HH:mm:ss||yyyy-MM-dd HH:mm:ss,SSS Z||yyyy/MM/dd HH:mm:ss,SSS Z||epoch_millis\",\n" + - " \"type\" : \"date\"\n" + - " }\n" + - " }\n" + - " },\n" + - " \"aliases\" : { }\n" + - " }"; -} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/constant/KafkaConstant.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/constant/KafkaConstant.java index 16fd7921..465f6f8a 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/constant/KafkaConstant.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/constant/KafkaConstant.java @@ -33,7 +33,7 @@ public class KafkaConstant { public static final Integer DATA_VERSION_ONE = 1; - public static final Integer ADMIN_CLIENT_REQUEST_TIME_OUT_UNIT_MS = 5000; + public static final Integer ADMIN_CLIENT_REQUEST_TIME_OUT_UNIT_MS = 10000; public static final Integer KAFKA_SASL_SCRAM_ITERATIONS = 8192; @@ -43,6 +43,10 @@ public class KafkaConstant { public static final String CONTROLLER_ROLE = "controller"; + public static final String DEFAULT_CONNECT_VERSION = "2.5.0"; + + public static final List CONFIG_SIMILAR_IGNORED_CONFIG_KEY_LIST = Arrays.asList("broker.id", "listeners", "name", "value", "advertised.listeners", "node.id"); + public static final Map KAFKA_ALL_CONFIG_DEF_MAP = new ConcurrentHashMap<>(); static { diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/constant/MsgConstant.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/constant/MsgConstant.java index 1be8dadf..2f510a84 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/constant/MsgConstant.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/constant/MsgConstant.java @@ -52,6 +52,10 @@ public class MsgConstant { /**************************************************** Partition ****************************************************/ + public static String getPartitionNoLeader(Long clusterPhyId) { + return String.format("集群ID:[%d] 所有分区NoLeader", clusterPhyId); + } + public static String getPartitionNoLeader(Long clusterPhyId, String topicName) { return String.format("集群ID:[%d] Topic名称:[%s] 所有分区NoLeader", clusterPhyId, topicName); } @@ -91,4 +95,26 @@ public class MsgConstant { public static String getJobNotExist(Long jobId) { return String.format("jobId:[%d] 不存在", jobId); } + + + /**************************************************** Connect-Cluster ****************************************************/ + + public static String getConnectClusterBizStr(Long clusterId, String clusterName){ + return String.format("Connect集群ID:[%d] 集群名称:[%s]", clusterId, clusterName); + } + + public static String getConnectClusterNotExist(Long clusterId) { + return String.format("Connect集群ID:[%d] 不存在或者未加载", clusterId); + } + + public static String getConnectorBizStr(Long clusterPhyId, String topicName) { + return String.format("Connect集群ID:[%d] Connector名称:[%s]", clusterPhyId, topicName); + } + + + /**************************************************** Connector ****************************************************/ + + public static String getConnectorNotExist(Long connectClusterId, String connectorName) { + return String.format("Connect集群ID:[%d] Connector名称:[%s] 不存在", connectClusterId, connectorName); + } } diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/constant/connect/KafkaConnectConstant.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/constant/connect/KafkaConnectConstant.java new file mode 100644 index 00000000..63612874 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/constant/connect/KafkaConnectConstant.java @@ -0,0 +1,32 @@ +package com.xiaojukeji.know.streaming.km.common.constant.connect; + +/** + * @author zengqiao + * @date 20/5/20 + */ +public class KafkaConnectConstant { + public static final String CONNECTOR_CLASS_FILED_NAME = "connector.class"; + + public static final String CONNECTOR_TOPICS_FILED_NAME = "topics"; + public static final String CONNECTOR_TOPICS_FILED_ERROR_VALUE = "know-streaming-connect-illegal-value"; + + public static final String MIRROR_MAKER_TOPIC_PARTITION_PATTERN = "kafka.connect.mirror:type=MirrorSourceConnector,target=*,topic=*,partition=*"; + + public static final String MIRROR_MAKER_SOURCE_CONNECTOR_TYPE = "org.apache.kafka.connect.mirror.MirrorSourceConnector"; + + public static final String MIRROR_MAKER_HEARTBEAT_CONNECTOR_TYPE = "org.apache.kafka.connect.mirror.MirrorHeartbeatConnector"; + + public static final String MIRROR_MAKER_CHECKPOINT_CONNECTOR_TYPE = "org.apache.kafka.connect.mirror.MirrorCheckpointConnector"; + + public static final String MIRROR_MAKER_TARGET_CLUSTER_BOOTSTRAP_SERVERS_FIELD_NAME = "target.cluster.bootstrap.servers"; + public static final String MIRROR_MAKER_TARGET_CLUSTER_ALIAS_FIELD_NAME = "target.cluster.alias"; + public static final String MIRROR_MAKER_TARGET_CLUSTER_FIELD_NAME = "target.cluster"; + + public static final String MIRROR_MAKER_SOURCE_CLUSTER_BOOTSTRAP_SERVERS_FIELD_NAME = "source.cluster.bootstrap.servers"; + public static final String MIRROR_MAKER_SOURCE_CLUSTER_ALIAS_FIELD_NAME = "source.cluster.alias"; + public static final String MIRROR_MAKER_SOURCE_CLUSTER_FIELD_NAME = "source.cluster"; + + public static final String MIRROR_MAKER_NAME_FIELD_NAME = "name"; + private KafkaConnectConstant() { + } +} \ No newline at end of file diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/converter/ConnectConverter.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/converter/ConnectConverter.java new file mode 100644 index 00000000..6dcc30e4 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/converter/ConnectConverter.java @@ -0,0 +1,162 @@ +package com.xiaojukeji.know.streaming.km.common.converter; + +import com.xiaojukeji.know.streaming.km.common.bean.entity.connect.ConnectCluster; +import com.xiaojukeji.know.streaming.km.common.bean.entity.connect.connector.KSConnector; +import com.xiaojukeji.know.streaming.km.common.bean.entity.connect.connector.KSConnectorInfo; +import com.xiaojukeji.know.streaming.km.common.bean.entity.connect.connector.KSConnectorStateInfo; +import com.xiaojukeji.know.streaming.km.common.bean.entity.metrics.connect.ConnectorMetrics; +import com.xiaojukeji.know.streaming.km.common.bean.po.connect.ConnectorPO; +import com.xiaojukeji.know.streaming.km.common.bean.vo.cluster.connect.ConnectClusterBasicCombineExistVO; +import com.xiaojukeji.know.streaming.km.common.bean.vo.cluster.connector.ClusterConnectorOverviewVO; +import com.xiaojukeji.know.streaming.km.common.bean.vo.cluster.connector.ConnectorBasicCombineExistVO; +import com.xiaojukeji.know.streaming.km.common.bean.vo.cluster.connector.ConnectorBasicVO; +import com.xiaojukeji.know.streaming.km.common.bean.vo.cluster.mm2.MirrorMakerBasicVO; +import com.xiaojukeji.know.streaming.km.common.bean.vo.metrics.line.MetricLineVO; +import com.xiaojukeji.know.streaming.km.common.bean.vo.metrics.line.MetricMultiLinesVO; +import com.xiaojukeji.know.streaming.km.common.constant.connect.KafkaConnectConstant; +import com.xiaojukeji.know.streaming.km.common.utils.CommonUtils; +import com.xiaojukeji.know.streaming.km.common.utils.ConvertUtil; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +public class ConnectConverter { + public static ConnectorBasicCombineExistVO convert2BasicVO(ConnectCluster connectCluster, ConnectorPO connectorPO) { + ConnectorBasicCombineExistVO vo = new ConnectorBasicCombineExistVO(); + if (connectCluster == null || connectorPO == null) { + vo.setExist(false); + return vo; + } + + vo.setExist(true); + vo.setConnectClusterId(connectorPO.getConnectClusterId()); + vo.setConnectClusterName(connectCluster.getName()); + vo.setConnectorName(connectorPO.getConnectorName()); + + return vo; + } + + public static List convert2BasicVOList( + List clusterList, + List poList) { + Map clusterMap = new HashMap<>(); + clusterList.stream().forEach(elem -> clusterMap.put(elem.getId(), elem)); + + List voList = new ArrayList<>(); + poList.stream().filter(item -> clusterMap.containsKey(item.getConnectClusterId())).forEach(elem -> { + ConnectorBasicVO vo = new ConnectorBasicVO(); + vo.setConnectClusterId(elem.getConnectClusterId()); + vo.setConnectClusterName(clusterMap.get(elem.getConnectClusterId()).getName()); + vo.setConnectorName(elem.getConnectorName()); + + voList.add(vo); + }); + + return voList; + } + + public static List convert2MirrorMakerBasicVOList( + List clusterList, + List poList) { + Map clusterMap = new HashMap<>(); + clusterList.stream().forEach(elem -> clusterMap.put(elem.getId(), elem)); + + List voList = new ArrayList<>(); + poList.stream().filter(item -> clusterMap.containsKey(item.getConnectClusterId())).forEach(elem -> { + MirrorMakerBasicVO vo = new MirrorMakerBasicVO(); + vo.setConnectClusterId(elem.getConnectClusterId()); + vo.setConnectClusterName(clusterMap.get(elem.getConnectClusterId()).getName()); + vo.setConnectorName(elem.getConnectorName()); + + voList.add(vo); + }); + + return voList; + } + + public static ConnectClusterBasicCombineExistVO convert2ConnectClusterBasicCombineExistVO(ConnectCluster connectCluster) { + if (connectCluster == null) { + ConnectClusterBasicCombineExistVO combineExistVO = new ConnectClusterBasicCombineExistVO(); + combineExistVO.setExist(false); + + return combineExistVO; + } + + ConnectClusterBasicCombineExistVO combineExistVO = ConvertUtil.obj2Obj(connectCluster, ConnectClusterBasicCombineExistVO.class); + combineExistVO.setExist(true); + return combineExistVO; + } + + public static List convert2ClusterConnectorOverviewVOList(List clusterList, + List poList, + List metricsList) { + Map clusterMap = new HashMap<>(); + clusterList.stream().forEach(elem -> clusterMap.put(elem.getId(), elem)); + + Map metricMap = metricsList.stream().collect(Collectors.toMap(elem -> elem.getConnectClusterId() + "@" + elem.getConnectorName(), Function.identity())); + + List voList = new ArrayList<>(); + poList.stream().filter(item -> clusterMap.containsKey(item.getConnectClusterId())).forEach(elem -> { + ClusterConnectorOverviewVO vo = new ClusterConnectorOverviewVO(); + vo.setConnectClusterId(elem.getConnectClusterId()); + vo.setConnectClusterName(clusterMap.get(elem.getConnectClusterId()).getName()); + vo.setConnectorName(elem.getConnectorName()); + vo.setConnectorClassName(elem.getConnectorClassName()); + vo.setConnectorType(elem.getConnectorType()); + vo.setState(elem.getState()); + vo.setTaskCount(elem.getTaskCount()); + vo.setTopicNameList(CommonUtils.string2StrList(elem.getTopics())); + vo.setLatestMetrics(metricMap.getOrDefault(elem.getConnectClusterId() + "@" + elem.getConnectorName(), new ConnectorMetrics(elem.getConnectClusterId(), elem.getConnectorName()))); + voList.add(vo); + }); + + return voList; + } + + public static List supplyData2ClusterConnectorOverviewVOList(List voList, + List metricLineVOList) { + Map> metricLineMap = new HashMap<>(); + if (metricLineVOList != null) { + for (MetricMultiLinesVO metricMultiLinesVO : metricLineVOList) { + metricMultiLinesVO.getMetricLines() + .forEach(metricLineVO -> { + String key = metricLineVO.getName(); + List metricLineVOS = metricLineMap.getOrDefault(key, new ArrayList<>()); + metricLineVOS.add(metricLineVO); + metricLineMap.put(key, metricLineVOS); + }); + } + } + + voList.forEach(elem -> { + elem.setMetricLines(metricLineMap.get(genConnectorKey(elem.getConnectClusterId(), elem.getConnectorName()))); + }); + + return voList; + } + + public static KSConnector convert2KSConnector(Long kafkaClusterPhyId, Long connectClusterId, KSConnectorInfo connectorInfo, KSConnectorStateInfo stateInfo, List topicNameList) { + KSConnector ksConnector = new KSConnector(); + ksConnector.setKafkaClusterPhyId(kafkaClusterPhyId); + ksConnector.setConnectClusterId(connectClusterId); + ksConnector.setConnectorName(connectorInfo.getName()); + ksConnector.setConnectorClassName(connectorInfo.getConfig().getOrDefault(KafkaConnectConstant.CONNECTOR_CLASS_FILED_NAME, "")); + ksConnector.setConnectorType(connectorInfo.getType().name()); + ksConnector.setTopics(topicNameList != null? CommonUtils.strList2String(topicNameList): ""); + ksConnector.setTaskCount(connectorInfo.getTasks() != null? connectorInfo.getTasks().size(): 0); + ksConnector.setState(stateInfo != null? stateInfo.getConnector().getState(): ""); + + return ksConnector; + } + + private static String genConnectorKey(Long connectorId, String connectorName){ + return connectorId + "#" + connectorName; + } + + private ConnectConverter() { + } +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/converter/HealthScoreVOConverter.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/converter/HealthScoreVOConverter.java index 150306dc..5625c604 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/converter/HealthScoreVOConverter.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/converter/HealthScoreVOConverter.java @@ -21,18 +21,11 @@ public class HealthScoreVOConverter { HealthScoreResultDetailVO vo = new HealthScoreResultDetailVO(); vo.setDimension(healthScoreResult.getCheckNameEnum().getDimensionEnum().getDimension()); vo.setDimensionName(healthScoreResult.getCheckNameEnum().getDimensionEnum().getMessage()); + vo.setDimensionDisplayName(healthScoreResult.getCheckNameEnum().getDimensionEnum().getDimensionDisplayName()); vo.setConfigName(healthScoreResult.getCheckNameEnum().getConfigName()); vo.setConfigItem(healthScoreResult.getCheckNameEnum().getConfigItem()); vo.setConfigDesc(healthScoreResult.getCheckNameEnum().getConfigDesc()); - - vo.setScore(healthScoreResult.calRawHealthScore()); - if (healthScoreResult.getTotalCount() <= 0) { - // 未知 - vo.setPassed(null); - } else { - vo.setPassed(healthScoreResult.getPassedCount().equals(healthScoreResult.getTotalCount())); - } - + vo.setPassed(healthScoreResult.getPassed()); vo.setCheckConfig(convert2HealthCheckConfigVO(ConfigGroupEnum.HEALTH.name(), healthScoreResult.getBaseConfig())); vo.setNotPassedResNameList(healthScoreResult.getNotPassedResNameList()); @@ -51,8 +44,7 @@ public class HealthScoreVOConverter { vo.setDimensionName(healthScoreResult.getCheckNameEnum().getDimensionEnum().getMessage()); vo.setConfigName(healthScoreResult.getCheckNameEnum().getConfigName()); vo.setConfigDesc(healthScoreResult.getCheckNameEnum().getConfigDesc()); - vo.setScore(healthScoreResult.calRawHealthScore()); - vo.setPassed(healthScoreResult.getPassedCount().equals(healthScoreResult.getTotalCount())); + vo.setPassed(healthScoreResult.getPassed()); vo.setCheckConfig(convert2HealthCheckConfigVO(ConfigGroupEnum.HEALTH.name(), healthScoreResult.getBaseConfig())); vo.setCreateTime(healthScoreResult.getCreateTime()); vo.setUpdateTime(healthScoreResult.getUpdateTime()); @@ -72,6 +64,7 @@ public class HealthScoreVOConverter { public static HealthCheckConfigVO convert2HealthCheckConfigVO(String groupName, BaseClusterHealthConfig config) { HealthCheckConfigVO vo = new HealthCheckConfigVO(); vo.setDimensionCode(config.getCheckNameEnum().getDimensionEnum().getDimension()); + vo.setDimensionDisplayName(config.getCheckNameEnum().getDimensionEnum().getDimensionDisplayName()); vo.setDimensionName(config.getCheckNameEnum().getDimensionEnum().name()); vo.setConfigGroup(groupName); vo.setConfigName(config.getCheckNameEnum().getConfigName()); diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/converter/TopicConverter.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/converter/TopicConverter.java index c935c7f4..9ad4ed46 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/converter/TopicConverter.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/converter/TopicConverter.java @@ -55,10 +55,6 @@ public class TopicConverter { * 仅合并Topic的元信息部分,业务信息和配置信息部分不合并 */ public static TopicPO mergeAndOnlyMetadata2NewTopicPO(Topic newTopicData, TopicPO oldDBTopicPO) { - if (newTopicData == null) { - return null; - } - TopicPO newTopicPO = new TopicPO(); newTopicPO.setId(oldDBTopicPO != null? oldDBTopicPO.getId(): null); @@ -68,6 +64,7 @@ public class TopicConverter { newTopicPO.setReplicaNum(newTopicData.getReplicaNum()); newTopicPO.setBrokerIds(CommonUtils.intList2String(new ArrayList<>(newTopicData.getBrokerIdSet()))); newTopicPO.setType(newTopicData.getType()); + newTopicPO.setPartitionMap(ConvertUtil.obj2Json(newTopicData.getPartitionMap())); if (newTopicData.getCreateTime() != null) { newTopicPO.setCreateTime(new Date(newTopicData.getCreateTime())); @@ -77,8 +74,8 @@ public class TopicConverter { newTopicPO.setUpdateTime(oldDBTopicPO != null? oldDBTopicPO.getUpdateTime(): new Date()); } - newTopicPO.setPartitionMap(ConvertUtil.obj2Json(newTopicData.getPartitionMap())); - + newTopicPO.setDescription(oldDBTopicPO != null? oldDBTopicPO.getDescription(): null); + newTopicPO.setRetentionMs(oldDBTopicPO != null? oldDBTopicPO.getRetentionMs(): null); return newTopicPO; } diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/converter/TopicVOConverter.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/converter/TopicVOConverter.java index 8f5d5c28..14afdd9f 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/converter/TopicVOConverter.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/converter/TopicVOConverter.java @@ -1,6 +1,5 @@ package com.xiaojukeji.know.streaming.km.common.converter; -import com.xiaojukeji.know.streaming.km.common.bean.entity.metrics.BaseMetrics; import com.xiaojukeji.know.streaming.km.common.bean.entity.metrics.PartitionMetrics; import com.xiaojukeji.know.streaming.km.common.bean.entity.metrics.TopicMetrics; import com.xiaojukeji.know.streaming.km.common.bean.entity.partition.Partition; @@ -14,7 +13,6 @@ import com.xiaojukeji.know.streaming.km.common.bean.vo.metrics.line.MetricMultiL import com.xiaojukeji.know.streaming.km.common.bean.vo.topic.TopicRecordVO; import com.xiaojukeji.know.streaming.km.common.bean.vo.topic.partition.TopicPartitionVO; import com.xiaojukeji.know.streaming.km.common.utils.ValidateUtils; -import io.swagger.annotations.ApiModelProperty; import org.apache.kafka.clients.consumer.ConsumerRecord; import org.apache.kafka.common.header.Header; @@ -79,7 +77,7 @@ public class TopicVOConverter { return vo; } - public static List convert2ClusterPhyTopicsOverviewVOList(List topicList, Map metricsMap) { + public static List convert2ClusterPhyTopicsOverviewVOList(List topicList, Map metricsMap, Set haTopicNameSet) { List voList = new ArrayList<>(); for (Topic topic: topicList) { ClusterPhyTopicsOverviewVO vo = new ClusterPhyTopicsOverviewVO(); @@ -94,6 +92,7 @@ public class TopicVOConverter { vo.setLatestMetrics(metricsMap.getOrDefault(topic.getTopicName(), new TopicMetrics(topic.getTopicName(), topic.getClusterPhyId()))); + vo.setInMirror(haTopicNameSet.contains(topic.getTopicName())); voList.add(vo); } diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/enterprise/rebalance/converter/ClusterBalanceConverter.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/enterprise/rebalance/converter/ClusterBalanceConverter.java index f65f9035..d5614563 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/enterprise/rebalance/converter/ClusterBalanceConverter.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/enterprise/rebalance/converter/ClusterBalanceConverter.java @@ -32,7 +32,7 @@ import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; -import static com.xiaojukeji.know.streaming.km.common.constant.ESIndexConstant.PARTITION_INDEX; +import static com.xiaojukeji.know.streaming.km.common.constant.ESConstant.*; @EnterpriseLoadReBalance public class ClusterBalanceConverter { diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/enums/connect/ConnectActionEnum.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/enums/connect/ConnectActionEnum.java new file mode 100644 index 00000000..83ee2505 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/enums/connect/ConnectActionEnum.java @@ -0,0 +1,32 @@ +package com.xiaojukeji.know.streaming.km.common.enums.connect; + +public enum ConnectActionEnum { + /** + * + */ + + STOP(2, "stop"), + + RESUME(3,"resume"), + + RESTART(4,"restart"), + + UNKNOWN(-1, "unknown"); + + ConnectActionEnum(int status, String value) { + this.status = status; + this.value = value; + } + + private final int status; + + private final String value; + + public int getStatus() { + return status; + } + + public String getValue() { + return value; + } +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/enums/connect/ConnectorTypeEnum.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/enums/connect/ConnectorTypeEnum.java new file mode 100644 index 00000000..ce275b62 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/enums/connect/ConnectorTypeEnum.java @@ -0,0 +1,32 @@ +package com.xiaojukeji.know.streaming.km.common.enums.connect; + +/** + * @author wyb + * @date 2022/11/25 + */ +public enum ConnectorTypeEnum { + + + UNKNOWN(-1, "unknown"), + SOURCE(1, "source"), + SINK(2, "sink"); + + private final int code; + + private final String value; + + ConnectorTypeEnum(int code, String value) { + this.code = code; + this.value = value; + } + + public static ConnectorTypeEnum getByName(String name) { + for (ConnectorTypeEnum typeEnum : ConnectorTypeEnum.values()) { + if (typeEnum.name().equals(name)) { + return typeEnum; + } + } + return UNKNOWN; + } + +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/enums/group/GroupTypeEnum.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/enums/group/GroupTypeEnum.java index ebb91ea1..e4909dae 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/enums/group/GroupTypeEnum.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/enums/group/GroupTypeEnum.java @@ -2,6 +2,7 @@ package com.xiaojukeji.know.streaming.km.common.enums.group; import lombok.Getter; + /** * @author wyb * @date 2022/10/11 @@ -13,12 +14,18 @@ public enum GroupTypeEnum { CONSUMER(0, "Consumer客户端的消费组"), - CONNECTOR(1, "Connector的消费组"); + CONNECTOR(1, "Connector的消费组"), + + CONNECT_CLUSTER(2, "Connect集群"); private final Integer code; private final String msg; + public static final String CONNECTOR_PROTOCOL_TYPE = "consumer"; + + public static final String CONNECT_CLUSTER_PROTOCOL_TYPE = "connect"; + GroupTypeEnum(Integer code, String msg) { this.code = code; this.msg = msg; @@ -33,4 +40,19 @@ public enum GroupTypeEnum { } return UNKNOWN; } + + public static GroupTypeEnum getTypeByProtocolType(String protocolType) { + if (protocolType == null) { + return UNKNOWN; + } + if (protocolType.isEmpty()) { + return CONSUMER; + } else if (CONNECTOR_PROTOCOL_TYPE.equals(protocolType)) { + return CONNECTOR; + } else if (CONNECT_CLUSTER_PROTOCOL_TYPE.equals(protocolType)) { + return CONNECT_CLUSTER; + } else { + return UNKNOWN; + } + } } diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/enums/ha/HaResTypeEnum.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/enums/ha/HaResTypeEnum.java new file mode 100644 index 00000000..1821f7ab --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/enums/ha/HaResTypeEnum.java @@ -0,0 +1,25 @@ +package com.xiaojukeji.know.streaming.km.common.enums.ha; + +import lombok.Getter; + +/** + * @author zengqiao + * @date 20/7/28 + */ +@Getter +public enum HaResTypeEnum { + CLUSTER(0, "Cluster"), + + MIRROR_TOPIC(1, "镜像Topic"), + + ; + + private final int code; + + private final String msg; + + HaResTypeEnum(int code, String msg) { + this.code = code; + this.msg = msg; + } +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/enums/health/HealthCheckDimensionEnum.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/enums/health/HealthCheckDimensionEnum.java index daa4e641..5312f57a 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/enums/health/HealthCheckDimensionEnum.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/enums/health/HealthCheckDimensionEnum.java @@ -8,17 +8,25 @@ import lombok.Getter; */ @Getter public enum HealthCheckDimensionEnum { - UNKNOWN(-1, "未知"), + UNKNOWN(-1, "未知", "未知"), - CLUSTER(0, "Cluster"), + CLUSTER(0, "Cluster", "Cluster"), - BROKER(1, "Broker"), + BROKER(1, "Broker", "Broker"), - TOPIC(2, "Topic"), + TOPIC(2, "Topic", "Topic"), - GROUP(3, "Group"), + GROUP(3, "Group", "Group"), - ZOOKEEPER(4, "Zookeeper"), + ZOOKEEPER(4, "Zookeeper", "Zookeeper"), + + CONNECT_CLUSTER(5, "ConnectCluster", "Connect"), + + CONNECTOR(6, "Connector", "Connect"), + + MIRROR_MAKER(7,"MirrorMaker","MirrorMaker"), + + MAX_VAL(100, "所有的dimension的值需要小于MAX_VAL", "Ignore") ; @@ -26,9 +34,12 @@ public enum HealthCheckDimensionEnum { private final String message; - HealthCheckDimensionEnum(int dimension, String message) { + private final String dimensionDisplayName; + + HealthCheckDimensionEnum(int dimension, String message, String dimensionDisplayName) { this.dimension = dimension; this.message = message; + this.dimensionDisplayName=dimensionDisplayName; } public static HealthCheckDimensionEnum getByCode(Integer dimension) { diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/enums/health/HealthCheckNameEnum.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/enums/health/HealthCheckNameEnum.java index 5b294e67..20ddccc3 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/enums/health/HealthCheckNameEnum.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/enums/health/HealthCheckNameEnum.java @@ -132,6 +132,70 @@ public enum HealthCheckNameEnum { false ), + CONNECT_CLUSTER_TASK_STARTUP_FAILURE_PERCENTAGE( + HealthCheckDimensionEnum.CONNECT_CLUSTER, + "TaskStartupFailurePercentage", + Constant.HC_CONFIG_NAME_PREFIX+"CONNECT_CLUSTER_TASK_STARTUP_FAILURE_PERCENTAGE", + "Connect集群任务启动失败概率", + HealthCompareValueConfig.class, + false + ), + + CONNECTOR_FAILED_TASK_COUNT( + HealthCheckDimensionEnum.CONNECTOR, + "ConnectorFailedTaskCount", + Constant.HC_CONFIG_NAME_PREFIX+"CONNECTOR_FAILED_TASK_COUNT", + "Connector失败状态的任务数量", + HealthCompareValueConfig.class, + false + ), + + CONNECTOR_UNASSIGNED_TASK_COUNT( + HealthCheckDimensionEnum.CONNECTOR, + "ConnectorUnassignedTaskCount", + Constant.HC_CONFIG_NAME_PREFIX+"CONNECTOR_UNASSIGNED_TASK_COUNT", + "Connector未被分配的任务数量", + HealthCompareValueConfig.class, + false + ), + + MIRROR_MAKER_FAILED_TASK_COUNT( + HealthCheckDimensionEnum.MIRROR_MAKER, + "MirrorMakerFailedTaskCount", + Constant.HC_CONFIG_NAME_PREFIX+"MIRROR_MAKER_FAILED_TASK_COUNT", + "MirrorMaker失败状态的任务数量", + HealthCompareValueConfig.class, + false + ), + + MIRROR_MAKER_UNASSIGNED_TASK_COUNT( + HealthCheckDimensionEnum.MIRROR_MAKER, + "MirrorMakerUnassignedTaskCount", + Constant.HC_CONFIG_NAME_PREFIX+"MIRROR_MAKER_UNASSIGNED_TASK_COUNT", + "MirrorMaker未被分配的任务数量", + HealthCompareValueConfig.class, + false + ), + + MIRROR_MAKER_TOTAL_RECORD_ERRORS( + HealthCheckDimensionEnum.MIRROR_MAKER, + "TotalRecord-errors", + Constant.HC_CONFIG_NAME_PREFIX + "MIRROR_MAKER_TOTAL_RECORD_ERRORS", + "MirrorMaker消息处理错误的次数", + HealthCompareValueConfig.class, + false + ), + + MIRROR_MAKER_REPLICATION_LATENCY_MS_MAX( + HealthCheckDimensionEnum.MIRROR_MAKER, + "ReplicationLatencyMsMax", + Constant.HC_CONFIG_NAME_PREFIX + "MIRROR_MAKER_REPLICATION_LATENCY_MS_MAX", + "MirrorMaker消息复制最大延迟时间", + HealthCompareValueConfig.class, + false + ) + + ; diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/enums/operaterecord/ModuleEnum.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/enums/operaterecord/ModuleEnum.java index 0e2b6abb..cc338cd2 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/enums/operaterecord/ModuleEnum.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/enums/operaterecord/ModuleEnum.java @@ -34,6 +34,9 @@ public enum ModuleEnum { KAFKA_CONTROLLER(70, "KafkaController"), + KAFKA_CONNECT_CLUSTER(80, "KafkaConnectCluster"), + KAFKA_CONNECT_CONNECTOR(81, "KafkaConnectConnector"), + PLATFORM_CONFIG(100, "平台配置"), JOB_KAFKA_REPLICA_REASSIGN(110, "Job-KafkaReplica迁移"), diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/enums/operaterecord/OperationEnum.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/enums/operaterecord/OperationEnum.java index 560ff34b..302cb38b 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/enums/operaterecord/OperationEnum.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/enums/operaterecord/OperationEnum.java @@ -30,6 +30,8 @@ public enum OperationEnum { CANCEL(10, "取消"), + RESTART(11, "重启"), + ; OperationEnum(int code, String desc) { diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/enums/version/VersionEnum.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/enums/version/VersionEnum.java index 133cb828..5c594848 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/enums/version/VersionEnum.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/enums/version/VersionEnum.java @@ -53,7 +53,11 @@ public enum VersionEnum { V_2_3_1("2.3.1", normailze("2.3.1")), V_2_4_0("2.4.0", normailze("2.4.0")), V_2_4_1("2.4.1", normailze("2.4.1")), + V_2_5_0("2.5.0", normailze("2.5.0")), + V_2_5_0_D_300("2.5.0-d-300", normailze("2.5.0-d-300")), + V_2_5_0_D_MAX("2.5.0-d-999", normailze("2.5.0-d-999")), + V_2_5_1("2.5.1", normailze("2.5.1")), V_2_6_0("2.6.0", normailze("2.6.0")), V_2_6_1("2.6.1", normailze("2.6.1")), @@ -77,9 +81,9 @@ public enum VersionEnum { ; - private String version; + private final String version; - private Long versionL; + private final Long versionL; VersionEnum(String version, Long versionL) { this.version = version; diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/enums/version/VersionItemTypeEnum.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/enums/version/VersionItemTypeEnum.java index 004dad6d..7bcf3234 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/enums/version/VersionItemTypeEnum.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/enums/version/VersionItemTypeEnum.java @@ -4,14 +4,18 @@ public enum VersionItemTypeEnum { /** * 指标 */ - METRIC_TOPIC(100, "topic_metric"), - METRIC_CLUSTER(101, "cluster_metric"), - METRIC_GROUP(102, "group_metric"), - METRIC_BROKER(103, "broker_metric"), - METRIC_PARTITION(104, "partition_metric"), - METRIC_REPLICATION(105, "replication_metric"), + METRIC_TOPIC(100, "TopicMetric"), + METRIC_CLUSTER(101, "ClusterMetric"), + METRIC_GROUP(102, "GroupMetric"), + METRIC_BROKER(103, "BrokerMetric"), + METRIC_PARTITION(104, "PartitionMetric"), + METRIC_REPLICATION(105, "ReplicaMetric"), - METRIC_ZOOKEEPER(110, "zookeeper_metric"), + METRIC_ZOOKEEPER(110, "ZookeeperMetric"), + + METRIC_CONNECT_CLUSTER(120, "ConnectClusterMetric"), + METRIC_CONNECT_CONNECTOR(121, "ConnectConnectorMetric"), + METRIC_CONNECT_MIRROR_MAKER(122, "ConnectMirrorMakerMetric"), /** * 服务端查询 @@ -37,6 +41,9 @@ public enum VersionItemTypeEnum { SERVICE_OP_REASSIGNMENT(330, "service_reassign_operation"), + SERVICE_OP_CONNECT_CLUSTER(400, "service_connect_cluster_operation"), + SERVICE_OP_CONNECT_CONNECTOR(401, "service_connect_connector_operation"), + SERVICE_OP_CONNECT_PLUGIN(402, "service_connect_plugin_operation"), /** * 前端操作 diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/jmx/JmxAttribute.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/jmx/JmxAttribute.java index a9bea1c3..3043b90f 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/jmx/JmxAttribute.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/jmx/JmxAttribute.java @@ -34,6 +34,142 @@ public class JmxAttribute { public static final String VERSION = "Version"; + /*********************************************************** connect cluster***********************************************************/ + public static final String TASK_COUNT = "task-count"; + + public static final String CONNECTOR_STARTUP_ATTEMPTS_TOTAL = "connector-startup-attempts-total"; + + public static final String CONNECTOR_STARTUP_FAILURE_PERCENTAGE = "connector-startup-failure-percentage"; + + public static final String CONNECTOR_STARTUP_FAILURE_TOTAL = "connector-startup-failure-total"; + + public static final String CONNECTOR_STARTUP_SUCCESS_PERCENTAGE = "connector-startup-success-percentage"; + + public static final String CONNECTOR_STARTUP_SUCCESS_TOTAL = "connector-startup-success-total"; + + public static final String TASK_STARTUP_ATTEMPTS_TOTAL = "task-startup-attempts-total"; + + public static final String TASK_STARTUP_FAILURE_PERCENTAGE = "task-startup-failure-percentage"; + + public static final String TASK_STARTUP_FAILURE_TOTAL = "task-startup-failure-total"; + + public static final String TASK_STARTUP_SUCCESS_PERCENTAGE = "task-startup-success-percentage"; + + public static final String TASK_STARTUP_SUCCESS_TOTAL = "task-startup-success-total"; + + /*********************************************************** connect ***********************************************************/ + public static final String CONNECTOR_TOTAL_TASK_COUNT = "connector-total-task-count"; + + public static final String CONNECTOR_RUNNING_TASK_COUNT = "connector-running-task-count"; + + public static final String CONNECTOR_PAUSED_TASK_COUNT = "connector-paused-task-count"; + + public static final String CONNECTOR_FAILED_TASK_COUNT = "connector-failed-task-count"; + + public static final String CONNECTOR_UNASSIGNED_TASK_COUNT = "connector-unassigned-task-count"; + + public static final String BATCH_SIZE_AVG = "batch-size-avg"; + + public static final String BATCH_SIZE_MAX = "batch-size-max"; + + public static final String OFFSET_COMMIT_AVG_TIME_MS = "offset-commit-avg-time-ms"; + + public static final String OFFSET_COMMIT_MAX_TIME_MS = "offset-commit-max-time-ms"; + + public static final String OFFSET_COMMIT_FAILURE_PERCENTAGE = "offset-commit-failure-percentage"; + + public static final String OFFSET_COMMIT_SUCCESS_PERCENTAGE = "offset-commit-success-percentage"; + + public static final String POLL_BATCH_AVG_TIME_MS = "poll-batch-avg-time-ms"; + + public static final String POLL_BATCH_MAX_TIME_MS = "poll-batch-max-time-ms"; + + public static final String SOURCE_RECORD_ACTIVE_COUNT = "source-record-active-count"; + + public static final String SOURCE_RECORD_ACTIVE_COUNT_AVG = "source-record-active-count-avg"; + + public static final String SOURCE_RECORD_ACTIVE_COUNT_MAX = "source-record-active-count-max"; + + public static final String SOURCE_RECORD_POLL_RATE = "source-record-poll-rate"; + + public static final String SOURCE_RECORD_POLL_TOTAL = "source-record-poll-total"; + + public static final String SOURCE_RECORD_WRITE_RATE = "source-record-write-rate"; + + public static final String SOURCE_RECORD_WRITE_TOTAL = "source-record-write-total"; + + public static final String OFFSET_COMMIT_COMPLETION_RATE = "offset-commit-completion-rate"; + + public static final String OFFSET_COMMIT_COMPLETION_TOTAL = "offset-commit-completion-total"; + + public static final String OFFSET_COMMIT_SKIP_RATE = "offset-commit-skip-rate"; + + public static final String OFFSET_COMMIT_SKIP_TOTAL = "offset-commit-skip-total"; + + public static final String PARTITION_COUNT = "partition-count"; + + public static final String PUT_BATCH_AVG_TIME_MS = "put-batch-avg-time-ms"; + + public static final String PUT_BATCH_MAX_TIME_MS = "put-batch-max-time-ms"; + + public static final String SINK_RECORD_ACTIVE_COUNT = "sink-record-active-count"; + + public static final String SINK_RECORD_ACTIVE_COUNT_AVG = "sink-record-active-count-avg"; + + public static final String SINK_RECORD_ACTIVE_COUNT_MAX = "sink-record-active-count-max"; + + public static final String SINK_RECORD_LAG_MAX = "sink-record-lag-max"; + + public static final String SINK_RECORD_READ_RATE = "sink-record-read-rate"; + + public static final String SINK_RECORD_READ_TOTAL = "sink-record-read-total"; + + public static final String SINK_RECORD_SEND_RATE = "sink-record-send-rate"; + + public static final String SINK_RECORD_SEND_TOTAL = "sink-record-send-total"; + + public static final String DEADLETTERQUEUE_PRODUCE_FAILURES = "deadletterqueue-produce-failures"; + + public static final String DEADLETTERQUEUE_PRODUCE_REQUESTS = "deadletterqueue-produce-requests"; + + public static final String LAST_ERROR_TIMESTAMP = "last-error-timestamp"; + + public static final String TOTAL_ERRORS_LOGGED = "total-errors-logged"; + + public static final String TOTAL_RECORD_ERRORS = "total-record-errors"; + + public static final String TOTAL_RECORD_FAILURES = "total-record-failures"; + + public static final String TOTAL_RECORDS_SKIPPED = "total-records-skipped"; + + public static final String TOTAL_RETRIES = "total-retries"; + + /*********************************************************** mm2 ***********************************************************/ + + public static final String BYTE_COUNT = "byte-count"; + + public static final String BYTE_RATE = "byte-rate"; + + public static final String RECORD_AGE_MS = "record-age-ms"; + + public static final String RECORD_AGE_MS_AVG = "record-age-ms-avg"; + + public static final String RECORD_AGE_MS_MAX = "record-age-ms-max"; + + public static final String RECORD_AGE_MS_MIN = "record-age-ms-min"; + + public static final String RECORD_COUNT = "record-count"; + + public static final String RECORD_RATE = "record-rate"; + + public static final String REPLICATION_LATENCY_MS = "replication-latency-ms"; + + public static final String REPLICATION_LATENCY_MS_AVG = "replication-latency-ms-avg"; + + public static final String REPLICATION_LATENCY_MS_MAX = "replication-latency-ms-max"; + + public static final String REPLICATION_LATENCY_MS_MIN = "replication-latency-ms-min"; + private JmxAttribute() { } } diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/jmx/JmxConnectorWrap.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/jmx/JmxConnectorWrap.java index ca7c01c4..d9cfb082 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/jmx/JmxConnectorWrap.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/jmx/JmxConnectorWrap.java @@ -28,9 +28,8 @@ import java.util.concurrent.atomic.AtomicInteger; public class JmxConnectorWrap { private static final Logger LOGGER = LoggerFactory.getLogger(JmxConnectorWrap.class); - private final Long physicalClusterId; - - private final Integer brokerId; + //jmx打印日志时的附带信息 + private final String clientLogIdent; private final Long brokerStartupTime; @@ -44,9 +43,8 @@ public class JmxConnectorWrap { private JmxConfig jmxConfig; - public JmxConnectorWrap(Long physicalClusterId, Integer brokerId, Long brokerStartupTime, String host, Integer port, JmxConfig jmxConfig) { - this.physicalClusterId = physicalClusterId; - this.brokerId = brokerId; + public JmxConnectorWrap(String clientLogIdent, Long brokerStartupTime, String host, Integer port, JmxConfig jmxConfig) { + this.clientLogIdent=clientLogIdent; this.brokerStartupTime = brokerStartupTime; this.host = host; @@ -93,7 +91,7 @@ public class JmxConnectorWrap { jmxConnector = null; } catch (IOException e) { - LOGGER.warn("close JmxConnector exception, physicalClusterId:{} brokerId:{} host:{} port:{}.", physicalClusterId, brokerId, host, port, e); + LOGGER.warn("close JmxConnector exception, clientLogIdent:{} host:{} port:{}.", clientLogIdent, host, port, e); } } @@ -176,12 +174,12 @@ public class JmxConnectorWrap { } jmxConnector = JMXConnectorFactory.connect(new JMXServiceURL(jmxUrl), environment); - LOGGER.info("JMX connect success, physicalClusterId:{} brokerId:{} host:{} port:{}.", physicalClusterId, brokerId, host, port); + LOGGER.info("JMX connect success, clientLogIdent:{} host:{} port:{}.", clientLogIdent, host, port); return true; } catch (MalformedURLException e) { - LOGGER.error("JMX url exception, physicalClusterId:{} brokerId:{} host:{} port:{} jmxUrl:{}", physicalClusterId, brokerId, host, port, jmxUrl, e); + LOGGER.error("JMX url exception, clientLogIdent:{} host:{} port:{} jmxUrl:{}", clientLogIdent, host, port, jmxUrl, e); } catch (Exception e) { - LOGGER.error("JMX connect exception, physicalClusterId:{} brokerId:{} host:{} port:{}.", physicalClusterId, brokerId, host, port, e); + LOGGER.error("JMX connect exception, clientLogIdent:{} host:{} port:{}.", clientLogIdent, host, port, e); } return false; } diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/jmx/JmxName.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/jmx/JmxName.java index db8b3197..39217986 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/jmx/JmxName.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/jmx/JmxName.java @@ -41,6 +41,8 @@ public class JmxName { public static final String JMX_SERVER_APP_INFO ="kafka.server:type=app-info"; + public static final String JMX_SERVER_TOPIC_MIRROR ="kafka.server:type=FetcherLagMetrics,name=ConsumerLag,clientId=*,topic=%s,partition=*"; + /*********************************************************** controller ***********************************************************/ public static final String JMX_CONTROLLER_ACTIVE_COUNT = "kafka.controller:type=KafkaController,name=ActiveControllerCount"; @@ -69,6 +71,24 @@ public class JmxName { public static final String JMX_ZK_SYNC_CONNECTS_PER_SEC = "kafka.server:type=SessionExpireListener,name=ZooKeeperSyncConnectsPerSec"; public static final String JMX_ZK_DISCONNECTORS_PER_SEC = "kafka.server:type=SessionExpireListener,name=ZooKeeperDisconnectsPerSec"; + /*********************************************************** connect ***********************************************************/ + public static final String JMX_CONNECT_WORKER_METRIC = "kafka.connect:type=connect-worker-metrics"; + + public static final String JMX_CONNECT_WORKER_CONNECTOR_METRIC = "kafka.connect:type=connect-worker-metrics,connector=%s"; + + public static final String JMX_CONNECTOR_TASK_CONNECTOR_METRIC = "kafka.connect:type=connector-task-metrics,connector=%s,task=%s"; + + public static final String JMX_CONNECTOR_SOURCE_TASK_METRICS = "kafka.connect:type=source-task-metrics,connector=%s,task=%s"; + + public static final String JMX_CONNECTOR_SINK_TASK_METRICS = "kafka.connect:type=sink-task-metrics,connector=%s,task=%s"; + + public static final String JMX_CONNECTOR_TASK_ERROR_METRICS = "kafka.connect:type=task-error-metrics,connector=%s,task=%s"; + + /*********************************************************** mm2 ***********************************************************/ + + public static final String JMX_MIRROR_MAKER_SOURCE = "kafka.connect.mirror:type=MirrorSourceConnector,target=%s,topic=%s,partition=%s"; + + private JmxName() { } } diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/CommonUtils.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/CommonUtils.java index f0a42192..48601795 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/CommonUtils.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/CommonUtils.java @@ -7,6 +7,7 @@ import org.springframework.web.multipart.MultipartFile; import java.math.BigDecimal; import java.math.BigInteger; +import java.net.URI; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.util.ArrayList; @@ -61,7 +62,7 @@ public class CommonUtils { //转换为16进制 return new BigInteger(1, digest).toString(16); } catch (Exception e) { - LOGGER.error("class=CommonUtils||method=getMD5||msg=获取文件的md5失败:{}", e.getMessage()); + LOGGER.error("method=getMD5||msg=获取文件的md5失败:{}", e.getMessage()); } return null; } @@ -251,4 +252,29 @@ public class CommonUtils { return true; } + + public static String getWorkerId(String url){ + try { + URI uri = new URI(url); + return uri.getHost() + ":" + uri.getPort(); + } catch (Exception e) { + return null; + } + } + + + /** + * 校验两个list的第一个元素是否相等,以","分隔元素。 + * @param str1 + * @param str2 + * @return + */ + public static boolean checkFirstElementIsEquals(String str1, String str2) { + if (ValidateUtils.anyBlank(str1, str2)) { + return false; + } + Integer targetLeader = CommonUtils.string2IntList(str1).get(0); + Integer originalLeader = CommonUtils.string2IntList(str2).get(0); + return originalLeader.equals(targetLeader); + } } diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/ConvertUtil.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/ConvertUtil.java index 71b611fd..10e87ca8 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/ConvertUtil.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/ConvertUtil.java @@ -210,7 +210,7 @@ public class ConvertUtil { BeanUtils.copyProperties(srcObj, tgt); consumer.accept(tgt); } catch (Exception e) { - LOGGER.warn("class=ConvertUtil||method=obj2Obj||msg={}", e.getMessage()); + LOGGER.warn("method=obj2Obj||msg={}", e.getMessage()); } return tgt; @@ -236,7 +236,7 @@ public class ConvertUtil { try { map.put(field.getName(), field.get(obj)); } catch (IllegalAccessException e) { - LOGGER.warn("class=ConvertUtil||method=Obj2Map||msg={}", e.getMessage(), e); + LOGGER.warn("method=Obj2Map||msg={}", e.getMessage(), e); } } return map; @@ -256,7 +256,7 @@ public class ConvertUtil { field.set(obj, map.get(field.getName())); } } catch (Exception e) { - LOGGER.warn("class=ConvertUtil||method=map2Obj||msg={}", e.getMessage(), e); + LOGGER.warn("method=map2Obj||msg={}", e.getMessage(), e); } return obj; diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/FutureNoWaitUtil.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/FutureNoWaitUtil.java index 6bd7ae19..5e7ca714 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/FutureNoWaitUtil.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/FutureNoWaitUtil.java @@ -23,7 +23,7 @@ public class FutureNoWaitUtil { private FutureNoWaitUtil() { } - public static FutureNoWaitUtil init(String name, int corePoolSize, int maxPoolSize, int queueSize) { + public static FutureNoWaitUtil init(String threadPoolName, int corePoolSize, int maxPoolSize, int queueSize) { FutureNoWaitUtil futureUtil = new FutureNoWaitUtil<>(); // 创建任务线程池 @@ -33,7 +33,7 @@ public class FutureNoWaitUtil { 300, TimeUnit.SECONDS, new LinkedBlockingDeque<>(queueSize), - new NamedThreadFactory("KS-KM-FutureNoWaitUtil-" + name), + new NamedThreadFactory(threadPoolName), new ThreadPoolExecutor.DiscardOldestPolicy() //对拒绝任务不抛弃,而是抛弃队列里面等待最久的一个线程,然后把拒绝任务加到队列。 ); futureUtil.executor.allowCoreThreadTimeOut(true); @@ -41,7 +41,7 @@ public class FutureNoWaitUtil { futureUtil.delayQueueData = new DelayQueue<>(); // 创建检查延迟队列的线程并启动 - futureUtil.checkDelayQueueThread = new Thread(() -> futureUtil.runCheck(), "KS-KM-FutureNoWaitUtil-CheckDelayQueueData-" + name); + futureUtil.checkDelayQueueThread = new Thread(() -> futureUtil.runCheck(), threadPoolName + "-CheckTaskTimeout"); futureUtil.checkDelayQueueThread.setDaemon(true); futureUtil.checkDelayQueueThread.start(); @@ -64,7 +64,7 @@ public class FutureNoWaitUtil { while (true) { FutureTaskDelayQueueData data = null; try { - LOGGER.debug("class=FutureNoWaitUtil||method=runCheck||delayQueueSize={}", delayQueueData.size()); + LOGGER.debug("method=runCheck||delayQueueSize={}", delayQueueData.size()); while (true) { data = delayQueueData.take(); @@ -81,7 +81,7 @@ public class FutureNoWaitUtil { // 停1000ms Thread.sleep(1000); } catch (Exception e) { - LOGGER.error("class=FutureNoWaitUtil||method=runCheck||taskName={}||errMsg=exception!", data == null? "": data.getTaskName(), e); + LOGGER.error("method=runCheck||taskName={}||errMsg=exception!", data == null? "": data.getTaskName(), e); } } } diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/FutureUtil.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/FutureUtil.java index 1e5cd875..ed68939f 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/FutureUtil.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/FutureUtil.java @@ -9,12 +9,12 @@ import java.util.concurrent.*; public class FutureUtil { private ThreadPoolExecutor executor; - public static final FutureUtil quickStartupFutureUtil = FutureUtil.init("QuickStartupFutureUtil", 8, 8, 10240); + public static final FutureUtil quickStartupFutureUtil = FutureUtil.init("QuickStartupTP", 8, 8, 10240); private FutureUtil() { } - public static FutureUtil init(String name, int corePoolSize, int maxPoolSize, int queueSize) { + public static FutureUtil init(String threadPoolName, int corePoolSize, int maxPoolSize, int queueSize) { FutureUtil futureUtil = new FutureUtil<>(); futureUtil.executor = new ThreadPoolExecutor( @@ -23,7 +23,7 @@ public class FutureUtil { 300, TimeUnit.SECONDS, new LinkedBlockingDeque<>(queueSize), - new NamedThreadFactory("FutureUtil-" + name), + new NamedThreadFactory(threadPoolName), new ThreadPoolExecutor.DiscardOldestPolicy() //对拒绝任务不抛弃,而是抛弃队列里面等待最久的一个线程,然后把拒绝任务加到队列。 ); futureUtil.executor.allowCoreThreadTimeOut(true); diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/FutureWaitUtil.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/FutureWaitUtil.java index cf2af736..28388358 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/FutureWaitUtil.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/FutureWaitUtil.java @@ -23,7 +23,7 @@ public class FutureWaitUtil { private FutureWaitUtil() { } - public static FutureWaitUtil init(String name, int corePoolSize, int maxPoolSize, int queueSize) { + public static FutureWaitUtil init(String threadPoolName, int corePoolSize, int maxPoolSize, int queueSize) { FutureWaitUtil futureUtil = new FutureWaitUtil<>(); futureUtil.executor = new ThreadPoolExecutor( @@ -32,7 +32,7 @@ public class FutureWaitUtil { 300, TimeUnit.SECONDS, new LinkedBlockingDeque<>(queueSize), - new NamedThreadFactory("FutureWaitUtil-" + name), + new NamedThreadFactory(threadPoolName), new ThreadPoolExecutor.DiscardOldestPolicy() //对拒绝任务不抛弃,而是抛弃队列里面等待最久的一个线程,然后把拒绝任务加到队列。 ); futureUtil.executor.allowCoreThreadTimeOut(true); @@ -123,11 +123,11 @@ public class FutureWaitUtil { } // 达到超时时间,但是任务未完成,则打印日志并强制取消 - LOGGER.error("class=FutureUtil||method=waitExecute||taskName={}||msg=cancel task", queueData.getTaskName()); + LOGGER.error("method=waitExecute||taskName={}||msg=cancel task", queueData.getTaskName()); queueData.getFutureTask().cancel(true); } catch (Exception e) { - LOGGER.error("class=FutureUtil||method=waitExecute||msg=exception", e); + LOGGER.error("method=waitExecute||msg=exception", e); } } @@ -155,7 +155,7 @@ public class FutureWaitUtil { return queueData.getFutureTask().get(stepWaitTimeUnitMs, TimeUnit.MILLISECONDS); } catch (Exception e) { // 达到超时时间,但是任务未完成,则打印日志并强制取消 - LOGGER.error("class=FutureUtil||method=stepWaitResult||taskName={}||errMsg=exception", queueData.getTaskName(), e); + LOGGER.error("method=stepWaitResult||taskName={}||errMsg=exception", queueData.getTaskName(), e); } return null; diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/LoggerUtil.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/LoggerUtil.java new file mode 100644 index 00000000..d8de462e --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/LoggerUtil.java @@ -0,0 +1,21 @@ +package com.xiaojukeji.know.streaming.km.common.utils; + +import com.didiglobal.logi.log.ILog; +import com.didiglobal.logi.log.LogFactory; + +public class LoggerUtil { + private static final ILog MetricCollectedLogger = LogFactory.getLog("METRIC_COLLECTED_LOGGER"); + + private static final ILog ESLogger = LogFactory.getLog("ES_LOGGER"); + + public static ILog getMetricCollectedLogger() { + return MetricCollectedLogger; + } + + public static ILog getESLogger() { + return ESLogger; + } + + private LoggerUtil() { + } +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/MirrorMakerUtil.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/MirrorMakerUtil.java new file mode 100644 index 00000000..d8145832 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/MirrorMakerUtil.java @@ -0,0 +1,11 @@ +package com.xiaojukeji.know.streaming.km.common.utils; + +public class MirrorMakerUtil { + public static String genCheckpointName(String sourceName) { + return sourceName == null? "-checkpoint": sourceName + "-checkpoint"; + } + + public static String genHeartbeatName(String sourceName) { + return sourceName == null? "-heartbeat": sourceName + "-heartbeat"; + } +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/PaginationMetricsUtil.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/PaginationMetricsUtil.java index 9d732917..430ea9c4 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/PaginationMetricsUtil.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/PaginationMetricsUtil.java @@ -37,6 +37,11 @@ public class PaginationMetricsUtil { return allDataList; } + //比较metricNameList中第一个不为空的metric值。 + public static void sortMetrics(List allDataList, String metricField, List metricNameList, String defaultSortField, String sortType) { + sortMetricList(allDataList, metricField, metricNameList, defaultSortField, sortType); + } + public static List sortMetrics(List allDataList, String metricName, String defaultSortField, String sortType) { sortMetricList(allDataList, metricName, defaultSortField, sortType); @@ -151,6 +156,102 @@ public class PaginationMetricsUtil { return allDataList; } + private static List sortMetricList(List allDataList, String metricFieldName, List metricNameList, String defaultFieldName, String sortType) { + if (ValidateUtils.anyBlank(defaultFieldName, sortType) || ValidateUtils.isEmptyList(allDataList)||ValidateUtils.isEmptyList(metricNameList)) { + return allDataList; + } + + try { + Field metricField = FieldUtils.getField(allDataList.get(0).getClass(), metricFieldName, true); + Field defaultField = FieldUtils.getField(allDataList.get(0).getClass(), defaultFieldName, true); + if(ValidateUtils.anyNull(defaultField, metricField)) { + log.debug("method=sortMetrics||className={}||metricFieldName={}||metricNameList={}||defaultFieldName={}||metricSortType={}||msg=field not exist.", + allDataList.get(0).getClass().getSimpleName(), metricFieldName, metricNameList, defaultFieldName, sortType); + + // 字段不存在,则排序失效,直接返回 + return allDataList; + } + + Collections.sort(allDataList, (a1, a2) -> { + try { + Object m1 = FieldUtils.readField(a1, metricField.getName(), true); + Object m2 = FieldUtils.readField(a2, metricField.getName(), true); + + return compareFirstNotNullMetricValue((BaseMetrics)m1, (BaseMetrics)m2, metricNameList, defaultField); + } catch (Exception e) { + log.error("method=sortMetrics||className={}||metricFieldName={}||metricNameList={}||defaultFieldName={}||metricSortType={}||errMsg=exception.", + allDataList.get(0).getClass().getSimpleName(), metricFieldName, metricNameList, defaultFieldName, sortType, e); + } + + return 0; + }); + } catch (Exception e) { + log.error("method=sortMetrics||className={}||metricFieldName={}||metricNameList={}||defaultFieldName={}||metricSortType={}||errMsg=exception.", + allDataList.get(0).getClass().getSimpleName(), metricFieldName, metricNameList, defaultFieldName, sortType, e); + } + + if (!SortTypeEnum.DESC.getSortType().equals(sortType)) { + Collections.reverse(allDataList); + } + return allDataList; + } + + private static int compareFirstNotNullMetricValue(BaseMetrics a1, BaseMetrics a2, List metricNameList, Field defaultField) { + try { + // 指标数据排序 + Float m1 = null; + Float m2 = null; + + //获取第一个非空指标 + for (String metric : metricNameList) { + m1 = a1.getMetric(metric); + if (m1 != null) { + break; + } + } + for (String metric : metricNameList) { + m2 = a2.getMetric(metric); + if (m2 != null) { + break; + } + } + + if (m1 != null && m2 == null) { + return -1; + } else if (m1 == null && m2 != null) { + return 1; + } else if (m1 != null && m2 != null) { + // 两个都不为空,则进行大小比较 + int val = compareObject(m2, m1); + if (val != 0) { + return val; + } + } + + // 默认字段排序 + Object f1 = FieldUtils.readField(a1, defaultField.getName(), true); + Object f2 = FieldUtils.readField(a2, defaultField.getName(), true); + if (f1 != null && f2 != null) { + // 两个都不为空,则进行大小比较 + return compareObject(f2, f1); + } + if (f1 != null) { + return -1; + } else if (f2 != null) { + return 1; + } + + return 0; + } catch (Exception e) { + log.debug("method=sortMetricsObject||metricsA={}||metricsB={}||metricNameList={}||defaultFieldName={}||errMsg=exception.", + a1, a2, metricNameList, defaultField.getName(), e); + } + + return 0; + } + + + private static List sortMetricList(List allDataList, String metricName, String defaultSortField, String sortType) { if (ValidateUtils.anyBlank(metricName, defaultSortField, sortType) || ValidateUtils.isEmptyList(allDataList)) { return allDataList; @@ -163,7 +264,7 @@ public class PaginationMetricsUtil { try { Field defaultField = FieldUtils.getField(allDataList.get(0).getClass(), defaultSortField, true); if(ValidateUtils.anyNull(defaultField)) { - log.debug("class=PaginationMetricsUtil||method=sortMetrics||className={}||metricName={}||defaultFieldName={}||metricSortType={}||msg=default field not exist.", + log.debug("method=sortMetrics||className={}||metricName={}||defaultFieldName={}||metricSortType={}||msg=default field not exist.", allDataList.get(0).getClass().getSimpleName(), metricName, defaultSortField, sortType); // 字段不存在,则排序失效,直接返回 @@ -172,7 +273,7 @@ public class PaginationMetricsUtil { Collections.sort(allDataList, (a1, a2) -> sortMetricsObject(a1, a2, metricName, defaultField)); } catch (Exception e) { - log.debug("class=PaginationMetricsUtil||method=sortMetrics||className={}||metricName={}||defaultFieldName={}||metricSortType={}||errMsg=exception.", + log.debug("method=sortMetrics||className={}||metricName={}||defaultFieldName={}||metricSortType={}||errMsg=exception.", allDataList.get(0).getClass().getSimpleName(), metricName, defaultSortField, sortType, e); } @@ -214,7 +315,7 @@ public class PaginationMetricsUtil { return 0; } catch (Exception e) { - log.debug("class=PaginationMetricsUtil||method=sortMetricsObject||metricsA={}||metricsB={}||metricName={}||defaultFieldName={}||errMsg=exception.", + log.debug("method=sortMetricsObject||metricsA={}||metricsB={}||metricName={}||defaultFieldName={}||errMsg=exception.", a1, a2, metricName, defaultField.getName(), e); } diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/RetryExecutor.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/RetryExecutor.java index fcf675e4..8b68a460 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/RetryExecutor.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/RetryExecutor.java @@ -94,12 +94,12 @@ public class RetryExecutor { } } catch (Exception e) { if (!handler.needRetry(e) || tryCount == retryCount) { - LOGGER.warn("class=RetryExecutor||method=execute||errMsg={}||handlerName={}||tryCount={}", + LOGGER.warn("method=execute||errMsg={}||handlerName={}||tryCount={}", e.getMessage(), name, tryCount, e); throw e; } - LOGGER.warn("class=RetryExecutor||method=execute||errMsg={}||handlerName={}||tryCount={}||maxTryCount={}", + LOGGER.warn("method=execute||errMsg={}||handlerName={}||tryCount={}||maxTryCount={}", e.getMessage(), name, tryCount,retryCount); } } while (tryCount++ < retryCount); diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/Tuple.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/Tuple.java index 405845a1..c4984604 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/Tuple.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/Tuple.java @@ -12,7 +12,6 @@ import lombok.Data; @JsonIgnoreProperties(value = { "hibernateLazyInitializer", "handler" }) @Data public class Tuple { - private T v1; private V v2; @@ -58,4 +57,12 @@ public class Tuple { result = 31 * result + (v2 != null ? v2.hashCode() : 0); return result; } + + @Override + public String toString() { + return "Tuple{" + + "v1=" + v1 + + ", v2=" + v2 + + '}'; + } } diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/VersionUtil.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/VersionUtil.java index c1bdd9b4..5eeb0a9b 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/VersionUtil.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/VersionUtil.java @@ -3,29 +3,25 @@ package com.xiaojukeji.know.streaming.km.common.utils; import com.xiaojukeji.know.streaming.km.common.enums.version.VersionEnum; import org.apache.commons.lang.StringUtils; + public class VersionUtil { + /** + * apache的kafka相关的版本信息 + */ + private static final long BASE_VAL = 10000L; + private static final long APACHE_STEP_VAL = 100L; + public static final long APACHE_MAX_VAL = 100000000L; private static final int MIN_VERSION_SECTIONS_3 = 3; private static final int MIN_VERSION_SECTIONS_4 = 4; private static final String VERSION_FORMAT_3 = "%d.%d.%d"; private static final String VERSION_FORMAT_4 = "%d.%d.%d.%d"; - public static boolean isValid(String version){ - if(StringUtils.isBlank(version)){return false;} - - String[] vers = version.split("\\."); - if(null == vers){return false;} - - if(vers.length < MIN_VERSION_SECTIONS_3){return false;} - - for(String ver : vers){ - if(!ver.chars().allMatch(Character::isDigit)){ - return false; - } - } - - return true; - } + /** + * XiaoJu的kafka相关的版本信息 + */ + private static final String XIAO_JU_VERSION_FEATURE = "-d-"; + private static final String XIAO_JU_VERSION_FORMAT_4 = "%d.%d.%d-d-%d"; /** @@ -34,20 +30,64 @@ public class VersionUtil { * @param version * @return */ - public static long normailze(String version){ - if (!isValid(version)) { + public static long normailze(String version) { + if(StringUtils.isBlank(version)) { return -1; } - String[] vers = version.split("\\."); - - if(MIN_VERSION_SECTIONS_3 == vers.length){ - return Long.parseLong(vers[0]) * 1000000 + Long.parseLong(vers[1]) * 10000 + Long.parseLong(vers[2]) * 100; - }else if(MIN_VERSION_SECTIONS_4 == vers.length){ - return Long.parseLong(vers[0]) * 1000000 + Long.parseLong(vers[1]) * 10000 + Long.parseLong(vers[2]) * 100 + Long.parseLong(vers[3]); + if (version.contains(XIAO_JU_VERSION_FEATURE)) { + // XiaoJu的kafka + return normalizeXiaoJuVersion(version); } - return -1; + // 检查是否合法 + String[] vers = version.split("\\."); + if(vers.length < MIN_VERSION_SECTIONS_3) { + return -1; + } + for(String ver : vers){ + if(!ver.chars().allMatch(Character::isDigit)){ + return -1; + } + } + + // 转为数字 + long val = -1; + if(MIN_VERSION_SECTIONS_3 == vers.length) { + val = Long.parseLong(vers[0]) * APACHE_STEP_VAL * APACHE_STEP_VAL * APACHE_STEP_VAL + Long.parseLong(vers[1]) * APACHE_STEP_VAL * APACHE_STEP_VAL + Long.parseLong(vers[2]) * APACHE_STEP_VAL; + } else if(MIN_VERSION_SECTIONS_4 == vers.length) { + val = Long.parseLong(vers[0]) * APACHE_STEP_VAL * APACHE_STEP_VAL * APACHE_STEP_VAL + Long.parseLong(vers[1]) * APACHE_STEP_VAL * APACHE_STEP_VAL + Long.parseLong(vers[2]) * APACHE_STEP_VAL + Long.parseLong(vers[3]); + } + + return val == -1? val: val * BASE_VAL; + } + + public static long normalizeXiaoJuVersion(String version) { + if(StringUtils.isBlank(version)) { + return -1; + } + + if (!version.contains(XIAO_JU_VERSION_FEATURE)) { + // 非XiaoJu的kafka + return normailze(version); + } + + String[] vers = version.split(XIAO_JU_VERSION_FEATURE); + if (vers.length < 2) { + return -1; + } + + long apacheVal = normailze(vers[0]); + if (apacheVal == -1) { + return apacheVal; + } + + Long xiaoJuVal = ConvertUtil.string2Long(vers[1]); + if (xiaoJuVal == null) { + return apacheVal; + } + + return apacheVal + xiaoJuVal; } /** @@ -55,15 +95,17 @@ public class VersionUtil { * @param version * @return */ - public static String dNormailze(long version){ - long version4 = version % 100; - long version3 = (version / 100) % 100; - long version2 = (version / 10000) % 100; - long version1 = (version / 1000000) % 100; + public static String dNormailze(long version) { + long version4 = (version / BASE_VAL) % APACHE_STEP_VAL; + long version3 = (version / BASE_VAL / APACHE_STEP_VAL) % APACHE_STEP_VAL; + long version2 = (version / BASE_VAL / APACHE_STEP_VAL / APACHE_STEP_VAL) % APACHE_STEP_VAL; + long version1 = (version / BASE_VAL / APACHE_STEP_VAL / APACHE_STEP_VAL / APACHE_STEP_VAL) % APACHE_STEP_VAL; - if(0 == version4){ + if (version % BASE_VAL != 0) { + return String.format(XIAO_JU_VERSION_FORMAT_4, version1, version2, version3, version % BASE_VAL); + } else if (0 == version4) { return String.format(VERSION_FORMAT_3, version1, version2, version3); - }else { + } else { return String.format(VERSION_FORMAT_4, version1, version2, version3, version4); } } @@ -71,18 +113,24 @@ public class VersionUtil { public static void main(String[] args){ long n1 = VersionUtil.normailze(VersionEnum.V_0_10_0_0.getVersion()); String v1 = VersionUtil.dNormailze(n1); - System.out.println(VersionEnum.V_0_10_0_0.getVersion() + ":" + n1 + ":" + v1); + System.out.println(VersionEnum.V_0_10_0_0.getVersion() + "\t:\t" + n1 + "\t:\t" + v1); long n2 = VersionUtil.normailze(VersionEnum.V_0_10_0_1.getVersion()); String v2 = VersionUtil.dNormailze(n2); - System.out.println(VersionEnum.V_0_10_0_1.getVersion() + ":" + n2 + ":" + v2); + System.out.println(VersionEnum.V_0_10_0_1.getVersion() + "\t:\t" + n2 + "\t:\t" + v2); long n3 = VersionUtil.normailze(VersionEnum.V_0_11_0_3.getVersion()); String v3 = VersionUtil.dNormailze(n3); - System.out.println(VersionEnum.V_0_11_0_3.getVersion() + ":" + n3 + ":" + v3); + System.out.println(VersionEnum.V_0_11_0_3.getVersion() + "\t:\t" + n3 + "\t:\t" + v3); long n4 = VersionUtil.normailze(VersionEnum.V_2_5_0.getVersion()); String v4 = VersionUtil.dNormailze(n4); - System.out.println(VersionEnum.V_2_5_0.getVersion() + ":" + n4 + ":" + v4); + System.out.println(VersionEnum.V_2_5_0.getVersion() + "\t:\t" + n4 + "\t:\t" + v4); + + long n5 = VersionUtil.normailze(VersionEnum.V_2_5_0_D_300.getVersion()); + String v5 = VersionUtil.dNormailze(n5); + System.out.println(VersionEnum.V_2_5_0_D_300.getVersion() + "\t:\t" + n4 + "\t:\t" + v5); + + System.out.println(Long.MAX_VALUE); } } diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/kafka/KSPartialKafkaAdminClient.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/kafka/KSPartialKafkaAdminClient.java new file mode 100644 index 00000000..f985fb01 --- /dev/null +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/kafka/KSPartialKafkaAdminClient.java @@ -0,0 +1,1539 @@ +package com.xiaojukeji.know.streaming.km.common.utils.kafka; + +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import com.xiaojukeji.know.streaming.km.common.annotations.KafkaSource; +import com.xiaojukeji.know.streaming.km.common.bean.entity.kafka.*; +import org.apache.kafka.clients.ApiVersions; +import org.apache.kafka.clients.ClientDnsLookup; +import org.apache.kafka.clients.ClientRequest; +import org.apache.kafka.clients.ClientResponse; +import org.apache.kafka.clients.ClientUtils; +import org.apache.kafka.clients.CommonClientConfigs; +import org.apache.kafka.clients.KafkaClient; +import org.apache.kafka.clients.NetworkClient; +import org.apache.kafka.clients.StaleMetadataException; +import org.apache.kafka.clients.admin.*; +import org.apache.kafka.clients.admin.internals.AdminMetadataManager; +import org.apache.kafka.clients.admin.internals.ConsumerGroupOperationContext; +import org.apache.kafka.clients.consumer.ConsumerPartitionAssignor.Assignment; +import org.apache.kafka.clients.consumer.internals.ConsumerProtocol; +import org.apache.kafka.common.*; +import org.apache.kafka.common.acl.AclOperation; +import org.apache.kafka.common.config.ConfigException; +import org.apache.kafka.common.errors.AuthenticationException; +import org.apache.kafka.common.errors.DisconnectException; +import org.apache.kafka.common.errors.InvalidGroupIdException; +import org.apache.kafka.common.errors.RetriableException; +import org.apache.kafka.common.errors.TimeoutException; +import org.apache.kafka.common.errors.UnsupportedVersionException; +import org.apache.kafka.common.internals.KafkaFutureImpl; +import org.apache.kafka.common.message.DescribeGroupsRequestData; +import org.apache.kafka.common.message.DescribeGroupsResponseData.DescribedGroup; +import org.apache.kafka.common.message.DescribeGroupsResponseData.DescribedGroupMember; +import org.apache.kafka.common.message.FindCoordinatorRequestData; +import org.apache.kafka.common.message.ListGroupsRequestData; +import org.apache.kafka.common.message.ListGroupsResponseData; +import org.apache.kafka.common.message.MetadataRequestData; +import org.apache.kafka.common.metrics.JmxReporter; +import org.apache.kafka.common.metrics.KafkaMetricsContext; +import org.apache.kafka.common.metrics.MetricConfig; +import org.apache.kafka.common.metrics.Metrics; +import org.apache.kafka.common.metrics.MetricsContext; +import org.apache.kafka.common.metrics.MetricsReporter; +import org.apache.kafka.common.metrics.Sensor; +import org.apache.kafka.common.network.ChannelBuilder; +import org.apache.kafka.common.network.Selector; +import org.apache.kafka.common.protocol.Errors; +import org.apache.kafka.common.requests.AbstractRequest; +import org.apache.kafka.common.requests.AbstractResponse; +import org.apache.kafka.common.requests.ApiError; +import org.apache.kafka.common.requests.DescribeGroupsRequest; +import org.apache.kafka.common.requests.DescribeGroupsResponse; +import org.apache.kafka.common.requests.FindCoordinatorRequest; +import org.apache.kafka.common.requests.FindCoordinatorRequest.CoordinatorType; +import org.apache.kafka.common.requests.FindCoordinatorResponse; +import org.apache.kafka.common.requests.ListGroupsRequest; +import org.apache.kafka.common.requests.ListGroupsResponse; +import org.apache.kafka.common.requests.MetadataRequest; +import org.apache.kafka.common.requests.MetadataResponse; +import org.apache.kafka.common.utils.AppInfoParser; +import org.apache.kafka.common.utils.KafkaThread; +import org.apache.kafka.common.utils.LogContext; +import org.apache.kafka.common.utils.Time; +import org.apache.kafka.common.utils.Utils; +import org.apache.kafka.connect.runtime.distributed.ConnectProtocol; +import org.slf4j.Logger; + +import java.net.InetSocketAddress; +import java.nio.ByteBuffer; +import java.time.Duration; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; +import java.util.function.Predicate; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +import static org.apache.kafka.common.utils.Utils.closeQuietly; + +/** + * The default implementation of {@link Admin}. An instance of this class is created by invoking one of the + * {@code create()} methods in {@code AdminClient}. Users should not refer to this class directly. + * + *

+ * This class is thread-safe. + *

+ * The API of this class is evolving, see {@link Admin} for details. + */ +@KafkaSource(modified = 1) +public class KSPartialKafkaAdminClient { + + /** + * The next integer to use to name a KafkaAdminClient which the user hasn't specified an explicit name for. + */ + private static final AtomicInteger ADMIN_CLIENT_ID_SEQUENCE = new AtomicInteger(1); + + /** + * The prefix to use for the JMX metrics for this class + */ + private static final String JMX_PREFIX = "ks-kafka.admin.client"; + + /** + * An invalid shutdown time which indicates that a shutdown has not yet been performed. + */ + private static final long INVALID_SHUTDOWN_TIME = -1; + + /** + * Thread name prefix for admin client network thread + */ + static final String NETWORK_THREAD_PREFIX = "ks-kafka-admin-client-thread"; + + private final Logger log; + + /** + * The default timeout to use for an operation. + */ + private final int defaultApiTimeoutMs; + + /** + * The timeout to use for a single request. + */ + private final int requestTimeoutMs; + + /** + * The name of this AdminClient instance. + */ + private final String clientId; + + /** + * Provides the time. + */ + private final Time time; + + /** + * The cluster metadata manager used by the KafkaClient. + */ + private final AdminMetadataManager metadataManager; + + /** + * The metrics for this KafkaAdminClient. + */ + private final Metrics metrics; + + /** + * The network client to use. + */ + private final KafkaClient client; + + /** + * The runnable used in the service thread for this admin client. + */ + private final AdminClientRunnable runnable; + + /** + * The network service thread for this admin client. + */ + private final Thread thread; + + /** + * During a close operation, this is the time at which we will time out all pending operations + * and force the RPC thread to exit. If the admin client is not closing, this will be 0. + */ + private final AtomicLong hardShutdownTimeMs = new AtomicLong(INVALID_SHUTDOWN_TIME); + + /** + * A factory which creates TimeoutProcessors for the RPC thread. + */ + private final TimeoutProcessorFactory timeoutProcessorFactory; + + private final int maxRetries; + + private final long retryBackoffMs; + + /** + * Get or create a list value from a map. + * + * @param map The map to get or create the element from. + * @param key The key. + * @param The key type. + * @param The value type. + * @return The list value. + */ + static List getOrCreateListValue(Map> map, K key) { + return map.computeIfAbsent(key, k -> new LinkedList<>()); + } + + /** + * Get the current time remaining before a deadline as an integer. + * + * @param now The current time in milliseconds. + * @param deadlineMs The deadline time in milliseconds. + * @return The time delta in milliseconds. + */ + static int calcTimeoutMsRemainingAsInt(long now, long deadlineMs) { + long deltaMs = deadlineMs - now; + if (deltaMs > Integer.MAX_VALUE) + deltaMs = Integer.MAX_VALUE; + else if (deltaMs < Integer.MIN_VALUE) + deltaMs = Integer.MIN_VALUE; + return (int) deltaMs; + } + + /** + * Generate the client id based on the configuration. + * + * @param config The configuration + * + * @return The client id + */ + static String generateClientId(AdminClientConfig config) { + String clientId = config.getString(AdminClientConfig.CLIENT_ID_CONFIG); + if (!clientId.isEmpty()) + return clientId; + return "adminclient-" + ADMIN_CLIENT_ID_SEQUENCE.getAndIncrement(); + } + + /** + * Get the deadline for a particular call. + * + * @param now The current time in milliseconds. + * @param optionTimeoutMs The timeout option given by the user. + * + * @return The deadline in milliseconds. + */ + private long calcDeadlineMs(long now, Integer optionTimeoutMs) { + if (optionTimeoutMs != null) + return now + Math.max(0, optionTimeoutMs); + return now + defaultApiTimeoutMs; + } + + /** + * Pretty-print an exception. + * + * @param throwable The exception. + * + * @return A compact human-readable string. + */ + static String prettyPrintException(Throwable throwable) { + if (throwable == null) + return "Null exception."; + if (throwable.getMessage() != null) { + return throwable.getClass().getSimpleName() + ": " + throwable.getMessage(); + } + return throwable.getClass().getSimpleName(); + } + + public static KSPartialKafkaAdminClient create(Properties props) { + return KSPartialKafkaAdminClient.createInternal(new AdminClientConfig(props), null); + } + + static KSPartialKafkaAdminClient createInternal(AdminClientConfig config, TimeoutProcessorFactory timeoutProcessorFactory) { + Metrics metrics = null; + NetworkClient networkClient = null; + Time time = Time.SYSTEM; + String clientId = generateClientId(config); + ChannelBuilder channelBuilder = null; + Selector selector = null; + ApiVersions apiVersions = new ApiVersions(); + LogContext logContext = createLogContext(clientId); + + try { + // Since we only request node information, it's safe to pass true for allowAutoTopicCreation (and it + // simplifies communication with older brokers) + AdminMetadataManager metadataManager = new AdminMetadataManager(logContext, + config.getLong(AdminClientConfig.RETRY_BACKOFF_MS_CONFIG), + config.getLong(AdminClientConfig.METADATA_MAX_AGE_CONFIG)); + List addresses = ClientUtils.parseAndValidateAddresses( + config.getList(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG), + config.getString(AdminClientConfig.CLIENT_DNS_LOOKUP_CONFIG)); + metadataManager.update(Cluster.bootstrap(addresses), time.milliseconds()); + List reporters = config.getConfiguredInstances(AdminClientConfig.METRIC_REPORTER_CLASSES_CONFIG, + MetricsReporter.class, + Collections.singletonMap(AdminClientConfig.CLIENT_ID_CONFIG, clientId)); + Map metricTags = Collections.singletonMap("client-id", clientId); + MetricConfig metricConfig = new MetricConfig().samples(config.getInt(AdminClientConfig.METRICS_NUM_SAMPLES_CONFIG)) + .timeWindow(config.getLong(AdminClientConfig.METRICS_SAMPLE_WINDOW_MS_CONFIG), TimeUnit.MILLISECONDS) + .recordLevel(Sensor.RecordingLevel.forName(config.getString(AdminClientConfig.METRICS_RECORDING_LEVEL_CONFIG))) + .tags(metricTags); + JmxReporter jmxReporter = new JmxReporter(); + jmxReporter.configure(config.originals()); + reporters.add(jmxReporter); + MetricsContext metricsContext = new KafkaMetricsContext(JMX_PREFIX, + config.originalsWithPrefix(CommonClientConfigs.METRICS_CONTEXT_PREFIX)); + metrics = new Metrics(metricConfig, reporters, time, metricsContext); + String metricGrpPrefix = "admin-client"; + channelBuilder = ClientUtils.createChannelBuilder(config, time, logContext); + selector = new Selector(config.getLong(AdminClientConfig.CONNECTIONS_MAX_IDLE_MS_CONFIG), + metrics, time, metricGrpPrefix, channelBuilder, logContext); + networkClient = new NetworkClient( + selector, + metadataManager.updater(), + clientId, + 1, + config.getLong(AdminClientConfig.RECONNECT_BACKOFF_MS_CONFIG), + config.getLong(AdminClientConfig.RECONNECT_BACKOFF_MAX_MS_CONFIG), + config.getInt(AdminClientConfig.SEND_BUFFER_CONFIG), + config.getInt(AdminClientConfig.RECEIVE_BUFFER_CONFIG), + (int) TimeUnit.HOURS.toMillis(1), + config.getLong(AdminClientConfig.SOCKET_CONNECTION_SETUP_TIMEOUT_MS_CONFIG), + config.getLong(AdminClientConfig.SOCKET_CONNECTION_SETUP_TIMEOUT_MAX_MS_CONFIG), + ClientDnsLookup.forConfig(config.getString(AdminClientConfig.CLIENT_DNS_LOOKUP_CONFIG)), + time, + true, + apiVersions, + logContext); + return new KSPartialKafkaAdminClient(config, clientId, time, metadataManager, metrics, networkClient, + timeoutProcessorFactory, logContext); + } catch (Throwable exc) { + closeQuietly(metrics, "Metrics"); + closeQuietly(networkClient, "NetworkClient"); + closeQuietly(selector, "Selector"); + closeQuietly(channelBuilder, "ChannelBuilder"); + throw new KafkaException("Failed to create new KafkaAdminClient", exc); + } + } + + static LogContext createLogContext(String clientId) { + return new LogContext("[AdminClient clientId=" + clientId + "] "); + } + + private KSPartialKafkaAdminClient(AdminClientConfig config, + String clientId, + Time time, + AdminMetadataManager metadataManager, + Metrics metrics, + KafkaClient client, + TimeoutProcessorFactory timeoutProcessorFactory, + LogContext logContext) { + this.clientId = clientId; + this.log = logContext.logger(KafkaAdminClient.class); + this.requestTimeoutMs = config.getInt(AdminClientConfig.REQUEST_TIMEOUT_MS_CONFIG); + this.defaultApiTimeoutMs = configureDefaultApiTimeoutMs(config); + this.time = time; + this.metadataManager = metadataManager; + this.metrics = metrics; + this.client = client; + this.runnable = new AdminClientRunnable(); + String threadName = NETWORK_THREAD_PREFIX + " | " + clientId; + this.thread = new KafkaThread(threadName, runnable, true); + this.timeoutProcessorFactory = (timeoutProcessorFactory == null) ? + new TimeoutProcessorFactory() : timeoutProcessorFactory; + this.maxRetries = config.getInt(AdminClientConfig.RETRIES_CONFIG); + this.retryBackoffMs = config.getLong(AdminClientConfig.RETRY_BACKOFF_MS_CONFIG); + config.logUnused(); + AppInfoParser.registerAppInfo(JMX_PREFIX, clientId, metrics, time.milliseconds()); + log.debug("Kafka admin client initialized"); + thread.start(); + } + + /** + * If a default.api.timeout.ms has been explicitly specified, raise an error if it conflicts with request.timeout.ms. + * If no default.api.timeout.ms has been configured, then set its value as the max of the default and request.timeout.ms. Also we should probably log a warning. + * Otherwise, use the provided values for both configurations. + * + * @param config The configuration + */ + private int configureDefaultApiTimeoutMs(AdminClientConfig config) { + int requestTimeoutMs = config.getInt(AdminClientConfig.REQUEST_TIMEOUT_MS_CONFIG); + int defaultApiTimeoutMs = config.getInt(AdminClientConfig.DEFAULT_API_TIMEOUT_MS_CONFIG); + + if (defaultApiTimeoutMs < requestTimeoutMs) { + if (config.originals().containsKey(AdminClientConfig.DEFAULT_API_TIMEOUT_MS_CONFIG)) { + throw new ConfigException("The specified value of " + AdminClientConfig.DEFAULT_API_TIMEOUT_MS_CONFIG + + " must be no smaller than the value of " + AdminClientConfig.REQUEST_TIMEOUT_MS_CONFIG + "."); + } else { + log.warn("Overriding the default value for {} ({}) with the explicitly configured request timeout {}", + AdminClientConfig.DEFAULT_API_TIMEOUT_MS_CONFIG, this.defaultApiTimeoutMs, + requestTimeoutMs); + return requestTimeoutMs; + } + } + return defaultApiTimeoutMs; + } + + public void close(Duration timeout) { + long waitTimeMs = timeout.toMillis(); + if (waitTimeMs < 0) + throw new IllegalArgumentException("The timeout cannot be negative."); + waitTimeMs = Math.min(TimeUnit.DAYS.toMillis(365), waitTimeMs); // Limit the timeout to a year. + long now = time.milliseconds(); + long newHardShutdownTimeMs = now + waitTimeMs; + long prev = INVALID_SHUTDOWN_TIME; + while (true) { + if (hardShutdownTimeMs.compareAndSet(prev, newHardShutdownTimeMs)) { + if (prev == INVALID_SHUTDOWN_TIME) { + log.debug("Initiating close operation."); + } else { + log.debug("Moving hard shutdown time forward."); + } + client.wakeup(); // Wake the thread, if it is blocked inside poll(). + break; + } + prev = hardShutdownTimeMs.get(); + if (prev < newHardShutdownTimeMs) { + log.debug("Hard shutdown time is already earlier than requested."); + newHardShutdownTimeMs = prev; + break; + } + } + if (log.isDebugEnabled()) { + long deltaMs = Math.max(0, newHardShutdownTimeMs - time.milliseconds()); + log.debug("Waiting for the I/O thread to exit. Hard shutdown in {} ms.", deltaMs); + } + try { + // close() can be called by AdminClient thread when it invokes callback. That will + // cause deadlock, so check for that condition. + if (Thread.currentThread() != thread) { + // Wait for the thread to be joined. + thread.join(waitTimeMs); + } + log.debug("Kafka admin client closed."); + } catch (InterruptedException e) { + log.debug("Interrupted while joining I/O thread", e); + Thread.currentThread().interrupt(); + } + } + + /** + * An interface for providing a node for a call. + */ + private interface NodeProvider { + Node provide(); + } + + private class MetadataUpdateNodeIdProvider implements NodeProvider { + @Override + public Node provide() { + return client.leastLoadedNode(time.milliseconds()); + } + } + + private class ConstantNodeIdProvider implements NodeProvider { + private final int nodeId; + + ConstantNodeIdProvider(int nodeId) { + this.nodeId = nodeId; + } + + @Override + public Node provide() { + if (metadataManager.isReady() && + (metadataManager.nodeById(nodeId) != null)) { + return metadataManager.nodeById(nodeId); + } + // If we can't find the node with the given constant ID, we schedule a + // metadata update and hope it appears. This behavior is useful for avoiding + // flaky behavior in tests when the cluster is starting up and not all nodes + // have appeared. + metadataManager.requestUpdate(); + return null; + } + } + + /** + * Provides the least loaded node. + */ + private class LeastLoadedNodeProvider implements NodeProvider { + @Override + public Node provide() { + if (metadataManager.isReady()) { + // This may return null if all nodes are busy. + // In that case, we will postpone node assignment. + return client.leastLoadedNode(time.milliseconds()); + } + metadataManager.requestUpdate(); + return null; + } + } + + abstract class Call { + private final boolean internal; + private final String callName; + private final long deadlineMs; + private final NodeProvider nodeProvider; + private int tries = 0; + private boolean aborted = false; + private Node curNode = null; + private long nextAllowedTryMs = 0; + + Call(boolean internal, String callName, long deadlineMs, NodeProvider nodeProvider) { + this.internal = internal; + this.callName = callName; + this.deadlineMs = deadlineMs; + this.nodeProvider = nodeProvider; + } + + Call(String callName, long deadlineMs, NodeProvider nodeProvider) { + this(false, callName, deadlineMs, nodeProvider); + } + + protected Node curNode() { + return curNode; + } + + /** + * Handle a failure. + * + * Depending on what the exception is and how many times we have already tried, we may choose to + * fail the Call, or retry it. It is important to print the stack traces here in some cases, + * since they are not necessarily preserved in ApiVersionException objects. + * + * @param now The current time in milliseconds. + * @param throwable The failure exception. + */ + final void fail(long now, Throwable throwable) { + if (aborted) { + // If the call was aborted while in flight due to a timeout, deliver a + // TimeoutException. In this case, we do not get any more retries - the call has + // failed. We increment tries anyway in order to display an accurate log message. + tries++; + failWithTimeout(now, throwable); + return; + } + // If this is an UnsupportedVersionException that we can retry, do so. Note that a + // protocol downgrade will not count against the total number of retries we get for + // this RPC. That is why 'tries' is not incremented. + if ((throwable instanceof UnsupportedVersionException) && + handleUnsupportedVersionException((UnsupportedVersionException) throwable)) { + log.debug("{} attempting protocol downgrade and then retry.", this); + runnable.enqueue(this, now); + return; + } + tries++; + nextAllowedTryMs = now + retryBackoffMs; + + // If the call has timed out, fail. + if (calcTimeoutMsRemainingAsInt(now, deadlineMs) < 0) { + failWithTimeout(now, throwable); + return; + } + // If the exception is not retriable, fail. + if (!(throwable instanceof RetriableException)) { + if (log.isDebugEnabled()) { + log.debug("{} failed with non-retriable exception after {} attempt(s)", this, tries, + new Exception(prettyPrintException(throwable))); + } + handleFailure(throwable); + return; + } + // If we are out of retries, fail. + if (tries > maxRetries) { + failWithTimeout(now, throwable); + return; + } + if (log.isDebugEnabled()) { + log.debug("{} failed: {}. Beginning retry #{}", + this, prettyPrintException(throwable), tries); + } + runnable.enqueue(this, now); + } + + private void failWithTimeout(long now, Throwable cause) { + if (log.isDebugEnabled()) { + log.debug("{} timed out at {} after {} attempt(s)", this, now, tries, + new Exception(prettyPrintException(cause))); + } + handleFailure(new TimeoutException(this + " timed out at " + now + + " after " + tries + " attempt(s)", cause)); + } + + /** + * Create an AbstractRequest.Builder for this Call. + * + * @param timeoutMs The timeout in milliseconds. + * + * @return The AbstractRequest builder. + */ + @SuppressWarnings("rawtypes") + abstract AbstractRequest.Builder createRequest(int timeoutMs); + + /** + * Process the call response. + * + * @param abstractResponse The AbstractResponse. + * + */ + abstract void handleResponse(AbstractResponse abstractResponse); + + /** + * Handle a failure. This will only be called if the failure exception was not + * retriable, or if we hit a timeout. + * + * @param throwable The exception. + */ + abstract void handleFailure(Throwable throwable); + + /** + * Handle an UnsupportedVersionException. + * + * @param exception The exception. + * + * @return True if the exception can be handled; false otherwise. + */ + boolean handleUnsupportedVersionException(UnsupportedVersionException exception) { + return false; + } + + @Override + public String toString() { + return "Call(callName=" + callName + ", deadlineMs=" + deadlineMs + + ", tries=" + tries + ", nextAllowedTryMs=" + nextAllowedTryMs + ")"; + } + + public boolean isInternal() { + return internal; + } + } + + static class TimeoutProcessorFactory { + TimeoutProcessor create(long now) { + return new TimeoutProcessor(now); + } + } + + static class TimeoutProcessor { + /** + * The current time in milliseconds. + */ + private final long now; + + /** + * The number of milliseconds until the next timeout. + */ + private int nextTimeoutMs; + + /** + * Create a new timeout processor. + * + * @param now The current time in milliseconds since the epoch. + */ + TimeoutProcessor(long now) { + this.now = now; + this.nextTimeoutMs = Integer.MAX_VALUE; + } + + /** + * Check for calls which have timed out. + * Timed out calls will be removed and failed. + * The remaining milliseconds until the next timeout will be updated. + * + * @param calls The collection of calls. + * + * @return The number of calls which were timed out. + */ + int handleTimeouts(Collection calls, String msg) { + int numTimedOut = 0; + for (Iterator iter = calls.iterator(); iter.hasNext(); ) { + Call call = iter.next(); + int remainingMs = calcTimeoutMsRemainingAsInt(now, call.deadlineMs); + if (remainingMs < 0) { + call.fail(now, new TimeoutException(msg + " Call: " + call.callName)); + iter.remove(); + numTimedOut++; + } else { + nextTimeoutMs = Math.min(nextTimeoutMs, remainingMs); + } + } + return numTimedOut; + } + + /** + * Check whether a call should be timed out. + * The remaining milliseconds until the next timeout will be updated. + * + * @param call The call. + * + * @return True if the call should be timed out. + */ + boolean callHasExpired(Call call) { + int remainingMs = calcTimeoutMsRemainingAsInt(now, call.deadlineMs); + if (remainingMs < 0) + return true; + nextTimeoutMs = Math.min(nextTimeoutMs, remainingMs); + return false; + } + + int nextTimeoutMs() { + return nextTimeoutMs; + } + } + + private final class AdminClientRunnable implements Runnable { + /** + * Calls which have not yet been assigned to a node. + * Only accessed from this thread. + */ + private final ArrayList pendingCalls = new ArrayList<>(); + + /** + * Maps nodes to calls that we want to send. + * Only accessed from this thread. + */ + private final Map> callsToSend = new HashMap<>(); + + /** + * Maps node ID strings to calls that have been sent. + * Only accessed from this thread. + */ + private final Map> callsInFlight = new HashMap<>(); + + /** + * Maps correlation IDs to calls that have been sent. + * Only accessed from this thread. + */ + private final Map correlationIdToCalls = new HashMap<>(); + + /** + * Pending calls. Protected by the object monitor. + * This will be null only if the thread has shut down. + */ + private List newCalls = new LinkedList<>(); + + /** + * Time out the elements in the pendingCalls list which are expired. + * + * @param processor The timeout processor. + */ + private void timeoutPendingCalls(TimeoutProcessor processor) { + int numTimedOut = processor.handleTimeouts(pendingCalls, "Timed out waiting for a node assignment."); + if (numTimedOut > 0) + log.debug("Timed out {} pending calls.", numTimedOut); + } + + /** + * Time out calls which have been assigned to nodes. + * + * @param processor The timeout processor. + */ + private int timeoutCallsToSend(TimeoutProcessor processor) { + int numTimedOut = 0; + for (List callList : callsToSend.values()) { + numTimedOut += processor.handleTimeouts(callList, + "Timed out waiting to send the call."); + } + if (numTimedOut > 0) + log.debug("Timed out {} call(s) with assigned nodes.", numTimedOut); + return numTimedOut; + } + + /** + * Drain all the calls from newCalls into pendingCalls. + * + * This function holds the lock for the minimum amount of time, to avoid blocking + * users of AdminClient who will also take the lock to add new calls. + */ + private synchronized void drainNewCalls() { + if (!newCalls.isEmpty()) { + pendingCalls.addAll(newCalls); + newCalls.clear(); + } + } + + /** + * Choose nodes for the calls in the pendingCalls list. + * + * @param now The current time in milliseconds. + * @return The minimum time until a call is ready to be retried if any of the pending + * calls are backing off after a failure + */ + private long maybeDrainPendingCalls(long now) { + long pollTimeout = Long.MAX_VALUE; + log.trace("Trying to choose nodes for {} at {}", pendingCalls, now); + + Iterator pendingIter = pendingCalls.iterator(); + while (pendingIter.hasNext()) { + Call call = pendingIter.next(); + + // If the call is being retried, await the proper backoff before finding the node + if (now < call.nextAllowedTryMs) { + pollTimeout = Math.min(pollTimeout, call.nextAllowedTryMs - now); + } else if (maybeDrainPendingCall(call, now)) { + pendingIter.remove(); + } + } + return pollTimeout; + } + + /** + * Check whether a pending call can be assigned a node. Return true if the pending call was either + * transferred to the callsToSend collection or if the call was failed. Return false if it + * should remain pending. + */ + private boolean maybeDrainPendingCall(Call call, long now) { + try { + Node node = call.nodeProvider.provide(); + if (node != null) { + log.trace("Assigned {} to node {}", call, node); + call.curNode = node; + getOrCreateListValue(callsToSend, node).add(call); + return true; + } else { + log.trace("Unable to assign {} to a node.", call); + return false; + } + } catch (Throwable t) { + // Handle authentication errors while choosing nodes. + log.debug("Unable to choose node for {}", call, t); + call.fail(now, t); + return true; + } + } + + /** + * Send the calls which are ready. + * + * @param now The current time in milliseconds. + * @return The minimum timeout we need for poll(). + */ + private long sendEligibleCalls(long now) { + long pollTimeout = Long.MAX_VALUE; + for (Iterator>> iter = callsToSend.entrySet().iterator(); iter.hasNext(); ) { + Map.Entry> entry = iter.next(); + List calls = entry.getValue(); + if (calls.isEmpty()) { + iter.remove(); + continue; + } + Node node = entry.getKey(); + if (!client.ready(node, now)) { + long nodeTimeout = client.pollDelayMs(node, now); + pollTimeout = Math.min(pollTimeout, nodeTimeout); + log.trace("Client is not ready to send to {}. Must delay {} ms", node, nodeTimeout); + continue; + } + Call call = calls.remove(0); + int requestTimeoutMs = Math.min(KSPartialKafkaAdminClient.this.requestTimeoutMs, + calcTimeoutMsRemainingAsInt(now, call.deadlineMs)); + AbstractRequest.Builder requestBuilder; + try { + requestBuilder = call.createRequest(requestTimeoutMs); + } catch (Throwable throwable) { + call.fail(now, new KafkaException(String.format( + "Internal error sending %s to %s.", call.callName, node))); + continue; + } + ClientRequest clientRequest = client.newClientRequest(node.idString(), requestBuilder, now, + true, requestTimeoutMs, null); + log.debug("Sending {} to {}. correlationId={}", requestBuilder, node, clientRequest.correlationId()); + client.send(clientRequest, now); + getOrCreateListValue(callsInFlight, node.idString()).add(call); + correlationIdToCalls.put(clientRequest.correlationId(), call); + } + return pollTimeout; + } + + /** + * Time out expired calls that are in flight. + * + * Calls that are in flight may have been partially or completely sent over the wire. They may + * even be in the process of being processed by the remote server. At the moment, our only option + * to time them out is to close the entire connection. + * + * @param processor The timeout processor. + */ + private void timeoutCallsInFlight(TimeoutProcessor processor) { + int numTimedOut = 0; + for (Map.Entry> entry : callsInFlight.entrySet()) { + List contexts = entry.getValue(); + if (contexts.isEmpty()) + continue; + String nodeId = entry.getKey(); + // We assume that the first element in the list is the earliest. So it should be the + // only one we need to check the timeout for. + Call call = contexts.get(0); + if (processor.callHasExpired(call)) { + if (call.aborted) { + log.warn("Aborted call {} is still in callsInFlight.", call); + } else { + log.debug("Closing connection to {} to time out {}", nodeId, call); + call.aborted = true; + client.disconnect(nodeId); + numTimedOut++; + // We don't remove anything from the callsInFlight data structure. Because the connection + // has been closed, the calls should be returned by the next client#poll(), + // and handled at that point. + } + } + } + if (numTimedOut > 0) + log.debug("Timed out {} call(s) in flight.", numTimedOut); + } + + /** + * Handle responses from the server. + * + * @param now The current time in milliseconds. + * @param responses The latest responses from KafkaClient. + **/ + private void handleResponses(long now, List responses) { + for (ClientResponse response : responses) { + int correlationId = response.requestHeader().correlationId(); + + Call call = correlationIdToCalls.get(correlationId); + if (call == null) { + // If the server returns information about a correlation ID we didn't use yet, + // an internal server error has occurred. Close the connection and log an error message. + log.error("Internal server error on {}: server returned information about unknown " + + "correlation ID {}, requestHeader = {}", response.destination(), correlationId, + response.requestHeader()); + client.disconnect(response.destination()); + continue; + } + + // Stop tracking this call. + correlationIdToCalls.remove(correlationId); + List calls = callsInFlight.get(response.destination()); + if ((calls == null) || (!calls.remove(call))) { + log.error("Internal server error on {}: ignoring call {} in correlationIdToCall " + + "that did not exist in callsInFlight", response.destination(), call); + continue; + } + + // Handle the result of the call. This may involve retrying the call, if we got a + // retriable exception. + if (response.versionMismatch() != null) { + call.fail(now, response.versionMismatch()); + } else if (response.wasDisconnected()) { + AuthenticationException authException = client.authenticationException(call.curNode()); + if (authException != null) { + call.fail(now, authException); + } else { + call.fail(now, new DisconnectException(String.format( + "Cancelled %s request with correlation id %s due to node %s being disconnected", + call.callName, correlationId, response.destination()))); + } + } else { + try { + call.handleResponse(response.responseBody()); + if (log.isTraceEnabled()) + log.trace("{} got response {}", call, response.responseBody()); + } catch (Throwable t) { + if (log.isTraceEnabled()) + log.trace("{} handleResponse failed with {}", call, prettyPrintException(t)); + call.fail(now, t); + } + } + } + } + + /** + * Unassign calls that have not yet been sent based on some predicate. For example, this + * is used to reassign the calls that have been assigned to a disconnected node. + * + * @param shouldUnassign Condition for reassignment. If the predicate is true, then the calls will + * be put back in the pendingCalls collection and they will be reassigned + */ + private void unassignUnsentCalls(Predicate shouldUnassign) { + for (Iterator>> iter = callsToSend.entrySet().iterator(); iter.hasNext(); ) { + Map.Entry> entry = iter.next(); + Node node = entry.getKey(); + List awaitingCalls = entry.getValue(); + + if (awaitingCalls.isEmpty()) { + iter.remove(); + } else if (shouldUnassign.test(node)) { + pendingCalls.addAll(awaitingCalls); + iter.remove(); + } + } + } + + private boolean hasActiveExternalCalls(Collection calls) { + for (Call call : calls) { + if (!call.isInternal()) { + return true; + } + } + return false; + } + + /** + * Return true if there are currently active external calls. + */ + private boolean hasActiveExternalCalls() { + if (hasActiveExternalCalls(pendingCalls)) { + return true; + } + for (List callList : callsToSend.values()) { + if (hasActiveExternalCalls(callList)) { + return true; + } + } + return hasActiveExternalCalls(correlationIdToCalls.values()); + } + + private boolean threadShouldExit(long now, long curHardShutdownTimeMs) { + if (!hasActiveExternalCalls()) { + log.trace("All work has been completed, and the I/O thread is now exiting."); + return true; + } + if (now >= curHardShutdownTimeMs) { + log.info("Forcing a hard I/O thread shutdown. Requests in progress will be aborted."); + return true; + } + log.debug("Hard shutdown in {} ms.", curHardShutdownTimeMs - now); + return false; + } + + @Override + public void run() { + log.trace("Thread starting"); + try { + processRequests(); + } finally { + AppInfoParser.unregisterAppInfo(JMX_PREFIX, clientId, metrics); + + int numTimedOut = 0; + TimeoutProcessor timeoutProcessor = new TimeoutProcessor(Long.MAX_VALUE); + synchronized (this) { + numTimedOut += timeoutProcessor.handleTimeouts(newCalls, "The AdminClient thread has exited."); + newCalls = null; + } + numTimedOut += timeoutProcessor.handleTimeouts(pendingCalls, "The AdminClient thread has exited."); + numTimedOut += timeoutCallsToSend(timeoutProcessor); + numTimedOut += timeoutProcessor.handleTimeouts(correlationIdToCalls.values(), + "The AdminClient thread has exited."); + if (numTimedOut > 0) { + log.debug("Timed out {} remaining operation(s).", numTimedOut); + } + closeQuietly(client, "KafkaClient"); + closeQuietly(metrics, "Metrics"); + log.debug("Exiting AdminClientRunnable thread."); + } + } + + private void processRequests() { + long now = time.milliseconds(); + while (true) { + // Copy newCalls into pendingCalls. + drainNewCalls(); + + // Check if the AdminClient thread should shut down. + long curHardShutdownTimeMs = hardShutdownTimeMs.get(); + if ((curHardShutdownTimeMs != INVALID_SHUTDOWN_TIME) && threadShouldExit(now, curHardShutdownTimeMs)) + break; + + // Handle timeouts. + TimeoutProcessor timeoutProcessor = timeoutProcessorFactory.create(now); + timeoutPendingCalls(timeoutProcessor); + timeoutCallsToSend(timeoutProcessor); + timeoutCallsInFlight(timeoutProcessor); + + long pollTimeout = Math.min(1200000, timeoutProcessor.nextTimeoutMs()); + if (curHardShutdownTimeMs != INVALID_SHUTDOWN_TIME) { + pollTimeout = Math.min(pollTimeout, curHardShutdownTimeMs - now); + } + + // Choose nodes for our pending calls. + pollTimeout = Math.min(pollTimeout, maybeDrainPendingCalls(now)); + long metadataFetchDelayMs = metadataManager.metadataFetchDelayMs(now); + if (metadataFetchDelayMs == 0) { + metadataManager.transitionToUpdatePending(now); + Call metadataCall = makeMetadataCall(now); + // Create a new metadata fetch call and add it to the end of pendingCalls. + // Assign a node for just the new call (we handled the other pending nodes above). + + if (!maybeDrainPendingCall(metadataCall, now)) + pendingCalls.add(metadataCall); + } + pollTimeout = Math.min(pollTimeout, sendEligibleCalls(now)); + + if (metadataFetchDelayMs > 0) { + pollTimeout = Math.min(pollTimeout, metadataFetchDelayMs); + } + + // Ensure that we use a small poll timeout if there are pending calls which need to be sent + if (!pendingCalls.isEmpty()) + pollTimeout = Math.min(pollTimeout, retryBackoffMs); + + // Wait for network responses. + log.trace("Entering KafkaClient#poll(timeout={})", pollTimeout); + List responses = client.poll(pollTimeout, now); + log.trace("KafkaClient#poll retrieved {} response(s)", responses.size()); + + // unassign calls to disconnected nodes + unassignUnsentCalls(client::connectionFailed); + + // Update the current time and handle the latest responses. + now = time.milliseconds(); + handleResponses(now, responses); + } + } + + /** + * Queue a call for sending. + * + * If the AdminClient thread has exited, this will fail. Otherwise, it will succeed (even + * if the AdminClient is shutting down). This function should called when retrying an + * existing call. + * + * @param call The new call object. + * @param now The current time in milliseconds. + */ + void enqueue(Call call, long now) { + if (call.tries > maxRetries) { + log.debug("Max retries {} for {} reached", maxRetries, call); + call.fail(time.milliseconds(), new TimeoutException()); + return; + } + if (log.isDebugEnabled()) { + log.debug("Queueing {} with a timeout {} ms from now.", call, call.deadlineMs - now); + } + boolean accepted = false; + synchronized (this) { + if (newCalls != null) { + newCalls.add(call); + accepted = true; + } + } + if (accepted) { + client.wakeup(); // wake the thread if it is in poll() + } else { + log.debug("The AdminClient thread has exited. Timing out {}.", call); + call.fail(Long.MAX_VALUE, new TimeoutException("The AdminClient thread has exited.")); + } + } + + /** + * Initiate a new call. + * + * This will fail if the AdminClient is scheduled to shut down. + * + * @param call The new call object. + * @param now The current time in milliseconds. + */ + void call(Call call, long now) { + if (hardShutdownTimeMs.get() != INVALID_SHUTDOWN_TIME) { + log.debug("The AdminClient is not accepting new calls. Timing out {}.", call); + call.fail(Long.MAX_VALUE, new TimeoutException("The AdminClient thread is not accepting new calls.")); + } else { + enqueue(call, now); + } + } + + /** + * Create a new metadata call. + */ + private Call makeMetadataCall(long now) { + return new Call(true, "fetchMetadata", calcDeadlineMs(now, requestTimeoutMs), + new MetadataUpdateNodeIdProvider()) { + @Override + public MetadataRequest.Builder createRequest(int timeoutMs) { + // Since this only requests node information, it's safe to pass true + // for allowAutoTopicCreation (and it simplifies communication with + // older brokers) + return new MetadataRequest.Builder(new MetadataRequestData() + .setTopics(Collections.emptyList()) + .setAllowAutoTopicCreation(true)); + } + + @Override + public void handleResponse(AbstractResponse abstractResponse) { + MetadataResponse response = (MetadataResponse) abstractResponse; + long now = time.milliseconds(); + metadataManager.update(response.buildCluster(), now); + + // Unassign all unsent requests after a metadata refresh to allow for a new + // destination to be selected from the new metadata + unassignUnsentCalls(node -> true); + } + + @Override + public void handleFailure(Throwable e) { + metadataManager.updateFailed(e); + } + }; + } + } + + private static boolean groupIdIsUnrepresentable(String groupId) { + return groupId == null; + } + + private void rescheduleFindCoordinatorTask(ConsumerGroupOperationContext context, Supplier nextCall, Call failedCall) { + log.info("Node {} is no longer the Coordinator. Retrying with new coordinator.", + context.node().orElse(null)); + // Requeue the task so that we can try with new coordinator + context.setNode(null); + + Call call = nextCall.get(); + call.tries = failedCall.tries + 1; + call.nextAllowedTryMs = calculateNextAllowedRetryMs(); + + Call findCoordinatorCall = getFindCoordinatorCall(context, nextCall); + runnable.call(findCoordinatorCall, time.milliseconds()); + } + + private static Map> createFutures(Collection groupIds) { + return new HashSet<>(groupIds).stream().collect( + Collectors.toMap(groupId -> groupId, + groupId -> { + if (groupIdIsUnrepresentable(groupId)) { + KafkaFutureImpl future = new KafkaFutureImpl<>(); + future.completeExceptionally(new InvalidGroupIdException("The given group id '" + + groupId + "' cannot be represented in a request.")); + return future; + } else { + return new KafkaFutureImpl<>(); + } + } + )); + } + + public KSDescribeGroupsResult describeConsumerGroups(final Collection groupIds, + final DescribeConsumerGroupsOptions options) { + + final Map> futures = createFutures(groupIds); + + // TODO: KAFKA-6788, we should consider grouping the request per coordinator and send one request with a list of + // all consumer groups this coordinator host + for (final Map.Entry> entry : futures.entrySet()) { + // skip sending request for those futures that already failed. + if (entry.getValue().isCompletedExceptionally()) + continue; + + final String groupId = entry.getKey(); + + final long startFindCoordinatorMs = time.milliseconds(); + final long deadline = calcDeadlineMs(startFindCoordinatorMs, options.timeoutMs()); + ConsumerGroupOperationContext context = + new ConsumerGroupOperationContext<>(groupId, options, deadline, futures.get(groupId)); + Call findCoordinatorCall = getFindCoordinatorCall(context, + () -> getDescribeConsumerGroupsCall(context)); + runnable.call(findCoordinatorCall, startFindCoordinatorMs); + } + + return new KSDescribeGroupsResult(new HashMap<>(futures)); + } + + /** + * Returns a {@code Call} object to fetch the coordinator for a consumer group id. Takes another Call + * parameter to schedule action that need to be taken using the coordinator. The param is a Supplier + * so that it can be lazily created, so that it can use the results of find coordinator call in its + * construction. + * + * @param The type of return value of the KafkaFuture, like ConsumerGroupDescription, Void etc. + * @param The type of configuration option, like DescribeConsumerGroupsOptions, ListConsumerGroupsOptions etc + */ + private > Call getFindCoordinatorCall(ConsumerGroupOperationContext context, + Supplier nextCall) { + return new Call("findCoordinator", context.deadline(), new LeastLoadedNodeProvider()) { + @Override + FindCoordinatorRequest.Builder createRequest(int timeoutMs) { + return new FindCoordinatorRequest.Builder( + new FindCoordinatorRequestData() + .setKeyType(CoordinatorType.GROUP.id()) + .setKey(context.groupId())); + } + + @Override + void handleResponse(AbstractResponse abstractResponse) { + final FindCoordinatorResponse response = (FindCoordinatorResponse) abstractResponse; + + if (handleGroupRequestError(response.error(), context.future())) + return; + + context.setNode(response.node()); + + runnable.call(nextCall.get(), time.milliseconds()); + } + + @Override + void handleFailure(Throwable throwable) { + context.future().completeExceptionally(throwable); + } + }; + } + + private Call getDescribeConsumerGroupsCall( + ConsumerGroupOperationContext context) { + return new Call("describeConsumerGroups", + context.deadline(), + new ConstantNodeIdProvider(context.node().get().id())) { + @Override + DescribeGroupsRequest.Builder createRequest(int timeoutMs) { + return new DescribeGroupsRequest.Builder( + new DescribeGroupsRequestData() + .setGroups(Collections.singletonList(context.groupId())) + .setIncludeAuthorizedOperations(context.options().includeAuthorizedOperations())); + } + + @Override + void handleResponse(AbstractResponse abstractResponse) { + final DescribeGroupsResponse response = (DescribeGroupsResponse) abstractResponse; + + List describedGroups = response.data().groups(); + if (describedGroups.isEmpty()) { + context.future().completeExceptionally( + new InvalidGroupIdException("No consumer group found for GroupId: " + context.groupId())); + return; + } + + if (describedGroups.size() > 1 || + !describedGroups.get(0).groupId().equals(context.groupId())) { + String ids = Arrays.toString(describedGroups.stream().map(DescribedGroup::groupId).toArray()); + context.future().completeExceptionally(new InvalidGroupIdException( + "DescribeConsumerGroup request for GroupId: " + context.groupId() + " returned " + ids)); + return; + } + + final DescribedGroup describedGroup = describedGroups.get(0); + + // If coordinator changed since we fetched it, retry + if (ConsumerGroupOperationContext.hasCoordinatorMoved(response)) { + Call call = getDescribeConsumerGroupsCall(context); + rescheduleFindCoordinatorTask(context, () -> call, this); + return; + } + + final Errors groupError = Errors.forCode(describedGroup.errorCode()); + if (handleGroupRequestError(groupError, context.future())) { + return; + } + + final String protocolType = describedGroup.protocolType(); + + final List memberDescriptions = new ArrayList<>(describedGroup.members().size()); + for (DescribedGroupMember groupMember : describedGroup.members()) { + KSMemberBaseAssignment memberBaseAssignment = null; + + if (protocolType.equals(ConsumerProtocol.PROTOCOL_TYPE) || protocolType.isEmpty()) { + if (groupMember.memberAssignment().length > 0) { + final Assignment assignment = ConsumerProtocol.deserializeAssignment(ByteBuffer.wrap(groupMember.memberAssignment())); + memberBaseAssignment = new KSMemberConsumerAssignment(new HashSet<>(assignment.partitions())); + } + } else { + ConnectProtocol.Assignment assignment = null; + if (groupMember.memberAssignment().length > 0) { + assignment = ConnectProtocol. + deserializeAssignment(ByteBuffer.wrap(groupMember.memberAssignment())); + } + + ConnectProtocol.WorkerState workerState = null; + if (groupMember.memberMetadata().length > 0) { + workerState = ConnectProtocol. + deserializeMetadata(ByteBuffer.wrap(groupMember.memberMetadata())); + } + + memberBaseAssignment = new KSMemberConnectAssignment(assignment, workerState); + } + + memberDescriptions.add(new KSMemberDescription( + groupMember.memberId(), + Optional.ofNullable(groupMember.groupInstanceId()), + groupMember.clientId(), + groupMember.clientHost(), + memberBaseAssignment + )); + } + + context.future().complete(new KSGroupDescription( + context.groupId(), + protocolType, + memberDescriptions, + describedGroup.protocolData(), + ConsumerGroupState.parse(describedGroup.groupState()), + context.node().get()) + ); + } + + @Override + void handleFailure(Throwable throwable) { + context.future().completeExceptionally(throwable); + } + }; + } + + + private Set validAclOperations(final int authorizedOperations) { + if (authorizedOperations == MetadataResponse.AUTHORIZED_OPERATIONS_OMITTED) { + return null; + } + return Utils.from32BitField(authorizedOperations) + .stream() + .map(AclOperation::fromCode) + .filter(operation -> operation != AclOperation.UNKNOWN + && operation != AclOperation.ALL + && operation != AclOperation.ANY) + .collect(Collectors.toSet()); + } + + private boolean handleGroupRequestError(Errors error, KafkaFutureImpl future) { + if (error == Errors.COORDINATOR_LOAD_IN_PROGRESS || error == Errors.COORDINATOR_NOT_AVAILABLE) { + throw error.exception(); + } else if (error != Errors.NONE) { + future.completeExceptionally(error.exception()); + return true; + } + return false; + } + + private final static class ListConsumerGroupsResults { + private final List errors; + private final HashMap listings; + private final HashSet remaining; + private final KafkaFutureImpl> future; + + ListConsumerGroupsResults(Collection leaders, + KafkaFutureImpl> future) { + this.errors = new ArrayList<>(); + this.listings = new HashMap<>(); + this.remaining = new HashSet<>(leaders); + this.future = future; + tryComplete(); + } + + synchronized void addError(Throwable throwable, Node node) { + ApiError error = ApiError.fromThrowable(throwable); + if (error.message() == null || error.message().isEmpty()) { + errors.add(error.error().exception("Error listing groups on " + node)); + } else { + errors.add(error.error().exception("Error listing groups on " + node + ": " + error.message())); + } + } + + synchronized void addListing(ConsumerGroupListing listing) { + listings.put(listing.groupId(), listing); + } + + synchronized void tryComplete(Node leader) { + remaining.remove(leader); + tryComplete(); + } + + private synchronized void tryComplete() { + if (remaining.isEmpty()) { + ArrayList results = new ArrayList<>(listings.values()); + results.addAll(errors); + future.complete(results); + } + } + } + + public KSListGroupsResult listConsumerGroups(ListConsumerGroupsOptions options) { + final KafkaFutureImpl> all = new KafkaFutureImpl<>(); + final long nowMetadata = time.milliseconds(); + final long deadline = calcDeadlineMs(nowMetadata, options.timeoutMs()); + runnable.call(new Call("findAllBrokers", deadline, new LeastLoadedNodeProvider()) { + @Override + MetadataRequest.Builder createRequest(int timeoutMs) { + return new MetadataRequest.Builder(new MetadataRequestData() + .setTopics(Collections.emptyList()) + .setAllowAutoTopicCreation(true)); + } + + @Override + void handleResponse(AbstractResponse abstractResponse) { + MetadataResponse metadataResponse = (MetadataResponse) abstractResponse; + Collection nodes = metadataResponse.brokers(); + if (nodes.isEmpty()) + throw new StaleMetadataException("Metadata fetch failed due to missing broker list"); + + HashSet allNodes = new HashSet<>(nodes); + final ListConsumerGroupsResults results = new ListConsumerGroupsResults(allNodes, all); + + for (final Node node : allNodes) { + final long nowList = time.milliseconds(); + runnable.call(new Call("listConsumerGroups", deadline, new ConstantNodeIdProvider(node.id())) { + @Override + ListGroupsRequest.Builder createRequest(int timeoutMs) { + List states = options.states() + .stream() + .map(s -> s.toString()) + .collect(Collectors.toList()); + return new ListGroupsRequest.Builder(new ListGroupsRequestData().setStatesFilter(states)); + } + + private void maybeAddConsumerGroup(ListGroupsResponseData.ListedGroup group) { + String protocolType = group.protocolType(); + + @KafkaSource(modified = 1, modifyDesc = "原先代码忽略了connect的消费组,这里修改为将其放开") + final String groupId = group.groupId(); + final Optional state = group.groupState().equals("") + ? Optional.empty() + : Optional.of(ConsumerGroupState.parse(group.groupState())); + final ConsumerGroupListing groupListing = new ConsumerGroupListing(groupId, protocolType.isEmpty(), state); + results.addListing(groupListing); + } + + @Override + void handleResponse(AbstractResponse abstractResponse) { + final ListGroupsResponse response = (ListGroupsResponse) abstractResponse; + synchronized (results) { + Errors error = Errors.forCode(response.data().errorCode()); + if (error == Errors.COORDINATOR_LOAD_IN_PROGRESS || error == Errors.COORDINATOR_NOT_AVAILABLE) { + throw error.exception(); + } else if (error != Errors.NONE) { + results.addError(error.exception(), node); + } else { + for (ListGroupsResponseData.ListedGroup group : response.data().groups()) { + maybeAddConsumerGroup(group); + } + } + results.tryComplete(node); + } + } + + @Override + void handleFailure(Throwable throwable) { + synchronized (results) { + results.addError(throwable, node); + results.tryComplete(node); + } + } + }, nowList); + } + } + + @Override + void handleFailure(Throwable throwable) { + KafkaException exception = new KafkaException("Failed to find brokers to send ListGroups", throwable); + all.complete(Collections.singletonList(exception)); + } + }, nowMetadata); + + return new KSListGroupsResult(all); + } + + + private long calculateNextAllowedRetryMs() { + return time.milliseconds() + retryBackoffMs; + } +} diff --git a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/zookeeper/FourLetterWordUtil.java b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/zookeeper/FourLetterWordUtil.java index a3ae31af..5c798b7c 100644 --- a/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/zookeeper/FourLetterWordUtil.java +++ b/km-common/src/main/java/com/xiaojukeji/know/streaming/km/common/utils/zookeeper/FourLetterWordUtil.java @@ -56,7 +56,7 @@ public class FourLetterWordUtil { return Result.buildSuc(dataParser.parseAndInitData(clusterPhyId, host, port, cmdData)); } catch (Exception e) { LOGGER.error( - "class=FourLetterWordUtil||method=executeFourLetterCmd||clusterPhyId={}||host={}||port={}||cmd={}||secure={}||timeout={}||errMsg=exception!", + "method=executeFourLetterCmd||clusterPhyId={}||host={}||port={}||cmd={}||secure={}||timeout={}||errMsg=exception!", clusterPhyId, host, port, dataParser.getCmd(), secure, timeout, e ); @@ -124,7 +124,7 @@ public class FourLetterWordUtil { outputStream.close(); } catch (IOException e) { LOGGER.error( - "class=FourLetterWordUtil||method=send4LetterWord||clusterPhyId={}||host={}||port={}||cmd={}||secure={}||timeout={}||errMsg=exception!", + "method=send4LetterWord||clusterPhyId={}||host={}||port={}||cmd={}||secure={}||timeout={}||errMsg=exception!", host, port, cmd, secure, timeout, e ); } @@ -135,7 +135,7 @@ public class FourLetterWordUtil { bufferedReader.close(); } catch (IOException e) { LOGGER.error( - "class=FourLetterWordUtil||method=send4LetterWord||host={}||port={}||cmd={}||secure={}||timeout={}||errMsg=exception!", + "method=send4LetterWord||host={}||port={}||cmd={}||secure={}||timeout={}||errMsg=exception!", host, port, cmd, secure, timeout, e ); } @@ -146,7 +146,7 @@ public class FourLetterWordUtil { socket.close(); } catch (IOException e) { LOGGER.error( - "class=FourLetterWordUtil||method=send4LetterWord||host={}||port={}||cmd={}||secure={}||timeout={}||errMsg=exception!", + "method=send4LetterWord||host={}||port={}||cmd={}||secure={}||timeout={}||errMsg=exception!", host, port, cmd, secure, timeout, e ); } diff --git a/km-console/.eslintrc.js b/km-console/.eslintrc.js index 1e900306..94649d20 100644 --- a/km-console/.eslintrc.js +++ b/km-console/.eslintrc.js @@ -30,5 +30,6 @@ module.exports = { 'prettier/prettier': 2, // 这项配置 对于不符合prettier规范的写法,eslint会提示报错 'no-console': 1, 'react/display-name': 0, + '@typescript-eslint/explicit-module-boundary-types': 'off', }, }; diff --git a/km-console/package-lock.json b/km-console/package-lock.json index cb07da96..0bf42709 100644 --- a/km-console/package-lock.json +++ b/km-console/package-lock.json @@ -13,13 +13,14 @@ } }, "@babel/generator": { - "version": "7.19.0", - "resolved": "https://registry.npmmirror.com/@babel/generator/-/generator-7.19.0.tgz", - "integrity": "sha512-S1ahxf1gZ2dpoiFgA+ohK9DIpz50bJ0CWs7Zlzb54Z4sG8qmdIrGrVqmy1sAtTVRb+9CU6U8VqT9L0Zj7hxHVg==", + "version": "7.21.1", + "resolved": "https://registry.npmmirror.com/@babel/generator/-/generator-7.21.1.tgz", + "integrity": "sha512-1lT45bAYlQhFn/BHivJs43AiW2rg3/UbLyShGfF3C0KmHvO5fSghWd5kBJy30kpRRucGzXStvnnCFniCR2kXAA==", "dev": true, "requires": { - "@babel/types": "^7.19.0", + "@babel/types": "^7.21.0", "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" } }, @@ -30,13 +31,13 @@ "dev": true }, "@babel/helper-function-name": { - "version": "7.19.0", - "resolved": "https://registry.npmmirror.com/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", - "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz", + "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==", "dev": true, "requires": { - "@babel/template": "^7.18.10", - "@babel/types": "^7.19.0" + "@babel/template": "^7.20.7", + "@babel/types": "^7.21.0" } }, "@babel/helper-hoist-variables": { @@ -58,9 +59,9 @@ } }, "@babel/helper-string-parser": { - "version": "7.18.10", - "resolved": "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz", - "integrity": "sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==", + "version": "7.19.4", + "resolved": "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", "dev": true }, "@babel/helper-validator-identifier": { @@ -133,67 +134,67 @@ } }, "@babel/parser": { - "version": "7.19.1", - "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.19.1.tgz", - "integrity": "sha512-h7RCSorm1DdTVGJf3P2Mhj3kdnkmF/EiysUkzS2TdgAYqyjFdMQJbVuXOBej2SBJaXan/lIVtT6KkGbyyq753A==", + "version": "7.21.1", + "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.21.1.tgz", + "integrity": "sha512-JzhBFpkuhBNYUY7qs+wTzNmyCWUHEaAFpQQD2YfU1rPL38/L43Wvid0fFkiOCnHvsGncRZgEPyGnltABLcVDTg==", "dev": true }, "@babel/runtime": { - "version": "7.19.0", - "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.19.0.tgz", - "integrity": "sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.21.0.tgz", + "integrity": "sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==", "dev": true, "requires": { - "regenerator-runtime": "^0.13.4" + "regenerator-runtime": "^0.13.11" } }, "@babel/runtime-corejs3": { - "version": "7.19.1", - "resolved": "https://registry.npmmirror.com/@babel/runtime-corejs3/-/runtime-corejs3-7.19.1.tgz", - "integrity": "sha512-j2vJGnkopRzH+ykJ8h68wrHnEUmtK//E723jjixiAl/PPf6FhqY/vYRcMVlNydRKQjQsTsYEjpx+DZMIvnGk/g==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/runtime-corejs3/-/runtime-corejs3-7.21.0.tgz", + "integrity": "sha512-TDD4UJzos3JJtM+tHX+w2Uc+KWj7GV+VKKFdMVd2Rx8sdA19hcc3P3AHFYd5LVOw+pYuSd5lICC3gm52B6Rwxw==", "dev": true, "requires": { "core-js-pure": "^3.25.1", - "regenerator-runtime": "^0.13.4" + "regenerator-runtime": "^0.13.11" } }, "@babel/template": { - "version": "7.18.10", - "resolved": "https://registry.npmmirror.com/@babel/template/-/template-7.18.10.tgz", - "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", + "version": "7.20.7", + "resolved": "https://registry.npmmirror.com/@babel/template/-/template-7.20.7.tgz", + "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", "dev": true, "requires": { "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.18.10", - "@babel/types": "^7.18.10" + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" } }, "@babel/traverse": { - "version": "7.19.1", - "resolved": "https://registry.npmmirror.com/@babel/traverse/-/traverse-7.19.1.tgz", - "integrity": "sha512-0j/ZfZMxKukDaag2PtOPDbwuELqIar6lLskVPPJDjXMXjfLb1Obo/1yjxIGqqAJrmfaTIY3z2wFLAQ7qSkLsuA==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/traverse/-/traverse-7.21.0.tgz", + "integrity": "sha512-Xdt2P1H4LKTO8ApPfnO1KmzYMFpp7D/EinoXzLYN/cHcBNrVCAkAtGUcXnHXrl/VGktureU6fkQrHSBE2URfoA==", "dev": true, "requires": { "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.19.0", + "@babel/generator": "^7.21.0", "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", + "@babel/helper-function-name": "^7.21.0", "@babel/helper-hoist-variables": "^7.18.6", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.19.1", - "@babel/types": "^7.19.0", + "@babel/parser": "^7.21.0", + "@babel/types": "^7.21.0", "debug": "^4.1.0", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.19.0", - "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.19.0.tgz", - "integrity": "sha512-YuGopBq3ke25BVSiS6fgF49Ul9gH1x70Bcr6bqRLjWCkcX8Hre1/5+z+IiWOIerRMSSEfGZVB9z9kyq7wVs9YA==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.21.0.tgz", + "integrity": "sha512-uR7NWq2VNFnDi7EYqiRz2Jv/VQIu38tu64Zy8TX2nQFQ6etJ9V/Rr2msW8BS132mum2rL645qpDrLtAJtVpuow==", "dev": true, "requires": { - "@babel/helper-string-parser": "^7.18.10", - "@babel/helper-validator-identifier": "^7.18.6", + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", "to-fast-properties": "^2.0.0" } }, @@ -435,9 +436,9 @@ }, "dependencies": { "globals": { - "version": "13.17.0", - "resolved": "https://registry.npmmirror.com/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "version": "13.20.0", + "resolved": "https://registry.npmmirror.com/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -522,26 +523,26 @@ "dev": true }, "@jridgewell/trace-mapping": { - "version": "0.3.15", - "resolved": "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz", - "integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==", + "version": "0.3.17", + "resolved": "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", "dev": true, "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" } }, "@lerna/add": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/add/-/add-5.5.1.tgz", - "integrity": "sha512-Vi6Zm8bt1QAoDYl7YERTOgjEn2bwbZNBqYxNz0DlsxcqKHW2GkefEemZLXxmd9G8YgbsbC71W4sz/yFlkSSsxQ==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/add/-/add-5.5.0.tgz", + "integrity": "sha512-RdJ8yyE8BizzrYRjZuqeXtgkHBE/KzcS7tmBG+UKCQ5QFLnkdORzaVECNy2sfZl0vTtrxj4cv+kuwxIeg/4XVQ==", "dev": true, "requires": { - "@lerna/bootstrap": "5.5.1", - "@lerna/command": "5.5.1", - "@lerna/filter-options": "5.5.1", - "@lerna/npm-conf": "5.5.1", - "@lerna/validation-error": "5.5.1", + "@lerna/bootstrap": "5.5.0", + "@lerna/command": "5.5.0", + "@lerna/filter-options": "5.5.0", + "@lerna/npm-conf": "5.5.0", + "@lerna/validation-error": "5.5.0", "dedent": "^0.7.0", "npm-package-arg": "8.1.1", "p-map": "^4.0.0", @@ -550,23 +551,23 @@ } }, "@lerna/bootstrap": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/bootstrap/-/bootstrap-5.5.1.tgz", - "integrity": "sha512-BNfrwZD3peUiJll5ZBVgLRyURWSY9px6hJna1i7zTT1DNged/ehqd2hfMqWV+7iX6mO+CvcfH/v3zJaUwU1aOw==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/bootstrap/-/bootstrap-5.5.0.tgz", + "integrity": "sha512-GeXLSDi6gxj2O3t5T7qgFabBKoC5EQwiFyQ4ufqx1Wm/mWxqRI+enTBnbaBbmhQaVQ9wfPvMPDukJ5Q9PCTUcQ==", "dev": true, "requires": { - "@lerna/command": "5.5.1", - "@lerna/filter-options": "5.5.1", - "@lerna/has-npm-version": "5.5.1", - "@lerna/npm-install": "5.5.1", - "@lerna/package-graph": "5.5.1", - "@lerna/pulse-till-done": "5.5.1", - "@lerna/rimraf-dir": "5.5.1", - "@lerna/run-lifecycle": "5.5.1", - "@lerna/run-topologically": "5.5.1", - "@lerna/symlink-binary": "5.5.1", - "@lerna/symlink-dependencies": "5.5.1", - "@lerna/validation-error": "5.5.1", + "@lerna/command": "5.5.0", + "@lerna/filter-options": "5.5.0", + "@lerna/has-npm-version": "5.5.0", + "@lerna/npm-install": "5.5.0", + "@lerna/package-graph": "5.5.0", + "@lerna/pulse-till-done": "5.5.0", + "@lerna/rimraf-dir": "5.5.0", + "@lerna/run-lifecycle": "5.5.0", + "@lerna/run-topologically": "5.5.0", + "@lerna/symlink-binary": "5.5.0", + "@lerna/symlink-dependencies": "5.5.0", + "@lerna/validation-error": "5.5.0", "@npmcli/arborist": "5.3.0", "dedent": "^0.7.0", "get-port": "^5.1.1", @@ -580,32 +581,32 @@ } }, "@lerna/changed": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/changed/-/changed-5.5.1.tgz", - "integrity": "sha512-aDm+KQZhOdivNSs74lqC71BO7lVtKHu9oyisqhqCb5MdZn7yjO3Ef2Y0CYN4+dt355zW+xI87NzwSWYGQEd/5Q==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/changed/-/changed-5.5.0.tgz", + "integrity": "sha512-ZEnVHrPEpf2Iii/Z59g1lfKEwPA1V2an5L27MzNQjbWe6JQZqTU+8V6m+Vmbr4VdEH5jfRL5NVETGCLl7qN/pQ==", "dev": true, "requires": { - "@lerna/collect-updates": "5.5.1", - "@lerna/command": "5.5.1", - "@lerna/listable": "5.5.1", - "@lerna/output": "5.5.1" + "@lerna/collect-updates": "5.5.0", + "@lerna/command": "5.5.0", + "@lerna/listable": "5.5.0", + "@lerna/output": "5.5.0" } }, "@lerna/check-working-tree": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/check-working-tree/-/check-working-tree-5.5.1.tgz", - "integrity": "sha512-scfv1KDYQVy1US6SA8C4uj56HN021E2GXCL0bXzc6VKFewdZ9LreJTo0zSN6JwRitxc0c45lTAfTqDueVWANNQ==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/check-working-tree/-/check-working-tree-5.5.0.tgz", + "integrity": "sha512-U35yV8R+tv6zQgoDr0rnBt4wm4gyhDcE4tUEeB8m7JHVu7g45Fjv2jFLH1z5RM1PVaEbzKVebqfN5ccB0EBuyg==", "dev": true, "requires": { - "@lerna/collect-uncommitted": "5.5.1", - "@lerna/describe-ref": "5.5.1", - "@lerna/validation-error": "5.5.1" + "@lerna/collect-uncommitted": "5.5.0", + "@lerna/describe-ref": "5.5.0", + "@lerna/validation-error": "5.5.0" } }, "@lerna/child-process": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/child-process/-/child-process-5.5.1.tgz", - "integrity": "sha512-rGVK5DIJa2EljPb3RW4ZAvwgiyX6xL3hZzRGRkSQWV7866W/Xy0aCgWhfSmUvxB7iiH1NBw5ANlCuBLk31T0QQ==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/child-process/-/child-process-5.5.0.tgz", + "integrity": "sha512-er7bsj2W/H8JWAIB+CkgCLk9IlMkyVzywbOZcMC+xic2fp7rmM/BdtAE4nTjkKwfaRYF/bwjHyZowZUR3s8cEg==", "dev": true, "requires": { "chalk": "^4.1.0", @@ -614,33 +615,44 @@ } }, "@lerna/clean": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/clean/-/clean-5.5.1.tgz", - "integrity": "sha512-Be0nQpoppH43oRhNoevNms6unRvZFwFnuz3sGABii+hyFYqLIpZiAz98ur0LtV8OVq1bUYLXp8bHf+XylgvXQg==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/clean/-/clean-5.5.0.tgz", + "integrity": "sha512-TRW4Gkv6QpWSy0tm72NrxvgmTAC+W0LqhLPlFM5k5feFS75/HGOycpf97M4JSUueyBCuVjsPfzqp/e6MB3Ntng==", "dev": true, "requires": { - "@lerna/command": "5.5.1", - "@lerna/filter-options": "5.5.1", - "@lerna/prompt": "5.5.1", - "@lerna/pulse-till-done": "5.5.1", - "@lerna/rimraf-dir": "5.5.1", + "@lerna/command": "5.5.0", + "@lerna/filter-options": "5.5.0", + "@lerna/prompt": "5.5.0", + "@lerna/pulse-till-done": "5.5.0", + "@lerna/rimraf-dir": "5.5.0", "p-map": "^4.0.0", "p-map-series": "^2.1.0", "p-waterfall": "^2.1.1" } }, "@lerna/cli": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/cli/-/cli-5.5.1.tgz", - "integrity": "sha512-57dEQoiJnMhLIgS5zAEhPmL70LLrZHUqfxoXYBCg+yqlmsGqZ7t0Re5XtBUbFk6hsUm81sblf9A4YI2fssGVrA==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/cli/-/cli-5.5.0.tgz", + "integrity": "sha512-7TtnO2xfnfrpWGIui6ANrH4/AVHmSfjaExSoZKNhh2dKSSEOETEUfFIIzfEAirAVR7EOXAJwDdFbbpB4lQtyUg==", "dev": true, "requires": { - "@lerna/global-options": "5.5.1", + "@lerna/global-options": "5.5.0", "dedent": "^0.7.0", "npmlog": "^6.0.2", "yargs": "^16.2.0" }, "dependencies": { + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmmirror.com/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, "yargs": { "version": "16.2.0", "resolved": "https://registry.npmmirror.com/yargs/-/yargs-16.2.0.tgz", @@ -659,40 +671,40 @@ } }, "@lerna/collect-uncommitted": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/collect-uncommitted/-/collect-uncommitted-5.5.1.tgz", - "integrity": "sha512-BPGpov4aYRugkY5aieolHEqJRV/6IQ9y6Xy+Fv/892jNhe2dFwi6+u2JbdmO+9JOkz/ZeDDZ85qEbnaiuVQDWg==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/collect-uncommitted/-/collect-uncommitted-5.5.0.tgz", + "integrity": "sha512-oVGXS0fC8q2d1lG695eCd8dkr0fhmUx4bWA1IshVd/u0Puk7f8+m71POcLV3h1gR/2Fqs7vb7G/sPyuzGtwn8w==", "dev": true, "requires": { - "@lerna/child-process": "5.5.1", + "@lerna/child-process": "5.5.0", "chalk": "^4.1.0", "npmlog": "^6.0.2" } }, "@lerna/collect-updates": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/collect-updates/-/collect-updates-5.5.1.tgz", - "integrity": "sha512-Dco+0KwmbnKv1Uv/4jWmFObZKEVTcY7YpN863LsXjieOyD5hz1B5z/2fVk8g6QP5lUsVBG0WUnSKtdapUO5yBw==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/collect-updates/-/collect-updates-5.5.0.tgz", + "integrity": "sha512-6kBMi6K6PHIBvZKlfp/0PvRgmzvvfx+eZpmLjF+0yjcfwBn+QDkq7H+QohBiCzt2vxHVHsM6zutNhl2jNTmChg==", "dev": true, "requires": { - "@lerna/child-process": "5.5.1", - "@lerna/describe-ref": "5.5.1", + "@lerna/child-process": "5.5.0", + "@lerna/describe-ref": "5.5.0", "minimatch": "^3.0.4", "npmlog": "^6.0.2", "slash": "^3.0.0" } }, "@lerna/command": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/command/-/command-5.5.1.tgz", - "integrity": "sha512-HHnGQpUh7kiHja/mB5rlnHnL3B3B12y4RBpJTxX22IkdcwsiO8g/n2FWh9MPQvuVcR2FRh4PWXhmfVnboZCAaw==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/command/-/command-5.5.0.tgz", + "integrity": "sha512-ut055kFWc1OJFdI9Cj1kDxtJ4ejvAsfRgUoVxWT1Fw4Me/OzQRHYmUupW0FK8Kc+7gcz4mGKzUVWmRmDBvn+Fw==", "dev": true, "requires": { - "@lerna/child-process": "5.5.1", - "@lerna/package-graph": "5.5.1", - "@lerna/project": "5.5.1", - "@lerna/validation-error": "5.5.1", - "@lerna/write-log-file": "5.5.1", + "@lerna/child-process": "5.5.0", + "@lerna/package-graph": "5.5.0", + "@lerna/project": "5.5.0", + "@lerna/validation-error": "5.5.0", + "@lerna/write-log-file": "5.5.0", "clone-deep": "^4.0.1", "dedent": "^0.7.0", "execa": "^5.0.0", @@ -701,12 +713,12 @@ } }, "@lerna/conventional-commits": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/conventional-commits/-/conventional-commits-5.5.1.tgz", - "integrity": "sha512-oYTt1SbCNc/5N98ESFFDjWImU61qcYmQZBVxdzBDeZku/VRlaXw7Km5lSnVy7GrGkIPRxayunL4r1k32w5SZpA==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/conventional-commits/-/conventional-commits-5.5.0.tgz", + "integrity": "sha512-qPTRNCm3H4MvZAdQLzyYq7ifJyofMSeZmel232b5mglW3OSehxPQUxzr/u/0p8Nqs89uZxZRHyznLnhRNdXcJQ==", "dev": true, "requires": { - "@lerna/validation-error": "5.5.1", + "@lerna/validation-error": "5.5.0", "conventional-changelog-angular": "^5.0.12", "conventional-changelog-core": "^4.2.4", "conventional-recommended-bump": "^6.1.0", @@ -739,15 +751,15 @@ } }, "@lerna/create": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/create/-/create-5.5.1.tgz", - "integrity": "sha512-ZkN0rTTrIRIk9B+FzMXsjL8tK8wy4Orw7U3lVu8xe7LkxmK+lYxSOqcgfwWJjmA1yyoiNK+Xn++RlqXF7LW++Q==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/create/-/create-5.5.0.tgz", + "integrity": "sha512-B+ERbzgFMYspsaU9We65Wqf9Y7sGsEYVFPi3EKpCXxkvVr65YRFL6Mz/WAVggwYkR49umduXXVmjnCWcuT0Ydw==", "dev": true, "requires": { - "@lerna/child-process": "5.5.1", - "@lerna/command": "5.5.1", - "@lerna/npm-conf": "5.5.1", - "@lerna/validation-error": "5.5.1", + "@lerna/child-process": "5.5.0", + "@lerna/command": "5.5.0", + "@lerna/npm-conf": "5.5.0", + "@lerna/validation-error": "5.5.0", "dedent": "^0.7.0", "fs-extra": "^9.1.0", "globby": "^11.0.2", @@ -808,9 +820,9 @@ } }, "@lerna/create-symlink": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/create-symlink/-/create-symlink-5.5.1.tgz", - "integrity": "sha512-yOo1dXzoyeqhX4QCeswS0FjMSFyfNmHxtwE73+1k4uIYPWHWPHA/PW3y3hkOqh6QbBBg+y6+KCRiCOPaftZb6g==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/create-symlink/-/create-symlink-5.5.0.tgz", + "integrity": "sha512-vWGvRbTh3ji3J/8mVyLPa9Yst4MZzp9W2+8hyYHw8eAzCtHPuH3Z0AReIHpYRfoViUvxIl/rEEuD2D1sDh61BQ==", "dev": true, "requires": { "cmd-shim": "^5.0.0", @@ -833,78 +845,78 @@ } }, "@lerna/describe-ref": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/describe-ref/-/describe-ref-5.5.1.tgz", - "integrity": "sha512-pioaEFDKUcYsdgqz/wnjJ5pZyfrh7etJMYdxDDxijysn/96R28zTQMBrgGgjrBmkFyV9zmaxNaQXz1gx+IMohA==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/describe-ref/-/describe-ref-5.5.0.tgz", + "integrity": "sha512-gNt9deRWcDoIKCwKRHu/TEt2HcHhQxzVlP8GQHYp4NuWTG9c+gTQfyuXvbZd0K9jCijPUBNy/oMb6usXceJWeg==", "dev": true, "requires": { - "@lerna/child-process": "5.5.1", + "@lerna/child-process": "5.5.0", "npmlog": "^6.0.2" } }, "@lerna/diff": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/diff/-/diff-5.5.1.tgz", - "integrity": "sha512-mqKSafF5hGteVbRUPI41b8OZutolr6vqg2ObkKXFXpT6RvAX2NPpppHf0c0XORLWjc47p14Iv8xsQMCNwJ0tzQ==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/diff/-/diff-5.5.0.tgz", + "integrity": "sha512-2PIka/4kKDOsh5Ht+X2OuLNTWzRk+LcnN5bCin87w7vGw3esdvlT1fj1tKjoZ1/aC/O8tqtKXyeP9WE6YHWVpw==", "dev": true, "requires": { - "@lerna/child-process": "5.5.1", - "@lerna/command": "5.5.1", - "@lerna/validation-error": "5.5.1", + "@lerna/child-process": "5.5.0", + "@lerna/command": "5.5.0", + "@lerna/validation-error": "5.5.0", "npmlog": "^6.0.2" } }, "@lerna/exec": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/exec/-/exec-5.5.1.tgz", - "integrity": "sha512-eip4MlIYkbxibIoV0ANjKdf9CSAER87C2zGY+GwHZKUSOD0I3xfhbPTkJozHBE3aqez6dR0pebi6cpNWvzEdIg==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/exec/-/exec-5.5.0.tgz", + "integrity": "sha512-4asvrCYFGgnEbXtSiKJLDd6DShUl7FIRRCWx7JXJfa0B6sg00cB9Cg3JTp+F+cQWCOspRkzqRetqu57o6wRpXg==", "dev": true, "requires": { - "@lerna/child-process": "5.5.1", - "@lerna/command": "5.5.1", - "@lerna/filter-options": "5.5.1", - "@lerna/profiler": "5.5.1", - "@lerna/run-topologically": "5.5.1", - "@lerna/validation-error": "5.5.1", + "@lerna/child-process": "5.5.0", + "@lerna/command": "5.5.0", + "@lerna/filter-options": "5.5.0", + "@lerna/profiler": "5.5.0", + "@lerna/run-topologically": "5.5.0", + "@lerna/validation-error": "5.5.0", "p-map": "^4.0.0" } }, "@lerna/filter-options": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/filter-options/-/filter-options-5.5.1.tgz", - "integrity": "sha512-U4erQgGBawazN0eDLQzWf5xu1mTaucVguzUblBSOfQm+fUBsYG5WYJtn9AvVLrUCQMwAV3L2+/NWb1FOkqArMw==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/filter-options/-/filter-options-5.5.0.tgz", + "integrity": "sha512-Hwn4sOixZdWVe6SFZ7aPFjhMYoSHz0zbwy3t40KXuhjLqT8T5RLmGWW1u2Al6dQ5fuQyhWXGS4DWfobs7Th62A==", "dev": true, "requires": { - "@lerna/collect-updates": "5.5.1", - "@lerna/filter-packages": "5.5.1", + "@lerna/collect-updates": "5.5.0", + "@lerna/filter-packages": "5.5.0", "dedent": "^0.7.0", "npmlog": "^6.0.2" } }, "@lerna/filter-packages": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/filter-packages/-/filter-packages-5.5.1.tgz", - "integrity": "sha512-970kc2w6Bzr9FAL8DFisOonDocj7VDFdNnVVJpaTbNnbuMLnCT4vPXHKHQku2XEgxfr1lgyFA+srzxiiLQGWaQ==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/filter-packages/-/filter-packages-5.5.0.tgz", + "integrity": "sha512-Ad23aRPKgr/zt6jMWi8xKL+2z47GBQyxC4HhsDEMp62OGeGhGyK1sGW+S8OTEh17sIVpGG2GX9eCfnG8pvfxUQ==", "dev": true, "requires": { - "@lerna/validation-error": "5.5.1", + "@lerna/validation-error": "5.5.0", "multimatch": "^5.0.0", "npmlog": "^6.0.2" } }, "@lerna/get-npm-exec-opts": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/get-npm-exec-opts/-/get-npm-exec-opts-5.5.1.tgz", - "integrity": "sha512-z8HoeCHbKVoHRjsyEwEhFF37vubX52CQOI+7TcEhjMYDXRrfKYfGcLXFh++DGihRQ7qk7ir27VrJgweeu/rcNw==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/get-npm-exec-opts/-/get-npm-exec-opts-5.5.0.tgz", + "integrity": "sha512-WRt560FB6rsj4yVtR1wIJWJufITajECaw1omNi2KkL7/o7ky4NvHACVOtibETUNMXrnuPJ/QBww4roLFVIAyog==", "dev": true, "requires": { "npmlog": "^6.0.2" } }, "@lerna/get-packed": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/get-packed/-/get-packed-5.5.1.tgz", - "integrity": "sha512-8zlT1Yzl1f8XfmNzu+zqJFKIqX28icbfVJp/hrbz7CEyn8JtTy9oNFokt3wbolmQ53LZ69B1gECZ1vlKOtoCSQ==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/get-packed/-/get-packed-5.5.0.tgz", + "integrity": "sha512-X+91ma9SQPrsVctsrFRBABn4+T87lnTEd/BngB7OYlYFsJCc+a6vd+5pnIWxKK5OiUr6+tRpMbJp8BUXJFdb4Q==", "dev": true, "requires": { "fs-extra": "^9.1.0", @@ -927,12 +939,12 @@ } }, "@lerna/github-client": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/github-client/-/github-client-5.5.1.tgz", - "integrity": "sha512-921aWALGJT3L7iF3pYkj9tzXS1D/nZw32qWNoGQweTyAs7ycqm037WhdJPS67k+bqZL8flC80CbGEOuEMQq8Xw==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/github-client/-/github-client-5.5.0.tgz", + "integrity": "sha512-CaBleVR0F+8Yv4FQu6r7Ocqnh3DEq6dQeu0r4RX+mc9jBn9J/N2SdLKRdC7vcvmkcLCxacg8ewuesYqvakQ8HQ==", "dev": true, "requires": { - "@lerna/child-process": "5.5.1", + "@lerna/child-process": "5.5.0", "@octokit/plugin-enterprise-rest": "^6.0.1", "@octokit/rest": "^19.0.3", "git-url-parse": "^12.0.0", @@ -940,9 +952,9 @@ } }, "@lerna/gitlab-client": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/gitlab-client/-/gitlab-client-5.5.1.tgz", - "integrity": "sha512-hp0/p6cITz6pdZ1ToYNHcLHh8iusdXzYNwoLZABSuMAqvvPBuJt2aOxhU7DXBYCB+sQUj8K8qcVP9qpvBs98Wg==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/gitlab-client/-/gitlab-client-5.5.0.tgz", + "integrity": "sha512-ktKfBgQnt0MtyiTM3wuec47Wk7nHc+k2YvoC1roDGaXpgWS7lOQnA8RyorX4Hal3ZsrL95qi9vZOolWvUnxS3w==", "dev": true, "requires": { "node-fetch": "^2.6.1", @@ -950,32 +962,32 @@ } }, "@lerna/global-options": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/global-options/-/global-options-5.5.1.tgz", - "integrity": "sha512-Hy/Yrskk5wuigpG+4GN8cAfBk9tGY/NlJlONmjqcZr5mKc3DkJ2It03jeGtUK/j7hP3GNZo2nx2VGnJf40RGuA==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/global-options/-/global-options-5.5.0.tgz", + "integrity": "sha512-ydEsnXi2LRpxkzpSf8GFeCdh1roTKANZdqzjkhuUlBHrKzKxywpNPpGbXmh6JziHMYdgKGZUjnY35TxBlVRN6Q==", "dev": true }, "@lerna/has-npm-version": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/has-npm-version/-/has-npm-version-5.5.1.tgz", - "integrity": "sha512-t/eff0L3pX31L97mt26LENvIkt+e9fye8hSHUiLoFmUqjmy2yA1qQz2g+oQpGbRXpy+oz9rCCpBx+G4i13aN9A==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/has-npm-version/-/has-npm-version-5.5.0.tgz", + "integrity": "sha512-ALvz0fF1I7Dx+c+0rvkFdqEtp/hs4F/Av2blhOaFWTs78D7FTQa7IpURmvdVDi56H30fqa9b4nEQqnaCRJZKpQ==", "dev": true, "requires": { - "@lerna/child-process": "5.5.1", + "@lerna/child-process": "5.5.0", "semver": "^7.3.4" } }, "@lerna/import": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/import/-/import-5.5.1.tgz", - "integrity": "sha512-9eeagJrw8EBXuONOIagm45zhdHlHrDN9iT5c9OWHV8yh1MBevd7ERbDc8UluHHg5/dP6aqFJxtv54cDdb/3aJg==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/import/-/import-5.5.0.tgz", + "integrity": "sha512-mn87JOcb/j4KBV37Kv589avN5uArcJcASBonm1iWcTwxTvcNFj2BjxnUoVVY6EFamDfBLwWBcAvCO+cvmJkj3Q==", "dev": true, "requires": { - "@lerna/child-process": "5.5.1", - "@lerna/command": "5.5.1", - "@lerna/prompt": "5.5.1", - "@lerna/pulse-till-done": "5.5.1", - "@lerna/validation-error": "5.5.1", + "@lerna/child-process": "5.5.0", + "@lerna/command": "5.5.0", + "@lerna/prompt": "5.5.0", + "@lerna/pulse-till-done": "5.5.0", + "@lerna/validation-error": "5.5.0", "dedent": "^0.7.0", "fs-extra": "^9.1.0", "p-map-series": "^2.1.0" @@ -996,25 +1008,25 @@ } }, "@lerna/info": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/info/-/info-5.5.1.tgz", - "integrity": "sha512-gRrC2yy0qm9scb0B2xSGlPWBGnFMurie5SbGTz4hPesOdZEoiplMaL+e5y5cr67KDEhYPwIkL1sUXHLkTYZekA==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/info/-/info-5.5.0.tgz", + "integrity": "sha512-2pgogAahv8tqY2sFarOCSXcxJFEag9z1pPGnHwKsq8NtekR0exLwFp93iTbDKRff8ScSmH82lNh22GFKZKLm/A==", "dev": true, "requires": { - "@lerna/command": "5.5.1", - "@lerna/output": "5.5.1", + "@lerna/command": "5.5.0", + "@lerna/output": "5.5.0", "envinfo": "^7.7.4" } }, "@lerna/init": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/init/-/init-5.5.1.tgz", - "integrity": "sha512-jyi8DZK2hylI8wjX5NgI/CBZEx2UJmmt12PiQuIvnfEvyTbd90MK0zj4AtyVMKpEal5oZCyprGFBb8MY8lS5Dg==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/init/-/init-5.5.0.tgz", + "integrity": "sha512-dPjuk12s2pSnSL6ib7KQ+RKFyFYvsWAnSMro3sanb07og3tJkwVne8srlmYQsd/NghU8sBdQFFKIV+pzg2sg9w==", "dev": true, "requires": { - "@lerna/child-process": "5.5.1", - "@lerna/command": "5.5.1", - "@lerna/project": "5.5.1", + "@lerna/child-process": "5.5.0", + "@lerna/command": "5.5.0", + "@lerna/project": "5.5.0", "fs-extra": "^9.1.0", "p-map": "^4.0.0", "write-json-file": "^4.3.0" @@ -1035,46 +1047,46 @@ } }, "@lerna/link": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/link/-/link-5.5.1.tgz", - "integrity": "sha512-U/voZ0f/3CHiui3cf9r2ad+jESQZnUAMf6n5oIysBFrT5YtAHHN4FYXtzjXJQ4TLFNke2YnLaw67mLaHeQDW+w==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/link/-/link-5.5.0.tgz", + "integrity": "sha512-wucP0DBKBG2Mkr9PNkPB9ez5pRxLEIY+6s0hB3iTxCTmef5GYPlQ+ftiaN2/IGVYb569AW97YilROuU2gDMrMw==", "dev": true, "requires": { - "@lerna/command": "5.5.1", - "@lerna/package-graph": "5.5.1", - "@lerna/symlink-dependencies": "5.5.1", - "@lerna/validation-error": "5.5.1", + "@lerna/command": "5.5.0", + "@lerna/package-graph": "5.5.0", + "@lerna/symlink-dependencies": "5.5.0", + "@lerna/validation-error": "5.5.0", "p-map": "^4.0.0", "slash": "^3.0.0" } }, "@lerna/list": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/list/-/list-5.5.1.tgz", - "integrity": "sha512-tRDUpV06ZpV6g2MvqRf35ozsRjKweCTCvS8z1o1/4laZen6aPK+Y9TIihvd36biDzCdNYz3IOLzvz8nO8WIJiA==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/list/-/list-5.5.0.tgz", + "integrity": "sha512-vic7CeD/TL0bh6hzpgHK2Ogz7MW1NB6Sws1J7cl5CTn4sAGm/KZ/g4MNsLFVLJNAiPh+t2cmT0ndyNluShnjqA==", "dev": true, "requires": { - "@lerna/command": "5.5.1", - "@lerna/filter-options": "5.5.1", - "@lerna/listable": "5.5.1", - "@lerna/output": "5.5.1" + "@lerna/command": "5.5.0", + "@lerna/filter-options": "5.5.0", + "@lerna/listable": "5.5.0", + "@lerna/output": "5.5.0" } }, "@lerna/listable": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/listable/-/listable-5.5.1.tgz", - "integrity": "sha512-EU+OUBV0vrySrDhlMHvfdA0NgwRtaTx5nc4XUtNrTN4Zqjav9iElrf6Xx9k0fUq27smiQ1tyutQEwGaNab0VTQ==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/listable/-/listable-5.5.0.tgz", + "integrity": "sha512-2kCpn8vlmRTVA3tGr1XRkHOW2ljXjb/hRNxSK3DUf0k6sl9sEdQFSH7cf5qPnCAPcuLHS7b8kuFhA6x8nXFP3g==", "dev": true, "requires": { - "@lerna/query-graph": "5.5.1", + "@lerna/query-graph": "5.5.0", "chalk": "^4.1.0", "columnify": "^1.6.0" } }, "@lerna/log-packed": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/log-packed/-/log-packed-5.5.1.tgz", - "integrity": "sha512-i6SomT53TquZwrl8Ib+bleU0xYo8z36jIWGqfb0OlbNZswEbHQ5nvVO73Kjjc14g+eM0JGHwGi79LHFictcjVw==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/log-packed/-/log-packed-5.5.0.tgz", + "integrity": "sha512-kVDEy29VfBQeha92IBuPq9W/kP6ffboCWuU64lBIAljTDdpFrMFBeLRrWfLSLIVe2fq8FpGk8PInNlDHmvT5PA==", "dev": true, "requires": { "byte-size": "^7.0.0", @@ -1084,9 +1096,9 @@ } }, "@lerna/npm-conf": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/npm-conf/-/npm-conf-5.5.1.tgz", - "integrity": "sha512-ARqXAUlkEfFL00fgZa84aFzvp9GSPxAm4Fy1wzGz9ltXTwg/1yyGu6AucSKO1qa/JvcF2giWuXuvkJ3jsY4Log==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/npm-conf/-/npm-conf-5.5.0.tgz", + "integrity": "sha512-ml1Pmn26a61y6nFijpNE9RAbsNOF2XL1Kqyd3x7+XFaDmqbSDqo2g5qlsb4gTdUj/Uy1niRGzy3XdC0FH5G+mg==", "dev": true, "requires": { "config-chain": "^1.1.12", @@ -1102,25 +1114,25 @@ } }, "@lerna/npm-dist-tag": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/npm-dist-tag/-/npm-dist-tag-5.5.1.tgz", - "integrity": "sha512-DN3l01gpgV3M2MYo7zhZOgZrl21ltr+PoxK2LBVv5Snbhc88WqKm6slCrF5LXnfM6FraZ2UQTjBYXx8fQnpIDw==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/npm-dist-tag/-/npm-dist-tag-5.5.0.tgz", + "integrity": "sha512-Hz6n9tqbGUuqI1q9IS3tAGx95TkOqLfXRay9kr/hjswj+HKp0Dtw1cu8YRtizA7CuIWw831eXCbqfFyILfytaA==", "dev": true, "requires": { - "@lerna/otplease": "5.5.1", + "@lerna/otplease": "5.5.0", "npm-package-arg": "8.1.1", "npm-registry-fetch": "^13.3.0", "npmlog": "^6.0.2" } }, "@lerna/npm-install": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/npm-install/-/npm-install-5.5.1.tgz", - "integrity": "sha512-O99aYWrWAz+EuHrsED2Wv0X6Ge1O9CrAfcIu6dMf8r5Q58LL67engi9AtH98cwx2LTeyYYHwksjewIsL/kn0ig==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/npm-install/-/npm-install-5.5.0.tgz", + "integrity": "sha512-axMtqZYuAl5qGcRCBYKqINimMrbQRM1f09sz9rKtwnx15066qT0IaKUt9YYo5bsZm/i3BXpBqcUxZXlGzQNWBQ==", "dev": true, "requires": { - "@lerna/child-process": "5.5.1", - "@lerna/get-npm-exec-opts": "5.5.1", + "@lerna/child-process": "5.5.0", + "@lerna/get-npm-exec-opts": "5.5.0", "fs-extra": "^9.1.0", "npm-package-arg": "8.1.1", "npmlog": "^6.0.2", @@ -1143,13 +1155,13 @@ } }, "@lerna/npm-publish": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/npm-publish/-/npm-publish-5.5.1.tgz", - "integrity": "sha512-ajdV2Vb9SOGGp7E7pvb0q7gHqQpd8fQ4DztPOQYrhMUILobJgu4oR3tojMp0XN7vki+pG/OmsOqrQY6M02AkPw==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/npm-publish/-/npm-publish-5.5.0.tgz", + "integrity": "sha512-eDcmga5CcXGmSdVXBO75eCX3vypEwQO/lN7VqRpLSOsIHIRUGbfwo/stbz8sIF4+HAkaAFGj6BScjvjlyoh2pQ==", "dev": true, "requires": { - "@lerna/otplease": "5.5.1", - "@lerna/run-lifecycle": "5.5.1", + "@lerna/otplease": "5.5.0", + "@lerna/run-lifecycle": "5.5.0", "fs-extra": "^9.1.0", "libnpmpublish": "^6.0.4", "npm-package-arg": "8.1.1", @@ -1179,53 +1191,53 @@ } }, "@lerna/npm-run-script": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/npm-run-script/-/npm-run-script-5.5.1.tgz", - "integrity": "sha512-/68rDfOHtAEHAeAVYC1KXidQkssMBnz/9kcXlcdUaqe88LXSCuhWz49w7qWsUJvSmqwCuD7BWtVR5zx4GnLXhQ==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/npm-run-script/-/npm-run-script-5.5.0.tgz", + "integrity": "sha512-ltEtw28CLpG/VaWX4PZ1enJ0wxA/Qw8ScAwhQTZj0xL6Lhkq5H0LoEALVRAq2gK10h1p2IUs/W034oXT1chH0w==", "dev": true, "requires": { - "@lerna/child-process": "5.5.1", - "@lerna/get-npm-exec-opts": "5.5.1", + "@lerna/child-process": "5.5.0", + "@lerna/get-npm-exec-opts": "5.5.0", "npmlog": "^6.0.2" } }, "@lerna/otplease": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/otplease/-/otplease-5.5.1.tgz", - "integrity": "sha512-I2SEuIb7JWWT4xNUNWvKP7qaRHeQslMuiSdJuO6dV1fnH7FM7xEiHnWIhgDsQqacsci17Ix92toORaYmkU/kqg==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/otplease/-/otplease-5.5.0.tgz", + "integrity": "sha512-zNS315iH2VRQz/LJTrqUUuEqMnNsCoMXOMOaBzcB/AL29mYMvJlT05dMqenMPKrRtW0tAFzPC7jLTzybdRa7Qg==", "dev": true, "requires": { - "@lerna/prompt": "5.5.1" + "@lerna/prompt": "5.5.0" } }, "@lerna/output": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/output/-/output-5.5.1.tgz", - "integrity": "sha512-G8WpRlXWUCaJqxtVTCrYRSu5hBy0lxsfdzoEJwkVW9wXL6mL4WwH5TkstPq8LFSEr+NkWa+Hz25VO7LywQQWaQ==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/output/-/output-5.5.0.tgz", + "integrity": "sha512-f+MXc9X1xEe2w0AC+CAMr093MumCTNYmyIt8eUMYQMmoRkWT2n4tN8/KvWw9ucSWLKMkZtOTJiC+S6RJ4nWUig==", "dev": true, "requires": { "npmlog": "^6.0.2" } }, "@lerna/pack-directory": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/pack-directory/-/pack-directory-5.5.1.tgz", - "integrity": "sha512-gvKnq9spvIPV4KGK1sxCk23jUjKdpzXtZFZ77QSDWfv2ZXOLcU9MvNC9xx23wcQRkX1IhKFngwMtIfcxrUZN2Q==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/pack-directory/-/pack-directory-5.5.0.tgz", + "integrity": "sha512-zHpIAeZOpIH/Slb8vuh75XR46mc4RZNwPS6XpwRgMRpp3Y1Bazlv6hDcq+pZTg1FwYKIDQDRfxW3IQi/aDPIjA==", "dev": true, "requires": { - "@lerna/get-packed": "5.5.1", - "@lerna/package": "5.5.1", - "@lerna/run-lifecycle": "5.5.1", - "@lerna/temp-write": "5.5.1", + "@lerna/get-packed": "5.5.0", + "@lerna/package": "5.5.0", + "@lerna/run-lifecycle": "5.5.0", + "@lerna/temp-write": "5.5.0", "npm-packlist": "^5.1.1", "npmlog": "^6.0.2", "tar": "^6.1.0" } }, "@lerna/package": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/package/-/package-5.5.1.tgz", - "integrity": "sha512-K2ylaS3DJ2SU/ptWHMeXkN1AUVPAOKNCP5/K8S42z/ZAmuLlt1LcTMznWPaCbYf2h3HExda8j3UmbEsOtYuixw==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/package/-/package-5.5.0.tgz", + "integrity": "sha512-vP08ZdMd3A7B0hEI4ZNgCeBef64yCidrnFUIiIhXb/tAsDmGCGqS2IFdGRNE9vv01tVg0WrPLim4tl8AjoigKw==", "dev": true, "requires": { "load-json-file": "^6.2.0", @@ -1254,31 +1266,31 @@ } }, "@lerna/package-graph": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/package-graph/-/package-graph-5.5.1.tgz", - "integrity": "sha512-BgkJquJcm/GaGwLmZRTCSAdUBitlGP4HmEP1NI9xrR1x9/OHgfVfkp5yDZBipA/6jY7ucumShU6mYE0fIP9CVA==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/package-graph/-/package-graph-5.5.0.tgz", + "integrity": "sha512-g378NrCTEmVXqkAkv9EX8L3K7JTioPNuxItXTHQxlHDhZ2RM9KCVbT/ihwefVujWwwMPNij10bmfJUaEp2TGPQ==", "dev": true, "requires": { - "@lerna/prerelease-id-from-version": "5.5.1", - "@lerna/validation-error": "5.5.1", + "@lerna/prerelease-id-from-version": "5.5.0", + "@lerna/validation-error": "5.5.0", "npm-package-arg": "8.1.1", "npmlog": "^6.0.2", "semver": "^7.3.4" } }, "@lerna/prerelease-id-from-version": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/prerelease-id-from-version/-/prerelease-id-from-version-5.5.1.tgz", - "integrity": "sha512-F12+2ubWOY3pnUyTpV/jgZUMaFWas0ehFwYs20WMAnQQVyRHCVjg+bBfvQPGVnuJ6r7n3kXzn69TLDzouhRJcQ==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/prerelease-id-from-version/-/prerelease-id-from-version-5.5.0.tgz", + "integrity": "sha512-cpy0EgfO/7fXPhl/EsJnD8uGv0f8d6FHG2R1Xr7sJvmkffhkIy90qkFA7uSaZAA+ar9QFSAUJ+wGox0bhGJhHA==", "dev": true, "requires": { "semver": "^7.3.4" } }, "@lerna/profiler": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/profiler/-/profiler-5.5.1.tgz", - "integrity": "sha512-WDPgXEYl0lU/dBZ7ejiiNLqwJkPFR+d4vmIkPAFR4RsKQV4VCOCtlJ2QxOHroOPLJ7FrKD71rKyX4cZUIrHl7Q==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/profiler/-/profiler-5.5.0.tgz", + "integrity": "sha512-2DkkMxYCq/RsBptN+gJtmqwdrFqji6QMpNlm7v9JgS9kN2aHUIxcavtHXDaYf9sdPoey/bGypRv9DDTDcuw9MA==", "dev": true, "requires": { "fs-extra": "^9.1.0", @@ -1301,13 +1313,13 @@ } }, "@lerna/project": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/project/-/project-5.5.1.tgz", - "integrity": "sha512-If3HOjNk/hcbe1gJDysKPws0RKvyG7rrGzkEmBGQ6bi6+eDdaK98XRFHTTAnHfBVOLLd1eimprZCUsYuCATdLg==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/project/-/project-5.5.0.tgz", + "integrity": "sha512-TD6/QGv/+Uh7GRXM/9m3EC0QpK2+U1WA+hoE5pSnpU5oDzwwUkynS3RuAcd2ID19e/u/ajfZtV+xcpaM7t+SHw==", "dev": true, "requires": { - "@lerna/package": "5.5.1", - "@lerna/validation-error": "5.5.1", + "@lerna/package": "5.5.0", + "@lerna/validation-error": "5.5.0", "cosmiconfig": "^7.0.0", "dedent": "^0.7.0", "dot-prop": "^6.0.1", @@ -1366,9 +1378,9 @@ } }, "@lerna/prompt": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/prompt/-/prompt-5.5.1.tgz", - "integrity": "sha512-pKxdfwW4VwIapLj3kZBR3V6usCbZmCfkYUJSO//Vcw/dYf8X1lI9a+qR6imXSa1VwGdU/29oimMGpFn89BjyCA==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/prompt/-/prompt-5.5.0.tgz", + "integrity": "sha512-B7QEmmyleR+1XAewqEPdgZPecekJgVoAZ8YZgR8l4QlAMvf5BTHI//3AJI/HPN4DYZWGcjDoGFLEkpX906T8Rw==", "dev": true, "requires": { "inquirer": "^8.2.4", @@ -1376,30 +1388,30 @@ } }, "@lerna/publish": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/publish/-/publish-5.5.1.tgz", - "integrity": "sha512-hQCEHGLHR4Wd3M/Ay7bmOViL1HRekI/VoJGy+JoG3rn/0H13cTh+lVhvwmtOGKJHsHBQkQ0WaZzwZF16/XLTzA==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/publish/-/publish-5.5.0.tgz", + "integrity": "sha512-ZstILgupYxB8TpGkWgPZg1uoFIQUij07kizHau1BZXdV3xwPU6jtYAzGXuztinJDnnxfwjc7SjuinoYZcbmJXg==", "dev": true, "requires": { - "@lerna/check-working-tree": "5.5.1", - "@lerna/child-process": "5.5.1", - "@lerna/collect-updates": "5.5.1", - "@lerna/command": "5.5.1", - "@lerna/describe-ref": "5.5.1", - "@lerna/log-packed": "5.5.1", - "@lerna/npm-conf": "5.5.1", - "@lerna/npm-dist-tag": "5.5.1", - "@lerna/npm-publish": "5.5.1", - "@lerna/otplease": "5.5.1", - "@lerna/output": "5.5.1", - "@lerna/pack-directory": "5.5.1", - "@lerna/prerelease-id-from-version": "5.5.1", - "@lerna/prompt": "5.5.1", - "@lerna/pulse-till-done": "5.5.1", - "@lerna/run-lifecycle": "5.5.1", - "@lerna/run-topologically": "5.5.1", - "@lerna/validation-error": "5.5.1", - "@lerna/version": "5.5.1", + "@lerna/check-working-tree": "5.5.0", + "@lerna/child-process": "5.5.0", + "@lerna/collect-updates": "5.5.0", + "@lerna/command": "5.5.0", + "@lerna/describe-ref": "5.5.0", + "@lerna/log-packed": "5.5.0", + "@lerna/npm-conf": "5.5.0", + "@lerna/npm-dist-tag": "5.5.0", + "@lerna/npm-publish": "5.5.0", + "@lerna/otplease": "5.5.0", + "@lerna/output": "5.5.0", + "@lerna/pack-directory": "5.5.0", + "@lerna/prerelease-id-from-version": "5.5.0", + "@lerna/prompt": "5.5.0", + "@lerna/pulse-till-done": "5.5.0", + "@lerna/run-lifecycle": "5.5.0", + "@lerna/run-topologically": "5.5.0", + "@lerna/validation-error": "5.5.0", + "@lerna/version": "5.5.0", "fs-extra": "^9.1.0", "libnpmaccess": "^6.0.3", "npm-package-arg": "8.1.1", @@ -1426,27 +1438,27 @@ } }, "@lerna/pulse-till-done": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/pulse-till-done/-/pulse-till-done-5.5.1.tgz", - "integrity": "sha512-fIE9+LRy172Utfei34QpAg34CFy890j2GCZFln6A+0M3aMNrXkLgF3Zn2awPCugXNu7tLqHRrdZ9ZiSeuk5FYg==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/pulse-till-done/-/pulse-till-done-5.5.0.tgz", + "integrity": "sha512-PcPSCWGzLp00UGJ5VHDpdqpBQ9C9Cs7E5FImEITGHE9UwcAC23LwSp7tOzdXWPyj3u8PLYLn+ebt9ml1jWSKgA==", "dev": true, "requires": { "npmlog": "^6.0.2" } }, "@lerna/query-graph": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/query-graph/-/query-graph-5.5.1.tgz", - "integrity": "sha512-BqkxJntH/2o+s9Qz0WUOnbA/SW+ASjkvrS/DJ9jVeZ6KQQykPx/VN+ZRcWCBaSDlJEjSyMiTZUPGqtbN5qV+QQ==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/query-graph/-/query-graph-5.5.0.tgz", + "integrity": "sha512-mqCzZRF+IDPSj2zYJ1eO3PQsZshiKf54BXAe7HnYYJNbs1i8JMRpdaLr3TEyKDpVTcVzbEmFKwGi7KMhJG6rBQ==", "dev": true, "requires": { - "@lerna/package-graph": "5.5.1" + "@lerna/package-graph": "5.5.0" } }, "@lerna/resolve-symlink": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/resolve-symlink/-/resolve-symlink-5.5.1.tgz", - "integrity": "sha512-xuVPN9SrtOfx9crgYbfJX7c/TpGKQj2cKlkGNt1HqfD2GvUvLzksn1Wjj1Mq23yinPNXo2QDXr7XgjHuDNd48w==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/resolve-symlink/-/resolve-symlink-5.5.0.tgz", + "integrity": "sha512-J44Kc6OWa1uNZh+YSWuIBorTpTuXhuuJ7DtX4vwfF3AAp2frW6pBrmFZMibOcyOQ6QCp+PeiHQCXCF42uSq8pA==", "dev": true, "requires": { "fs-extra": "^9.1.0", @@ -1469,64 +1481,64 @@ } }, "@lerna/rimraf-dir": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/rimraf-dir/-/rimraf-dir-5.5.1.tgz", - "integrity": "sha512-bS7NUKFMT1HsqEFA8mxtHD3jDnpS2xLfQjCyCb7FHHatL46ByZ4oex2965XqL2/aOf+C5aCvYmLFHQ9JN7E2cQ==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/rimraf-dir/-/rimraf-dir-5.5.0.tgz", + "integrity": "sha512-dwWN5SGXQ39FocRAZ3uL7tYUuK98r/VHQZRcJjJ8hxpuxti+EPzGegtA05NsvvmW2PpFsBzYKITFQHX3GX4LWA==", "dev": true, "requires": { - "@lerna/child-process": "5.5.1", + "@lerna/child-process": "5.5.0", "npmlog": "^6.0.2", "path-exists": "^4.0.0", "rimraf": "^3.0.2" } }, "@lerna/run": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/run/-/run-5.5.1.tgz", - "integrity": "sha512-IVXkiOmTMm1jtrDznunzQx796D9LrwKhlmsTv4YTNfnnyPBlyDAobm/PmOUekf30LKrKvcgTRnbEQ6vWXTR93Q==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/run/-/run-5.5.0.tgz", + "integrity": "sha512-yYR65A/GcDgEMmk2lMSBHGAbdgLMi6wICugLzVXfXISuTbEMzN1dCwSeGBOxzK2cvKV2Bpn4WeEYs64FNmNJbQ==", "dev": true, "requires": { - "@lerna/command": "5.5.1", - "@lerna/filter-options": "5.5.1", - "@lerna/npm-run-script": "5.5.1", - "@lerna/output": "5.5.1", - "@lerna/profiler": "5.5.1", - "@lerna/run-topologically": "5.5.1", - "@lerna/timer": "5.5.1", - "@lerna/validation-error": "5.5.1", + "@lerna/command": "5.5.0", + "@lerna/filter-options": "5.5.0", + "@lerna/npm-run-script": "5.5.0", + "@lerna/output": "5.5.0", + "@lerna/profiler": "5.5.0", + "@lerna/run-topologically": "5.5.0", + "@lerna/timer": "5.5.0", + "@lerna/validation-error": "5.5.0", "p-map": "^4.0.0" } }, "@lerna/run-lifecycle": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/run-lifecycle/-/run-lifecycle-5.5.1.tgz", - "integrity": "sha512-ZM66N7e1sUxsckBnJxdP1NenPNo3hKjPi8fop4do61kwHrWakyRZHl5EEw3CgCWtC7QT+d3zQ/XgDQeJMYEUZg==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/run-lifecycle/-/run-lifecycle-5.5.0.tgz", + "integrity": "sha512-BtnEO3IlZ7znUmQtSxd7oSSmgzJbSH+v58foTpbuvMtOBFJxV4LNyv2uyto2t4bYdCWEnw4ybd8j32aEEG9UNQ==", "dev": true, "requires": { - "@lerna/npm-conf": "5.5.1", + "@lerna/npm-conf": "5.5.0", "@npmcli/run-script": "^4.1.7", "npmlog": "^6.0.2", "p-queue": "^6.6.2" } }, "@lerna/run-topologically": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/run-topologically/-/run-topologically-5.5.1.tgz", - "integrity": "sha512-27n6SY2X8hWIU2VkttNx+G9D5pUXkxvkum6fvWkOrT/3a5miIwmeZvk0t1qhJ2VHxheB3hpd8HntAb2I2tR62g==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/run-topologically/-/run-topologically-5.5.0.tgz", + "integrity": "sha512-zl4I/SNg/yiLja1aF0B4X22CRzpRdvLB47KGjAgiGydcHwx2TUmI3MPoQVjvUbaOuctF/wSMS2tI6Hgdo60I0Q==", "dev": true, "requires": { - "@lerna/query-graph": "5.5.1", + "@lerna/query-graph": "5.5.0", "p-queue": "^6.6.2" } }, "@lerna/symlink-binary": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/symlink-binary/-/symlink-binary-5.5.1.tgz", - "integrity": "sha512-PhrpeO2+3S1bYURb8y7QykmvwS/3KT2nF6Tvv23aqHJOBnrD61I2x0lQdjZK71+WOvi+EN+CatHckNWez14zpw==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/symlink-binary/-/symlink-binary-5.5.0.tgz", + "integrity": "sha512-vpVzEWgVfKGzMheb9XizF8hF/Ypfov0iMPBSAzVNxu5eNQVUz3KFrIZNgiBsFdIVN4W/y4jLwOSgXXKwvIodkA==", "dev": true, "requires": { - "@lerna/create-symlink": "5.5.1", - "@lerna/package": "5.5.1", + "@lerna/create-symlink": "5.5.0", + "@lerna/package": "5.5.0", "fs-extra": "^9.1.0", "p-map": "^4.0.0" }, @@ -1546,14 +1558,14 @@ } }, "@lerna/symlink-dependencies": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/symlink-dependencies/-/symlink-dependencies-5.5.1.tgz", - "integrity": "sha512-xfxTIbg/fUC0afRODbXnFeJ7inEEow4Jkt3agrI10BrztjDKOmoG65KPPh8j0TGKk46TmeN5DI2Ob/5sKRiRzA==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/symlink-dependencies/-/symlink-dependencies-5.5.0.tgz", + "integrity": "sha512-gqFZ4AeVr+nqyfg8c2xNizGzBemfgtCpGv4NnjA/66HJWCE+/fT7NTIi8Qk2glbYf37ojRcjUfc0RvW7NGv5qA==", "dev": true, "requires": { - "@lerna/create-symlink": "5.5.1", - "@lerna/resolve-symlink": "5.5.1", - "@lerna/symlink-binary": "5.5.1", + "@lerna/create-symlink": "5.5.0", + "@lerna/resolve-symlink": "5.5.0", + "@lerna/symlink-binary": "5.5.0", "fs-extra": "^9.1.0", "p-map": "^4.0.0", "p-map-series": "^2.1.0" @@ -1574,9 +1586,9 @@ } }, "@lerna/temp-write": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/temp-write/-/temp-write-5.5.1.tgz", - "integrity": "sha512-Msuv4OBXXKJlbxhD4kAUs95XsPYGshoKwQSI2sqOinFXnOkkbhdPdRz+7cd4JKs5qMCEy0+5dh7haruYDnSWmQ==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/temp-write/-/temp-write-5.5.0.tgz", + "integrity": "sha512-7MmqTfyWcjGkgPkWHaldmCmDBSLka50z0+lsmZuGLwIvQl72ZfC+ZJF/6107m+hgtUJBpJQ3UYEhrrdfR4L46Q==", "dev": true, "requires": { "graceful-fs": "^4.1.15", @@ -1616,40 +1628,40 @@ } }, "@lerna/timer": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/timer/-/timer-5.5.1.tgz", - "integrity": "sha512-DLmCZG0dKh7+Ie/CzK+iz6RPRyAJbXt+4D8OA7n6o/K/Q6AERuNabCDS/3AhJKTdReEjoA2UpswrHXfBN48xVg==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/timer/-/timer-5.5.0.tgz", + "integrity": "sha512-jgCL2ZmZNn7sWL+M/TuGJukTkUs/il6EwBYcgd10h0JazQ4fAiBhFq36ZzTvYkz6ujKvKOcqyWrMdmi8Q339qA==", "dev": true }, "@lerna/validation-error": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/validation-error/-/validation-error-5.5.1.tgz", - "integrity": "sha512-sO5Y6GKmMPtYSKHHR5bNXf/HKISb2g/7uny96X28h+/DihiLhHb0q09fIqmY5WHA1AHsJProZFVEN3BlNrtfEg==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/validation-error/-/validation-error-5.5.0.tgz", + "integrity": "sha512-o/8sEaZKdZdE4/t+E/cFpnYIiDzt7uMHVpWmpCG0l6nZSDzB8+5ehAAudy2qJOwxEAKJ6QGvi7jWLjc2NWa4HQ==", "dev": true, "requires": { "npmlog": "^6.0.2" } }, "@lerna/version": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/version/-/version-5.5.1.tgz", - "integrity": "sha512-P2AWTBKRytnSOSS243u3/cz1ecOPG2LTMbiyVBcFnYSAgzHf8AcJYtyfu4aMFzpSD5JfVyYSMvraRiZqK4r7+Q==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/version/-/version-5.5.0.tgz", + "integrity": "sha512-E6ZrzTrYwof5cSvyTpztZKOiJKAK+aXi/gfsGbLdbYGMArY4B/pYOMOcRMXHBh7BuLicMih/mRUb4M7uCnuE0A==", "dev": true, "requires": { - "@lerna/check-working-tree": "5.5.1", - "@lerna/child-process": "5.5.1", - "@lerna/collect-updates": "5.5.1", - "@lerna/command": "5.5.1", - "@lerna/conventional-commits": "5.5.1", - "@lerna/github-client": "5.5.1", - "@lerna/gitlab-client": "5.5.1", - "@lerna/output": "5.5.1", - "@lerna/prerelease-id-from-version": "5.5.1", - "@lerna/prompt": "5.5.1", - "@lerna/run-lifecycle": "5.5.1", - "@lerna/run-topologically": "5.5.1", - "@lerna/temp-write": "5.5.1", - "@lerna/validation-error": "5.5.1", + "@lerna/check-working-tree": "5.5.0", + "@lerna/child-process": "5.5.0", + "@lerna/collect-updates": "5.5.0", + "@lerna/command": "5.5.0", + "@lerna/conventional-commits": "5.5.0", + "@lerna/github-client": "5.5.0", + "@lerna/gitlab-client": "5.5.0", + "@lerna/output": "5.5.0", + "@lerna/prerelease-id-from-version": "5.5.0", + "@lerna/prompt": "5.5.0", + "@lerna/run-lifecycle": "5.5.0", + "@lerna/run-topologically": "5.5.0", + "@lerna/temp-write": "5.5.0", + "@lerna/validation-error": "5.5.0", "chalk": "^4.1.0", "dedent": "^0.7.0", "load-json-file": "^6.2.0", @@ -1685,9 +1697,9 @@ } }, "@lerna/write-log-file": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/@lerna/write-log-file/-/write-log-file-5.5.1.tgz", - "integrity": "sha512-gWdDQsG6bHsExa+/1+oHyPI/W+pW6IoKw8fKxs62YOZKei3jKxyQbgMZyMqOTSs76kIe2LiY5JsoBD7saN/ORg==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/@lerna/write-log-file/-/write-log-file-5.5.0.tgz", + "integrity": "sha512-XPnp5B+bcmwpXJpJn45V8e2SU6Z1oTwW0vW9uW3l0nmbOvpT9PbPkf9hC80cZOWovXSBefUDwEGqA5fQdhvqGg==", "dev": true, "requires": { "npmlog": "^6.0.2", @@ -1784,24 +1796,33 @@ } }, "hosted-git-info": { - "version": "5.1.0", - "resolved": "https://registry.npmmirror.com/hosted-git-info/-/hosted-git-info-5.1.0.tgz", - "integrity": "sha512-Ek+QmMEqZF8XrbFdwoDjSbm7rT23pCgEMOJmz6GPk/s4yH//RQfNPArhIxbguNxROq/+5lNBwCDHMhA903Kx1Q==", + "version": "5.2.1", + "resolved": "https://registry.npmmirror.com/hosted-git-info/-/hosted-git-info-5.2.1.tgz", + "integrity": "sha512-xIcQYMnhcx2Nr4JTjsFmwwnr9vldugPy9uVm0o87bjqqWMv9GaqsTeT+i99wTl0mk1uLxJtHxLb8kymqTENQsw==", "dev": true, "requires": { "lru-cache": "^7.5.1" } }, "lru-cache": { - "version": "7.14.0", - "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-7.14.0.tgz", - "integrity": "sha512-EIRtP1GrSJny0dqb50QXRUNBxHJhcpxHC++M5tD7RYbvLLn5KVWKsbyswSSqDuU15UFi3bgTQIY8nhDMeF6aDQ==", + "version": "7.17.0", + "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-7.17.0.tgz", + "integrity": "sha512-zSxlVVwOabhVyTi6E8gYv2cr6bXK+8ifYz5/uyJb9feXX6NACVDwY4p5Ut3WC3Ivo/QhpARHU3iujx2xGAYHbQ==", "dev": true }, + "nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "dev": true, + "requires": { + "abbrev": "1" + } + }, "npm-package-arg": { - "version": "9.1.0", - "resolved": "https://registry.npmmirror.com/npm-package-arg/-/npm-package-arg-9.1.0.tgz", - "integrity": "sha512-4J0GL+u2Nh6OnhvUKXRr2ZMG4lR8qtLp+kv7UiV00Y+nGiSxtttCyIRHCt5L5BNkXQld/RceYItau3MDOoGiBw==", + "version": "9.1.2", + "resolved": "https://registry.npmmirror.com/npm-package-arg/-/npm-package-arg-9.1.2.tgz", + "integrity": "sha512-pzd9rLEx4TfNJkovvlBSLGhq31gGu2QDexFPWT19yCDh0JgnRhlBLNo5759N0AJmBk+kQ9Y/hXoLnlgFD+ukmg==", "dev": true, "requires": { "hosted-git-info": "^5.0.0", @@ -1811,9 +1832,9 @@ } }, "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmmirror.com/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmmirror.com/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -1869,9 +1890,9 @@ }, "dependencies": { "lru-cache": { - "version": "7.14.0", - "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-7.14.0.tgz", - "integrity": "sha512-EIRtP1GrSJny0dqb50QXRUNBxHJhcpxHC++M5tD7RYbvLLn5KVWKsbyswSSqDuU15UFi3bgTQIY8nhDMeF6aDQ==", + "version": "7.17.0", + "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-7.17.0.tgz", + "integrity": "sha512-zSxlVVwOabhVyTi6E8gYv2cr6bXK+8ifYz5/uyJb9feXX6NACVDwY4p5Ut3WC3Ivo/QhpARHU3iujx2xGAYHbQ==", "dev": true } } @@ -1908,9 +1929,9 @@ } }, "glob": { - "version": "8.0.3", - "resolved": "https://registry.npmmirror.com/glob/-/glob-8.0.3.tgz", - "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", + "version": "8.1.0", + "resolved": "https://registry.npmmirror.com/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -1921,9 +1942,9 @@ } }, "minimatch": { - "version": "5.1.0", - "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-5.1.0.tgz", - "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", + "version": "5.1.6", + "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, "requires": { "brace-expansion": "^2.0.1" @@ -1997,54 +2018,117 @@ } }, "@nrwl/cli": { - "version": "14.7.5", - "resolved": "https://registry.npmmirror.com/@nrwl/cli/-/cli-14.7.5.tgz", - "integrity": "sha512-hkkavBDHPZKuxG9q8bcib9/TYnTn13t8CaePjx1JvYqWTYblWVLrzlPhJKFC44Dkch+rtvZ/USs5Fih76se25g==", + "version": "15.7.2", + "resolved": "https://registry.npmmirror.com/@nrwl/cli/-/cli-15.7.2.tgz", + "integrity": "sha512-A/72FAW1e0ku8YB/PaCqN9BpVvciO83MS5F5bvX5PA8xCNqe1+iXp/5T2ASnN2lB9zR3fQJmvR7mHKTKQlqQQQ==", "dev": true, "requires": { - "nx": "14.7.5" + "nx": "15.7.2" } }, + "@nrwl/nx-darwin-arm64": { + "version": "15.7.2", + "resolved": "https://registry.npmmirror.com/@nrwl/nx-darwin-arm64/-/nx-darwin-arm64-15.7.2.tgz", + "integrity": "sha512-F82exjuqkAkElSTxEcTFeLMhHpbGiccfTQh2VjXMS+ONldxM+Kd7atJjtUG8wKNXfg0lxxjjAdnzLy3iBuN/HQ==", + "dev": true, + "optional": true + }, + "@nrwl/nx-darwin-x64": { + "version": "15.7.2", + "resolved": "https://registry.npmmirror.com/@nrwl/nx-darwin-x64/-/nx-darwin-x64-15.7.2.tgz", + "integrity": "sha512-MNT7Bxz6yhoVLCgGpR0NtVkj20SER1CbrCaY7tmsKVNY9iA/EOZhz9qa3LeA1KZ4lw8Gpi2vD42mOngn7Mwr7w==", + "dev": true, + "optional": true + }, + "@nrwl/nx-linux-arm-gnueabihf": { + "version": "15.7.2", + "resolved": "https://registry.npmmirror.com/@nrwl/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-15.7.2.tgz", + "integrity": "sha512-QGyPkYnZ9LnUnuCzrP50bwsMJ9n6r8K2bNC1sQQwioijY+4MHNL+bMTOGWc8+lYBP7Ju3gpTqozGV3FQVkaM2w==", + "dev": true, + "optional": true + }, + "@nrwl/nx-linux-arm64-gnu": { + "version": "15.7.2", + "resolved": "https://registry.npmmirror.com/@nrwl/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-15.7.2.tgz", + "integrity": "sha512-HqufFVIvuunfChEFGkIhsLhhQjWLTFcCH2aQBSNesHpm6AhFVRGyokNu+PT6NNobr+BTrqJMocBqNQR1uvSyRQ==", + "dev": true, + "optional": true + }, + "@nrwl/nx-linux-arm64-musl": { + "version": "15.7.2", + "resolved": "https://registry.npmmirror.com/@nrwl/nx-linux-arm64-musl/-/nx-linux-arm64-musl-15.7.2.tgz", + "integrity": "sha512-9B8q6I/OVyQuYe+Yg2wNyxza/CsbvejIUsrK3QGGWUwHlkklqOSmUOHyTrcyMHUSped6CWPyKdIywngYOQzltQ==", + "dev": true, + "optional": true + }, + "@nrwl/nx-linux-x64-gnu": { + "version": "15.7.2", + "resolved": "https://registry.npmmirror.com/@nrwl/nx-linux-x64-gnu/-/nx-linux-x64-gnu-15.7.2.tgz", + "integrity": "sha512-8/6WtQn4derYKUWu5SxWWM+1dGihSZXMhDW9l/sXOr/qbMZu3XBmM2XZSguw/+p9gEVHcMmN0+D+Cai+q6/vDQ==", + "dev": true, + "optional": true + }, + "@nrwl/nx-linux-x64-musl": { + "version": "15.7.2", + "resolved": "https://registry.npmmirror.com/@nrwl/nx-linux-x64-musl/-/nx-linux-x64-musl-15.7.2.tgz", + "integrity": "sha512-c5SbqYZZBeBHhH5E30xwb4cHzCMVa/GQMCyTpZgsS/AHAPHbdkv+pO6bxxALvLPTyimcub7V+xbLCL7rgALzyw==", + "dev": true, + "optional": true + }, + "@nrwl/nx-win32-arm64-msvc": { + "version": "15.7.2", + "resolved": "https://registry.npmmirror.com/@nrwl/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-15.7.2.tgz", + "integrity": "sha512-gWD/+gSO3XBma8PHX1Dp86fM6EcntHFfa7n/BISwDFkZ19MfV/gK6HbO847fkD6I34/IcDM/z1PsFwoIpTeoow==", + "dev": true, + "optional": true + }, + "@nrwl/nx-win32-x64-msvc": { + "version": "15.7.2", + "resolved": "https://registry.npmmirror.com/@nrwl/nx-win32-x64-msvc/-/nx-win32-x64-msvc-15.7.2.tgz", + "integrity": "sha512-ARE4qGPgk+e+pSm0uPhHan5UCRtwNYc5ddVNS88NFrVoDTPm5MxYLGdvLnshWWio/Bx526FcwUMSCBWSW8HIFw==", + "dev": true, + "optional": true + }, "@nrwl/tao": { - "version": "14.7.5", - "resolved": "https://registry.npmmirror.com/@nrwl/tao/-/tao-14.7.5.tgz", - "integrity": "sha512-MzfJMqVbiMitYjWXaL5/7dDKw1hDG7acciGeu5SyUX8J2J0ymKzXhqjshPvn/Ga1E9QtnMckd6aKmLlvochVag==", + "version": "15.7.2", + "resolved": "https://registry.npmmirror.com/@nrwl/tao/-/tao-15.7.2.tgz", + "integrity": "sha512-srx9heMIt/QIyuqfewiVYbRpFcD/2pHkTkrEEUKspPd25kzAL2adcAITQKVCHI7/VS2sPdDR67pVsGQPZFBMRQ==", "dev": true, "requires": { - "nx": "14.7.5" + "nx": "15.7.2" } }, "@octokit/auth-token": { - "version": "3.0.1", - "resolved": "https://registry.npmmirror.com/@octokit/auth-token/-/auth-token-3.0.1.tgz", - "integrity": "sha512-/USkK4cioY209wXRpund6HZzHo9GmjakpV9ycOkpMcMxMk7QVcVFVyCMtzvXYiHsB2crgDgrtNYSELYFBXhhaA==", + "version": "3.0.3", + "resolved": "https://registry.npmmirror.com/@octokit/auth-token/-/auth-token-3.0.3.tgz", + "integrity": "sha512-/aFM2M4HVDBT/jjDBa84sJniv1t9Gm/rLkalaz9htOm+L+8JMj1k9w0CkUdcxNyNxZPlTxKPVko+m1VlM58ZVA==", "dev": true, "requires": { - "@octokit/types": "^7.0.0" + "@octokit/types": "^9.0.0" } }, "@octokit/core": { - "version": "4.0.5", - "resolved": "https://registry.npmmirror.com/@octokit/core/-/core-4.0.5.tgz", - "integrity": "sha512-4R3HeHTYVHCfzSAi0C6pbGXV8UDI5Rk+k3G7kLVNckswN9mvpOzW9oENfjfH3nEmzg8y3AmKmzs8Sg6pLCeOCA==", + "version": "4.2.0", + "resolved": "https://registry.npmmirror.com/@octokit/core/-/core-4.2.0.tgz", + "integrity": "sha512-AgvDRUg3COpR82P7PBdGZF/NNqGmtMq2NiPqeSsDIeCfYFOZ9gddqWNQHnFdEUf+YwOj4aZYmJnlPp7OXmDIDg==", "dev": true, "requires": { "@octokit/auth-token": "^3.0.0", "@octokit/graphql": "^5.0.0", "@octokit/request": "^6.0.0", "@octokit/request-error": "^3.0.0", - "@octokit/types": "^7.0.0", + "@octokit/types": "^9.0.0", "before-after-hook": "^2.2.0", "universal-user-agent": "^6.0.0" } }, "@octokit/endpoint": { - "version": "7.0.2", - "resolved": "https://registry.npmmirror.com/@octokit/endpoint/-/endpoint-7.0.2.tgz", - "integrity": "sha512-8/AUACfE9vpRpehE6ZLfEtzkibe5nfsSwFZVMsG8qabqRt1M81qZYUFRZa1B8w8lP6cdfDJfRq9HWS+MbmR7tw==", + "version": "7.0.5", + "resolved": "https://registry.npmmirror.com/@octokit/endpoint/-/endpoint-7.0.5.tgz", + "integrity": "sha512-LG4o4HMY1Xoaec87IqQ41TQ+glvIeTKqfjkCEmt5AIwDZJwQeVZFIEYXrYY6yLwK+pAScb9Gj4q+Nz2qSw1roA==", "dev": true, "requires": { - "@octokit/types": "^7.0.0", + "@octokit/types": "^9.0.0", "is-plain-object": "^5.0.0", "universal-user-agent": "^6.0.0" }, @@ -2058,20 +2142,20 @@ } }, "@octokit/graphql": { - "version": "5.0.1", - "resolved": "https://registry.npmmirror.com/@octokit/graphql/-/graphql-5.0.1.tgz", - "integrity": "sha512-sxmnewSwAixkP1TrLdE6yRG53eEhHhDTYUykUwdV9x8f91WcbhunIHk9x1PZLALdBZKRPUO2HRcm4kezZ79HoA==", + "version": "5.0.5", + "resolved": "https://registry.npmmirror.com/@octokit/graphql/-/graphql-5.0.5.tgz", + "integrity": "sha512-Qwfvh3xdqKtIznjX9lz2D458r7dJPP8l6r4GQkIdWQouZwHQK0mVT88uwiU2bdTU2OtT1uOlKpRciUWldpG0yQ==", "dev": true, "requires": { "@octokit/request": "^6.0.0", - "@octokit/types": "^7.0.0", + "@octokit/types": "^9.0.0", "universal-user-agent": "^6.0.0" } }, "@octokit/openapi-types": { - "version": "13.10.0", - "resolved": "https://registry.npmmirror.com/@octokit/openapi-types/-/openapi-types-13.10.0.tgz", - "integrity": "sha512-wPQDpTyy35D6VS/lekXDaKcxy6LI2hzcbmXBnP180Pdgz3dXRzoHdav0w09yZzzWX8HHLGuqwAeyMqEPtWY2XA==", + "version": "16.0.0", + "resolved": "https://registry.npmmirror.com/@octokit/openapi-types/-/openapi-types-16.0.0.tgz", + "integrity": "sha512-JbFWOqTJVLHZSUUoF4FzAZKYtqdxWu9Z5m2QQnOyEa04fOFljvyh7D3GYKbfuaSWisqehImiVIMG4eyJeP5VEA==", "dev": true }, "@octokit/plugin-enterprise-rest": { @@ -2081,12 +2165,12 @@ "dev": true }, "@octokit/plugin-paginate-rest": { - "version": "4.3.0", - "resolved": "https://registry.npmmirror.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-4.3.0.tgz", - "integrity": "sha512-4V8hWMoXuxb03xPs3s3RjUb5Bzx4HmVRhG+gvbO08PB48ag6G8mk6/HDFKlAXz9XEorDIkc0pXcXnaOz8spHgg==", + "version": "6.0.0", + "resolved": "https://registry.npmmirror.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.0.0.tgz", + "integrity": "sha512-Sq5VU1PfT6/JyuXPyt04KZNVsFOSBaYOAq2QRZUwzVlI10KFvcbUo8lR258AAQL1Et60b0WuVik+zOWKLuDZxw==", "dev": true, "requires": { - "@octokit/types": "^7.4.0" + "@octokit/types": "^9.0.0" } }, "@octokit/plugin-request-log": { @@ -2096,24 +2180,24 @@ "dev": true }, "@octokit/plugin-rest-endpoint-methods": { - "version": "6.6.0", - "resolved": "https://registry.npmmirror.com/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-6.6.0.tgz", - "integrity": "sha512-IAuT/e1gIUVszNmV+vfXNxa6xXI9dlghhBDqLGEmjz3so9sHqOlXN4R5gWcCRJkt4mum4NCaNjUk17yTrK76Rw==", + "version": "7.0.1", + "resolved": "https://registry.npmmirror.com/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-7.0.1.tgz", + "integrity": "sha512-pnCaLwZBudK5xCdrR823xHGNgqOzRnJ/mpC/76YPpNP7DybdsJtP7mdOwh+wYZxK5jqeQuhu59ogMI4NRlBUvA==", "dev": true, "requires": { - "@octokit/types": "^7.4.0", + "@octokit/types": "^9.0.0", "deprecation": "^2.3.1" } }, "@octokit/request": { - "version": "6.2.1", - "resolved": "https://registry.npmmirror.com/@octokit/request/-/request-6.2.1.tgz", - "integrity": "sha512-gYKRCia3cpajRzDSU+3pt1q2OcuC6PK8PmFIyxZDWCzRXRSIBH8jXjFJ8ZceoygBIm0KsEUg4x1+XcYBz7dHPQ==", + "version": "6.2.3", + "resolved": "https://registry.npmmirror.com/@octokit/request/-/request-6.2.3.tgz", + "integrity": "sha512-TNAodj5yNzrrZ/VxP+H5HiYaZep0H3GU0O7PaF+fhDrt8FPrnkei9Aal/txsN/1P7V3CPiThG0tIvpPDYUsyAA==", "dev": true, "requires": { "@octokit/endpoint": "^7.0.0", "@octokit/request-error": "^3.0.0", - "@octokit/types": "^7.0.0", + "@octokit/types": "^9.0.0", "is-plain-object": "^5.0.0", "node-fetch": "^2.6.7", "universal-user-agent": "^6.0.0" @@ -2128,35 +2212,35 @@ } }, "@octokit/request-error": { - "version": "3.0.1", - "resolved": "https://registry.npmmirror.com/@octokit/request-error/-/request-error-3.0.1.tgz", - "integrity": "sha512-ym4Bp0HTP7F3VFssV88WD1ZyCIRoE8H35pXSKwLeMizcdZAYc/t6N9X9Yr9n6t3aG9IH75XDnZ6UeZph0vHMWQ==", + "version": "3.0.3", + "resolved": "https://registry.npmmirror.com/@octokit/request-error/-/request-error-3.0.3.tgz", + "integrity": "sha512-crqw3V5Iy2uOU5Np+8M/YexTlT8zxCfI+qu+LxUB7SZpje4Qmx3mub5DfEKSO8Ylyk0aogi6TYdf6kxzh2BguQ==", "dev": true, "requires": { - "@octokit/types": "^7.0.0", + "@octokit/types": "^9.0.0", "deprecation": "^2.0.0", "once": "^1.4.0" } }, "@octokit/rest": { - "version": "19.0.4", - "resolved": "https://registry.npmmirror.com/@octokit/rest/-/rest-19.0.4.tgz", - "integrity": "sha512-LwG668+6lE8zlSYOfwPj4FxWdv/qFXYBpv79TWIQEpBLKA9D/IMcWsF/U9RGpA3YqMVDiTxpgVpEW3zTFfPFTA==", + "version": "19.0.7", + "resolved": "https://registry.npmmirror.com/@octokit/rest/-/rest-19.0.7.tgz", + "integrity": "sha512-HRtSfjrWmWVNp2uAkEpQnuGMJsu/+dBr47dRc5QVgsCbnIc1+GFEaoKBWkYG+zjrsHpSqcAElMio+n10c0b5JA==", "dev": true, "requires": { - "@octokit/core": "^4.0.0", - "@octokit/plugin-paginate-rest": "^4.0.0", + "@octokit/core": "^4.1.0", + "@octokit/plugin-paginate-rest": "^6.0.0", "@octokit/plugin-request-log": "^1.0.4", - "@octokit/plugin-rest-endpoint-methods": "^6.0.0" + "@octokit/plugin-rest-endpoint-methods": "^7.0.0" } }, "@octokit/types": { - "version": "7.4.0", - "resolved": "https://registry.npmmirror.com/@octokit/types/-/types-7.4.0.tgz", - "integrity": "sha512-ln1GW0p72+P8qeRjHGj0wyR5ePy6slqvczveOqonMk1w1UWua6UgrkwFzv6S0vKWjSqt/ijYXF1ehNVRRRSvLA==", + "version": "9.0.0", + "resolved": "https://registry.npmmirror.com/@octokit/types/-/types-9.0.0.tgz", + "integrity": "sha512-LUewfj94xCMH2rbD5YJ+6AQ4AVjFYTgpp6rboWM5T7N3IsIF65SBEOVcYMGAEzO/kKNiNaW4LoWtoThOhH06gw==", "dev": true, "requires": { - "@octokit/openapi-types": "^13.10.0" + "@octokit/openapi-types": "^16.0.0" } }, "@parcel/watcher": { @@ -2181,12 +2265,6 @@ "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", "dev": true }, - "@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmmirror.com/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true - }, "@types/minimatch": { "version": "3.0.5", "resolved": "https://registry.npmmirror.com/@types/minimatch/-/minimatch-3.0.5.tgz", @@ -2295,6 +2373,22 @@ "eslint-visitor-keys": "^2.0.0" } }, + "@yarnpkg/lockfile": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", + "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", + "dev": true + }, + "@yarnpkg/parsers": { + "version": "3.0.0-rc.39", + "resolved": "https://registry.npmmirror.com/@yarnpkg/parsers/-/parsers-3.0.0-rc.39.tgz", + "integrity": "sha512-BsD4zq3EVmaHqlynXTceNuEFAtrfToV4fI9GA54moKlWZL4Eb2eXrhgf1jV2nMYx18SZxYO4Jc5Kf1sCDNRjOg==", + "dev": true, + "requires": { + "js-yaml": "^3.10.0", + "tslib": "^2.4.0" + } + }, "JSONStream": { "version": "1.3.5", "resolved": "https://registry.npmmirror.com/JSONStream/-/JSONStream-1.3.5.tgz", @@ -2409,16 +2503,6 @@ "color-convert": "^2.0.1" } }, - "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, "aproba": { "version": "2.0.0", "resolved": "https://registry.npmmirror.com/aproba/-/aproba-2.0.0.tgz", @@ -2473,15 +2557,15 @@ "dev": true }, "array-includes": { - "version": "3.1.5", - "resolved": "https://registry.npmmirror.com/array-includes/-/array-includes-3.1.5.tgz", - "integrity": "sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==", + "version": "3.1.6", + "resolved": "https://registry.npmmirror.com/array-includes/-/array-includes-3.1.6.tgz", + "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", "dev": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", - "es-abstract": "^1.19.5", - "get-intrinsic": "^1.1.1", + "es-abstract": "^1.20.4", + "get-intrinsic": "^1.1.3", "is-string": "^1.0.7" } }, @@ -2492,14 +2576,14 @@ "dev": true }, "array.prototype.flatmap": { - "version": "1.3.0", - "resolved": "https://registry.npmmirror.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.0.tgz", - "integrity": "sha512-PZC9/8TKAIxcWKdyeb77EzULHPrIX/tIZebLJUQOMR1OwYosT8yggdfWScfTBCDj5utONvOuPQQumYsU2ULbkg==", + "version": "1.3.1", + "resolved": "https://registry.npmmirror.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", + "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", "es-shim-unscopables": "^1.0.0" } }, @@ -2527,18 +2611,41 @@ "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true + }, "at-least-node": { "version": "1.0.0", "resolved": "https://registry.npmmirror.com/at-least-node/-/at-least-node-1.0.0.tgz", "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", "dev": true }, - "axe-core": { - "version": "4.4.3", - "resolved": "https://registry.npmmirror.com/axe-core/-/axe-core-4.4.3.tgz", - "integrity": "sha512-32+ub6kkdhhWick/UjvEwRchgoetXqTK14INLqbGm5U2TzBkBNF3nQtLYm8ovxSkQWArjEQvftCKryjZaATu3w==", + "available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", "dev": true }, + "axe-core": { + "version": "4.6.3", + "resolved": "https://registry.npmmirror.com/axe-core/-/axe-core-4.6.3.tgz", + "integrity": "sha512-/BQzOX780JhsxDnPpH4ZiyrJAzcd8AfzFPkv+89veFSr1rcMjuq2JDCwypKaPeB6ljHp9KjXhPpjgCvQlWYuqg==", + "dev": true + }, + "axios": { + "version": "1.3.4", + "resolved": "https://registry.npmmirror.com/axios/-/axios-1.3.4.tgz", + "integrity": "sha512-toYm+Bsyl6VC5wSkfkbbNB6ROv7KY93PEBBL6xyDczaIHasAiv4wPqQ/c4RjoQzipxRD2W5g21cOqQulZ7rHwQ==", + "dev": true, + "requires": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "axobject-query": { "version": "2.2.0", "resolved": "https://registry.npmmirror.com/axobject-query/-/axobject-query-2.2.0.tgz", @@ -2580,9 +2687,9 @@ "dev": true }, "before-after-hook": { - "version": "2.2.2", - "resolved": "https://registry.npmmirror.com/before-after-hook/-/before-after-hook-2.2.2.tgz", - "integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ==", + "version": "2.2.3", + "resolved": "https://registry.npmmirror.com/before-after-hook/-/before-after-hook-2.2.3.tgz", + "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", "dev": true }, "bin-links": { @@ -2617,12 +2724,6 @@ } } }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true - }, "bl": { "version": "4.1.0", "resolved": "https://registry.npmmirror.com/bl/-/bl-4.1.0.tgz", @@ -2717,9 +2818,9 @@ } }, "glob": { - "version": "8.0.3", - "resolved": "https://registry.npmmirror.com/glob/-/glob-8.0.3.tgz", - "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", + "version": "8.1.0", + "resolved": "https://registry.npmmirror.com/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -2730,15 +2831,15 @@ } }, "lru-cache": { - "version": "7.14.0", - "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-7.14.0.tgz", - "integrity": "sha512-EIRtP1GrSJny0dqb50QXRUNBxHJhcpxHC++M5tD7RYbvLLn5KVWKsbyswSSqDuU15UFi3bgTQIY8nhDMeF6aDQ==", + "version": "7.17.0", + "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-7.17.0.tgz", + "integrity": "sha512-zSxlVVwOabhVyTi6E8gYv2cr6bXK+8ifYz5/uyJb9feXX6NACVDwY4p5Ut3WC3Ivo/QhpARHU3iujx2xGAYHbQ==", "dev": true }, "minimatch": { - "version": "5.1.0", - "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-5.1.0.tgz", - "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", + "version": "5.1.6", + "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, "requires": { "brace-expansion": "^2.0.1" @@ -2801,22 +2902,6 @@ "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "dev": true }, - "chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - } - }, "chownr": { "version": "2.0.0", "resolved": "https://registry.npmmirror.com/chownr/-/chownr-2.0.0.tgz", @@ -2880,13 +2965,13 @@ "dev": true }, "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmmirror.com/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "version": "8.0.1", + "resolved": "https://registry.npmmirror.com/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, "requires": { "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", + "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, @@ -2953,6 +3038,15 @@ "wcwidth": "^1.0.0" } }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, "commander": { "version": "6.2.1", "resolved": "https://registry.npmmirror.com/commander/-/commander-6.2.1.tgz", @@ -2960,9 +3054,9 @@ "dev": true }, "commitizen": { - "version": "4.2.5", - "resolved": "https://registry.npmmirror.com/commitizen/-/commitizen-4.2.5.tgz", - "integrity": "sha512-9sXju8Qrz1B4Tw7kC5KhnvwYQN88qs2zbiB8oyMsnXZyJ24PPGiNM3nHr73d32dnE3i8VJEXddBFIbOgYSEXtQ==", + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/commitizen/-/commitizen-4.3.0.tgz", + "integrity": "sha512-H0iNtClNEhT0fotHvGV3E9tDejDeS04sN1veIebsKYGMuGscFaswRoYJKmT3eW85eIJAs0F28bG2+a/9wCOfPw==", "dev": true, "requires": { "cachedir": "2.3.0", @@ -2973,10 +3067,10 @@ "find-root": "1.1.0", "fs-extra": "9.1.0", "glob": "7.2.3", - "inquirer": "8.2.4", + "inquirer": "8.2.5", "is-utf8": "^0.2.1", "lodash": "4.17.21", - "minimist": "1.2.6", + "minimist": "1.2.7", "strip-bom": "4.0.0", "strip-json-comments": "3.1.1" }, @@ -3381,9 +3475,9 @@ } }, "core-js-pure": { - "version": "3.25.1", - "resolved": "https://registry.npmmirror.com/core-js-pure/-/core-js-pure-3.25.1.tgz", - "integrity": "sha512-7Fr74bliUDdeJCBMxkkIuQ4xfxn/SwrVg+HkJUAoNEXVqYLv55l6Af0dJ5Lq2YBUW9yKqSkLXaS5SYPK6MGa/A==", + "version": "3.28.0", + "resolved": "https://registry.npmmirror.com/core-js-pure/-/core-js-pure-3.28.0.tgz", + "integrity": "sha512-DSOVleA9/v3LNj/vFxAPfUHttKTzrB2RXhAPvR5TPXn4vrra3Z2ssytvRyt8eruJwAfwAiFADEbrjcRdcvPLQQ==", "dev": true }, "core-util-is": { @@ -3393,9 +3487,9 @@ "dev": true }, "cosmiconfig": { - "version": "7.0.1", - "resolved": "https://registry.npmmirror.com/cosmiconfig/-/cosmiconfig-7.0.1.tgz", - "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", + "version": "7.1.0", + "resolved": "https://registry.npmmirror.com/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", "dev": true, "requires": { "@types/parse-json": "^4.0.0", @@ -3597,9 +3691,9 @@ "dev": true }, "decamelize-keys": { - "version": "1.1.0", - "resolved": "https://registry.npmmirror.com/decamelize-keys/-/decamelize-keys-1.1.0.tgz", - "integrity": "sha512-ocLWuYzRPoS9bfiSdDd3cxvrzovVMZnRDVEzAs+hWIVXGDbHxWMECij2OBuyB/An0FFW/nLuq6Kv1i/YC5Qfzg==", + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/decamelize-keys/-/decamelize-keys-1.1.1.tgz", + "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", "dev": true, "requires": { "decamelize": "^1.1.0", @@ -3627,9 +3721,9 @@ "dev": true }, "defaults": { - "version": "1.0.3", - "resolved": "https://registry.npmmirror.com/defaults/-/defaults-1.0.3.tgz", - "integrity": "sha512-s82itHOnYrN0Ib8r+z7laQz3sdE+4FP3d9Q7VLO7U+KRT+CR0GsWuyHxzdAY82I7cXv0G/twrqomTJLOssO5HA==", + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", "dev": true, "requires": { "clone": "^1.0.2" @@ -3642,15 +3736,21 @@ "dev": true }, "define-properties": { - "version": "1.1.4", - "resolved": "https://registry.npmmirror.com/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/define-properties/-/define-properties-1.2.0.tgz", + "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", "dev": true, "requires": { "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" } }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true + }, "delegates": { "version": "1.0.0", "resolved": "https://registry.npmmirror.com/delegates/-/delegates-1.0.0.tgz", @@ -3810,34 +3910,55 @@ } }, "es-abstract": { - "version": "1.20.2", - "resolved": "https://registry.npmmirror.com/es-abstract/-/es-abstract-1.20.2.tgz", - "integrity": "sha512-XxXQuVNrySBNlEkTYJoDNFe5+s2yIOpzq80sUHEdPdQr0S5nTLz4ZPPPswNIpKseDDUS5yghX1gfLIHQZ1iNuQ==", + "version": "1.21.1", + "resolved": "https://registry.npmmirror.com/es-abstract/-/es-abstract-1.21.1.tgz", + "integrity": "sha512-QudMsPOz86xYz/1dG1OuGBKOELjCh99IIWHLzy5znUB6j8xG2yMA7bfTV86VSqKF+Y/H08vQPR+9jyXpuC6hfg==", "dev": true, "requires": { + "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", + "es-set-tostringtag": "^2.0.1", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.1.2", + "get-intrinsic": "^1.1.3", "get-symbol-description": "^1.0.0", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", "has": "^1.0.3", "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", "has-symbols": "^1.0.3", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", + "internal-slot": "^1.0.4", + "is-array-buffer": "^3.0.1", + "is-callable": "^1.2.7", "is-negative-zero": "^2.0.2", "is-regex": "^1.1.4", "is-shared-array-buffer": "^1.0.2", "is-string": "^1.0.7", + "is-typed-array": "^1.1.10", "is-weakref": "^1.0.2", "object-inspect": "^1.12.2", "object-keys": "^1.1.1", "object.assign": "^4.1.4", "regexp.prototype.flags": "^1.4.3", - "string.prototype.trimend": "^1.0.5", - "string.prototype.trimstart": "^1.0.5", - "unbox-primitive": "^1.0.2" + "safe-regex-test": "^1.0.0", + "string.prototype.trimend": "^1.0.6", + "string.prototype.trimstart": "^1.0.6", + "typed-array-length": "^1.0.4", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.9" + } + }, + "es-set-tostringtag": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", + "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.3", + "has": "^1.0.3", + "has-tostringtag": "^1.0.0" } }, "es-shim-unscopables": { @@ -3936,9 +4057,9 @@ "dev": true }, "globals": { - "version": "13.17.0", - "resolved": "https://registry.npmmirror.com/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "version": "13.20.0", + "resolved": "https://registry.npmmirror.com/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -4095,9 +4216,9 @@ "dev": true }, "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmmirror.com/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "version": "1.4.2", + "resolved": "https://registry.npmmirror.com/esquery/-/esquery-1.4.2.tgz", + "integrity": "sha512-JVSoLdTlTDkmjFmab7H/9SL9qGSyjElT3myyKp7krqjVFQCDLmj1QFaCLRFBszBKI0XVZaiiXvuPIX3ZwHe1Ng==", "dev": true, "requires": { "estraverse": "^5.1.0" @@ -4221,9 +4342,9 @@ "dev": true }, "fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmmirror.com/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "version": "1.15.0", + "resolved": "https://registry.npmmirror.com/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", "dev": true, "requires": { "reusify": "^1.0.4" @@ -4325,6 +4446,32 @@ "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, + "follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "dev": true + }, + "for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmmirror.com/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "requires": { + "is-callable": "^1.1.3" + } + }, + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, "fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmmirror.com/fs-constants/-/fs-constants-1.0.0.tgz", @@ -4357,13 +4504,6 @@ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.1.tgz", @@ -4417,9 +4557,9 @@ "dev": true }, "get-intrinsic": { - "version": "1.1.3", - "resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.1.3.tgz", - "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.2.0.tgz", + "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", "dev": true, "requires": { "function-bind": "^1.1.1", @@ -4445,6 +4585,17 @@ "yargs": "^16.2.0" }, "dependencies": { + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmmirror.com/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, "readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-2.3.7.tgz", @@ -4666,6 +4817,15 @@ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true }, + "globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3" + } + }, "globby": { "version": "11.1.0", "resolved": "https://registry.npmmirror.com/globby/-/globby-11.1.0.tgz", @@ -4680,6 +4840,15 @@ "slash": "^3.0.0" } }, + "gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.3" + } + }, "graceful-fs": { "version": "4.2.10", "resolved": "https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.10.tgz", @@ -4735,6 +4904,12 @@ "get-intrinsic": "^1.1.1" } }, + "has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "dev": true + }, "has-symbols": { "version": "1.0.3", "resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.0.3.tgz", @@ -4775,9 +4950,9 @@ } }, "http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmmirror.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "version": "4.1.1", + "resolved": "https://registry.npmmirror.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", "dev": true }, "http-proxy-agent": { @@ -4850,9 +5025,9 @@ "dev": true }, "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmmirror.com/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "version": "5.2.4", + "resolved": "https://registry.npmmirror.com/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", "dev": true }, "ignore-walk": { @@ -4874,9 +5049,9 @@ } }, "minimatch": { - "version": "5.1.0", - "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-5.1.0.tgz", - "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", + "version": "5.1.6", + "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, "requires": { "brace-expansion": "^2.0.1" @@ -4988,24 +5163,24 @@ } }, "hosted-git-info": { - "version": "5.1.0", - "resolved": "https://registry.npmmirror.com/hosted-git-info/-/hosted-git-info-5.1.0.tgz", - "integrity": "sha512-Ek+QmMEqZF8XrbFdwoDjSbm7rT23pCgEMOJmz6GPk/s4yH//RQfNPArhIxbguNxROq/+5lNBwCDHMhA903Kx1Q==", + "version": "5.2.1", + "resolved": "https://registry.npmmirror.com/hosted-git-info/-/hosted-git-info-5.2.1.tgz", + "integrity": "sha512-xIcQYMnhcx2Nr4JTjsFmwwnr9vldugPy9uVm0o87bjqqWMv9GaqsTeT+i99wTl0mk1uLxJtHxLb8kymqTENQsw==", "dev": true, "requires": { "lru-cache": "^7.5.1" } }, "lru-cache": { - "version": "7.14.0", - "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-7.14.0.tgz", - "integrity": "sha512-EIRtP1GrSJny0dqb50QXRUNBxHJhcpxHC++M5tD7RYbvLLn5KVWKsbyswSSqDuU15UFi3bgTQIY8nhDMeF6aDQ==", + "version": "7.17.0", + "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-7.17.0.tgz", + "integrity": "sha512-zSxlVVwOabhVyTi6E8gYv2cr6bXK+8ifYz5/uyJb9feXX6NACVDwY4p5Ut3WC3Ivo/QhpARHU3iujx2xGAYHbQ==", "dev": true }, "npm-package-arg": { - "version": "9.1.0", - "resolved": "https://registry.npmmirror.com/npm-package-arg/-/npm-package-arg-9.1.0.tgz", - "integrity": "sha512-4J0GL+u2Nh6OnhvUKXRr2ZMG4lR8qtLp+kv7UiV00Y+nGiSxtttCyIRHCt5L5BNkXQld/RceYItau3MDOoGiBw==", + "version": "9.1.2", + "resolved": "https://registry.npmmirror.com/npm-package-arg/-/npm-package-arg-9.1.2.tgz", + "integrity": "sha512-pzd9rLEx4TfNJkovvlBSLGhq31gGu2QDexFPWT19yCDh0JgnRhlBLNo5759N0AJmBk+kQ9Y/hXoLnlgFD+ukmg==", "dev": true, "requires": { "hosted-git-info": "^5.0.0", @@ -5026,9 +5201,9 @@ } }, "inquirer": { - "version": "8.2.4", - "resolved": "https://registry.npmmirror.com/inquirer/-/inquirer-8.2.4.tgz", - "integrity": "sha512-nn4F01dxU8VeKfq192IjLsxu0/OmMZ4Lg3xKAns148rCaXP6ntAoEkVYZThWjwON8AlzdZZi6oqnhNbxUG9hVg==", + "version": "8.2.5", + "resolved": "https://registry.npmmirror.com/inquirer/-/inquirer-8.2.5.tgz", + "integrity": "sha512-QAgPDQMEgrDssk1XiwwHoOGYF9BAbUcc1+j+FhEvaOt8/cKRqyLn0U5qA6F74fGhTMGxf92pOvPBeh29jQJDTQ==", "dev": true, "requires": { "ansi-escapes": "^4.2.1", @@ -5049,12 +5224,12 @@ } }, "internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmmirror.com/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/internal-slot/-/internal-slot-1.0.5.tgz", + "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", "dev": true, "requires": { - "get-intrinsic": "^1.1.0", + "get-intrinsic": "^1.2.0", "has": "^1.0.3", "side-channel": "^1.0.4" } @@ -5065,6 +5240,17 @@ "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==", "dev": true }, + "is-array-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/is-array-buffer/-/is-array-buffer-3.0.1.tgz", + "integrity": "sha512-ASfLknmY8Xa2XtB4wmbz13Wu202baeA18cJBCeCy0wXUHZF0IPyVEXqKEcd+t2fNSLLL1vC6k7lxZEojNbISXQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-typed-array": "^1.1.10" + } + }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmmirror.com/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -5080,15 +5266,6 @@ "has-bigints": "^1.0.1" } }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmmirror.com/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, "is-boolean-object": { "version": "1.1.2", "resolved": "https://registry.npmmirror.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz", @@ -5100,9 +5277,9 @@ } }, "is-callable": { - "version": "1.2.6", - "resolved": "https://registry.npmmirror.com/is-callable/-/is-callable-1.2.6.tgz", - "integrity": "sha512-krO72EO2NptOGAX2KYyqbP9vYMlNAXdB53rq6f8LXY6RY7JdSR/3BD6wLUlPHSAesmY9vstNrjvqGaCiRK/91Q==", + "version": "1.2.7", + "resolved": "https://registry.npmmirror.com/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "dev": true }, "is-ci": { @@ -5115,9 +5292,9 @@ } }, "is-core-module": { - "version": "2.10.0", - "resolved": "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.10.0.tgz", - "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", + "version": "2.11.0", + "resolved": "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", "dev": true, "requires": { "has": "^1.0.3" @@ -5280,6 +5457,19 @@ "text-extensions": "^1.0.0" } }, + "is-typed-array": { + "version": "1.1.10", + "resolved": "https://registry.npmmirror.com/is-typed-array/-/is-typed-array-1.1.10.tgz", + "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", + "dev": true, + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + } + }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmmirror.com/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -5399,18 +5589,15 @@ "dev": true }, "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmmirror.com/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } + "version": "2.2.3", + "resolved": "https://registry.npmmirror.com/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true }, "jsonc-parser": { - "version": "3.0.0", - "resolved": "https://registry.npmmirror.com/jsonc-parser/-/jsonc-parser-3.0.0.tgz", - "integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==", + "version": "3.2.0", + "resolved": "https://registry.npmmirror.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", "dev": true }, "jsonfile": { @@ -5440,15 +5627,15 @@ } }, "just-diff": { - "version": "5.1.1", - "resolved": "https://registry.npmmirror.com/just-diff/-/just-diff-5.1.1.tgz", - "integrity": "sha512-u8HXJ3HlNrTzY7zrYYKjNEfBlyjqhdBkoyTVdjtn7p02RJD5NvR8rIClzeGA7t+UYP1/7eAkWNLU0+P3QrEqKQ==", + "version": "5.2.0", + "resolved": "https://registry.npmmirror.com/just-diff/-/just-diff-5.2.0.tgz", + "integrity": "sha512-6ufhP9SHjb7jibNFrNxyFZ6od3g+An6Ai9mhGRvcYe8UJlH0prseN64M+6ZBBUoKYHZsitDP42gAJ8+eVWr3lw==", "dev": true }, "just-diff-apply": { - "version": "5.4.1", - "resolved": "https://registry.npmmirror.com/just-diff-apply/-/just-diff-apply-5.4.1.tgz", - "integrity": "sha512-AAV5Jw7tsniWwih8Ly3fXxEZ06y+6p5TwQMsw0dzZ/wPKilzyDgdAnL0Ug4NNIquPUOh1vfFWEHbmXUqM5+o8g==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/just-diff-apply/-/just-diff-apply-5.5.0.tgz", + "integrity": "sha512-OYTthRfSh55WOItVqwpefPtNt2VdKsq5AnAK6apdtR6yCH8pr0CmSr710J0Mf+WdQy7K/OzMy7K2MgAfdQURDw==", "dev": true }, "kind-of": { @@ -5464,36 +5651,36 @@ "dev": true }, "language-tags": { - "version": "1.0.5", - "resolved": "https://registry.npmmirror.com/language-tags/-/language-tags-1.0.5.tgz", - "integrity": "sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ==", + "version": "1.0.8", + "resolved": "https://registry.npmmirror.com/language-tags/-/language-tags-1.0.8.tgz", + "integrity": "sha512-aWAZwgPLS8hJ20lNPm9HNVs4inexz6S2sQa3wx/+ycuutMNE5/IfYxiWYBbi+9UWCQVaXYCOPUl6gFrPR7+jGg==", "dev": true, "requires": { - "language-subtag-registry": "~0.3.2" + "language-subtag-registry": "^0.3.20" } }, "lerna": { - "version": "5.5.1", - "resolved": "https://registry.npmmirror.com/lerna/-/lerna-5.5.1.tgz", - "integrity": "sha512-Ofvlm5FRRxF8IQXnx47YbIXmRDHnDaegDwJ4Kq+cVnafbB0VZvRVy/S4ppmnftnqvd4MBXU022lhW9uGN66iZw==", + "version": "5.5.0", + "resolved": "https://registry.npmmirror.com/lerna/-/lerna-5.5.0.tgz", + "integrity": "sha512-1cZIijUWcI9ZqK+ejj1dBejTOLL64b0pIjYXb9KN8soNIONm/1zbJiSBiAyF4Hd6x4XuIC3kdFx7Ff3Pb9KsYA==", "dev": true, "requires": { - "@lerna/add": "5.5.1", - "@lerna/bootstrap": "5.5.1", - "@lerna/changed": "5.5.1", - "@lerna/clean": "5.5.1", - "@lerna/cli": "5.5.1", - "@lerna/create": "5.5.1", - "@lerna/diff": "5.5.1", - "@lerna/exec": "5.5.1", - "@lerna/import": "5.5.1", - "@lerna/info": "5.5.1", - "@lerna/init": "5.5.1", - "@lerna/link": "5.5.1", - "@lerna/list": "5.5.1", - "@lerna/publish": "5.5.1", - "@lerna/run": "5.5.1", - "@lerna/version": "5.5.1", + "@lerna/add": "5.5.0", + "@lerna/bootstrap": "5.5.0", + "@lerna/changed": "5.5.0", + "@lerna/clean": "5.5.0", + "@lerna/cli": "5.5.0", + "@lerna/create": "5.5.0", + "@lerna/diff": "5.5.0", + "@lerna/exec": "5.5.0", + "@lerna/import": "5.5.0", + "@lerna/info": "5.5.0", + "@lerna/init": "5.5.0", + "@lerna/link": "5.5.0", + "@lerna/list": "5.5.0", + "@lerna/publish": "5.5.0", + "@lerna/run": "5.5.0", + "@lerna/version": "5.5.0", "import-local": "^3.0.2", "npmlog": "^6.0.2", "nx": ">=14.6.1 < 16", @@ -5532,24 +5719,24 @@ } }, "hosted-git-info": { - "version": "5.1.0", - "resolved": "https://registry.npmmirror.com/hosted-git-info/-/hosted-git-info-5.1.0.tgz", - "integrity": "sha512-Ek+QmMEqZF8XrbFdwoDjSbm7rT23pCgEMOJmz6GPk/s4yH//RQfNPArhIxbguNxROq/+5lNBwCDHMhA903Kx1Q==", + "version": "5.2.1", + "resolved": "https://registry.npmmirror.com/hosted-git-info/-/hosted-git-info-5.2.1.tgz", + "integrity": "sha512-xIcQYMnhcx2Nr4JTjsFmwwnr9vldugPy9uVm0o87bjqqWMv9GaqsTeT+i99wTl0mk1uLxJtHxLb8kymqTENQsw==", "dev": true, "requires": { "lru-cache": "^7.5.1" } }, "lru-cache": { - "version": "7.14.0", - "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-7.14.0.tgz", - "integrity": "sha512-EIRtP1GrSJny0dqb50QXRUNBxHJhcpxHC++M5tD7RYbvLLn5KVWKsbyswSSqDuU15UFi3bgTQIY8nhDMeF6aDQ==", + "version": "7.17.0", + "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-7.17.0.tgz", + "integrity": "sha512-zSxlVVwOabhVyTi6E8gYv2cr6bXK+8ifYz5/uyJb9feXX6NACVDwY4p5Ut3WC3Ivo/QhpARHU3iujx2xGAYHbQ==", "dev": true }, "npm-package-arg": { - "version": "9.1.0", - "resolved": "https://registry.npmmirror.com/npm-package-arg/-/npm-package-arg-9.1.0.tgz", - "integrity": "sha512-4J0GL+u2Nh6OnhvUKXRr2ZMG4lR8qtLp+kv7UiV00Y+nGiSxtttCyIRHCt5L5BNkXQld/RceYItau3MDOoGiBw==", + "version": "9.1.2", + "resolved": "https://registry.npmmirror.com/npm-package-arg/-/npm-package-arg-9.1.2.tgz", + "integrity": "sha512-pzd9rLEx4TfNJkovvlBSLGhq31gGu2QDexFPWT19yCDh0JgnRhlBLNo5759N0AJmBk+kQ9Y/hXoLnlgFD+ukmg==", "dev": true, "requires": { "hosted-git-info": "^5.0.0", @@ -5592,18 +5779,18 @@ } }, "hosted-git-info": { - "version": "5.1.0", - "resolved": "https://registry.npmmirror.com/hosted-git-info/-/hosted-git-info-5.1.0.tgz", - "integrity": "sha512-Ek+QmMEqZF8XrbFdwoDjSbm7rT23pCgEMOJmz6GPk/s4yH//RQfNPArhIxbguNxROq/+5lNBwCDHMhA903Kx1Q==", + "version": "5.2.1", + "resolved": "https://registry.npmmirror.com/hosted-git-info/-/hosted-git-info-5.2.1.tgz", + "integrity": "sha512-xIcQYMnhcx2Nr4JTjsFmwwnr9vldugPy9uVm0o87bjqqWMv9GaqsTeT+i99wTl0mk1uLxJtHxLb8kymqTENQsw==", "dev": true, "requires": { "lru-cache": "^7.5.1" } }, "lru-cache": { - "version": "7.14.0", - "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-7.14.0.tgz", - "integrity": "sha512-EIRtP1GrSJny0dqb50QXRUNBxHJhcpxHC++M5tD7RYbvLLn5KVWKsbyswSSqDuU15UFi3bgTQIY8nhDMeF6aDQ==", + "version": "7.17.0", + "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-7.17.0.tgz", + "integrity": "sha512-zSxlVVwOabhVyTi6E8gYv2cr6bXK+8ifYz5/uyJb9feXX6NACVDwY4p5Ut3WC3Ivo/QhpARHU3iujx2xGAYHbQ==", "dev": true }, "normalize-package-data": { @@ -5619,9 +5806,9 @@ } }, "npm-package-arg": { - "version": "9.1.0", - "resolved": "https://registry.npmmirror.com/npm-package-arg/-/npm-package-arg-9.1.0.tgz", - "integrity": "sha512-4J0GL+u2Nh6OnhvUKXRr2ZMG4lR8qtLp+kv7UiV00Y+nGiSxtttCyIRHCt5L5BNkXQld/RceYItau3MDOoGiBw==", + "version": "9.1.2", + "resolved": "https://registry.npmmirror.com/npm-package-arg/-/npm-package-arg-9.1.2.tgz", + "integrity": "sha512-pzd9rLEx4TfNJkovvlBSLGhq31gGu2QDexFPWT19yCDh0JgnRhlBLNo5759N0AJmBk+kQ9Y/hXoLnlgFD+ukmg==", "dev": true, "requires": { "hosted-git-info": "^5.0.0", @@ -5631,9 +5818,9 @@ } }, "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmmirror.com/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmmirror.com/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -5941,9 +6128,9 @@ }, "dependencies": { "lru-cache": { - "version": "7.14.0", - "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-7.14.0.tgz", - "integrity": "sha512-EIRtP1GrSJny0dqb50QXRUNBxHJhcpxHC++M5tD7RYbvLLn5KVWKsbyswSSqDuU15UFi3bgTQIY8nhDMeF6aDQ==", + "version": "7.17.0", + "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-7.17.0.tgz", + "integrity": "sha512-zSxlVVwOabhVyTi6E8gYv2cr6bXK+8ifYz5/uyJb9feXX6NACVDwY4p5Ut3WC3Ivo/QhpARHU3iujx2xGAYHbQ==", "dev": true } } @@ -6001,6 +6188,21 @@ "picomatch": "^2.3.1" } }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "requires": { + "mime-db": "1.52.0" + } + }, "mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmmirror.com/mimic-fn/-/mimic-fn-2.1.0.tgz", @@ -6023,9 +6225,9 @@ } }, "minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmmirror.com/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", + "version": "1.2.7", + "resolved": "https://registry.npmmirror.com/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", "dev": true }, "minimist-options": { @@ -6040,9 +6242,9 @@ } }, "minipass": { - "version": "3.3.4", - "resolved": "https://registry.npmmirror.com/minipass/-/minipass-3.3.4.tgz", - "integrity": "sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw==", + "version": "3.3.6", + "resolved": "https://registry.npmmirror.com/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", "dev": true, "requires": { "yallist": "^4.0.0" @@ -6197,25 +6399,25 @@ "dev": true }, "node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmmirror.com/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "version": "2.6.9", + "resolved": "https://registry.npmmirror.com/node-fetch/-/node-fetch-2.6.9.tgz", + "integrity": "sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==", "dev": true, "requires": { "whatwg-url": "^5.0.0" } }, "node-gyp": { - "version": "9.1.0", - "resolved": "https://registry.npmmirror.com/node-gyp/-/node-gyp-9.1.0.tgz", - "integrity": "sha512-HkmN0ZpQJU7FLbJauJTHkHlSVAXlNGDAzH/VYFZGDOnFyn/Na3GlNJfkudmufOdS6/jNFhy88ObzL7ERz9es1g==", + "version": "9.3.1", + "resolved": "https://registry.npmmirror.com/node-gyp/-/node-gyp-9.3.1.tgz", + "integrity": "sha512-4Q16ZCqq3g8awk6UplT7AuxQ35XN4R/yf/+wSAwcBUAjg7l58RTactWaP8fIDTi0FzI7YcVLujwExakZlfWkXg==", "dev": true, "requires": { "env-paths": "^2.2.0", "glob": "^7.1.4", "graceful-fs": "^4.2.6", "make-fetch-happen": "^10.0.3", - "nopt": "^5.0.0", + "nopt": "^6.0.0", "npmlog": "^6.0.0", "rimraf": "^3.0.2", "semver": "^7.3.5", @@ -6224,18 +6426,18 @@ } }, "node-gyp-build": { - "version": "4.5.0", - "resolved": "https://registry.npmmirror.com/node-gyp-build/-/node-gyp-build-4.5.0.tgz", - "integrity": "sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg==", + "version": "4.6.0", + "resolved": "https://registry.npmmirror.com/node-gyp-build/-/node-gyp-build-4.6.0.tgz", + "integrity": "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==", "dev": true }, "nopt": { - "version": "5.0.0", - "resolved": "https://registry.npmmirror.com/nopt/-/nopt-5.0.0.tgz", - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "version": "6.0.0", + "resolved": "https://registry.npmmirror.com/nopt/-/nopt-6.0.0.tgz", + "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==", "dev": true, "requires": { - "abbrev": "1" + "abbrev": "^1.0.0" } }, "normalize-package-data": { @@ -6330,9 +6532,9 @@ } }, "glob": { - "version": "8.0.3", - "resolved": "https://registry.npmmirror.com/glob/-/glob-8.0.3.tgz", - "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", + "version": "8.1.0", + "resolved": "https://registry.npmmirror.com/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -6343,9 +6545,9 @@ } }, "minimatch": { - "version": "5.1.0", - "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-5.1.0.tgz", - "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", + "version": "5.1.6", + "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, "requires": { "brace-expansion": "^2.0.1" @@ -6390,18 +6592,18 @@ } }, "hosted-git-info": { - "version": "5.1.0", - "resolved": "https://registry.npmmirror.com/hosted-git-info/-/hosted-git-info-5.1.0.tgz", - "integrity": "sha512-Ek+QmMEqZF8XrbFdwoDjSbm7rT23pCgEMOJmz6GPk/s4yH//RQfNPArhIxbguNxROq/+5lNBwCDHMhA903Kx1Q==", + "version": "5.2.1", + "resolved": "https://registry.npmmirror.com/hosted-git-info/-/hosted-git-info-5.2.1.tgz", + "integrity": "sha512-xIcQYMnhcx2Nr4JTjsFmwwnr9vldugPy9uVm0o87bjqqWMv9GaqsTeT+i99wTl0mk1uLxJtHxLb8kymqTENQsw==", "dev": true, "requires": { "lru-cache": "^7.5.1" } }, "lru-cache": { - "version": "7.14.0", - "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-7.14.0.tgz", - "integrity": "sha512-EIRtP1GrSJny0dqb50QXRUNBxHJhcpxHC++M5tD7RYbvLLn5KVWKsbyswSSqDuU15UFi3bgTQIY8nhDMeF6aDQ==", + "version": "7.17.0", + "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-7.17.0.tgz", + "integrity": "sha512-zSxlVVwOabhVyTi6E8gYv2cr6bXK+8ifYz5/uyJb9feXX6NACVDwY4p5Ut3WC3Ivo/QhpARHU3iujx2xGAYHbQ==", "dev": true }, "npm-normalize-package-bin": { @@ -6411,9 +6613,9 @@ "dev": true }, "npm-package-arg": { - "version": "9.1.0", - "resolved": "https://registry.npmmirror.com/npm-package-arg/-/npm-package-arg-9.1.0.tgz", - "integrity": "sha512-4J0GL+u2Nh6OnhvUKXRr2ZMG4lR8qtLp+kv7UiV00Y+nGiSxtttCyIRHCt5L5BNkXQld/RceYItau3MDOoGiBw==", + "version": "9.1.2", + "resolved": "https://registry.npmmirror.com/npm-package-arg/-/npm-package-arg-9.1.2.tgz", + "integrity": "sha512-pzd9rLEx4TfNJkovvlBSLGhq31gGu2QDexFPWT19yCDh0JgnRhlBLNo5759N0AJmBk+kQ9Y/hXoLnlgFD+ukmg==", "dev": true, "requires": { "hosted-git-info": "^5.0.0", @@ -6458,24 +6660,24 @@ } }, "hosted-git-info": { - "version": "5.1.0", - "resolved": "https://registry.npmmirror.com/hosted-git-info/-/hosted-git-info-5.1.0.tgz", - "integrity": "sha512-Ek+QmMEqZF8XrbFdwoDjSbm7rT23pCgEMOJmz6GPk/s4yH//RQfNPArhIxbguNxROq/+5lNBwCDHMhA903Kx1Q==", + "version": "5.2.1", + "resolved": "https://registry.npmmirror.com/hosted-git-info/-/hosted-git-info-5.2.1.tgz", + "integrity": "sha512-xIcQYMnhcx2Nr4JTjsFmwwnr9vldugPy9uVm0o87bjqqWMv9GaqsTeT+i99wTl0mk1uLxJtHxLb8kymqTENQsw==", "dev": true, "requires": { "lru-cache": "^7.5.1" } }, "lru-cache": { - "version": "7.14.0", - "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-7.14.0.tgz", - "integrity": "sha512-EIRtP1GrSJny0dqb50QXRUNBxHJhcpxHC++M5tD7RYbvLLn5KVWKsbyswSSqDuU15UFi3bgTQIY8nhDMeF6aDQ==", + "version": "7.17.0", + "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-7.17.0.tgz", + "integrity": "sha512-zSxlVVwOabhVyTi6E8gYv2cr6bXK+8ifYz5/uyJb9feXX6NACVDwY4p5Ut3WC3Ivo/QhpARHU3iujx2xGAYHbQ==", "dev": true }, "npm-package-arg": { - "version": "9.1.0", - "resolved": "https://registry.npmmirror.com/npm-package-arg/-/npm-package-arg-9.1.0.tgz", - "integrity": "sha512-4J0GL+u2Nh6OnhvUKXRr2ZMG4lR8qtLp+kv7UiV00Y+nGiSxtttCyIRHCt5L5BNkXQld/RceYItau3MDOoGiBw==", + "version": "9.1.2", + "resolved": "https://registry.npmmirror.com/npm-package-arg/-/npm-package-arg-9.1.2.tgz", + "integrity": "sha512-pzd9rLEx4TfNJkovvlBSLGhq31gGu2QDexFPWT19yCDh0JgnRhlBLNo5759N0AJmBk+kQ9Y/hXoLnlgFD+ukmg==", "dev": true, "requires": { "hosted-git-info": "^5.0.0", @@ -6517,16 +6719,28 @@ } }, "nx": { - "version": "14.7.5", - "resolved": "https://registry.npmmirror.com/nx/-/nx-14.7.5.tgz", - "integrity": "sha512-hp8TYk/t15MJVXQCafSduriZqoxR2zvw5mDHqg32Mjt2jFEFKaPWtaO5l/qKj+rlLE8cPYTeGL5qAS9WZkAWtg==", + "version": "15.7.2", + "resolved": "https://registry.npmmirror.com/nx/-/nx-15.7.2.tgz", + "integrity": "sha512-VRb+CZCji3G4ikdMAGoh6TeU9Q6n5atRwqRSFhUX63er8zhlMvWHLskPMZC4q/81edo/E7RhbmEVUD5MB0JoeA==", "dev": true, "requires": { - "@nrwl/cli": "14.7.5", - "@nrwl/tao": "14.7.5", + "@nrwl/cli": "15.7.2", + "@nrwl/nx-darwin-arm64": "15.7.2", + "@nrwl/nx-darwin-x64": "15.7.2", + "@nrwl/nx-linux-arm-gnueabihf": "15.7.2", + "@nrwl/nx-linux-arm64-gnu": "15.7.2", + "@nrwl/nx-linux-arm64-musl": "15.7.2", + "@nrwl/nx-linux-x64-gnu": "15.7.2", + "@nrwl/nx-linux-x64-musl": "15.7.2", + "@nrwl/nx-win32-arm64-msvc": "15.7.2", + "@nrwl/nx-win32-x64-msvc": "15.7.2", + "@nrwl/tao": "15.7.2", "@parcel/watcher": "2.0.4", - "chalk": "4.1.0", - "chokidar": "^3.5.1", + "@yarnpkg/lockfile": "^1.1.0", + "@yarnpkg/parsers": "^3.0.0-rc.18", + "@zkochan/js-yaml": "0.0.6", + "axios": "^1.0.0", + "chalk": "^4.1.0", "cli-cursor": "3.1.0", "cli-spinners": "2.6.1", "cliui": "^7.0.2", @@ -6535,47 +6749,59 @@ "fast-glob": "3.2.7", "figures": "3.2.0", "flat": "^5.0.2", - "fs-extra": "^10.1.0", + "fs-extra": "^11.1.0", "glob": "7.1.4", "ignore": "^5.0.4", "js-yaml": "4.1.0", - "jsonc-parser": "3.0.0", + "jsonc-parser": "3.2.0", + "lines-and-columns": "~2.0.3", "minimatch": "3.0.5", "npm-run-path": "^4.0.1", "open": "^8.4.0", "semver": "7.3.4", "string-width": "^4.2.3", + "strong-log-transformer": "^2.1.0", "tar-stream": "~2.2.0", "tmp": "~0.2.1", - "tsconfig-paths": "^3.9.0", + "tsconfig-paths": "^4.1.2", "tslib": "^2.3.0", "v8-compile-cache": "2.3.0", - "yargs": "^17.4.0", - "yargs-parser": "21.0.1" + "yargs": "^17.6.2", + "yargs-parser": "21.1.1" }, "dependencies": { + "@zkochan/js-yaml": { + "version": "0.0.6", + "resolved": "https://registry.npmmirror.com/@zkochan/js-yaml/-/js-yaml-0.0.6.tgz", + "integrity": "sha512-nzvgl3VfhcELQ8LyVrYOru+UtAy1nrygk2+AGbTm8a5YcO6o8lSjAT+pfg3vJWxIoZKOUhrK6UU7xW/+00kQrg==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, "argparse": { "version": "2.0.1", "resolved": "https://registry.npmmirror.com/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, "cli-spinners": { "version": "2.6.1", "resolved": "https://registry.npmmirror.com/cli-spinners/-/cli-spinners-2.6.1.tgz", "integrity": "sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==", "dev": true }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmmirror.com/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, "fast-glob": { "version": "3.2.7", "resolved": "https://registry.npmmirror.com/fast-glob/-/fast-glob-3.2.7.tgz", @@ -6589,6 +6815,17 @@ "micromatch": "^4.0.4" } }, + "fs-extra": { + "version": "11.1.0", + "resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-11.1.0.tgz", + "integrity": "sha512-0rcTq621PD5jM/e0a3EJoGC/1TC5ZBCERW82LQuwfGnCa1V8w7dpYH1yNu+SLb6E5dkeCBzKEyLGlFrnr+dUyw==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, "glob": { "version": "7.1.4", "resolved": "https://registry.npmmirror.com/glob/-/glob-7.1.4.tgz", @@ -6612,6 +6849,12 @@ "argparse": "^2.0.1" } }, + "lines-and-columns": { + "version": "2.0.3", + "resolved": "https://registry.npmmirror.com/lines-and-columns/-/lines-and-columns-2.0.3.tgz", + "integrity": "sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w==", + "dev": true + }, "minimatch": { "version": "3.0.5", "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-3.0.5.tgz", @@ -6640,9 +6883,9 @@ } }, "yargs-parser": { - "version": "21.0.1", - "resolved": "https://registry.npmmirror.com/yargs-parser/-/yargs-parser-21.0.1.tgz", - "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==", + "version": "21.1.1", + "resolved": "https://registry.npmmirror.com/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true } } @@ -6654,9 +6897,9 @@ "dev": true }, "object-inspect": { - "version": "1.12.2", - "resolved": "https://registry.npmmirror.com/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "version": "1.12.3", + "resolved": "https://registry.npmmirror.com/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", "dev": true }, "object-keys": { @@ -6678,36 +6921,36 @@ } }, "object.entries": { - "version": "1.1.5", - "resolved": "https://registry.npmmirror.com/object.entries/-/object.entries-1.1.5.tgz", - "integrity": "sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==", + "version": "1.1.6", + "resolved": "https://registry.npmmirror.com/object.entries/-/object.entries-1.1.6.tgz", + "integrity": "sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" } }, "object.fromentries": { - "version": "2.0.5", - "resolved": "https://registry.npmmirror.com/object.fromentries/-/object.fromentries-2.0.5.tgz", - "integrity": "sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw==", + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/object.fromentries/-/object.fromentries-2.0.6.tgz", + "integrity": "sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" } }, "object.values": { - "version": "1.1.5", - "resolved": "https://registry.npmmirror.com/object.values/-/object.values-1.1.5.tgz", - "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", + "version": "1.1.6", + "resolved": "https://registry.npmmirror.com/object.values/-/object.values-1.1.6.tgz", + "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" } }, "once": { @@ -6729,9 +6972,9 @@ } }, "open": { - "version": "8.4.0", - "resolved": "https://registry.npmmirror.com/open/-/open-8.4.0.tgz", - "integrity": "sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==", + "version": "8.4.2", + "resolved": "https://registry.npmmirror.com/open/-/open-8.4.2.tgz", + "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", "dev": true, "requires": { "define-lazy-prop": "^2.0.0", @@ -6906,24 +7149,24 @@ } }, "hosted-git-info": { - "version": "5.1.0", - "resolved": "https://registry.npmmirror.com/hosted-git-info/-/hosted-git-info-5.1.0.tgz", - "integrity": "sha512-Ek+QmMEqZF8XrbFdwoDjSbm7rT23pCgEMOJmz6GPk/s4yH//RQfNPArhIxbguNxROq/+5lNBwCDHMhA903Kx1Q==", + "version": "5.2.1", + "resolved": "https://registry.npmmirror.com/hosted-git-info/-/hosted-git-info-5.2.1.tgz", + "integrity": "sha512-xIcQYMnhcx2Nr4JTjsFmwwnr9vldugPy9uVm0o87bjqqWMv9GaqsTeT+i99wTl0mk1uLxJtHxLb8kymqTENQsw==", "dev": true, "requires": { "lru-cache": "^7.5.1" } }, "lru-cache": { - "version": "7.14.0", - "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-7.14.0.tgz", - "integrity": "sha512-EIRtP1GrSJny0dqb50QXRUNBxHJhcpxHC++M5tD7RYbvLLn5KVWKsbyswSSqDuU15UFi3bgTQIY8nhDMeF6aDQ==", + "version": "7.17.0", + "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-7.17.0.tgz", + "integrity": "sha512-zSxlVVwOabhVyTi6E8gYv2cr6bXK+8ifYz5/uyJb9feXX6NACVDwY4p5Ut3WC3Ivo/QhpARHU3iujx2xGAYHbQ==", "dev": true }, "npm-package-arg": { - "version": "9.1.0", - "resolved": "https://registry.npmmirror.com/npm-package-arg/-/npm-package-arg-9.1.0.tgz", - "integrity": "sha512-4J0GL+u2Nh6OnhvUKXRr2ZMG4lR8qtLp+kv7UiV00Y+nGiSxtttCyIRHCt5L5BNkXQld/RceYItau3MDOoGiBw==", + "version": "9.1.2", + "resolved": "https://registry.npmmirror.com/npm-package-arg/-/npm-package-arg-9.1.2.tgz", + "integrity": "sha512-pzd9rLEx4TfNJkovvlBSLGhq31gGu2QDexFPWT19yCDh0JgnRhlBLNo5759N0AJmBk+kQ9Y/hXoLnlgFD+ukmg==", "dev": true, "requires": { "hosted-git-info": "^5.0.0", @@ -7200,6 +7443,12 @@ "integrity": "sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q==", "dev": true }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true + }, "pump": { "version": "3.0.0", "resolved": "https://registry.npmmirror.com/pump/-/pump-3.0.0.tgz", @@ -7211,9 +7460,9 @@ } }, "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmmirror.com/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "version": "2.3.0", + "resolved": "https://registry.npmmirror.com/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", "dev": true }, "q": { @@ -7277,9 +7526,9 @@ } }, "glob": { - "version": "8.0.3", - "resolved": "https://registry.npmmirror.com/glob/-/glob-8.0.3.tgz", - "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", + "version": "8.1.0", + "resolved": "https://registry.npmmirror.com/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -7290,24 +7539,24 @@ } }, "hosted-git-info": { - "version": "5.1.0", - "resolved": "https://registry.npmmirror.com/hosted-git-info/-/hosted-git-info-5.1.0.tgz", - "integrity": "sha512-Ek+QmMEqZF8XrbFdwoDjSbm7rT23pCgEMOJmz6GPk/s4yH//RQfNPArhIxbguNxROq/+5lNBwCDHMhA903Kx1Q==", + "version": "5.2.1", + "resolved": "https://registry.npmmirror.com/hosted-git-info/-/hosted-git-info-5.2.1.tgz", + "integrity": "sha512-xIcQYMnhcx2Nr4JTjsFmwwnr9vldugPy9uVm0o87bjqqWMv9GaqsTeT+i99wTl0mk1uLxJtHxLb8kymqTENQsw==", "dev": true, "requires": { "lru-cache": "^7.5.1" } }, "lru-cache": { - "version": "7.14.0", - "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-7.14.0.tgz", - "integrity": "sha512-EIRtP1GrSJny0dqb50QXRUNBxHJhcpxHC++M5tD7RYbvLLn5KVWKsbyswSSqDuU15UFi3bgTQIY8nhDMeF6aDQ==", + "version": "7.17.0", + "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-7.17.0.tgz", + "integrity": "sha512-zSxlVVwOabhVyTi6E8gYv2cr6bXK+8ifYz5/uyJb9feXX6NACVDwY4p5Ut3WC3Ivo/QhpARHU3iujx2xGAYHbQ==", "dev": true }, "minimatch": { - "version": "5.1.0", - "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-5.1.0.tgz", - "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", + "version": "5.1.6", + "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, "requires": { "brace-expansion": "^2.0.1" @@ -7429,15 +7678,6 @@ "once": "^1.3.0" } }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmmirror.com/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } - }, "redent": { "version": "3.0.0", "resolved": "https://registry.npmmirror.com/redent/-/redent-3.0.0.tgz", @@ -7449,9 +7689,9 @@ } }, "regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==", + "version": "0.13.11", + "resolved": "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", "dev": true }, "regexp.prototype.flags": { @@ -7581,9 +7821,9 @@ } }, "rxjs": { - "version": "7.5.6", - "resolved": "https://registry.npmmirror.com/rxjs/-/rxjs-7.5.6.tgz", - "integrity": "sha512-dnyv2/YsXhnm461G+R/Pe5bWP41Nm6LBXEYWI6eiFP4fiwx6WRI/CD0zbdVAudd9xwLEF2IDcKXLHit0FYjUzw==", + "version": "7.8.0", + "resolved": "https://registry.npmmirror.com/rxjs/-/rxjs-7.8.0.tgz", + "integrity": "sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==", "dev": true, "requires": { "tslib": "^2.1.0" @@ -7595,6 +7835,17 @@ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true }, + "safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + } + }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -7693,9 +7944,9 @@ "dev": true }, "socks": { - "version": "2.7.0", - "resolved": "https://registry.npmmirror.com/socks/-/socks-2.7.0.tgz", - "integrity": "sha512-scnOe9y4VuiNUULJN72GrM26BNOjVsfPXI+j+98PkyEfsIXroa5ofyjT+FzGvn/xHs73U2JtoBYAVx9Hl4quSA==", + "version": "2.7.1", + "resolved": "https://registry.npmmirror.com/socks/-/socks-2.7.1.tgz", + "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", "dev": true, "requires": { "ip": "^2.0.0", @@ -7821,41 +8072,41 @@ } }, "string.prototype.matchall": { - "version": "4.0.7", - "resolved": "https://registry.npmmirror.com/string.prototype.matchall/-/string.prototype.matchall-4.0.7.tgz", - "integrity": "sha512-f48okCX7JiwVi1NXCVWcFnZgADDC/n2vePlQ/KUCNqCikLLilQvwjMO8+BHVKvgzH0JB0J9LEPgxOGT02RoETg==", + "version": "4.0.8", + "resolved": "https://registry.npmmirror.com/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz", + "integrity": "sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1", - "get-intrinsic": "^1.1.1", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "get-intrinsic": "^1.1.3", "has-symbols": "^1.0.3", "internal-slot": "^1.0.3", - "regexp.prototype.flags": "^1.4.1", + "regexp.prototype.flags": "^1.4.3", "side-channel": "^1.0.4" } }, "string.prototype.trimend": { - "version": "1.0.5", - "resolved": "https://registry.npmmirror.com/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", - "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", + "version": "1.0.6", + "resolved": "https://registry.npmmirror.com/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", + "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", "dev": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" + "es-abstract": "^1.20.4" } }, "string.prototype.trimstart": { - "version": "1.0.5", - "resolved": "https://registry.npmmirror.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", - "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", + "version": "1.0.6", + "resolved": "https://registry.npmmirror.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", + "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", "dev": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" + "es-abstract": "^1.20.4" } }, "string_decoder": { @@ -7949,9 +8200,9 @@ "dev": true }, "table": { - "version": "6.8.0", - "resolved": "https://registry.npmmirror.com/table/-/table-6.8.0.tgz", - "integrity": "sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==", + "version": "6.8.1", + "resolved": "https://registry.npmmirror.com/table/-/table-6.8.1.tgz", + "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", "dev": true, "requires": { "ajv": "^8.0.1", @@ -7962,9 +8213,9 @@ }, "dependencies": { "ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmmirror.com/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "version": "8.12.0", + "resolved": "https://registry.npmmirror.com/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -7982,17 +8233,25 @@ } }, "tar": { - "version": "6.1.11", - "resolved": "https://registry.npmmirror.com/tar/-/tar-6.1.11.tgz", - "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", + "version": "6.1.13", + "resolved": "https://registry.npmmirror.com/tar/-/tar-6.1.13.tgz", + "integrity": "sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw==", "dev": true, "requires": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", + "minipass": "^4.0.0", "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" + }, + "dependencies": { + "minipass": { + "version": "4.2.0", + "resolved": "https://registry.npmmirror.com/minipass/-/minipass-4.2.0.tgz", + "integrity": "sha512-ExlilAIS7zJ2EWUMaVXi14H+FnZ18kr17kFkGemMqBx6jW0m8P6XfqwYVPEG53ENlgsED+alVP9ZxC3JzkK23Q==", + "dev": true + } } }, "tar-stream": { @@ -8108,13 +8367,12 @@ } }, "tsconfig-paths": { - "version": "3.14.1", - "resolved": "https://registry.npmmirror.com/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", - "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/tsconfig-paths/-/tsconfig-paths-4.1.2.tgz", + "integrity": "sha512-uhxiMgnXQp1IR622dUXI+9Ehnws7i/y6xvpZB9IbUVOPy0muvdvgXeZOn88UcGPiT98Vp3rJPTa8bFoalZ3Qhw==", "dev": true, "requires": { - "@types/json5": "^0.0.29", - "json5": "^1.0.1", + "json5": "^2.2.2", "minimist": "^1.2.6", "strip-bom": "^3.0.0" }, @@ -8128,9 +8386,9 @@ } }, "tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", + "version": "2.5.0", + "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.5.0.tgz", + "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==", "dev": true }, "tsutils": { @@ -8165,6 +8423,17 @@ "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", "dev": true }, + "typed-array-length": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/typed-array-length/-/typed-array-length-1.0.4.tgz", + "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "is-typed-array": "^1.1.9" + } + }, "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmmirror.com/typedarray/-/typedarray-0.0.6.tgz", @@ -8181,15 +8450,15 @@ } }, "typescript": { - "version": "4.8.3", - "resolved": "https://registry.npmmirror.com/typescript/-/typescript-4.8.3.tgz", - "integrity": "sha512-goMHfm00nWPa8UvR/CPSvykqf6dVV8x/dp0c5mFTMTIu0u0FlGWRioyy7Nn0PGAdHxpJZnuO/ut+PpQ8UiHAig==", + "version": "4.9.5", + "resolved": "https://registry.npmmirror.com/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true }, "uglify-js": { - "version": "3.17.0", - "resolved": "https://registry.npmmirror.com/uglify-js/-/uglify-js-3.17.0.tgz", - "integrity": "sha512-aTeNPVmgIMPpm1cxXr2Q/nEbvkmV8yq66F3om7X3P/cvOXQ0TMQ64Wk63iyT1gPlmdmGzjGpyLh1f3y8MZWXGg==", + "version": "3.17.4", + "resolved": "https://registry.npmmirror.com/uglify-js/-/uglify-js-3.17.4.tgz", + "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", "dev": true, "optional": true }, @@ -8346,6 +8615,20 @@ "integrity": "sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==", "dev": true }, + "which-typed-array": { + "version": "1.1.9", + "resolved": "https://registry.npmmirror.com/which-typed-array/-/which-typed-array-1.1.9.tgz", + "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", + "dev": true, + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0", + "is-typed-array": "^1.1.10" + } + }, "wide-align": { "version": "1.1.5", "resolved": "https://registry.npmmirror.com/wide-align/-/wide-align-1.1.5.tgz", @@ -8523,18 +8806,18 @@ "dev": true }, "yargs": { - "version": "17.5.1", - "resolved": "https://registry.npmmirror.com/yargs/-/yargs-17.5.1.tgz", - "integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==", + "version": "17.7.1", + "resolved": "https://registry.npmmirror.com/yargs/-/yargs-17.7.1.tgz", + "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", "dev": true, "requires": { - "cliui": "^7.0.2", + "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^21.0.0" + "yargs-parser": "^21.1.1" }, "dependencies": { "yargs-parser": { diff --git a/km-console/package.json b/km-console/package.json index d02345af..92b30d0d 100644 --- a/km-console/package.json +++ b/km-console/package.json @@ -17,7 +17,7 @@ "eslint-plugin-react": "7.22.0", "eslint-plugin-react-hooks": "^4.2.0", "husky": "4.3.7", - "lerna": "^5.5.0", + "lerna": "5.5.0", "lint-staged": "10.5.3", "prettier": "2.3.2" }, diff --git a/km-console/packages/config-manager-fe/config/theme.js b/km-console/packages/config-manager-fe/config/theme.js index cd58375e..3d57d2ab 100755 --- a/km-console/packages/config-manager-fe/config/theme.js +++ b/km-console/packages/config-manager-fe/config/theme.js @@ -1,7 +1,7 @@ const themeConfig = { - primaryColor: '#556ee6', + primaryColor: '#5664FF', theme: { - 'primary-color': '#556ee6', + 'primary-color': '#5664FF', 'border-radius-base': '2px', 'border-radius-sm': '2px', 'font-size-base': '12px', diff --git a/km-console/packages/config-manager-fe/package-lock.json b/km-console/packages/config-manager-fe/package-lock.json index 8db0ed4a..2085ec02 100644 --- a/km-console/packages/config-manager-fe/package-lock.json +++ b/km-console/packages/config-manager-fe/package-lock.json @@ -22,9 +22,9 @@ } }, "@ant-design/icons": { - "version": "4.7.0", - "resolved": "https://registry.npmmirror.com/@ant-design/icons/-/icons-4.7.0.tgz", - "integrity": "sha512-aoB4Z7JA431rt6d4u+8xcNPPCrdufSRMUOpxa1ab6mz1JCQZOEVolj2WVs/tDFmN62zzK30mNelEsprLYsSF3g==", + "version": "4.8.0", + "resolved": "https://registry.npmmirror.com/@ant-design/icons/-/icons-4.8.0.tgz", + "integrity": "sha512-T89P2jG2vM7OJ0IfGx2+9FC5sQjtTzRSz+mCHTXkFn/ELZc2YpfStmYHmqzq2Jx55J0F7+O6i5/ZKFSVNWCKNg==", "requires": { "@ant-design/colors": "^6.0.0", "@ant-design/icons-svg": "^4.2.1", @@ -59,39 +59,40 @@ } }, "@babel/compat-data": { - "version": "7.19.1", - "resolved": "https://registry.npmmirror.com/@babel/compat-data/-/compat-data-7.19.1.tgz", - "integrity": "sha512-72a9ghR0gnESIa7jBN53U32FOVCEoztyIlKaNoU05zRhEecduGK9L9c3ww7Mp06JiR+0ls0GBPFJQwwtjn9ksg==" + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/compat-data/-/compat-data-7.21.0.tgz", + "integrity": "sha512-gMuZsmsgxk/ENC3O/fRw5QY8A9/uxQbbCEypnLIiYYc/qVJtEV7ouxC3EllIIwNzMqAQee5tanFabWsUOutS7g==" }, "@babel/core": { - "version": "7.19.1", - "resolved": "https://registry.npmmirror.com/@babel/core/-/core-7.19.1.tgz", - "integrity": "sha512-1H8VgqXme4UXCRv7/Wa1bq7RVymKOzC7znjyFM8KiEzwFqcKUKYNoQef4GhdklgNvoBXyW4gYhuBNCM5o1zImw==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/core/-/core-7.21.0.tgz", + "integrity": "sha512-PuxUbxcW6ZYe656yL3EAhpy7qXKq0DmYsrJLpbB8XrsCP9Nm+XCg9XFMb5vIDliPD7+U/+M+QJlH17XOcB7eXA==", "requires": { - "@ampproject/remapping": "^2.1.0", + "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.19.0", - "@babel/helper-compilation-targets": "^7.19.1", - "@babel/helper-module-transforms": "^7.19.0", - "@babel/helpers": "^7.19.0", - "@babel/parser": "^7.19.1", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.1", - "@babel/types": "^7.19.0", + "@babel/generator": "^7.21.0", + "@babel/helper-compilation-targets": "^7.20.7", + "@babel/helper-module-transforms": "^7.21.0", + "@babel/helpers": "^7.21.0", + "@babel/parser": "^7.21.0", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.21.0", + "@babel/types": "^7.21.0", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", + "json5": "^2.2.2", "semver": "^6.3.0" } }, "@babel/generator": { - "version": "7.19.0", - "resolved": "https://registry.npmmirror.com/@babel/generator/-/generator-7.19.0.tgz", - "integrity": "sha512-S1ahxf1gZ2dpoiFgA+ohK9DIpz50bJ0CWs7Zlzb54Z4sG8qmdIrGrVqmy1sAtTVRb+9CU6U8VqT9L0Zj7hxHVg==", + "version": "7.21.1", + "resolved": "https://registry.npmmirror.com/@babel/generator/-/generator-7.21.1.tgz", + "integrity": "sha512-1lT45bAYlQhFn/BHivJs43AiW2rg3/UbLyShGfF3C0KmHvO5fSghWd5kBJy30kpRRucGzXStvnnCFniCR2kXAA==", "requires": { - "@babel/types": "^7.19.0", + "@babel/types": "^7.21.0", "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" }, "dependencies": { @@ -125,37 +126,39 @@ } }, "@babel/helper-compilation-targets": { - "version": "7.19.1", - "resolved": "https://registry.npmmirror.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.1.tgz", - "integrity": "sha512-LlLkkqhCMyz2lkQPvJNdIYU7O5YjWRgC2R4omjCTpZd8u8KMQzZvX4qce+/BluN1rcQiV7BoGUpmQ0LeHerbhg==", + "version": "7.20.7", + "resolved": "https://registry.npmmirror.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", + "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", "requires": { - "@babel/compat-data": "^7.19.1", + "@babel/compat-data": "^7.20.5", "@babel/helper-validator-option": "^7.18.6", "browserslist": "^4.21.3", + "lru-cache": "^5.1.1", "semver": "^6.3.0" } }, "@babel/helper-create-class-features-plugin": { - "version": "7.19.0", - "resolved": "https://registry.npmmirror.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.19.0.tgz", - "integrity": "sha512-NRz8DwF4jT3UfrmUoZjd0Uph9HQnP30t7Ash+weACcyNkiYTywpIjDBgReJMKgr+n86sn2nPVVmJ28Dm053Kqw==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.21.0.tgz", + "integrity": "sha512-Q8wNiMIdwsv5la5SPxNYzzkPnjgC0Sy0i7jLkVOCdllu/xcVNkr3TeZzbHBJrj+XXRqzX5uCyCoV9eu6xUG7KQ==", "requires": { "@babel/helper-annotate-as-pure": "^7.18.6", "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-member-expression-to-functions": "^7.18.9", + "@babel/helper-function-name": "^7.21.0", + "@babel/helper-member-expression-to-functions": "^7.21.0", "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-replace-supers": "^7.18.9", + "@babel/helper-replace-supers": "^7.20.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", "@babel/helper-split-export-declaration": "^7.18.6" } }, "@babel/helper-create-regexp-features-plugin": { - "version": "7.19.0", - "resolved": "https://registry.npmmirror.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.19.0.tgz", - "integrity": "sha512-htnV+mHX32DF81amCDrwIDr8nrp1PTm+3wfBN9/v8QJOLEioOCOG7qNyq0nHeFiWbT3Eb7gsPwEmV64UCQ1jzw==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.21.0.tgz", + "integrity": "sha512-N+LaFW/auRSWdx7SHD/HiARwXQju1vXTW4fKr4u5SgBUTm51OKEjKgj+cs00ggW3kEvNqwErnlwuq7Y3xBe4eg==", "requires": { "@babel/helper-annotate-as-pure": "^7.18.6", - "regexpu-core": "^5.1.0" + "regexpu-core": "^5.3.1" } }, "@babel/helper-define-polyfill-provider": { @@ -185,12 +188,12 @@ } }, "@babel/helper-function-name": { - "version": "7.19.0", - "resolved": "https://registry.npmmirror.com/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", - "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz", + "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==", "requires": { - "@babel/template": "^7.18.10", - "@babel/types": "^7.19.0" + "@babel/template": "^7.20.7", + "@babel/types": "^7.21.0" } }, "@babel/helper-hoist-variables": { @@ -202,11 +205,11 @@ } }, "@babel/helper-member-expression-to-functions": { - "version": "7.18.9", - "resolved": "https://registry.npmmirror.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz", - "integrity": "sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.21.0.tgz", + "integrity": "sha512-Muu8cdZwNN6mRRNG6lAYErJ5X3bRevgYR2O8wN0yn7jJSnGDu6eG59RfT29JHxGUovyfrh6Pj0XzmR7drNVL3Q==", "requires": { - "@babel/types": "^7.18.9" + "@babel/types": "^7.21.0" } }, "@babel/helper-module-imports": { @@ -218,18 +221,18 @@ } }, "@babel/helper-module-transforms": { - "version": "7.19.0", - "resolved": "https://registry.npmmirror.com/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz", - "integrity": "sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/helper-module-transforms/-/helper-module-transforms-7.21.0.tgz", + "integrity": "sha512-eD/JQ21IG2i1FraJnTMbUarAUkA7G988ofehG5MDCRXaUU91rEBJuCeSoou2Sk1y4RbLYXzqEg1QLwEmRU4qcQ==", "requires": { "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.18.6", + "@babel/helper-simple-access": "^7.20.2", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.18.6", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.0", - "@babel/types": "^7.19.0" + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.21.0", + "@babel/types": "^7.21.0" } }, "@babel/helper-optimise-call-expression": { @@ -241,9 +244,9 @@ } }, "@babel/helper-plugin-utils": { - "version": "7.19.0", - "resolved": "https://registry.npmmirror.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz", - "integrity": "sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==" + "version": "7.20.2", + "resolved": "https://registry.npmmirror.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", + "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==" }, "@babel/helper-remap-async-to-generator": { "version": "7.18.9", @@ -257,31 +260,32 @@ } }, "@babel/helper-replace-supers": { - "version": "7.19.1", - "resolved": "https://registry.npmmirror.com/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz", - "integrity": "sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw==", + "version": "7.20.7", + "resolved": "https://registry.npmmirror.com/@babel/helper-replace-supers/-/helper-replace-supers-7.20.7.tgz", + "integrity": "sha512-vujDMtB6LVfNW13jhlCrp48QNslK6JXi7lQG736HVbHz/mbf4Dc7tIRh1Xf5C0rF7BP8iiSxGMCmY6Ci1ven3A==", "requires": { "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-member-expression-to-functions": "^7.18.9", + "@babel/helper-member-expression-to-functions": "^7.20.7", "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/traverse": "^7.19.1", - "@babel/types": "^7.19.0" + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.7", + "@babel/types": "^7.20.7" } }, "@babel/helper-simple-access": { - "version": "7.18.6", - "resolved": "https://registry.npmmirror.com/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz", - "integrity": "sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==", + "version": "7.20.2", + "resolved": "https://registry.npmmirror.com/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", + "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", "requires": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.20.2" } }, "@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.18.9", - "resolved": "https://registry.npmmirror.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.18.9.tgz", - "integrity": "sha512-imytd2gHi3cJPsybLRbmFrF7u5BIEuI2cNheyKi3/iOBC63kNn3q8Crn2xVuESli0aM4KYsyEqKyS7lFL8YVtw==", + "version": "7.20.0", + "resolved": "https://registry.npmmirror.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz", + "integrity": "sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==", "requires": { - "@babel/types": "^7.18.9" + "@babel/types": "^7.20.0" } }, "@babel/helper-split-export-declaration": { @@ -293,9 +297,9 @@ } }, "@babel/helper-string-parser": { - "version": "7.18.10", - "resolved": "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz", - "integrity": "sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==" + "version": "7.19.4", + "resolved": "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==" }, "@babel/helper-validator-identifier": { "version": "7.19.1", @@ -303,29 +307,29 @@ "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==" }, "@babel/helper-validator-option": { - "version": "7.18.6", - "resolved": "https://registry.npmmirror.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", - "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==" + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz", + "integrity": "sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==" }, "@babel/helper-wrap-function": { - "version": "7.19.0", - "resolved": "https://registry.npmmirror.com/@babel/helper-wrap-function/-/helper-wrap-function-7.19.0.tgz", - "integrity": "sha512-txX8aN8CZyYGTwcLhlk87KRqncAzhh5TpQamZUa0/u3an36NtDpUP6bQgBCBcLeBs09R/OwQu3OjK0k/HwfNDg==", + "version": "7.20.5", + "resolved": "https://registry.npmmirror.com/@babel/helper-wrap-function/-/helper-wrap-function-7.20.5.tgz", + "integrity": "sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q==", "requires": { "@babel/helper-function-name": "^7.19.0", "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.0", - "@babel/types": "^7.19.0" + "@babel/traverse": "^7.20.5", + "@babel/types": "^7.20.5" } }, "@babel/helpers": { - "version": "7.19.0", - "resolved": "https://registry.npmmirror.com/@babel/helpers/-/helpers-7.19.0.tgz", - "integrity": "sha512-DRBCKGwIEdqY3+rPJgG/dKfQy9+08rHIAJx8q2p+HSWP87s2HCrQmaAMMyMll2kIXKCW0cO1RdQskx15Xakftg==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/helpers/-/helpers-7.21.0.tgz", + "integrity": "sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA==", "requires": { - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.0", - "@babel/types": "^7.19.0" + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.21.0", + "@babel/types": "^7.21.0" } }, "@babel/highlight": { @@ -339,9 +343,9 @@ } }, "@babel/parser": { - "version": "7.19.1", - "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.19.1.tgz", - "integrity": "sha512-h7RCSorm1DdTVGJf3P2Mhj3kdnkmF/EiysUkzS2TdgAYqyjFdMQJbVuXOBej2SBJaXan/lIVtT6KkGbyyq753A==" + "version": "7.21.1", + "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.21.1.tgz", + "integrity": "sha512-JzhBFpkuhBNYUY7qs+wTzNmyCWUHEaAFpQQD2YfU1rPL38/L43Wvid0fFkiOCnHvsGncRZgEPyGnltABLcVDTg==" }, "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { "version": "7.18.6", @@ -352,22 +356,22 @@ } }, "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.18.9", - "resolved": "https://registry.npmmirror.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.9.tgz", - "integrity": "sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg==", + "version": "7.20.7", + "resolved": "https://registry.npmmirror.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.20.7.tgz", + "integrity": "sha512-sbr9+wNE5aXMBBFBICk01tt7sBf2Oc9ikRFEcem/ZORup9IMUdNhW7/wVLEbbtlWOsEubJet46mHAL2C8+2jKQ==", "requires": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", - "@babel/plugin-proposal-optional-chaining": "^7.18.9" + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", + "@babel/plugin-proposal-optional-chaining": "^7.20.7" } }, "@babel/plugin-proposal-async-generator-functions": { - "version": "7.19.1", - "resolved": "https://registry.npmmirror.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.19.1.tgz", - "integrity": "sha512-0yu8vNATgLy4ivqMNBIwb1HebCelqN7YX8SL3FDXORv/RqT0zEEWUCH4GH44JsSrvCu6GqnAdR5EBFAPeNBB4Q==", + "version": "7.20.7", + "resolved": "https://registry.npmmirror.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.7.tgz", + "integrity": "sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA==", "requires": { "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-plugin-utils": "^7.20.2", "@babel/helper-remap-async-to-generator": "^7.18.9", "@babel/plugin-syntax-async-generators": "^7.8.4" } @@ -382,25 +386,25 @@ } }, "@babel/plugin-proposal-class-static-block": { - "version": "7.18.6", - "resolved": "https://registry.npmmirror.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.6.tgz", - "integrity": "sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.21.0.tgz", + "integrity": "sha512-XP5G9MWNUskFuP30IfFSEFB0Z6HzLIUcjYM4bYOPHXl7eiJ9HFv8tWj6TXTN5QODiEhDZAeI4hLok2iHFFV4hw==", "requires": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-create-class-features-plugin": "^7.21.0", + "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-class-static-block": "^7.14.5" } }, "@babel/plugin-proposal-decorators": { - "version": "7.19.1", - "resolved": "https://registry.npmmirror.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.19.1.tgz", - "integrity": "sha512-LfIKNBBY7Q1OX5C4xAgRQffOg2OnhAo9fnbcOHgOC9Yytm2Sw+4XqHufRYU86tHomzepxtvuVaNO+3EVKR4ivw==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.21.0.tgz", + "integrity": "sha512-MfgX49uRrFUTL/HvWtmx3zmpyzMMr4MTj3d527MLlr/4RTT9G/ytFFP7qet2uM2Ve03b+BkpWUpK+lRXnQ+v9w==", "requires": { - "@babel/helper-create-class-features-plugin": "^7.19.0", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-replace-supers": "^7.19.1", + "@babel/helper-create-class-features-plugin": "^7.21.0", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-replace-supers": "^7.20.7", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/plugin-syntax-decorators": "^7.19.0" + "@babel/plugin-syntax-decorators": "^7.21.0" } }, "@babel/plugin-proposal-dynamic-import": { @@ -441,11 +445,11 @@ } }, "@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.18.9", - "resolved": "https://registry.npmmirror.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.9.tgz", - "integrity": "sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q==", + "version": "7.20.7", + "resolved": "https://registry.npmmirror.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.20.7.tgz", + "integrity": "sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug==", "requires": { - "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" } }, @@ -468,15 +472,15 @@ } }, "@babel/plugin-proposal-object-rest-spread": { - "version": "7.18.9", - "resolved": "https://registry.npmmirror.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.18.9.tgz", - "integrity": "sha512-kDDHQ5rflIeY5xl69CEqGEZ0KY369ehsCIEbTGb4siHG5BE9sga/T0r0OUwyZNLMmZE79E1kbsqAjwFCW4ds6Q==", + "version": "7.20.7", + "resolved": "https://registry.npmmirror.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz", + "integrity": "sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==", "requires": { - "@babel/compat-data": "^7.18.8", - "@babel/helper-compilation-targets": "^7.18.9", - "@babel/helper-plugin-utils": "^7.18.9", + "@babel/compat-data": "^7.20.5", + "@babel/helper-compilation-targets": "^7.20.7", + "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.18.8" + "@babel/plugin-transform-parameters": "^7.20.7" } }, "@babel/plugin-proposal-optional-catch-binding": { @@ -489,12 +493,12 @@ } }, "@babel/plugin-proposal-optional-chaining": { - "version": "7.18.9", - "resolved": "https://registry.npmmirror.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.9.tgz", - "integrity": "sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz", + "integrity": "sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==", "requires": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", "@babel/plugin-syntax-optional-chaining": "^7.8.3" } }, @@ -508,13 +512,13 @@ } }, "@babel/plugin-proposal-private-property-in-object": { - "version": "7.18.6", - "resolved": "https://registry.npmmirror.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.18.6.tgz", - "integrity": "sha512-9Rysx7FOctvT5ouj5JODjAFAkgGoudQuLPamZb0v1TGLpapdNaftzifU8NTWQm0IRjqoYypdrSmyWgkocDQ8Dw==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0.tgz", + "integrity": "sha512-ha4zfehbJjc5MmXBlHec1igel5TJXXLDDRbuJ4+XT2TJcyD9/V1919BA8gMvsdHcNMBy4WBUBiRb3nw/EQUtBw==", "requires": { "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-create-class-features-plugin": "^7.21.0", + "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-private-property-in-object": "^7.14.5" } }, @@ -552,11 +556,11 @@ } }, "@babel/plugin-syntax-decorators": { - "version": "7.19.0", - "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.19.0.tgz", - "integrity": "sha512-xaBZUEDntt4faL1yN8oIFlhfXeQAWJW7CLKYsHTUqriCUbj8xOra8bfxxKGi/UwExPFBuPdH4XfHc9rGQhrVkQ==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.21.0.tgz", + "integrity": "sha512-tIoPpGBR8UuM4++ccWN3gifhVvQu7ZizuR1fklhRJrd5ewgbkUS+0KVFeWWxELtn18NTLoW32XV7zyOgIAiz+w==", "requires": { - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-plugin-utils": "^7.20.2" } }, "@babel/plugin-syntax-dynamic-import": { @@ -593,11 +597,11 @@ } }, "@babel/plugin-syntax-import-assertions": { - "version": "7.18.6", - "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.18.6.tgz", - "integrity": "sha512-/DU3RXad9+bZwrgWJQKbr39gYbJpLJHezqEzRzi/BHRlJ9zsQb4CK2CA/5apllXNomwA1qHwzvHl+AdEmC5krQ==", + "version": "7.20.0", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz", + "integrity": "sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==", "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.19.0" } }, "@babel/plugin-syntax-json-strings": { @@ -681,29 +685,29 @@ } }, "@babel/plugin-syntax-typescript": { - "version": "7.18.6", - "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz", - "integrity": "sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA==", + "version": "7.20.0", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz", + "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==", "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.19.0" } }, "@babel/plugin-transform-arrow-functions": { - "version": "7.18.6", - "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.18.6.tgz", - "integrity": "sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ==", + "version": "7.20.7", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.20.7.tgz", + "integrity": "sha512-3poA5E7dzDomxj9WXWwuD6A5F3kc7VXwIJO+E+J8qtDtS+pXPAhrgEyh+9GBwBgPq1Z+bB+/JD60lp5jsN7JPQ==", "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.20.2" } }, "@babel/plugin-transform-async-to-generator": { - "version": "7.18.6", - "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz", - "integrity": "sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag==", + "version": "7.20.7", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.20.7.tgz", + "integrity": "sha512-Uo5gwHPT9vgnSXQxqGtpdufUiWp96gk7yiP4Mp5bm1QMkEmLXBO7PAGYbKoJ6DhAwiNkcHFBol/x5zZZkL/t0Q==", "requires": { "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-remap-async-to-generator": "^7.18.6" + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-remap-async-to-generator": "^7.18.9" } }, "@babel/plugin-transform-block-scoped-functions": { @@ -715,43 +719,44 @@ } }, "@babel/plugin-transform-block-scoping": { - "version": "7.18.9", - "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.18.9.tgz", - "integrity": "sha512-5sDIJRV1KtQVEbt/EIBwGy4T01uYIo4KRB3VUqzkhrAIOGx7AoctL9+Ux88btY0zXdDyPJ9mW+bg+v+XEkGmtw==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.21.0.tgz", + "integrity": "sha512-Mdrbunoh9SxwFZapeHVrwFmri16+oYotcZysSzhNIVDwIAb1UV+kvnxULSYq9J3/q5MDG+4X6w8QVgD1zhBXNQ==", "requires": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.20.2" } }, "@babel/plugin-transform-classes": { - "version": "7.19.0", - "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.19.0.tgz", - "integrity": "sha512-YfeEE9kCjqTS9IitkgfJuxjcEtLUHMqa8yUJ6zdz8vR7hKuo6mOy2C05P0F1tdMmDCeuyidKnlrw/iTppHcr2A==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.21.0.tgz", + "integrity": "sha512-RZhbYTCEUAe6ntPehC4hlslPWosNHDox+vAs4On/mCLRLfoDVHf6hVEd7kuxr1RnHwJmxFfUM3cZiZRmPxJPXQ==", "requires": { "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-compilation-targets": "^7.19.0", + "@babel/helper-compilation-targets": "^7.20.7", "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", + "@babel/helper-function-name": "^7.21.0", "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-replace-supers": "^7.18.9", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-replace-supers": "^7.20.7", "@babel/helper-split-export-declaration": "^7.18.6", "globals": "^11.1.0" } }, "@babel/plugin-transform-computed-properties": { - "version": "7.18.9", - "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz", - "integrity": "sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw==", + "version": "7.20.7", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.20.7.tgz", + "integrity": "sha512-Lz7MvBK6DTjElHAmfu6bfANzKcxpyNPeYBGEafyA6E5HtRpjpZwU+u7Qrgz/2OR0z+5TvKYbPdphfSaAcZBrYQ==", "requires": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/template": "^7.20.7" } }, "@babel/plugin-transform-destructuring": { - "version": "7.18.13", - "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.18.13.tgz", - "integrity": "sha512-TodpQ29XekIsex2A+YJPj5ax2plkGa8YYY6mFjCohk/IG9IY42Rtuj1FuDeemfg2ipxIFLzPeA83SIBnlhSIow==", + "version": "7.20.7", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.7.tgz", + "integrity": "sha512-Xwg403sRrZb81IVB79ZPqNQME23yhugYVqgTxAhT99h485F4f+GMELFhhOsscDUB7HCswepKeCKLn/GZvUKoBA==", "requires": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.20.2" } }, "@babel/plugin-transform-dotall-regex": { @@ -781,20 +786,20 @@ } }, "@babel/plugin-transform-flow-strip-types": { - "version": "7.19.0", - "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.19.0.tgz", - "integrity": "sha512-sgeMlNaQVbCSpgLSKP4ZZKfsJVnFnNQlUSk6gPYzR/q7tzCgQF2t8RBKAP6cKJeZdveei7Q7Jm527xepI8lNLg==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.21.0.tgz", + "integrity": "sha512-FlFA2Mj87a6sDkW4gfGrQQqwY/dLlBAyJa2dJEZ+FHXUVHBflO2wyKvg+OOEzXfrKYIa4HWl0mgmbCzt0cMb7w==", "requires": { - "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-flow": "^7.18.6" } }, "@babel/plugin-transform-for-of": { - "version": "7.18.8", - "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz", - "integrity": "sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.21.0.tgz", + "integrity": "sha512-LlUYlydgDkKpIY7mcBWvyPPmMcOphEyYA27Ef4xpbh1IiDNLr0kZsos2nf92vz3IccvJI25QUwp86Eo5s6HmBQ==", "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.20.2" } }, "@babel/plugin-transform-function-name": { @@ -824,36 +829,33 @@ } }, "@babel/plugin-transform-modules-amd": { - "version": "7.18.6", - "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.18.6.tgz", - "integrity": "sha512-Pra5aXsmTsOnjM3IajS8rTaLCy++nGM4v3YR4esk5PCsyg9z8NA5oQLwxzMUtDBd8F+UmVza3VxoAaWCbzH1rg==", + "version": "7.20.11", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.20.11.tgz", + "integrity": "sha512-NuzCt5IIYOW0O30UvqktzHYR2ud5bOWbY0yaxWZ6G+aFzOMJvrs5YHNikrbdaT15+KNO31nPOy5Fim3ku6Zb5g==", "requires": { - "@babel/helper-module-transforms": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "babel-plugin-dynamic-import-node": "^2.3.3" + "@babel/helper-module-transforms": "^7.20.11", + "@babel/helper-plugin-utils": "^7.20.2" } }, "@babel/plugin-transform-modules-commonjs": { - "version": "7.18.6", - "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.18.6.tgz", - "integrity": "sha512-Qfv2ZOWikpvmedXQJDSbxNqy7Xr/j2Y8/KfijM0iJyKkBTmWuvCA1yeH1yDM7NJhBW/2aXxeucLj6i80/LAJ/Q==", + "version": "7.20.11", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.20.11.tgz", + "integrity": "sha512-S8e1f7WQ7cimJQ51JkAaDrEtohVEitXjgCGAS2N8S31Y42E+kWwfSz83LYz57QdBm7q9diARVqanIaH2oVgQnw==", "requires": { - "@babel/helper-module-transforms": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-simple-access": "^7.18.6", - "babel-plugin-dynamic-import-node": "^2.3.3" + "@babel/helper-module-transforms": "^7.20.11", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-simple-access": "^7.20.2" } }, "@babel/plugin-transform-modules-systemjs": { - "version": "7.19.0", - "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.0.tgz", - "integrity": "sha512-x9aiR0WXAWmOWsqcsnrzGR+ieaTMVyGyffPVA7F8cXAGt/UxefYv6uSHZLkAFChN5M5Iy1+wjE+xJuPt22H39A==", + "version": "7.20.11", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.20.11.tgz", + "integrity": "sha512-vVu5g9BPQKSFEmvt2TA4Da5N+QVS66EX21d8uoOihC+OCpUoGvzVsXeqFdtAEfVa5BILAeFt+U7yVmLbQnAJmw==", "requires": { "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-module-transforms": "^7.19.0", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-validator-identifier": "^7.18.6", - "babel-plugin-dynamic-import-node": "^2.3.3" + "@babel/helper-module-transforms": "^7.20.11", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-validator-identifier": "^7.19.1" } }, "@babel/plugin-transform-modules-umd": { @@ -866,12 +868,12 @@ } }, "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.19.1", - "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.19.1.tgz", - "integrity": "sha512-oWk9l9WItWBQYS4FgXD4Uyy5kq898lvkXpXQxoJEY1RnvPk4R/Dvu2ebXU9q8lP+rlMwUQTFf2Ok6d78ODa0kw==", + "version": "7.20.5", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.20.5.tgz", + "integrity": "sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA==", "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.19.0", - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-create-regexp-features-plugin": "^7.20.5", + "@babel/helper-plugin-utils": "^7.20.2" } }, "@babel/plugin-transform-new-target": { @@ -901,11 +903,11 @@ } }, "@babel/plugin-transform-parameters": { - "version": "7.18.8", - "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.18.8.tgz", - "integrity": "sha512-ivfbE3X2Ss+Fj8nnXvKJS6sjRG4gzwPMsP+taZC+ZzEGjAYlvENixmt1sZ5Ca6tWls+BlKSGKPJ6OOXvXCbkFg==", + "version": "7.20.7", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.7.tgz", + "integrity": "sha512-WiWBIkeHKVOSYPO0pWkxGPfKeWrCJyD3NJ53+Lrp/QMSZbsVPovrVl2aWZ19D/LTVnaDv5Ap7GJ/B2CTOZdrfA==", "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.20.2" } }, "@babel/plugin-transform-property-literals": { @@ -925,15 +927,15 @@ } }, "@babel/plugin-transform-react-jsx": { - "version": "7.19.0", - "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.19.0.tgz", - "integrity": "sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.21.0.tgz", + "integrity": "sha512-6OAWljMvQrZjR2DaNhVfRz6dkCAVV+ymcLUmaf8bccGOHn2v5rHJK3tTpij0BuhdYWP4LLaqj5lwcdlpAAPuvg==", "requires": { "@babel/helper-annotate-as-pure": "^7.18.6", "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-jsx": "^7.18.6", - "@babel/types": "^7.19.0" + "@babel/types": "^7.21.0" } }, "@babel/plugin-transform-react-jsx-development": { @@ -954,12 +956,12 @@ } }, "@babel/plugin-transform-regenerator": { - "version": "7.18.6", - "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.6.tgz", - "integrity": "sha512-poqRI2+qiSdeldcz4wTSTXBRryoq3Gc70ye7m7UD5Ww0nE29IXqMl6r7Nd15WBgRd74vloEMlShtH6CKxVzfmQ==", + "version": "7.20.5", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.20.5.tgz", + "integrity": "sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ==", "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "regenerator-transform": "^0.15.0" + "@babel/helper-plugin-utils": "^7.20.2", + "regenerator-transform": "^0.15.1" } }, "@babel/plugin-transform-reserved-words": { @@ -971,12 +973,12 @@ } }, "@babel/plugin-transform-runtime": { - "version": "7.19.1", - "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.19.1.tgz", - "integrity": "sha512-2nJjTUFIzBMP/f/miLxEK9vxwW/KUXsdvN4sR//TmuDhe6yU2h57WmIOE12Gng3MDP/xpjUV/ToZRdcf8Yj4fA==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.21.0.tgz", + "integrity": "sha512-ReY6pxwSzEU0b3r2/T/VhqMKg/AkceBT19X0UptA3/tYi5Pe2eXgEUH+NNMC5nok6c6XQz5tyVTUpuezRfSMSg==", "requires": { "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-plugin-utils": "^7.20.2", "babel-plugin-polyfill-corejs2": "^0.3.3", "babel-plugin-polyfill-corejs3": "^0.6.0", "babel-plugin-polyfill-regenerator": "^0.4.1", @@ -992,12 +994,12 @@ } }, "@babel/plugin-transform-spread": { - "version": "7.19.0", - "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz", - "integrity": "sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w==", + "version": "7.20.7", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.20.7.tgz", + "integrity": "sha512-ewBbHQ+1U/VnH1fxltbJqDeWBU1oNLG8Dj11uIv3xVf7nrQu0bPGe5Rf716r7K5Qz+SqtAOVswoVunoiBtGhxw==", "requires": { - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9" + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0" } }, "@babel/plugin-transform-sticky-regex": { @@ -1025,13 +1027,13 @@ } }, "@babel/plugin-transform-typescript": { - "version": "7.19.1", - "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.19.1.tgz", - "integrity": "sha512-+ILcOU+6mWLlvCwnL920m2Ow3wWx3Wo8n2t5aROQmV55GZt+hOiLvBaa3DNzRjSEHa1aauRs4/YLmkCfFkhhRQ==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.21.0.tgz", + "integrity": "sha512-xo///XTPp3mDzTtrqXoBlK9eiAYW3wv9JXglcn/u1bi60RW11dEUxIgA8cbnDhutS1zacjMRmAwxE0gMklLnZg==", "requires": { - "@babel/helper-create-class-features-plugin": "^7.19.0", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/plugin-syntax-typescript": "^7.18.6" + "@babel/helper-create-class-features-plugin": "^7.21.0", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/plugin-syntax-typescript": "^7.20.0" } }, "@babel/plugin-transform-unicode-escapes": { @@ -1052,17 +1054,17 @@ } }, "@babel/preset-env": { - "version": "7.19.1", - "resolved": "https://registry.npmmirror.com/@babel/preset-env/-/preset-env-7.19.1.tgz", - "integrity": "sha512-c8B2c6D16Lp+Nt6HcD+nHl0VbPKVnNPTpszahuxJJnurfMtKeZ80A+qUv48Y7wqvS+dTFuLuaM9oYxyNHbCLWA==", + "version": "7.20.2", + "resolved": "https://registry.npmmirror.com/@babel/preset-env/-/preset-env-7.20.2.tgz", + "integrity": "sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg==", "requires": { - "@babel/compat-data": "^7.19.1", - "@babel/helper-compilation-targets": "^7.19.1", - "@babel/helper-plugin-utils": "^7.19.0", + "@babel/compat-data": "^7.20.1", + "@babel/helper-compilation-targets": "^7.20.0", + "@babel/helper-plugin-utils": "^7.20.2", "@babel/helper-validator-option": "^7.18.6", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9", - "@babel/plugin-proposal-async-generator-functions": "^7.19.1", + "@babel/plugin-proposal-async-generator-functions": "^7.20.1", "@babel/plugin-proposal-class-properties": "^7.18.6", "@babel/plugin-proposal-class-static-block": "^7.18.6", "@babel/plugin-proposal-dynamic-import": "^7.18.6", @@ -1071,7 +1073,7 @@ "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9", "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", "@babel/plugin-proposal-numeric-separator": "^7.18.6", - "@babel/plugin-proposal-object-rest-spread": "^7.18.9", + "@babel/plugin-proposal-object-rest-spread": "^7.20.2", "@babel/plugin-proposal-optional-catch-binding": "^7.18.6", "@babel/plugin-proposal-optional-chaining": "^7.18.9", "@babel/plugin-proposal-private-methods": "^7.18.6", @@ -1082,7 +1084,7 @@ "@babel/plugin-syntax-class-static-block": "^7.14.5", "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.18.6", + "@babel/plugin-syntax-import-assertions": "^7.20.0", "@babel/plugin-syntax-json-strings": "^7.8.3", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", @@ -1095,10 +1097,10 @@ "@babel/plugin-transform-arrow-functions": "^7.18.6", "@babel/plugin-transform-async-to-generator": "^7.18.6", "@babel/plugin-transform-block-scoped-functions": "^7.18.6", - "@babel/plugin-transform-block-scoping": "^7.18.9", - "@babel/plugin-transform-classes": "^7.19.0", + "@babel/plugin-transform-block-scoping": "^7.20.2", + "@babel/plugin-transform-classes": "^7.20.2", "@babel/plugin-transform-computed-properties": "^7.18.9", - "@babel/plugin-transform-destructuring": "^7.18.13", + "@babel/plugin-transform-destructuring": "^7.20.2", "@babel/plugin-transform-dotall-regex": "^7.18.6", "@babel/plugin-transform-duplicate-keys": "^7.18.9", "@babel/plugin-transform-exponentiation-operator": "^7.18.6", @@ -1106,14 +1108,14 @@ "@babel/plugin-transform-function-name": "^7.18.9", "@babel/plugin-transform-literals": "^7.18.9", "@babel/plugin-transform-member-expression-literals": "^7.18.6", - "@babel/plugin-transform-modules-amd": "^7.18.6", - "@babel/plugin-transform-modules-commonjs": "^7.18.6", - "@babel/plugin-transform-modules-systemjs": "^7.19.0", + "@babel/plugin-transform-modules-amd": "^7.19.6", + "@babel/plugin-transform-modules-commonjs": "^7.19.6", + "@babel/plugin-transform-modules-systemjs": "^7.19.6", "@babel/plugin-transform-modules-umd": "^7.18.6", "@babel/plugin-transform-named-capturing-groups-regex": "^7.19.1", "@babel/plugin-transform-new-target": "^7.18.6", "@babel/plugin-transform-object-super": "^7.18.6", - "@babel/plugin-transform-parameters": "^7.18.8", + "@babel/plugin-transform-parameters": "^7.20.1", "@babel/plugin-transform-property-literals": "^7.18.6", "@babel/plugin-transform-regenerator": "^7.18.6", "@babel/plugin-transform-reserved-words": "^7.18.6", @@ -1125,7 +1127,7 @@ "@babel/plugin-transform-unicode-escapes": "^7.18.10", "@babel/plugin-transform-unicode-regex": "^7.18.6", "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.19.0", + "@babel/types": "^7.20.2", "babel-plugin-polyfill-corejs2": "^0.3.3", "babel-plugin-polyfill-corejs3": "^0.6.0", "babel-plugin-polyfill-regenerator": "^0.4.1", @@ -1159,64 +1161,75 @@ } }, "@babel/preset-typescript": { - "version": "7.18.6", - "resolved": "https://registry.npmmirror.com/@babel/preset-typescript/-/preset-typescript-7.18.6.tgz", - "integrity": "sha512-s9ik86kXBAnD760aybBucdpnLsAt0jK1xqJn2juOn9lkOvSHV60os5hxoVJsPzMQxvnUJFAlkont2DvvaYEBtQ==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/preset-typescript/-/preset-typescript-7.21.0.tgz", + "integrity": "sha512-myc9mpoVA5m1rF8K8DgLEatOYFDpwC+RkMkjZ0Du6uI62YvDe8uxIEYVs/VCdSJ097nlALiU/yBC7//3nI+hNg==", "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-validator-option": "^7.18.6", - "@babel/plugin-transform-typescript": "^7.18.6" + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-validator-option": "^7.21.0", + "@babel/plugin-transform-typescript": "^7.21.0" } }, + "@babel/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmmirror.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==" + }, "@babel/runtime": { - "version": "7.19.0", - "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.19.0.tgz", - "integrity": "sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.21.0.tgz", + "integrity": "sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==", "requires": { - "regenerator-runtime": "^0.13.4" + "regenerator-runtime": "^0.13.11" } }, "@babel/template": { - "version": "7.18.10", - "resolved": "https://registry.npmmirror.com/@babel/template/-/template-7.18.10.tgz", - "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", + "version": "7.20.7", + "resolved": "https://registry.npmmirror.com/@babel/template/-/template-7.20.7.tgz", + "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", "requires": { "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.18.10", - "@babel/types": "^7.18.10" + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" } }, "@babel/traverse": { - "version": "7.19.1", - "resolved": "https://registry.npmmirror.com/@babel/traverse/-/traverse-7.19.1.tgz", - "integrity": "sha512-0j/ZfZMxKukDaag2PtOPDbwuELqIar6lLskVPPJDjXMXjfLb1Obo/1yjxIGqqAJrmfaTIY3z2wFLAQ7qSkLsuA==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/traverse/-/traverse-7.21.0.tgz", + "integrity": "sha512-Xdt2P1H4LKTO8ApPfnO1KmzYMFpp7D/EinoXzLYN/cHcBNrVCAkAtGUcXnHXrl/VGktureU6fkQrHSBE2URfoA==", "requires": { "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.19.0", + "@babel/generator": "^7.21.0", "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", + "@babel/helper-function-name": "^7.21.0", "@babel/helper-hoist-variables": "^7.18.6", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.19.1", - "@babel/types": "^7.19.0", + "@babel/parser": "^7.21.0", + "@babel/types": "^7.21.0", "debug": "^4.1.0", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.19.0", - "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.19.0.tgz", - "integrity": "sha512-YuGopBq3ke25BVSiS6fgF49Ul9gH1x70Bcr6bqRLjWCkcX8Hre1/5+z+IiWOIerRMSSEfGZVB9z9kyq7wVs9YA==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.21.0.tgz", + "integrity": "sha512-uR7NWq2VNFnDi7EYqiRz2Jv/VQIu38tu64Zy8TX2nQFQ6etJ9V/Rr2msW8BS132mum2rL645qpDrLtAJtVpuow==", "requires": { - "@babel/helper-string-parser": "^7.18.10", - "@babel/helper-validator-identifier": "^7.18.6", + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", "to-fast-properties": "^2.0.0" } }, "@ctrl/tinycolor": { - "version": "3.4.1", - "resolved": "https://registry.npmmirror.com/@ctrl/tinycolor/-/tinycolor-3.4.1.tgz", - "integrity": "sha512-ej5oVy6lykXsvieQtqZxCOaLT+xD4+QNarq78cIYISHmZXshCvROLudpQN3lfL8G0NL7plMSSK+zlyvCaIJ4Iw==" + "version": "3.6.0", + "resolved": "https://registry.npmmirror.com/@ctrl/tinycolor/-/tinycolor-3.6.0.tgz", + "integrity": "sha512-/Z3l6pXthq0JvMYdUFyX9j0MaCltlIn6mfh9jLyQwg5aPKxkyNa0PTHtU1AlFXLNk55ZuAeJRcpvq+tmLfKmaQ==" + }, + "@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmmirror.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "dev": true }, "@eslint/eslintrc": { "version": "0.4.3", @@ -1236,9 +1249,9 @@ }, "dependencies": { "globals": { - "version": "13.17.0", - "resolved": "https://registry.npmmirror.com/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "version": "13.20.0", + "resolved": "https://registry.npmmirror.com/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -1336,12 +1349,12 @@ "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" }, "@jridgewell/trace-mapping": { - "version": "0.3.15", - "resolved": "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz", - "integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==", + "version": "0.3.17", + "resolved": "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" } }, "@knowdesign/icons": { @@ -1381,18 +1394,18 @@ } }, "@pmmmwh/react-refresh-webpack-plugin": { - "version": "0.5.7", - "resolved": "https://registry.npmmirror.com/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.7.tgz", - "integrity": "sha512-bcKCAzF0DV2IIROp9ZHkRJa6O4jy7NlnHdWL3GmcUxYWNjLXkK5kfELELwEfSP5hXPfVL/qOGMAROuMQb9GG8Q==", + "version": "0.5.10", + "resolved": "https://registry.npmmirror.com/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.10.tgz", + "integrity": "sha512-j0Ya0hCFZPd4x40qLzbhGsh9TMtdb+CJQiso+WxLOPNasohq9cc5SNUcwsZaRH6++Xh91Xkm/xHCkuIiIu0LUA==", "dev": true, "requires": { "ansi-html-community": "^0.0.8", "common-path-prefix": "^3.0.0", - "core-js-pure": "^3.8.1", + "core-js-pure": "^3.23.3", "error-stack-parser": "^2.0.6", "find-up": "^5.0.0", "html-entities": "^2.1.0", - "loader-utils": "^2.0.0", + "loader-utils": "^2.0.4", "schema-utils": "^3.0.0", "source-map": "^0.7.3" }, @@ -1482,9 +1495,9 @@ "dev": true }, "@types/lodash": { - "version": "4.14.185", - "resolved": "https://registry.npmmirror.com/@types/lodash/-/lodash-4.14.185.tgz", - "integrity": "sha512-evMDG1bC4rgQg4ku9tKpuMh5iBNEwNa3tf9zRHdP1qlv+1WUg44xat4IxCE14gIpZRGUUWAx2VhItCZc25NfMA==", + "version": "4.14.191", + "resolved": "https://registry.npmmirror.com/@types/lodash/-/lodash-4.14.191.tgz", + "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==", "dev": true }, "@types/minimatch": { @@ -1494,9 +1507,9 @@ "dev": true }, "@types/node": { - "version": "18.7.18", - "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.7.18.tgz", - "integrity": "sha512-m+6nTEOadJZuTPkKR/SYK3A2d7FZrgElol9UP1Kae90VVU4a6mxnPuLiIW1m4Cq4gZ/nWb9GrdVXJCoCazDAbg==", + "version": "18.14.0", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.14.0.tgz", + "integrity": "sha512-5EWrvLmglK+imbCJY0+INViFWUHg1AHel1sq4ZVSfdcNqGy9Edv3UB9IIzzg+xPaUcAgZYcfVs2fBcwDeZzU0A==", "dev": true }, "@types/parse-json": { @@ -1521,9 +1534,9 @@ "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" }, "@types/react": { - "version": "18.0.20", - "resolved": "https://registry.npmmirror.com/@types/react/-/react-18.0.20.tgz", - "integrity": "sha512-MWul1teSPxujEHVwZl4a5HxQ9vVNsjTchVA+xRqv/VYGCuKGAU6UhfrTdF5aBefwD1BHUD8i/zq+O/vyCm/FrA==", + "version": "18.0.28", + "resolved": "https://registry.npmmirror.com/@types/react/-/react-18.0.28.tgz", + "integrity": "sha512-RD0ivG1kEztNBdoAK7lekI9M+azSnitIn85h4iOiaLjaTrMjzslhaqCGaI4IyCJ1RljWiLCEu4jyrLLgqxBTew==", "requires": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -1531,18 +1544,18 @@ } }, "@types/react-dom": { - "version": "17.0.17", - "resolved": "https://registry.npmmirror.com/@types/react-dom/-/react-dom-17.0.17.tgz", - "integrity": "sha512-VjnqEmqGnasQKV0CWLevqMTXBYG9GbwuE6x3VetERLh0cq2LTptFE73MrQi2S7GkKXCf2GgwItB/melLnxfnsg==", + "version": "17.0.19", + "resolved": "https://registry.npmmirror.com/@types/react-dom/-/react-dom-17.0.19.tgz", + "integrity": "sha512-PiYG40pnQRdPHnlf7tZnp0aQ6q9tspYr72vD61saO6zFCybLfMqwUCN0va1/P+86DXn18ZWeW30Bk7xlC5eEAQ==", "dev": true, "requires": { "@types/react": "^17" }, "dependencies": { "@types/react": { - "version": "17.0.50", - "resolved": "https://registry.npmmirror.com/@types/react/-/react-17.0.50.tgz", - "integrity": "sha512-ZCBHzpDb5skMnc1zFXAXnL3l1FAdi+xZvwxK+PkglMmBrwjpp9nKaWuEvrGnSifCJmBFGxZOOFuwC6KH/s0NuA==", + "version": "17.0.53", + "resolved": "https://registry.npmmirror.com/@types/react/-/react-17.0.53.tgz", + "integrity": "sha512-1yIpQR2zdYu1Z/dc1OxC+MA6GR240u3gcnP4l6mvj/PJiVaqHsQPmWttsvHsfnhfPbU2FuGmo0wSITPygjBmsw==", "dev": true, "requires": { "@types/prop-types": "*", @@ -1601,9 +1614,9 @@ "dev": true }, "@types/uglify-js": { - "version": "3.17.0", - "resolved": "https://registry.npmmirror.com/@types/uglify-js/-/uglify-js-3.17.0.tgz", - "integrity": "sha512-3HO6rm0y+/cqvOyA8xcYLweF0TKXlAxmQASjbOi49Co51A1N4nR4bEwBgRoD9kNM+rqFGArjKr654SLp2CoGmQ==", + "version": "3.17.1", + "resolved": "https://registry.npmmirror.com/@types/uglify-js/-/uglify-js-3.17.1.tgz", + "integrity": "sha512-GkewRA4i5oXacU/n4MA9+bLgt5/L3F1mKrYvFGm7r2ouLXhRKjuWwo9XHNnbx6WF3vlGW21S3fCvgqxvxXXc5g==", "dev": true, "requires": { "source-map": "^0.6.1" @@ -1615,9 +1628,9 @@ "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==" }, "@types/webpack": { - "version": "4.41.32", - "resolved": "https://registry.npmmirror.com/@types/webpack/-/webpack-4.41.32.tgz", - "integrity": "sha512-cb+0ioil/7oz5//7tZUSwbrSAN/NWHrQylz5cW8G0dWTcF/g+/dSdMlKVZspBYuMAN1+WnwHrkxiRrLcwd0Heg==", + "version": "4.41.33", + "resolved": "https://registry.npmmirror.com/@types/webpack/-/webpack-4.41.33.tgz", + "integrity": "sha512-PPajH64Ft2vWevkerISMtnZ8rTs4YmRbs+23c402J0INmxDKCrhZNvwZYtzx96gY2wAtXdrK1BS2fiC8MlLr3g==", "dev": true, "requires": { "@types/node": "*", @@ -1663,14 +1676,29 @@ "tsutils": "^3.17.1" }, "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmmirror.com/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmmirror.com/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "requires": { "lru-cache": "^6.0.0" } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true } } }, @@ -1732,14 +1760,29 @@ "tsutils": "^3.17.1" }, "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmmirror.com/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmmirror.com/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "requires": { "lru-cache": "^6.0.0" } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true } } }, @@ -2061,9 +2104,9 @@ } }, "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "version": "3.1.3", + "resolved": "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, "requires": { "normalize-path": "^3.0.0", @@ -2110,15 +2153,15 @@ "dev": true }, "array-includes": { - "version": "3.1.5", - "resolved": "https://registry.npmmirror.com/array-includes/-/array-includes-3.1.5.tgz", - "integrity": "sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==", + "version": "3.1.6", + "resolved": "https://registry.npmmirror.com/array-includes/-/array-includes-3.1.6.tgz", + "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", "dev": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", - "es-abstract": "^1.19.5", - "get-intrinsic": "^1.1.1", + "es-abstract": "^1.20.4", + "get-intrinsic": "^1.1.3", "is-string": "^1.0.7" } }, @@ -2151,26 +2194,26 @@ "dev": true }, "array.prototype.flatmap": { - "version": "1.3.0", - "resolved": "https://registry.npmmirror.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.0.tgz", - "integrity": "sha512-PZC9/8TKAIxcWKdyeb77EzULHPrIX/tIZebLJUQOMR1OwYosT8yggdfWScfTBCDj5utONvOuPQQumYsU2ULbkg==", + "version": "1.3.1", + "resolved": "https://registry.npmmirror.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", + "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", "es-shim-unscopables": "^1.0.0" } }, "array.prototype.reduce": { - "version": "1.0.4", - "resolved": "https://registry.npmmirror.com/array.prototype.reduce/-/array.prototype.reduce-1.0.4.tgz", - "integrity": "sha512-WnM+AjG/DvLRLo4DDl+r+SvCzYtD2Jd9oeBYMcEaI7t3fFrHY9M53/wdLcTvmZNQ70IU6Htj0emFkZ5TS+lrdw==", + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/array.prototype.reduce/-/array.prototype.reduce-1.0.5.tgz", + "integrity": "sha512-kDdugMl7id9COE8R7MHF5jWk7Dqt/fs4Pv+JXoICnYwqpjjjbUurz6w5fT5IG6brLdJhv6/VoHB0H7oyIBXd+Q==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", "es-array-method-boxes-properly": "^1.0.0", "is-string": "^1.0.7" } @@ -2211,12 +2254,6 @@ "integrity": "sha512-8nWq2nLTAwd02jTqJExUYFSD/fKq6VH9Y/oG2accc/kdI0V98Bag8d5a4gi3XHz73rDWa2PvTtvcWYquKqSENA==", "dev": true }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmmirror.com/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true - }, "util": { "version": "0.10.3", "resolved": "https://registry.npmmirror.com/util/-/util-0.10.3.tgz", @@ -2247,9 +2284,9 @@ "dev": true }, "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmmirror.com/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", + "version": "1.0.6", + "resolved": "https://registry.npmmirror.com/async-each/-/async-each-1.0.6.tgz", + "integrity": "sha512-c646jH1avxr+aVpndVMeAfYw7wAa6idufrlN3LPA4PmKS0QEGp6PIC9nwz0WQkkvBGAMEki3pFdtxaF39J9vvg==", "dev": true }, "async-limiter": { @@ -2269,6 +2306,12 @@ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", "dev": true }, + "available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "dev": true + }, "axios": { "version": "0.21.4", "resolved": "https://registry.npmmirror.com/axios/-/axios-0.21.4.tgz", @@ -2300,9 +2343,9 @@ } }, "babel-loader": { - "version": "8.2.5", - "resolved": "https://registry.npmmirror.com/babel-loader/-/babel-loader-8.2.5.tgz", - "integrity": "sha512-OSiFfH89LrEMiWd4pLNqGz4CwJDtbs2ZVc+iGu2HrkRfPxId9F2anQj38IxWpmRfsUY0aBZYi1EFcd3mhtRMLQ==", + "version": "8.3.0", + "resolved": "https://registry.npmmirror.com/babel-loader/-/babel-loader-8.3.0.tgz", + "integrity": "sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q==", "dev": true, "requires": { "find-cache-dir": "^3.3.1", @@ -2333,18 +2376,10 @@ } } }, - "babel-plugin-dynamic-import-node": { - "version": "2.3.3", - "resolved": "https://registry.npmmirror.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", - "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", - "requires": { - "object.assign": "^4.1.0" - } - }, "babel-plugin-import": { - "version": "1.13.5", - "resolved": "https://registry.npmmirror.com/babel-plugin-import/-/babel-plugin-import-1.13.5.tgz", - "integrity": "sha512-IkqnoV+ov1hdJVofly9pXRJmeDm9EtROfrc5i6eII0Hix2xMs5FEm8FG3ExMvazbnZBbgHIt6qdO8And6lCloQ==", + "version": "1.13.6", + "resolved": "https://registry.npmmirror.com/babel-plugin-import/-/babel-plugin-import-1.13.6.tgz", + "integrity": "sha512-N7FYnGh0DFsvDRkAPsvFq/metVfVD7P2h1rokOPpEH4cZbdRHCW+2jbXt0nnuqowkm/xhh2ww1anIdEpfYa7ZA==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.0.0" @@ -2540,9 +2575,9 @@ "dev": true }, "body-parser": { - "version": "1.20.0", - "resolved": "https://registry.npmmirror.com/body-parser/-/body-parser-1.20.0.tgz", - "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", + "version": "1.20.1", + "resolved": "https://registry.npmmirror.com/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", "dev": true, "requires": { "bytes": "3.1.2", @@ -2553,7 +2588,7 @@ "http-errors": "2.0.0", "iconv-lite": "0.4.24", "on-finished": "2.4.1", - "qs": "6.10.3", + "qs": "6.11.0", "raw-body": "2.5.1", "type-is": "~1.6.18", "unpipe": "1.0.0" @@ -2579,15 +2614,6 @@ "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true - }, - "qs": { - "version": "6.10.3", - "resolved": "https://registry.npmmirror.com/qs/-/qs-6.10.3.tgz", - "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", - "dev": true, - "requires": { - "side-channel": "^1.0.4" - } } } }, @@ -2729,14 +2755,14 @@ } }, "browserslist": { - "version": "4.21.3", - "resolved": "https://registry.npmmirror.com/browserslist/-/browserslist-4.21.3.tgz", - "integrity": "sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ==", + "version": "4.21.5", + "resolved": "https://registry.npmmirror.com/browserslist/-/browserslist-4.21.5.tgz", + "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", "requires": { - "caniuse-lite": "^1.0.30001370", - "electron-to-chromium": "^1.4.202", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.5" + "caniuse-lite": "^1.0.30001449", + "electron-to-chromium": "^1.4.284", + "node-releases": "^2.0.8", + "update-browserslist-db": "^1.0.10" } }, "buffer": { @@ -2815,23 +2841,6 @@ "ssri": "^6.0.1", "unique-filename": "^1.1.1", "y18n": "^4.0.0" - }, - "dependencies": { - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmmirror.com/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - } } }, "cache-base": { @@ -2866,18 +2875,18 @@ }, "dependencies": { "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmmirror.com/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, "requires": { "minimist": "^1.2.0" } }, "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "version": "1.4.2", + "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-1.4.2.tgz", + "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", "dev": true, "requires": { "big.js": "^5.2.2", @@ -2949,9 +2958,9 @@ }, "dependencies": { "tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", + "version": "2.5.0", + "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.5.0.tgz", + "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==", "dev": true } } @@ -2975,9 +2984,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001400", - "resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001400.tgz", - "integrity": "sha512-Mv659Hn65Z4LgZdJ7ge5JTVbE3rqbJaaXgW5LEI9/tOaXclfIZ8DW7D7FCWWWmWiiPS7AC48S8kf3DApSxQdgA==" + "version": "1.0.30001457", + "resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001457.tgz", + "integrity": "sha512-SDIV6bgE1aVbK6XyxdURbUE89zY7+k1BBBaOwYwkNCglXlel/E7mELiHC64HQ+W0xSKlqWhV9Wh7iHxUjMs4fA==" }, "case-sensitive-paths-webpack-plugin": { "version": "2.4.0", @@ -3249,9 +3258,9 @@ } }, "codemirror": { - "version": "5.65.8", - "resolved": "https://registry.npmmirror.com/codemirror/-/codemirror-5.65.8.tgz", - "integrity": "sha512-TNGkSkkoAsmZSf6W6g35LMVQJBHKasc2CKwhr/fTxSYun7cn6J+CbtyNjV/MYlFVkNTsqZoviegyCZimWhoMMA==" + "version": "5.65.12", + "resolved": "https://registry.npmmirror.com/codemirror/-/codemirror-5.65.12.tgz", + "integrity": "sha512-z2jlHBocElRnPYysN2HAuhXbO3DNB0bcSKmNz3hcWR2Js2Dkhc1bEOxG93Z3DeUrnm+qx56XOY5wQmbP5KY0sw==" }, "collection-visit": { "version": "1.0.0", @@ -3379,9 +3388,9 @@ } }, "compute-scroll-into-view": { - "version": "1.0.17", - "resolved": "https://registry.npmmirror.com/compute-scroll-into-view/-/compute-scroll-into-view-1.0.17.tgz", - "integrity": "sha512-j4dx+Fb0URmzbwwMUrhqWM2BEWHdFGx+qZ9qqASHRPqvTYdqvWnHg0H1hIbcyLnvgnoNAVMlwkepyqM3DaIFUg==" + "version": "1.0.20", + "resolved": "https://registry.npmmirror.com/compute-scroll-into-view/-/compute-scroll-into-view-1.0.20.tgz", + "integrity": "sha512-UCB0ioiyj8CRjtrvaceBLqqhZCVP+1B8+NWQhmdsm0VXOJtobBCf1dBQmebCCo34qZmUwZfIH2MZLqNHazrfjg==" }, "concat-map": { "version": "0.0.1", @@ -3437,18 +3446,15 @@ } }, "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmmirror.com/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "dev": true }, "convert-source-map": { - "version": "1.8.0", - "resolved": "https://registry.npmmirror.com/convert-source-map/-/convert-source-map-1.8.0.tgz", - "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", - "requires": { - "safe-buffer": "~5.1.1" - } + "version": "1.9.0", + "resolved": "https://registry.npmmirror.com/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" }, "cookie": { "version": "0.5.0", @@ -3491,9 +3497,9 @@ "dev": true }, "copy-to-clipboard": { - "version": "3.3.2", - "resolved": "https://registry.npmmirror.com/copy-to-clipboard/-/copy-to-clipboard-3.3.2.tgz", - "integrity": "sha512-Vme1Z6RUDzrb6xAI7EZlVZ5uvOk2F//GaxKUxajDqm9LhOVM1inxNAD2vy+UZDYsd0uyA9s7b3/FVZPSxqrCfg==", + "version": "3.3.3", + "resolved": "https://registry.npmmirror.com/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz", + "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==", "requires": { "toggle-selection": "^1.0.6" } @@ -3504,17 +3510,17 @@ "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==" }, "core-js-compat": { - "version": "3.25.1", - "resolved": "https://registry.npmmirror.com/core-js-compat/-/core-js-compat-3.25.1.tgz", - "integrity": "sha512-pOHS7O0i8Qt4zlPW/eIFjwp+NrTPx+wTL0ctgI2fHn31sZOq89rDsmtc/A2vAX7r6shl+bmVI+678He46jgBlw==", + "version": "3.28.0", + "resolved": "https://registry.npmmirror.com/core-js-compat/-/core-js-compat-3.28.0.tgz", + "integrity": "sha512-myzPgE7QodMg4nnd3K1TDoES/nADRStM8Gpz0D6nhkwbmwEnE0ZGJgoWsvQ722FR8D7xS0n0LV556RcEicjTyg==", "requires": { - "browserslist": "^4.21.3" + "browserslist": "^4.21.5" } }, "core-js-pure": { - "version": "3.25.1", - "resolved": "https://registry.npmmirror.com/core-js-pure/-/core-js-pure-3.25.1.tgz", - "integrity": "sha512-7Fr74bliUDdeJCBMxkkIuQ4xfxn/SwrVg+HkJUAoNEXVqYLv55l6Af0dJ5Lq2YBUW9yKqSkLXaS5SYPK6MGa/A==", + "version": "3.28.0", + "resolved": "https://registry.npmmirror.com/core-js-pure/-/core-js-pure-3.28.0.tgz", + "integrity": "sha512-DSOVleA9/v3LNj/vFxAPfUHttKTzrB2RXhAPvR5TPXn4vrra3Z2ssytvRyt8eruJwAfwAiFADEbrjcRdcvPLQQ==", "dev": true }, "core-util-is": { @@ -3524,9 +3530,9 @@ "dev": true }, "cosmiconfig": { - "version": "7.0.1", - "resolved": "https://registry.npmmirror.com/cosmiconfig/-/cosmiconfig-7.0.1.tgz", - "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", + "version": "7.1.0", + "resolved": "https://registry.npmmirror.com/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", "requires": { "@types/parse-json": "^4.0.0", "import-fresh": "^3.2.1", @@ -3660,18 +3666,18 @@ }, "dependencies": { "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmmirror.com/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, "requires": { "minimist": "^1.2.0" } }, "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "version": "1.4.2", + "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-1.4.2.tgz", + "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", "dev": true, "requires": { "big.js": "^5.2.2", @@ -3899,9 +3905,9 @@ "integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==" }, "dayjs": { - "version": "1.11.5", - "resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.5.tgz", - "integrity": "sha512-CAdX5Q3YW3Gclyo5Vpqkgpj8fSdLQcRuzfX6mC6Phy0nfJ0eGYOeS7m4mt2plDWLAtA4TqTakvbboHvUxfe4iA==" + "version": "1.11.7", + "resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.7.tgz", + "integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==" }, "debug": { "version": "4.3.4", @@ -3918,9 +3924,9 @@ "dev": true }, "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmmirror.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==" + "version": "0.2.2", + "resolved": "https://registry.npmmirror.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz", + "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==" }, "dedent": { "version": "0.7.0", @@ -4049,9 +4055,10 @@ } }, "define-properties": { - "version": "1.1.4", - "resolved": "https://registry.npmmirror.com/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/define-properties/-/define-properties-1.2.0.tgz", + "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", + "dev": true, "requires": { "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" @@ -4142,12 +4149,6 @@ "dev": true } } - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmmirror.com/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true } } }, @@ -4264,9 +4265,9 @@ } }, "dom-align": { - "version": "1.12.3", - "resolved": "https://registry.npmmirror.com/dom-align/-/dom-align-1.12.3.tgz", - "integrity": "sha512-Gj9hZN3a07cbR6zviMUBOMPdWxYhbMI+x+WS0NAIu2zFZmbK8ys9R79g+iG9qLnlCwpFoaB+fKy8Pdv470GsPA==" + "version": "1.12.4", + "resolved": "https://registry.npmmirror.com/dom-align/-/dom-align-1.12.4.tgz", + "integrity": "sha512-R8LUSEay/68zE5c8/3BDxiTEvgb4xZTF0RKmAHfiEVN3klfIpXfi2/QCoiWPccVQ0J/ZGdz9OjzL4uJEP/MRAw==" }, "dom-converter": { "version": "0.2.0", @@ -4340,9 +4341,9 @@ }, "dependencies": { "tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", + "version": "2.5.0", + "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.5.0.tgz", + "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==", "dev": true } } @@ -4365,9 +4366,9 @@ } }, "dotenv": { - "version": "16.0.2", - "resolved": "https://registry.npmmirror.com/dotenv/-/dotenv-16.0.2.tgz", - "integrity": "sha512-JvpYKUmzQhYoIFgK2MOnF3bciIZoItIIoryihy0rIA+H4Jy0FmgyKYAHCTN98P5ybGSJcIFbh6QKeJdtZd1qhA==" + "version": "16.0.3", + "resolved": "https://registry.npmmirror.com/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==" }, "duplexer": { "version": "0.1.2", @@ -4388,12 +4389,12 @@ } }, "echarts": { - "version": "5.3.3", - "resolved": "https://registry.npmmirror.com/echarts/-/echarts-5.3.3.tgz", - "integrity": "sha512-BRw2serInRwO5SIwRviZ6Xgm5Lb7irgz+sLiFMmy/HOaf4SQ+7oYqxKzRHAKp4xHQ05AuHw1xvoQWJjDQq/FGw==", + "version": "5.4.1", + "resolved": "https://registry.npmmirror.com/echarts/-/echarts-5.4.1.tgz", + "integrity": "sha512-9ltS3M2JB0w2EhcYjCdmtrJ+6haZcW6acBolMGIuf01Hql1yrIV01L1aRj7jsaaIULJslEP9Z3vKlEmnJaWJVQ==", "requires": { "tslib": "2.3.0", - "zrender": "5.3.2" + "zrender": "5.4.1" }, "dependencies": { "tslib": { @@ -4419,9 +4420,9 @@ "dev": true }, "electron-to-chromium": { - "version": "1.4.251", - "resolved": "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.4.251.tgz", - "integrity": "sha512-k4o4cFrWPv4SoJGGAydd07GmlRVzmeDIJ6MaEChTUjk4Dmomn189tCicSzil2oyvbPoGgg2suwPDNWq4gWRhoQ==" + "version": "1.4.308", + "resolved": "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.4.308.tgz", + "integrity": "sha512-qyTx2aDFjEni4UnRWEME9ubd2Xc9c0zerTUl/ZinvD4QPsF0S7kJTV/Es/lPCTkNX6smyYar+z/n8Cl6pFr8yQ==" }, "elliptic": { "version": "6.5.4", @@ -4525,34 +4526,44 @@ } }, "es-abstract": { - "version": "1.20.2", - "resolved": "https://registry.npmmirror.com/es-abstract/-/es-abstract-1.20.2.tgz", - "integrity": "sha512-XxXQuVNrySBNlEkTYJoDNFe5+s2yIOpzq80sUHEdPdQr0S5nTLz4ZPPPswNIpKseDDUS5yghX1gfLIHQZ1iNuQ==", + "version": "1.21.1", + "resolved": "https://registry.npmmirror.com/es-abstract/-/es-abstract-1.21.1.tgz", + "integrity": "sha512-QudMsPOz86xYz/1dG1OuGBKOELjCh99IIWHLzy5znUB6j8xG2yMA7bfTV86VSqKF+Y/H08vQPR+9jyXpuC6hfg==", "dev": true, "requires": { + "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", + "es-set-tostringtag": "^2.0.1", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.1.2", + "get-intrinsic": "^1.1.3", "get-symbol-description": "^1.0.0", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", "has": "^1.0.3", "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", "has-symbols": "^1.0.3", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", + "internal-slot": "^1.0.4", + "is-array-buffer": "^3.0.1", + "is-callable": "^1.2.7", "is-negative-zero": "^2.0.2", "is-regex": "^1.1.4", "is-shared-array-buffer": "^1.0.2", "is-string": "^1.0.7", + "is-typed-array": "^1.1.10", "is-weakref": "^1.0.2", "object-inspect": "^1.12.2", "object-keys": "^1.1.1", "object.assign": "^4.1.4", "regexp.prototype.flags": "^1.4.3", - "string.prototype.trimend": "^1.0.5", - "string.prototype.trimstart": "^1.0.5", - "unbox-primitive": "^1.0.2" + "safe-regex-test": "^1.0.0", + "string.prototype.trimend": "^1.0.6", + "string.prototype.trimstart": "^1.0.6", + "typed-array-length": "^1.0.4", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.9" } }, "es-array-method-boxes-properly": { @@ -4561,6 +4572,17 @@ "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", "dev": true }, + "es-set-tostringtag": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", + "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.3", + "has": "^1.0.3", + "has-tostringtag": "^1.0.0" + } + }, "es-shim-unscopables": { "version": "1.0.0", "resolved": "https://registry.npmmirror.com/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", @@ -4695,9 +4717,9 @@ "dev": true }, "globals": { - "version": "13.17.0", - "resolved": "https://registry.npmmirror.com/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "version": "13.20.0", + "resolved": "https://registry.npmmirror.com/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -4715,10 +4737,19 @@ "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmmirror.com/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmmirror.com/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -4732,6 +4763,12 @@ "requires": { "has-flag": "^4.0.0" } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true } } }, @@ -4845,9 +4882,9 @@ "dev": true }, "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmmirror.com/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "version": "1.4.2", + "resolved": "https://registry.npmmirror.com/esquery/-/esquery-1.4.2.tgz", + "integrity": "sha512-JVSoLdTlTDkmjFmab7H/9SL9qGSyjElT3myyKp7krqjVFQCDLmj1QFaCLRFBszBKI0XVZaiiXvuPIX3ZwHe1Ng==", "dev": true, "requires": { "estraverse": "^5.1.0" @@ -5000,14 +5037,14 @@ } }, "express": { - "version": "4.18.1", - "resolved": "https://registry.npmmirror.com/express/-/express-4.18.1.tgz", - "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==", + "version": "4.18.2", + "resolved": "https://registry.npmmirror.com/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", "dev": true, "requires": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.0", + "body-parser": "1.20.1", "content-disposition": "0.5.4", "content-type": "~1.0.4", "cookie": "0.5.0", @@ -5026,7 +5063,7 @@ "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", "proxy-addr": "~2.0.7", - "qs": "6.10.3", + "qs": "6.11.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", "send": "0.18.0", @@ -5065,15 +5102,6 @@ "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", "dev": true }, - "qs": { - "version": "6.10.3", - "resolved": "https://registry.npmmirror.com/qs/-/qs-6.10.3.tgz", - "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", - "dev": true, - "requires": { - "side-channel": "^1.0.4" - } - }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -5205,9 +5233,9 @@ "dev": true }, "fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmmirror.com/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "version": "1.15.0", + "resolved": "https://registry.npmmirror.com/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", "dev": true, "requires": { "reusify": "^1.0.4" @@ -5513,6 +5541,15 @@ "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.2.tgz", "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" }, + "for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmmirror.com/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "requires": { + "is-callable": "^1.1.3" + } + }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmmirror.com/for-in/-/for-in-1.0.2.tgz", @@ -5621,9 +5658,9 @@ "dev": true }, "get-intrinsic": { - "version": "1.1.3", - "resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.1.3.tgz", - "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.2.0.tgz", + "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", "requires": { "function-bind": "^1.1.1", "has": "^1.0.3", @@ -5744,6 +5781,15 @@ "resolved": "https://registry.npmmirror.com/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" }, + "globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3" + } + }, "globby": { "version": "11.1.0", "resolved": "https://registry.npmmirror.com/globby/-/globby-11.1.0.tgz", @@ -5758,6 +5804,15 @@ "slash": "^3.0.0" } }, + "gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.3" + } + }, "graceful-fs": { "version": "4.2.10", "resolved": "https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.10.tgz", @@ -5963,10 +6018,17 @@ "version": "1.0.0", "resolved": "https://registry.npmmirror.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "dev": true, "requires": { "get-intrinsic": "^1.1.1" } }, + "has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "dev": true + }, "has-symbols": { "version": "1.0.3", "resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.0.3.tgz", @@ -6216,18 +6278,18 @@ }, "dependencies": { "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmmirror.com/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, "requires": { "minimist": "^1.2.0" } }, "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "version": "1.4.2", + "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-1.4.2.tgz", + "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", "dev": true, "requires": { "big.js": "^5.2.2", @@ -6529,9 +6591,9 @@ "dev": true }, "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmmirror.com/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "version": "5.2.4", + "resolved": "https://registry.npmmirror.com/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", "dev": true }, "image-size": { @@ -6670,12 +6732,12 @@ } }, "internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmmirror.com/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/internal-slot/-/internal-slot-1.0.5.tgz", + "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", "dev": true, "requires": { - "get-intrinsic": "^1.1.0", + "get-intrinsic": "^1.2.0", "has": "^1.0.3", "side-channel": "^1.0.4" } @@ -6784,6 +6846,17 @@ "has-tostringtag": "^1.0.0" } }, + "is-array-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/is-array-buffer/-/is-array-buffer-3.0.1.tgz", + "integrity": "sha512-ASfLknmY8Xa2XtB4wmbz13Wu202baeA18cJBCeCy0wXUHZF0IPyVEXqKEcd+t2fNSLLL1vC6k7lxZEojNbISXQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-typed-array": "^1.1.10" + } + }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmmirror.com/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -6825,9 +6898,9 @@ "dev": true }, "is-callable": { - "version": "1.2.6", - "resolved": "https://registry.npmmirror.com/is-callable/-/is-callable-1.2.6.tgz", - "integrity": "sha512-krO72EO2NptOGAX2KYyqbP9vYMlNAXdB53rq6f8LXY6RY7JdSR/3BD6wLUlPHSAesmY9vstNrjvqGaCiRK/91Q==", + "version": "1.2.7", + "resolved": "https://registry.npmmirror.com/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "dev": true }, "is-color-stop": { @@ -6845,9 +6918,9 @@ } }, "is-core-module": { - "version": "2.10.0", - "resolved": "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.10.0.tgz", - "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", + "version": "2.11.0", + "resolved": "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", "requires": { "has": "^1.0.3" } @@ -7064,6 +7137,19 @@ "has-symbols": "^1.0.2" } }, + "is-typed-array": { + "version": "1.1.10", + "resolved": "https://registry.npmmirror.com/is-typed-array/-/is-typed-array-1.1.10.tgz", + "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", + "dev": true, + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + } + }, "is-unicode-supported": { "version": "0.1.0", "resolved": "https://registry.npmmirror.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", @@ -7129,9 +7215,9 @@ } }, "jsencrypt": { - "version": "3.2.1", - "resolved": "https://registry.npmmirror.com/jsencrypt/-/jsencrypt-3.2.1.tgz", - "integrity": "sha512-k1sD5QV0KPn+D8uG9AdGzTQuamt82QZ3A3l6f7TRwMU6Oi2Vg0BsL+wZIQBONcraO1pc78ExMdvmBBJ8WhNYUA==" + "version": "3.3.1", + "resolved": "https://registry.npmmirror.com/jsencrypt/-/jsencrypt-3.3.1.tgz", + "integrity": "sha512-dVvV54GdFuJgmEKn+oBiaifDMen4p6o6j/lJh0OVMcouME8sST0bJ7bldIgKBQk4za0zyGn0/pm4vOznR25mLw==" }, "jsesc": { "version": "2.5.2", @@ -7176,9 +7262,9 @@ } }, "json5": { - "version": "2.2.1", - "resolved": "https://registry.npmmirror.com/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==" + "version": "2.2.3", + "resolved": "https://registry.npmmirror.com/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" }, "jsx-ast-utils": { "version": "3.3.3", @@ -7196,6 +7282,13 @@ "integrity": "sha512-iCxmRTlUAWmXwHZxN0JSx/T7eRi0SkKAskE0lp+j4W1mzdNp49ja/9QI2ZmlggPM95RqnDw5ioYjw0EcvpIClw==", "requires": { "object-assign": "^3.0.0" + }, + "dependencies": { + "object-assign": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/object-assign/-/object-assign-3.0.0.tgz", + "integrity": "sha512-jHP15vXVGeVh1HuaA2wY6lxk+whK/x4KBG88VXeRma7CCun7iGD5qPc4eYykQ9sdQvg8jkwFKsSxHln2ybW3xQ==" + } } }, "killable": { @@ -7307,11 +7400,11 @@ }, "dependencies": { "query-string": { - "version": "7.1.1", - "resolved": "https://registry.npmmirror.com/query-string/-/query-string-7.1.1.tgz", - "integrity": "sha512-MplouLRDHBZSG9z7fpuAAcI7aAYjDLhtsiVZsevsfaHWDS2IDdORKbSd1kWUA+V4zyva/HZoSfpwnYMMQDhb0w==", + "version": "7.1.3", + "resolved": "https://registry.npmmirror.com/query-string/-/query-string-7.1.3.tgz", + "integrity": "sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==", "requires": { - "decode-uri-component": "^0.2.0", + "decode-uri-component": "^0.2.2", "filter-obj": "^1.1.0", "split-on-first": "^1.0.0", "strict-uri-encode": "^2.0.0" @@ -7364,18 +7457,18 @@ }, "dependencies": { "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmmirror.com/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, "requires": { "minimist": "^1.2.0" } }, "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "version": "1.4.2", + "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-1.4.2.tgz", + "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", "dev": true, "requires": { "big.js": "^5.2.2", @@ -7520,9 +7613,9 @@ "dev": true }, "loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", + "version": "2.0.4", + "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", "dev": true, "requires": { "big.js": "^5.2.2", @@ -7684,9 +7777,9 @@ } }, "loglevel": { - "version": "1.8.0", - "resolved": "https://registry.npmmirror.com/loglevel/-/loglevel-1.8.0.tgz", - "integrity": "sha512-G6A/nJLRgWOuuwdNuA6koovfEV1YpqqAG4pRUlFaz3jj2QNZ8M4vBqnVA+HBTmU/AMNUtlOsMmSpF6NyOjztbA==", + "version": "1.8.1", + "resolved": "https://registry.npmmirror.com/loglevel/-/loglevel-1.8.1.tgz", + "integrity": "sha512-tCRIJM51SHjAayKwC+QAg8hT8vg6z7GSgLJKGvzuPb1Wc+hLzqtuVLxp6/HzSPOozuK+8ErAhy7U/sVzw8Dgfg==", "dev": true }, "loose-envify": { @@ -7707,9 +7800,9 @@ }, "dependencies": { "tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", + "version": "2.5.0", + "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.5.0.tgz", + "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==", "dev": true } } @@ -7724,12 +7817,11 @@ } }, "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, + "version": "5.1.1", + "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "requires": { - "yallist": "^4.0.0" + "yallist": "^3.0.2" } }, "make-dir": { @@ -7831,9 +7923,9 @@ "dev": true }, "metismenujs": { - "version": "1.3.1", - "resolved": "https://registry.npmmirror.com/metismenujs/-/metismenujs-1.3.1.tgz", - "integrity": "sha512-bb2f78827KWj/zeY9ZmnEnuEU9kRaW/WL1r5jJ2ALAtY34qSIvygE/HzNw1QXWQrW6t4ILELZGS6CcDz6gr5mw==" + "version": "1.4.0", + "resolved": "https://registry.npmmirror.com/metismenujs/-/metismenujs-1.4.0.tgz", + "integrity": "sha512-a+3/XVkG8fVA6HBYu1yQkUkVpbh2n9po3vhSzu/Pu5k6s2hbteFZMRzUQyHt6FF28N8pLOpzcb47w4ErBHEsDQ==" }, "micromatch": { "version": "4.0.5", @@ -7931,9 +8023,9 @@ } }, "minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmmirror.com/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", + "version": "1.2.8", + "resolved": "https://registry.npmmirror.com/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true }, "mississippi": { @@ -8049,9 +8141,9 @@ "dev": true }, "nan": { - "version": "2.16.0", - "resolved": "https://registry.npmmirror.com/nan/-/nan-2.16.0.tgz", - "integrity": "sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA==", + "version": "2.17.0", + "resolved": "https://registry.npmmirror.com/nan/-/nan-2.17.0.tgz", + "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==", "dev": true, "optional": true }, @@ -8115,9 +8207,9 @@ }, "dependencies": { "tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", + "version": "2.5.0", + "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.5.0.tgz", + "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==", "dev": true } } @@ -8174,9 +8266,9 @@ "dev": true }, "node-releases": { - "version": "2.0.6", - "resolved": "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.6.tgz", - "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==" + "version": "2.0.10", + "resolved": "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.10.tgz", + "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==" }, "normalize-path": { "version": "3.0.0", @@ -8214,9 +8306,9 @@ } }, "object-assign": { - "version": "3.0.0", - "resolved": "https://registry.npmmirror.com/object-assign/-/object-assign-3.0.0.tgz", - "integrity": "sha512-jHP15vXVGeVh1HuaA2wY6lxk+whK/x4KBG88VXeRma7CCun7iGD5qPc4eYykQ9sdQvg8jkwFKsSxHln2ybW3xQ==" + "version": "4.1.1", + "resolved": "https://registry.npmmirror.com/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" }, "object-copy": { "version": "0.1.0", @@ -8250,9 +8342,9 @@ } }, "object-inspect": { - "version": "1.12.2", - "resolved": "https://registry.npmmirror.com/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==" + "version": "1.12.3", + "resolved": "https://registry.npmmirror.com/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==" }, "object-is": { "version": "1.1.5", @@ -8267,7 +8359,8 @@ "object-keys": { "version": "1.1.1", "resolved": "https://registry.npmmirror.com/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true }, "object-visit": { "version": "1.0.1", @@ -8282,6 +8375,7 @@ "version": "4.1.4", "resolved": "https://registry.npmmirror.com/object.assign/-/object.assign-4.1.4.tgz", "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "dev": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", @@ -8290,37 +8384,37 @@ } }, "object.entries": { - "version": "1.1.5", - "resolved": "https://registry.npmmirror.com/object.entries/-/object.entries-1.1.5.tgz", - "integrity": "sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==", + "version": "1.1.6", + "resolved": "https://registry.npmmirror.com/object.entries/-/object.entries-1.1.6.tgz", + "integrity": "sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" } }, "object.fromentries": { - "version": "2.0.5", - "resolved": "https://registry.npmmirror.com/object.fromentries/-/object.fromentries-2.0.5.tgz", - "integrity": "sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw==", + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/object.fromentries/-/object.fromentries-2.0.6.tgz", + "integrity": "sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" } }, "object.getownpropertydescriptors": { - "version": "2.1.4", - "resolved": "https://registry.npmmirror.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.4.tgz", - "integrity": "sha512-sccv3L/pMModT6dJAYF3fzGMVcb38ysQ0tEE6ixv2yXJDtEIPph268OlAdJj5/qZMZDq2g/jqvwppt36uS/uQQ==", + "version": "2.1.5", + "resolved": "https://registry.npmmirror.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.5.tgz", + "integrity": "sha512-yDNzckpM6ntyQiGTik1fKV1DcVDRS+w8bvpWNCBanvH5LfRX9O8WTHqQzG4RZwRAM4I0oU7TV11Lj5v0g20ibw==", "dev": true, "requires": { - "array.prototype.reduce": "^1.0.4", + "array.prototype.reduce": "^1.0.5", "call-bind": "^1.0.2", "define-properties": "^1.1.4", - "es-abstract": "^1.20.1" + "es-abstract": "^1.20.4" } }, "object.pick": { @@ -8333,14 +8427,14 @@ } }, "object.values": { - "version": "1.1.5", - "resolved": "https://registry.npmmirror.com/object.values/-/object.values-1.1.5.tgz", - "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", + "version": "1.1.6", + "resolved": "https://registry.npmmirror.com/object.values/-/object.values-1.1.6.tgz", + "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" } }, "obuf": { @@ -8514,9 +8608,9 @@ }, "dependencies": { "tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", + "version": "2.5.0", + "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.5.0.tgz", + "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==", "dev": true } } @@ -8589,9 +8683,9 @@ }, "dependencies": { "tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", + "version": "2.5.0", + "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.5.0.tgz", + "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==", "dev": true } } @@ -9170,9 +9264,9 @@ } }, "postcss-selector-parser": { - "version": "6.0.10", - "resolved": "https://registry.npmmirror.com/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", - "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", + "version": "6.0.11", + "resolved": "https://registry.npmmirror.com/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz", + "integrity": "sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==", "dev": true, "requires": { "cssesc": "^3.0.0", @@ -9334,13 +9428,6 @@ "loose-envify": "^1.4.0", "object-assign": "^4.1.1", "react-is": "^16.13.1" - }, - "dependencies": { - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmmirror.com/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" - } } }, "property-information": { @@ -9422,9 +9509,9 @@ } }, "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmmirror.com/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "version": "2.3.0", + "resolved": "https://registry.npmmirror.com/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", "dev": true }, "q": { @@ -9451,11 +9538,6 @@ "strict-uri-encode": "^1.0.0" }, "dependencies": { - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmmirror.com/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" - }, "strict-uri-encode": { "version": "1.1.0", "resolved": "https://registry.npmmirror.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", @@ -9541,15 +9623,14 @@ } }, "rc-align": { - "version": "4.0.12", - "resolved": "https://registry.npmmirror.com/rc-align/-/rc-align-4.0.12.tgz", - "integrity": "sha512-3DuwSJp8iC/dgHzwreOQl52soj40LchlfUHtgACOUtwGuoFIOVh6n/sCpfqCU8kO5+iz6qR0YKvjgB8iPdE3aQ==", + "version": "4.0.15", + "resolved": "https://registry.npmmirror.com/rc-align/-/rc-align-4.0.15.tgz", + "integrity": "sha512-wqJtVH60pka/nOX7/IspElA8gjPNQKIx/ZqJ6heATCkXpe1Zg4cPVrMD2vC96wjsFFL8WsmhPbx9tdMo1qqlIA==", "requires": { "@babel/runtime": "^7.10.1", "classnames": "2.x", "dom-align": "^1.7.0", - "lodash": "^4.17.21", - "rc-util": "^5.3.0", + "rc-util": "^5.26.0", "resize-observer-polyfill": "^1.5.1" } }, @@ -9641,9 +9722,9 @@ } }, "rc-input-number": { - "version": "7.3.7", - "resolved": "https://registry.npmmirror.com/rc-input-number/-/rc-input-number-7.3.7.tgz", - "integrity": "sha512-W9jDwfhJyNjg0iZX401r0GctTGX4ETURzF6SisC42GR0AkJxtaPD89eGwbTdAudUjEx0Pkn2rGmfvVGGdQACKA==", + "version": "7.3.11", + "resolved": "https://registry.npmmirror.com/rc-input-number/-/rc-input-number-7.3.11.tgz", + "integrity": "sha512-aMWPEjFeles6PQnMqP5eWpxzsvHm9rh1jQOWXExUEIxhX62Fyl/ptifLHOn17+waDG1T/YUb6flfJbvwRhHrbA==", "requires": { "@babel/runtime": "^7.10.1", "classnames": "^2.2.5", @@ -9694,9 +9775,9 @@ } }, "rc-motion": { - "version": "2.6.2", - "resolved": "https://registry.npmmirror.com/rc-motion/-/rc-motion-2.6.2.tgz", - "integrity": "sha512-4w1FaX3dtV749P8GwfS4fYnFG4Rb9pxvCYPc/b2fw1cmlHJWNNgOFIz7ysiD+eOrzJSvnLJWlNQQncpNMXwwpg==", + "version": "2.6.3", + "resolved": "https://registry.npmmirror.com/rc-motion/-/rc-motion-2.6.3.tgz", + "integrity": "sha512-xFLkes3/7VL/J+ah9jJruEW/Akbx5F6jVa2wG5o/ApGKQKSOd5FR3rseHLL9+xtJg4PmCwo6/1tqhDO/T+jFHA==", "requires": { "@babel/runtime": "^7.11.1", "classnames": "^2.2.1", @@ -9769,13 +9850,13 @@ } }, "rc-resize-observer": { - "version": "1.2.0", - "resolved": "https://registry.npmmirror.com/rc-resize-observer/-/rc-resize-observer-1.2.0.tgz", - "integrity": "sha512-6W+UzT3PyDM0wVCEHfoW3qTHPTvbdSgiA43buiy8PzmeMnfgnDeb9NjdimMXMl3/TcrvvWl5RRVdp+NqcR47pQ==", + "version": "1.3.1", + "resolved": "https://registry.npmmirror.com/rc-resize-observer/-/rc-resize-observer-1.3.1.tgz", + "integrity": "sha512-iFUdt3NNhflbY3mwySv5CA1TC06zdJ+pfo0oc27xpf4PIOvfZwZGtD9Kz41wGYqC4SLio93RVAirSSpYlV/uYg==", "requires": { - "@babel/runtime": "^7.10.1", + "@babel/runtime": "^7.20.7", "classnames": "^2.2.1", - "rc-util": "^5.15.0", + "rc-util": "^5.27.0", "resize-observer-polyfill": "^1.5.1" } }, @@ -9912,9 +9993,9 @@ } }, "rc-trigger": { - "version": "5.3.1", - "resolved": "https://registry.npmmirror.com/rc-trigger/-/rc-trigger-5.3.1.tgz", - "integrity": "sha512-5gaFbDkYSefZ14j2AdzucXzlWgU2ri5uEjkHvsf1ynRhdJbKxNOnw4PBZ9+FVULNGFiDzzlVF8RJnR9P/xrnKQ==", + "version": "5.3.4", + "resolved": "https://registry.npmmirror.com/rc-trigger/-/rc-trigger-5.3.4.tgz", + "integrity": "sha512-mQv+vas0TwKcjAO2izNPkqR4j86OemLRmvL2nOzdP9OWNWA1ivoTt5hzFqYNW9zACwmTezRiN8bttrC7cZzYSw==", "requires": { "@babel/runtime": "^7.18.3", "classnames": "^2.2.6", @@ -9934,20 +10015,20 @@ } }, "rc-util": { - "version": "5.24.2", - "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.24.2.tgz", - "integrity": "sha512-MWd0ZEV7xSwN4HM9jz9BwpnMzwCPjYJ7K90lePsrdgAkrmm8U7b4BOTIsv/84BQsaF7N3ejNkcrZ3AfEwc9HXA==", + "version": "5.28.0", + "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.28.0.tgz", + "integrity": "sha512-KYDjhGodswVj29v0TRciKTqRPgumIFvFDndbCD227pitQ+0Cei196rxk+OXb/blu6V8zdTRK5RjCJn+WmHLvBA==", "requires": { "@babel/runtime": "^7.18.3", - "react-is": "^16.12.0", - "shallowequal": "^1.1.0" + "react-is": "^16.12.0" } }, "rc-virtual-list": { - "version": "3.4.8", - "resolved": "https://registry.npmmirror.com/rc-virtual-list/-/rc-virtual-list-3.4.8.tgz", - "integrity": "sha512-qSN+Rv4i/E7RCTvTMr1uZo7f3crJJg/5DekoCagydo9zsXrxj07zsFSxqizqW+ldGA16lwa8So/bIbV9Ofjddg==", + "version": "3.4.13", + "resolved": "https://registry.npmmirror.com/rc-virtual-list/-/rc-virtual-list-3.4.13.tgz", + "integrity": "sha512-cPOVDmcNM7rH6ANotanMDilW/55XnFPw0Jh/GQYtrzZSy3AmWvCnqVNyNC/pgg3lfVmX2994dlzAhuUrd4jG7w==", "requires": { + "@babel/runtime": "^7.20.0", "classnames": "^2.2.6", "rc-resize-observer": "^1.0.0", "rc-util": "^5.15.0" @@ -9961,13 +10042,6 @@ "loose-envify": "^1.1.0", "object-assign": "^4.1.1", "prop-types": "^15.6.2" - }, - "dependencies": { - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmmirror.com/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" - } } }, "react-codemirror2": { @@ -10035,13 +10109,6 @@ "object-assign": "^4.1.1", "prop-types": "^15.6.2", "scheduler": "^0.18.0" - }, - "dependencies": { - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmmirror.com/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" - } } }, "react-draggable": { @@ -10247,13 +10314,6 @@ "requires": { "object-assign": "^4.1.1", "react-is": "^16.12.0 || ^17.0.0 || ^18.0.0" - }, - "dependencies": { - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmmirror.com/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" - } } }, "react-side-effect": { @@ -10306,11 +10366,6 @@ "scheduler": "^0.20.2" }, "dependencies": { - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmmirror.com/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" - }, "react-is": { "version": "17.0.2", "resolved": "https://registry.npmmirror.com/react-is/-/react-is-17.0.2.tgz", @@ -10378,9 +10433,9 @@ } }, "react-window": { - "version": "1.8.7", - "resolved": "https://registry.npmmirror.com/react-window/-/react-window-1.8.7.tgz", - "integrity": "sha512-JHEZbPXBpKMmoNO1bNhoXOOLg/ujhL/BU4IqVU9r8eQPcy5KQnGHIHDRkJ0ns9IM5+Aq5LNwt3j8t3tIrePQzA==", + "version": "1.8.8", + "resolved": "https://registry.npmmirror.com/react-window/-/react-window-1.8.8.tgz", + "integrity": "sha512-D4IiBeRtGXziZ1n0XklnFGu7h9gU684zepqyKzgPNzrsrk7xOCxni+TCckjg2Nr/DiaEEGVVmnhYSlT2rB47dQ==", "requires": { "@babel/runtime": "^7.0.0", "memoize-one": ">=3.1.1 <6" @@ -10402,9 +10457,9 @@ } }, "reactstrap": { - "version": "9.1.4", - "resolved": "https://registry.npmmirror.com/reactstrap/-/reactstrap-9.1.4.tgz", - "integrity": "sha512-kn+Ex58V4tZatogn472n5fkgvCkXwhQvlqCRGTjpM1MzkD9wv0rp5W0VcM60purpdtzkud2ku6KHvJrqYqnv0w==", + "version": "9.1.6", + "resolved": "https://registry.npmmirror.com/reactstrap/-/reactstrap-9.1.6.tgz", + "integrity": "sha512-79h/L/pvMJIz198VULMpLbEyXFeArFTLAnEtk5anppJhAnZnfyM1pNuQWZNGXy6cUlgsaEy2gBziAw4tockOnw==", "requires": { "@babel/runtime": "^7.12.5", "@popperjs/core": "^2.6.0", @@ -10448,9 +10503,9 @@ } }, "redux": { - "version": "4.2.0", - "resolved": "https://registry.npmmirror.com/redux/-/redux-4.2.0.tgz", - "integrity": "sha512-oSBmcKKIuIR4ME29/AeNUnl5L+hvBq7OaJWzaptTQJAntaPvxIJqfnjbaEiCzzaIz+XmVILfqAM3Ob0aXLPfjA==", + "version": "4.2.1", + "resolved": "https://registry.npmmirror.com/redux/-/redux-4.2.1.tgz", + "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", "requires": { "@babel/runtime": "^7.9.2" } @@ -10486,14 +10541,14 @@ } }, "regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" + "version": "0.13.11", + "resolved": "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" }, "regenerator-transform": { - "version": "0.15.0", - "resolved": "https://registry.npmmirror.com/regenerator-transform/-/regenerator-transform-0.15.0.tgz", - "integrity": "sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg==", + "version": "0.15.1", + "resolved": "https://registry.npmmirror.com/regenerator-transform/-/regenerator-transform-0.15.1.tgz", + "integrity": "sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==", "requires": { "@babel/runtime": "^7.8.4" } @@ -10526,23 +10581,18 @@ "dev": true }, "regexpu-core": { - "version": "5.2.1", - "resolved": "https://registry.npmmirror.com/regexpu-core/-/regexpu-core-5.2.1.tgz", - "integrity": "sha512-HrnlNtpvqP1Xkb28tMhBUO2EbyUHdQlsnlAhzWcwHy8WJR53UWr7/MAvqrsQKMbV4qdpv03oTMG8iIhfsPFktQ==", + "version": "5.3.1", + "resolved": "https://registry.npmmirror.com/regexpu-core/-/regexpu-core-5.3.1.tgz", + "integrity": "sha512-nCOzW2V/X15XpLsK2rlgdwrysrBq+AauCn+omItIz4R1pIcmeot5zvjdmOBRLzEH/CkC6IxMJVmxDe3QcMuNVQ==", "requires": { + "@babel/regjsgen": "^0.8.0", "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.1.0", - "regjsgen": "^0.7.1", "regjsparser": "^0.9.1", "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.0.0" + "unicode-match-property-value-ecmascript": "^2.1.0" } }, - "regjsgen": { - "version": "0.7.1", - "resolved": "https://registry.npmmirror.com/regjsgen/-/regjsgen-0.7.1.tgz", - "integrity": "sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==" - }, "regjsparser": { "version": "0.9.1", "resolved": "https://registry.npmmirror.com/regjsparser/-/regjsparser-0.9.1.tgz", @@ -10791,18 +10841,18 @@ } }, "rxjs": { - "version": "7.5.6", - "resolved": "https://registry.npmmirror.com/rxjs/-/rxjs-7.5.6.tgz", - "integrity": "sha512-dnyv2/YsXhnm461G+R/Pe5bWP41Nm6LBXEYWI6eiFP4fiwx6WRI/CD0zbdVAudd9xwLEF2IDcKXLHit0FYjUzw==", + "version": "7.8.0", + "resolved": "https://registry.npmmirror.com/rxjs/-/rxjs-7.8.0.tgz", + "integrity": "sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==", "dev": true, "requires": { "tslib": "^2.1.0" }, "dependencies": { "tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", + "version": "2.5.0", + "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.5.0.tgz", + "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==", "dev": true } } @@ -10810,7 +10860,8 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true }, "safe-regex": { "version": "1.1.0", @@ -10821,6 +10872,17 @@ "ret": "~0.1.10" } }, + "safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + } + }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -10840,13 +10902,6 @@ "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" - }, - "dependencies": { - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmmirror.com/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" - } } }, "schema-utils": { @@ -10861,11 +10916,11 @@ } }, "scroll-into-view-if-needed": { - "version": "2.2.29", - "resolved": "https://registry.npmmirror.com/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.29.tgz", - "integrity": "sha512-hxpAR6AN+Gh53AdAimHM6C8oTN1ppwVZITihix+WqalywBeFcQ6LdQP5ABNl26nX8GTEL7VT+b8lKpdqq65wXg==", + "version": "2.2.31", + "resolved": "https://registry.npmmirror.com/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.31.tgz", + "integrity": "sha512-dGCXy99wZQivjmjIqihaBQNjryrz5rueJY7eHfTdyWEiR4ttYpsajb14rn9s5d4DY4EcY6+4+U/maARBXJedkA==", "requires": { - "compute-scroll-into-view": "^1.0.17" + "compute-scroll-into-view": "^1.0.20" } }, "select-hose": { @@ -11620,41 +11675,41 @@ } }, "string.prototype.matchall": { - "version": "4.0.7", - "resolved": "https://registry.npmmirror.com/string.prototype.matchall/-/string.prototype.matchall-4.0.7.tgz", - "integrity": "sha512-f48okCX7JiwVi1NXCVWcFnZgADDC/n2vePlQ/KUCNqCikLLilQvwjMO8+BHVKvgzH0JB0J9LEPgxOGT02RoETg==", + "version": "4.0.8", + "resolved": "https://registry.npmmirror.com/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz", + "integrity": "sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1", - "get-intrinsic": "^1.1.1", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "get-intrinsic": "^1.1.3", "has-symbols": "^1.0.3", "internal-slot": "^1.0.3", - "regexp.prototype.flags": "^1.4.1", + "regexp.prototype.flags": "^1.4.3", "side-channel": "^1.0.4" } }, "string.prototype.trimend": { - "version": "1.0.5", - "resolved": "https://registry.npmmirror.com/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", - "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", + "version": "1.0.6", + "resolved": "https://registry.npmmirror.com/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", + "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", "dev": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" + "es-abstract": "^1.20.4" } }, "string.prototype.trimstart": { - "version": "1.0.5", - "resolved": "https://registry.npmmirror.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", - "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", + "version": "1.0.6", + "resolved": "https://registry.npmmirror.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", + "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", "dev": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" + "es-abstract": "^1.20.4" } }, "string_decoder": { @@ -11826,9 +11881,9 @@ } }, "table": { - "version": "6.8.0", - "resolved": "https://registry.npmmirror.com/table/-/table-6.8.0.tgz", - "integrity": "sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==", + "version": "6.8.1", + "resolved": "https://registry.npmmirror.com/table/-/table-6.8.1.tgz", + "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", "dev": true, "requires": { "ajv": "^8.0.1", @@ -11839,9 +11894,9 @@ }, "dependencies": { "ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmmirror.com/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "version": "8.12.0", + "resolved": "https://registry.npmmirror.com/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -12025,9 +12080,9 @@ "dev": true }, "tiny-invariant": { - "version": "1.2.0", - "resolved": "https://registry.npmmirror.com/tiny-invariant/-/tiny-invariant-1.2.0.tgz", - "integrity": "sha512-1Uhn/aqw5C6RI4KejVeTg6mIS7IqxnLJ8Mv2tV5rTc0qWobay7pDUz6Wi392Cnc8ak1H0F2cjoRzb2/AW4+Fvg==" + "version": "1.3.1", + "resolved": "https://registry.npmmirror.com/tiny-invariant/-/tiny-invariant-1.3.1.tgz", + "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==" }, "tiny-warning": { "version": "1.0.3", @@ -12035,9 +12090,9 @@ "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" }, "tinycolor2": { - "version": "1.4.2", - "resolved": "https://registry.npmmirror.com/tinycolor2/-/tinycolor2-1.4.2.tgz", - "integrity": "sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA==" + "version": "1.6.0", + "resolved": "https://registry.npmmirror.com/tinycolor2/-/tinycolor2-1.6.0.tgz", + "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==" }, "to-arraybuffer": { "version": "1.0.1", @@ -12161,10 +12216,19 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmmirror.com/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmmirror.com/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -12178,6 +12242,12 @@ "requires": { "has-flag": "^4.0.0" } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true } } }, @@ -12234,6 +12304,17 @@ "mime-types": "~2.1.24" } }, + "typed-array-length": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/typed-array-length/-/typed-array-length-1.0.4.tgz", + "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "is-typed-array": "^1.1.9" + } + }, "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmmirror.com/typedarray/-/typedarray-0.0.6.tgz", @@ -12273,9 +12354,9 @@ } }, "unicode-match-property-value-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmmirror.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz", - "integrity": "sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==" + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", + "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==" }, "unicode-property-aliases-ecmascript": { "version": "2.1.0", @@ -12389,9 +12470,9 @@ "dev": true }, "update-browserslist-db": { - "version": "1.0.9", - "resolved": "https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.0.9.tgz", - "integrity": "sha512-/xsqn21EGVdXI3EXSum1Yckj3ZVZugqyOZQ/CxYPBD/R+ko9NSUScf8tFF4dOKY+2pvSSJA/S+5B8s4Zr4kyvg==", + "version": "1.0.10", + "resolved": "https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", "requires": { "escalade": "^3.1.1", "picocolors": "^1.0.0" @@ -12905,18 +12986,18 @@ } }, "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmmirror.com/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, "requires": { "minimist": "^1.2.0" } }, "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "version": "1.4.2", + "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-1.4.2.tgz", + "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", "dev": true, "requires": { "big.js": "^5.2.2", @@ -12979,11 +13060,12 @@ } }, "webpack-bundle-analyzer": { - "version": "4.6.1", - "resolved": "https://registry.npmmirror.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.6.1.tgz", - "integrity": "sha512-oKz9Oz9j3rUciLNfpGFjOb49/jEpXNmWdVH8Ls//zNcnLlQdTGXQQMsBbb/gR7Zl8WNLxVCq+0Hqbx3zv6twBw==", + "version": "4.8.0", + "resolved": "https://registry.npmmirror.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.8.0.tgz", + "integrity": "sha512-ZzoSBePshOKhr+hd8u6oCkZVwpVaXgpw23ScGLFpR6SjYI7+7iIWYarjN6OEYOfRt8o7ZyZZQk0DuMizJ+LEIg==", "dev": true, "requires": { + "@discoveryjs/json-ext": "0.5.7", "acorn": "^8.0.4", "acorn-walk": "^8.0.0", "chalk": "^4.1.0", @@ -12996,9 +13078,9 @@ }, "dependencies": { "acorn": { - "version": "8.8.0", - "resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", + "version": "8.8.2", + "resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", "dev": true }, "ansi-styles": { @@ -13091,18 +13173,18 @@ } }, "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmmirror.com/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, "requires": { "minimist": "^1.2.0" } }, "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "version": "1.4.2", + "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-1.4.2.tgz", + "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", "dev": true, "requires": { "big.js": "^5.2.2", @@ -13583,6 +13665,20 @@ "integrity": "sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==", "dev": true }, + "which-typed-array": { + "version": "1.1.9", + "resolved": "https://registry.npmmirror.com/which-typed-array/-/which-typed-array-1.1.9.tgz", + "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", + "dev": true, + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0", + "is-typed-array": "^1.1.10" + } + }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmmirror.com/word-wrap/-/word-wrap-1.2.3.tgz", @@ -13701,10 +13797,9 @@ "dev": true }, "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" }, "yaml": { "version": "1.10.2", @@ -13829,9 +13924,9 @@ "dev": true }, "zrender": { - "version": "5.3.2", - "resolved": "https://registry.npmmirror.com/zrender/-/zrender-5.3.2.tgz", - "integrity": "sha512-8IiYdfwHj2rx0UeIGZGGU4WEVSDEdeVCaIg/fomejg1Xu6OifAL1GVzIPHg2D+MyUkbNgPWji90t0a8IDk+39w==", + "version": "5.4.1", + "resolved": "https://registry.npmmirror.com/zrender/-/zrender-5.4.1.tgz", + "integrity": "sha512-M4Z05BHWtajY2241EmMPHglDQAJ1UyHQcYsxDNzD9XLSkPDqMq4bB28v9Pb4mvHnVQ0GxyTklZ/69xCFP6RXBA==", "requires": { "tslib": "2.3.0" }, diff --git a/km-console/packages/config-manager-fe/package.json b/km-console/packages/config-manager-fe/package.json index 42f8c3c8..28ed2fbc 100644 --- a/km-console/packages/config-manager-fe/package.json +++ b/km-console/packages/config-manager-fe/package.json @@ -8,13 +8,6 @@ "ident": "config", "homepage": "", "license": "ISC", - "publishConfig": { - "registry": "http://registry.npm.xiaojukeji.com/" - }, - "repository": { - "type": "git", - "url": "git@git.xiaojukeji.com:bigdata-cloud/d1.git" - }, "scripts": { "test": "echo \"Error: run tests from root\" && exit 1", "start": "cross-env NODE_ENV=development webpack-dev-server", diff --git a/km-console/packages/config-manager-fe/src/components/TypicalListCard/index.less b/km-console/packages/config-manager-fe/src/components/TypicalListCard/index.less index 9a48d134..a4272ad7 100644 --- a/km-console/packages/config-manager-fe/src/components/TypicalListCard/index.less +++ b/km-console/packages/config-manager-fe/src/components/TypicalListCard/index.less @@ -32,6 +32,15 @@ color: #74788d; cursor: pointer; } + .refresh-icon{ + .icon{ + padding: 3px; + border-radius: 50%; + &:hover { + background: rgba(33, 37, 41, 0.04); + } + } + } .right .search-input { width: 248px; margin-right: 8px; diff --git a/km-console/packages/config-manager-fe/src/pages/UserManage/RoleTabContent.tsx b/km-console/packages/config-manager-fe/src/pages/UserManage/RoleTabContent.tsx index f7db974b..eb0b82e9 100644 --- a/km-console/packages/config-manager-fe/src/pages/UserManage/RoleTabContent.tsx +++ b/km-console/packages/config-manager-fe/src/pages/UserManage/RoleTabContent.tsx @@ -423,7 +423,7 @@ export default (props: { curTabKey: string }): JSX.Element => { dataIndex: 'authedUserCnt', width: 100, render(cnt: Pick, record: RoleProps) { - return ( + return cnt ? ( { {cnt} + ) : ( + ); }, }, diff --git a/km-console/packages/config-manager-fe/src/pages/UserManage/UserTabContent.tsx b/km-console/packages/config-manager-fe/src/pages/UserManage/UserTabContent.tsx index 0ca3ca29..8a569b3b 100644 --- a/km-console/packages/config-manager-fe/src/pages/UserManage/UserTabContent.tsx +++ b/km-console/packages/config-manager-fe/src/pages/UserManage/UserTabContent.tsx @@ -53,7 +53,7 @@ const EditUserDrawer = forwardRef((props, ref) => { }) : request(api.editUser, { method: 'POST', - data: { ...formData }, + data: { ...formData, phone: Date.now() }, }); requestPromise.then( (res) => { diff --git a/km-console/packages/layout-clusters-fe/config/theme.js b/km-console/packages/layout-clusters-fe/config/theme.js index cd58375e..3d57d2ab 100755 --- a/km-console/packages/layout-clusters-fe/config/theme.js +++ b/km-console/packages/layout-clusters-fe/config/theme.js @@ -1,7 +1,7 @@ const themeConfig = { - primaryColor: '#556ee6', + primaryColor: '#5664FF', theme: { - 'primary-color': '#556ee6', + 'primary-color': '#5664FF', 'border-radius-base': '2px', 'border-radius-sm': '2px', 'font-size-base': '12px', diff --git a/km-console/packages/layout-clusters-fe/config/webpack.dev.js b/km-console/packages/layout-clusters-fe/config/webpack.dev.js index 6c7776ca..60f2bbf2 100644 --- a/km-console/packages/layout-clusters-fe/config/webpack.dev.js +++ b/km-console/packages/layout-clusters-fe/config/webpack.dev.js @@ -34,11 +34,11 @@ module.exports = { proxy: { '/ks-km/api/v3': { changeOrigin: true, - target: 'http://localhost:8080/', + target: 'https://api-kylin-xg02.intra.xiaojukeji.com/ks-km/', }, '/logi-security/api/v1': { changeOrigin: true, - target: 'http://localhost:8080/', + target: 'https://api-kylin-xg02.intra.xiaojukeji.com/ks-km/', }, }, }, diff --git a/km-console/packages/layout-clusters-fe/package-lock.json b/km-console/packages/layout-clusters-fe/package-lock.json index 7a98639a..837de6ae 100644 --- a/km-console/packages/layout-clusters-fe/package-lock.json +++ b/km-console/packages/layout-clusters-fe/package-lock.json @@ -38,9 +38,9 @@ } }, "@ant-design/icons": { - "version": "4.7.0", - "resolved": "https://registry.npmmirror.com/@ant-design/icons/-/icons-4.7.0.tgz", - "integrity": "sha512-aoB4Z7JA431rt6d4u+8xcNPPCrdufSRMUOpxa1ab6mz1JCQZOEVolj2WVs/tDFmN62zzK30mNelEsprLYsSF3g==", + "version": "4.8.0", + "resolved": "https://registry.npmmirror.com/@ant-design/icons/-/icons-4.8.0.tgz", + "integrity": "sha512-T89P2jG2vM7OJ0IfGx2+9FC5sQjtTzRSz+mCHTXkFn/ELZc2YpfStmYHmqzq2Jx55J0F7+O6i5/ZKFSVNWCKNg==", "requires": { "@ant-design/colors": "^6.0.0", "@ant-design/icons-svg": "^4.2.1", @@ -50,13 +50,12 @@ }, "dependencies": { "rc-util": { - "version": "5.24.2", - "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.24.2.tgz", - "integrity": "sha512-MWd0ZEV7xSwN4HM9jz9BwpnMzwCPjYJ7K90lePsrdgAkrmm8U7b4BOTIsv/84BQsaF7N3ejNkcrZ3AfEwc9HXA==", + "version": "5.28.0", + "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.28.0.tgz", + "integrity": "sha512-KYDjhGodswVj29v0TRciKTqRPgumIFvFDndbCD227pitQ+0Cei196rxk+OXb/blu6V8zdTRK5RjCJn+WmHLvBA==", "requires": { "@babel/runtime": "^7.18.3", - "react-is": "^16.12.0", - "shallowequal": "^1.1.0" + "react-is": "^16.12.0" } } } @@ -87,39 +86,40 @@ } }, "@babel/compat-data": { - "version": "7.19.1", - "resolved": "https://registry.npmmirror.com/@babel/compat-data/-/compat-data-7.19.1.tgz", - "integrity": "sha512-72a9ghR0gnESIa7jBN53U32FOVCEoztyIlKaNoU05zRhEecduGK9L9c3ww7Mp06JiR+0ls0GBPFJQwwtjn9ksg==" + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/compat-data/-/compat-data-7.21.0.tgz", + "integrity": "sha512-gMuZsmsgxk/ENC3O/fRw5QY8A9/uxQbbCEypnLIiYYc/qVJtEV7ouxC3EllIIwNzMqAQee5tanFabWsUOutS7g==" }, "@babel/core": { - "version": "7.19.1", - "resolved": "https://registry.npmmirror.com/@babel/core/-/core-7.19.1.tgz", - "integrity": "sha512-1H8VgqXme4UXCRv7/Wa1bq7RVymKOzC7znjyFM8KiEzwFqcKUKYNoQef4GhdklgNvoBXyW4gYhuBNCM5o1zImw==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/core/-/core-7.21.0.tgz", + "integrity": "sha512-PuxUbxcW6ZYe656yL3EAhpy7qXKq0DmYsrJLpbB8XrsCP9Nm+XCg9XFMb5vIDliPD7+U/+M+QJlH17XOcB7eXA==", "requires": { - "@ampproject/remapping": "^2.1.0", + "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.19.0", - "@babel/helper-compilation-targets": "^7.19.1", - "@babel/helper-module-transforms": "^7.19.0", - "@babel/helpers": "^7.19.0", - "@babel/parser": "^7.19.1", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.1", - "@babel/types": "^7.19.0", + "@babel/generator": "^7.21.0", + "@babel/helper-compilation-targets": "^7.20.7", + "@babel/helper-module-transforms": "^7.21.0", + "@babel/helpers": "^7.21.0", + "@babel/parser": "^7.21.0", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.21.0", + "@babel/types": "^7.21.0", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", + "json5": "^2.2.2", "semver": "^6.3.0" } }, "@babel/generator": { - "version": "7.19.0", - "resolved": "https://registry.npmmirror.com/@babel/generator/-/generator-7.19.0.tgz", - "integrity": "sha512-S1ahxf1gZ2dpoiFgA+ohK9DIpz50bJ0CWs7Zlzb54Z4sG8qmdIrGrVqmy1sAtTVRb+9CU6U8VqT9L0Zj7hxHVg==", + "version": "7.21.1", + "resolved": "https://registry.npmmirror.com/@babel/generator/-/generator-7.21.1.tgz", + "integrity": "sha512-1lT45bAYlQhFn/BHivJs43AiW2rg3/UbLyShGfF3C0KmHvO5fSghWd5kBJy30kpRRucGzXStvnnCFniCR2kXAA==", "requires": { - "@babel/types": "^7.19.0", + "@babel/types": "^7.21.0", "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" }, "dependencies": { @@ -153,37 +153,39 @@ } }, "@babel/helper-compilation-targets": { - "version": "7.19.1", - "resolved": "https://registry.npmmirror.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.1.tgz", - "integrity": "sha512-LlLkkqhCMyz2lkQPvJNdIYU7O5YjWRgC2R4omjCTpZd8u8KMQzZvX4qce+/BluN1rcQiV7BoGUpmQ0LeHerbhg==", + "version": "7.20.7", + "resolved": "https://registry.npmmirror.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", + "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", "requires": { - "@babel/compat-data": "^7.19.1", + "@babel/compat-data": "^7.20.5", "@babel/helper-validator-option": "^7.18.6", "browserslist": "^4.21.3", + "lru-cache": "^5.1.1", "semver": "^6.3.0" } }, "@babel/helper-create-class-features-plugin": { - "version": "7.19.0", - "resolved": "https://registry.npmmirror.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.19.0.tgz", - "integrity": "sha512-NRz8DwF4jT3UfrmUoZjd0Uph9HQnP30t7Ash+weACcyNkiYTywpIjDBgReJMKgr+n86sn2nPVVmJ28Dm053Kqw==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.21.0.tgz", + "integrity": "sha512-Q8wNiMIdwsv5la5SPxNYzzkPnjgC0Sy0i7jLkVOCdllu/xcVNkr3TeZzbHBJrj+XXRqzX5uCyCoV9eu6xUG7KQ==", "requires": { "@babel/helper-annotate-as-pure": "^7.18.6", "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-member-expression-to-functions": "^7.18.9", + "@babel/helper-function-name": "^7.21.0", + "@babel/helper-member-expression-to-functions": "^7.21.0", "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-replace-supers": "^7.18.9", + "@babel/helper-replace-supers": "^7.20.7", + "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", "@babel/helper-split-export-declaration": "^7.18.6" } }, "@babel/helper-create-regexp-features-plugin": { - "version": "7.19.0", - "resolved": "https://registry.npmmirror.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.19.0.tgz", - "integrity": "sha512-htnV+mHX32DF81amCDrwIDr8nrp1PTm+3wfBN9/v8QJOLEioOCOG7qNyq0nHeFiWbT3Eb7gsPwEmV64UCQ1jzw==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.21.0.tgz", + "integrity": "sha512-N+LaFW/auRSWdx7SHD/HiARwXQju1vXTW4fKr4u5SgBUTm51OKEjKgj+cs00ggW3kEvNqwErnlwuq7Y3xBe4eg==", "requires": { "@babel/helper-annotate-as-pure": "^7.18.6", - "regexpu-core": "^5.1.0" + "regexpu-core": "^5.3.1" } }, "@babel/helper-define-polyfill-provider": { @@ -213,12 +215,12 @@ } }, "@babel/helper-function-name": { - "version": "7.19.0", - "resolved": "https://registry.npmmirror.com/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", - "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz", + "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==", "requires": { - "@babel/template": "^7.18.10", - "@babel/types": "^7.19.0" + "@babel/template": "^7.20.7", + "@babel/types": "^7.21.0" } }, "@babel/helper-hoist-variables": { @@ -230,11 +232,11 @@ } }, "@babel/helper-member-expression-to-functions": { - "version": "7.18.9", - "resolved": "https://registry.npmmirror.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz", - "integrity": "sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.21.0.tgz", + "integrity": "sha512-Muu8cdZwNN6mRRNG6lAYErJ5X3bRevgYR2O8wN0yn7jJSnGDu6eG59RfT29JHxGUovyfrh6Pj0XzmR7drNVL3Q==", "requires": { - "@babel/types": "^7.18.9" + "@babel/types": "^7.21.0" } }, "@babel/helper-module-imports": { @@ -246,18 +248,18 @@ } }, "@babel/helper-module-transforms": { - "version": "7.19.0", - "resolved": "https://registry.npmmirror.com/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz", - "integrity": "sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/helper-module-transforms/-/helper-module-transforms-7.21.0.tgz", + "integrity": "sha512-eD/JQ21IG2i1FraJnTMbUarAUkA7G988ofehG5MDCRXaUU91rEBJuCeSoou2Sk1y4RbLYXzqEg1QLwEmRU4qcQ==", "requires": { "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.18.6", + "@babel/helper-simple-access": "^7.20.2", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.18.6", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.0", - "@babel/types": "^7.19.0" + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.21.0", + "@babel/types": "^7.21.0" } }, "@babel/helper-optimise-call-expression": { @@ -269,9 +271,9 @@ } }, "@babel/helper-plugin-utils": { - "version": "7.19.0", - "resolved": "https://registry.npmmirror.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz", - "integrity": "sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==" + "version": "7.20.2", + "resolved": "https://registry.npmmirror.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", + "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==" }, "@babel/helper-remap-async-to-generator": { "version": "7.18.9", @@ -285,31 +287,32 @@ } }, "@babel/helper-replace-supers": { - "version": "7.19.1", - "resolved": "https://registry.npmmirror.com/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz", - "integrity": "sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw==", + "version": "7.20.7", + "resolved": "https://registry.npmmirror.com/@babel/helper-replace-supers/-/helper-replace-supers-7.20.7.tgz", + "integrity": "sha512-vujDMtB6LVfNW13jhlCrp48QNslK6JXi7lQG736HVbHz/mbf4Dc7tIRh1Xf5C0rF7BP8iiSxGMCmY6Ci1ven3A==", "requires": { "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-member-expression-to-functions": "^7.18.9", + "@babel/helper-member-expression-to-functions": "^7.20.7", "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/traverse": "^7.19.1", - "@babel/types": "^7.19.0" + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.7", + "@babel/types": "^7.20.7" } }, "@babel/helper-simple-access": { - "version": "7.18.6", - "resolved": "https://registry.npmmirror.com/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz", - "integrity": "sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==", + "version": "7.20.2", + "resolved": "https://registry.npmmirror.com/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", + "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", "requires": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.20.2" } }, "@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.18.9", - "resolved": "https://registry.npmmirror.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.18.9.tgz", - "integrity": "sha512-imytd2gHi3cJPsybLRbmFrF7u5BIEuI2cNheyKi3/iOBC63kNn3q8Crn2xVuESli0aM4KYsyEqKyS7lFL8YVtw==", + "version": "7.20.0", + "resolved": "https://registry.npmmirror.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz", + "integrity": "sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==", "requires": { - "@babel/types": "^7.18.9" + "@babel/types": "^7.20.0" } }, "@babel/helper-split-export-declaration": { @@ -321,9 +324,9 @@ } }, "@babel/helper-string-parser": { - "version": "7.18.10", - "resolved": "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz", - "integrity": "sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==" + "version": "7.19.4", + "resolved": "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==" }, "@babel/helper-validator-identifier": { "version": "7.19.1", @@ -331,29 +334,29 @@ "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==" }, "@babel/helper-validator-option": { - "version": "7.18.6", - "resolved": "https://registry.npmmirror.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", - "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==" + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz", + "integrity": "sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==" }, "@babel/helper-wrap-function": { - "version": "7.19.0", - "resolved": "https://registry.npmmirror.com/@babel/helper-wrap-function/-/helper-wrap-function-7.19.0.tgz", - "integrity": "sha512-txX8aN8CZyYGTwcLhlk87KRqncAzhh5TpQamZUa0/u3an36NtDpUP6bQgBCBcLeBs09R/OwQu3OjK0k/HwfNDg==", + "version": "7.20.5", + "resolved": "https://registry.npmmirror.com/@babel/helper-wrap-function/-/helper-wrap-function-7.20.5.tgz", + "integrity": "sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q==", "requires": { "@babel/helper-function-name": "^7.19.0", "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.0", - "@babel/types": "^7.19.0" + "@babel/traverse": "^7.20.5", + "@babel/types": "^7.20.5" } }, "@babel/helpers": { - "version": "7.19.0", - "resolved": "https://registry.npmmirror.com/@babel/helpers/-/helpers-7.19.0.tgz", - "integrity": "sha512-DRBCKGwIEdqY3+rPJgG/dKfQy9+08rHIAJx8q2p+HSWP87s2HCrQmaAMMyMll2kIXKCW0cO1RdQskx15Xakftg==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/helpers/-/helpers-7.21.0.tgz", + "integrity": "sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA==", "requires": { - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.0", - "@babel/types": "^7.19.0" + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.21.0", + "@babel/types": "^7.21.0" } }, "@babel/highlight": { @@ -367,9 +370,9 @@ } }, "@babel/parser": { - "version": "7.19.1", - "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.19.1.tgz", - "integrity": "sha512-h7RCSorm1DdTVGJf3P2Mhj3kdnkmF/EiysUkzS2TdgAYqyjFdMQJbVuXOBej2SBJaXan/lIVtT6KkGbyyq753A==" + "version": "7.21.1", + "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.21.1.tgz", + "integrity": "sha512-JzhBFpkuhBNYUY7qs+wTzNmyCWUHEaAFpQQD2YfU1rPL38/L43Wvid0fFkiOCnHvsGncRZgEPyGnltABLcVDTg==" }, "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { "version": "7.18.6", @@ -380,22 +383,22 @@ } }, "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.18.9", - "resolved": "https://registry.npmmirror.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.9.tgz", - "integrity": "sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg==", + "version": "7.20.7", + "resolved": "https://registry.npmmirror.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.20.7.tgz", + "integrity": "sha512-sbr9+wNE5aXMBBFBICk01tt7sBf2Oc9ikRFEcem/ZORup9IMUdNhW7/wVLEbbtlWOsEubJet46mHAL2C8+2jKQ==", "requires": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", - "@babel/plugin-proposal-optional-chaining": "^7.18.9" + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", + "@babel/plugin-proposal-optional-chaining": "^7.20.7" } }, "@babel/plugin-proposal-async-generator-functions": { - "version": "7.19.1", - "resolved": "https://registry.npmmirror.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.19.1.tgz", - "integrity": "sha512-0yu8vNATgLy4ivqMNBIwb1HebCelqN7YX8SL3FDXORv/RqT0zEEWUCH4GH44JsSrvCu6GqnAdR5EBFAPeNBB4Q==", + "version": "7.20.7", + "resolved": "https://registry.npmmirror.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.7.tgz", + "integrity": "sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA==", "requires": { "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-plugin-utils": "^7.20.2", "@babel/helper-remap-async-to-generator": "^7.18.9", "@babel/plugin-syntax-async-generators": "^7.8.4" } @@ -410,25 +413,25 @@ } }, "@babel/plugin-proposal-class-static-block": { - "version": "7.18.6", - "resolved": "https://registry.npmmirror.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.6.tgz", - "integrity": "sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.21.0.tgz", + "integrity": "sha512-XP5G9MWNUskFuP30IfFSEFB0Z6HzLIUcjYM4bYOPHXl7eiJ9HFv8tWj6TXTN5QODiEhDZAeI4hLok2iHFFV4hw==", "requires": { - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-create-class-features-plugin": "^7.21.0", + "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-class-static-block": "^7.14.5" } }, "@babel/plugin-proposal-decorators": { - "version": "7.19.1", - "resolved": "https://registry.npmmirror.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.19.1.tgz", - "integrity": "sha512-LfIKNBBY7Q1OX5C4xAgRQffOg2OnhAo9fnbcOHgOC9Yytm2Sw+4XqHufRYU86tHomzepxtvuVaNO+3EVKR4ivw==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.21.0.tgz", + "integrity": "sha512-MfgX49uRrFUTL/HvWtmx3zmpyzMMr4MTj3d527MLlr/4RTT9G/ytFFP7qet2uM2Ve03b+BkpWUpK+lRXnQ+v9w==", "requires": { - "@babel/helper-create-class-features-plugin": "^7.19.0", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-replace-supers": "^7.19.1", + "@babel/helper-create-class-features-plugin": "^7.21.0", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-replace-supers": "^7.20.7", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/plugin-syntax-decorators": "^7.19.0" + "@babel/plugin-syntax-decorators": "^7.21.0" } }, "@babel/plugin-proposal-dynamic-import": { @@ -469,11 +472,11 @@ } }, "@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.18.9", - "resolved": "https://registry.npmmirror.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.9.tgz", - "integrity": "sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q==", + "version": "7.20.7", + "resolved": "https://registry.npmmirror.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.20.7.tgz", + "integrity": "sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug==", "requires": { - "@babel/helper-plugin-utils": "^7.18.9", + "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" } }, @@ -496,15 +499,15 @@ } }, "@babel/plugin-proposal-object-rest-spread": { - "version": "7.18.9", - "resolved": "https://registry.npmmirror.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.18.9.tgz", - "integrity": "sha512-kDDHQ5rflIeY5xl69CEqGEZ0KY369ehsCIEbTGb4siHG5BE9sga/T0r0OUwyZNLMmZE79E1kbsqAjwFCW4ds6Q==", + "version": "7.20.7", + "resolved": "https://registry.npmmirror.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz", + "integrity": "sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==", "requires": { - "@babel/compat-data": "^7.18.8", - "@babel/helper-compilation-targets": "^7.18.9", - "@babel/helper-plugin-utils": "^7.18.9", + "@babel/compat-data": "^7.20.5", + "@babel/helper-compilation-targets": "^7.20.7", + "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.18.8" + "@babel/plugin-transform-parameters": "^7.20.7" } }, "@babel/plugin-proposal-optional-catch-binding": { @@ -517,12 +520,12 @@ } }, "@babel/plugin-proposal-optional-chaining": { - "version": "7.18.9", - "resolved": "https://registry.npmmirror.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.9.tgz", - "integrity": "sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz", + "integrity": "sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==", "requires": { - "@babel/helper-plugin-utils": "^7.18.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0", "@babel/plugin-syntax-optional-chaining": "^7.8.3" } }, @@ -536,13 +539,13 @@ } }, "@babel/plugin-proposal-private-property-in-object": { - "version": "7.18.6", - "resolved": "https://registry.npmmirror.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.18.6.tgz", - "integrity": "sha512-9Rysx7FOctvT5ouj5JODjAFAkgGoudQuLPamZb0v1TGLpapdNaftzifU8NTWQm0IRjqoYypdrSmyWgkocDQ8Dw==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0.tgz", + "integrity": "sha512-ha4zfehbJjc5MmXBlHec1igel5TJXXLDDRbuJ4+XT2TJcyD9/V1919BA8gMvsdHcNMBy4WBUBiRb3nw/EQUtBw==", "requires": { "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-create-class-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", + "@babel/helper-create-class-features-plugin": "^7.21.0", + "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-private-property-in-object": "^7.14.5" } }, @@ -580,11 +583,11 @@ } }, "@babel/plugin-syntax-decorators": { - "version": "7.19.0", - "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.19.0.tgz", - "integrity": "sha512-xaBZUEDntt4faL1yN8oIFlhfXeQAWJW7CLKYsHTUqriCUbj8xOra8bfxxKGi/UwExPFBuPdH4XfHc9rGQhrVkQ==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.21.0.tgz", + "integrity": "sha512-tIoPpGBR8UuM4++ccWN3gifhVvQu7ZizuR1fklhRJrd5ewgbkUS+0KVFeWWxELtn18NTLoW32XV7zyOgIAiz+w==", "requires": { - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-plugin-utils": "^7.20.2" } }, "@babel/plugin-syntax-dynamic-import": { @@ -621,11 +624,11 @@ } }, "@babel/plugin-syntax-import-assertions": { - "version": "7.18.6", - "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.18.6.tgz", - "integrity": "sha512-/DU3RXad9+bZwrgWJQKbr39gYbJpLJHezqEzRzi/BHRlJ9zsQb4CK2CA/5apllXNomwA1qHwzvHl+AdEmC5krQ==", + "version": "7.20.0", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz", + "integrity": "sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==", "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.19.0" } }, "@babel/plugin-syntax-json-strings": { @@ -709,29 +712,29 @@ } }, "@babel/plugin-syntax-typescript": { - "version": "7.18.6", - "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz", - "integrity": "sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA==", + "version": "7.20.0", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz", + "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==", "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.19.0" } }, "@babel/plugin-transform-arrow-functions": { - "version": "7.18.6", - "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.18.6.tgz", - "integrity": "sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ==", + "version": "7.20.7", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.20.7.tgz", + "integrity": "sha512-3poA5E7dzDomxj9WXWwuD6A5F3kc7VXwIJO+E+J8qtDtS+pXPAhrgEyh+9GBwBgPq1Z+bB+/JD60lp5jsN7JPQ==", "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.20.2" } }, "@babel/plugin-transform-async-to-generator": { - "version": "7.18.6", - "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz", - "integrity": "sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag==", + "version": "7.20.7", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.20.7.tgz", + "integrity": "sha512-Uo5gwHPT9vgnSXQxqGtpdufUiWp96gk7yiP4Mp5bm1QMkEmLXBO7PAGYbKoJ6DhAwiNkcHFBol/x5zZZkL/t0Q==", "requires": { "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-remap-async-to-generator": "^7.18.6" + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-remap-async-to-generator": "^7.18.9" } }, "@babel/plugin-transform-block-scoped-functions": { @@ -743,43 +746,44 @@ } }, "@babel/plugin-transform-block-scoping": { - "version": "7.18.9", - "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.18.9.tgz", - "integrity": "sha512-5sDIJRV1KtQVEbt/EIBwGy4T01uYIo4KRB3VUqzkhrAIOGx7AoctL9+Ux88btY0zXdDyPJ9mW+bg+v+XEkGmtw==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.21.0.tgz", + "integrity": "sha512-Mdrbunoh9SxwFZapeHVrwFmri16+oYotcZysSzhNIVDwIAb1UV+kvnxULSYq9J3/q5MDG+4X6w8QVgD1zhBXNQ==", "requires": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.20.2" } }, "@babel/plugin-transform-classes": { - "version": "7.19.0", - "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.19.0.tgz", - "integrity": "sha512-YfeEE9kCjqTS9IitkgfJuxjcEtLUHMqa8yUJ6zdz8vR7hKuo6mOy2C05P0F1tdMmDCeuyidKnlrw/iTppHcr2A==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.21.0.tgz", + "integrity": "sha512-RZhbYTCEUAe6ntPehC4hlslPWosNHDox+vAs4On/mCLRLfoDVHf6hVEd7kuxr1RnHwJmxFfUM3cZiZRmPxJPXQ==", "requires": { "@babel/helper-annotate-as-pure": "^7.18.6", - "@babel/helper-compilation-targets": "^7.19.0", + "@babel/helper-compilation-targets": "^7.20.7", "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", + "@babel/helper-function-name": "^7.21.0", "@babel/helper-optimise-call-expression": "^7.18.6", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-replace-supers": "^7.18.9", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-replace-supers": "^7.20.7", "@babel/helper-split-export-declaration": "^7.18.6", "globals": "^11.1.0" } }, "@babel/plugin-transform-computed-properties": { - "version": "7.18.9", - "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz", - "integrity": "sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw==", + "version": "7.20.7", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.20.7.tgz", + "integrity": "sha512-Lz7MvBK6DTjElHAmfu6bfANzKcxpyNPeYBGEafyA6E5HtRpjpZwU+u7Qrgz/2OR0z+5TvKYbPdphfSaAcZBrYQ==", "requires": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/template": "^7.20.7" } }, "@babel/plugin-transform-destructuring": { - "version": "7.18.13", - "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.18.13.tgz", - "integrity": "sha512-TodpQ29XekIsex2A+YJPj5ax2plkGa8YYY6mFjCohk/IG9IY42Rtuj1FuDeemfg2ipxIFLzPeA83SIBnlhSIow==", + "version": "7.20.7", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.20.7.tgz", + "integrity": "sha512-Xwg403sRrZb81IVB79ZPqNQME23yhugYVqgTxAhT99h485F4f+GMELFhhOsscDUB7HCswepKeCKLn/GZvUKoBA==", "requires": { - "@babel/helper-plugin-utils": "^7.18.9" + "@babel/helper-plugin-utils": "^7.20.2" } }, "@babel/plugin-transform-dotall-regex": { @@ -809,20 +813,20 @@ } }, "@babel/plugin-transform-flow-strip-types": { - "version": "7.19.0", - "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.19.0.tgz", - "integrity": "sha512-sgeMlNaQVbCSpgLSKP4ZZKfsJVnFnNQlUSk6gPYzR/q7tzCgQF2t8RBKAP6cKJeZdveei7Q7Jm527xepI8lNLg==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.21.0.tgz", + "integrity": "sha512-FlFA2Mj87a6sDkW4gfGrQQqwY/dLlBAyJa2dJEZ+FHXUVHBflO2wyKvg+OOEzXfrKYIa4HWl0mgmbCzt0cMb7w==", "requires": { - "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-flow": "^7.18.6" } }, "@babel/plugin-transform-for-of": { - "version": "7.18.8", - "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz", - "integrity": "sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.21.0.tgz", + "integrity": "sha512-LlUYlydgDkKpIY7mcBWvyPPmMcOphEyYA27Ef4xpbh1IiDNLr0kZsos2nf92vz3IccvJI25QUwp86Eo5s6HmBQ==", "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.20.2" } }, "@babel/plugin-transform-function-name": { @@ -852,36 +856,33 @@ } }, "@babel/plugin-transform-modules-amd": { - "version": "7.18.6", - "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.18.6.tgz", - "integrity": "sha512-Pra5aXsmTsOnjM3IajS8rTaLCy++nGM4v3YR4esk5PCsyg9z8NA5oQLwxzMUtDBd8F+UmVza3VxoAaWCbzH1rg==", + "version": "7.20.11", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.20.11.tgz", + "integrity": "sha512-NuzCt5IIYOW0O30UvqktzHYR2ud5bOWbY0yaxWZ6G+aFzOMJvrs5YHNikrbdaT15+KNO31nPOy5Fim3ku6Zb5g==", "requires": { - "@babel/helper-module-transforms": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "babel-plugin-dynamic-import-node": "^2.3.3" + "@babel/helper-module-transforms": "^7.20.11", + "@babel/helper-plugin-utils": "^7.20.2" } }, "@babel/plugin-transform-modules-commonjs": { - "version": "7.18.6", - "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.18.6.tgz", - "integrity": "sha512-Qfv2ZOWikpvmedXQJDSbxNqy7Xr/j2Y8/KfijM0iJyKkBTmWuvCA1yeH1yDM7NJhBW/2aXxeucLj6i80/LAJ/Q==", + "version": "7.20.11", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.20.11.tgz", + "integrity": "sha512-S8e1f7WQ7cimJQ51JkAaDrEtohVEitXjgCGAS2N8S31Y42E+kWwfSz83LYz57QdBm7q9diARVqanIaH2oVgQnw==", "requires": { - "@babel/helper-module-transforms": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-simple-access": "^7.18.6", - "babel-plugin-dynamic-import-node": "^2.3.3" + "@babel/helper-module-transforms": "^7.20.11", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-simple-access": "^7.20.2" } }, "@babel/plugin-transform-modules-systemjs": { - "version": "7.19.0", - "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.0.tgz", - "integrity": "sha512-x9aiR0WXAWmOWsqcsnrzGR+ieaTMVyGyffPVA7F8cXAGt/UxefYv6uSHZLkAFChN5M5Iy1+wjE+xJuPt22H39A==", + "version": "7.20.11", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.20.11.tgz", + "integrity": "sha512-vVu5g9BPQKSFEmvt2TA4Da5N+QVS66EX21d8uoOihC+OCpUoGvzVsXeqFdtAEfVa5BILAeFt+U7yVmLbQnAJmw==", "requires": { "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-module-transforms": "^7.19.0", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-validator-identifier": "^7.18.6", - "babel-plugin-dynamic-import-node": "^2.3.3" + "@babel/helper-module-transforms": "^7.20.11", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-validator-identifier": "^7.19.1" } }, "@babel/plugin-transform-modules-umd": { @@ -894,12 +895,12 @@ } }, "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.19.1", - "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.19.1.tgz", - "integrity": "sha512-oWk9l9WItWBQYS4FgXD4Uyy5kq898lvkXpXQxoJEY1RnvPk4R/Dvu2ebXU9q8lP+rlMwUQTFf2Ok6d78ODa0kw==", + "version": "7.20.5", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.20.5.tgz", + "integrity": "sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA==", "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.19.0", - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-create-regexp-features-plugin": "^7.20.5", + "@babel/helper-plugin-utils": "^7.20.2" } }, "@babel/plugin-transform-new-target": { @@ -929,11 +930,11 @@ } }, "@babel/plugin-transform-parameters": { - "version": "7.18.8", - "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.18.8.tgz", - "integrity": "sha512-ivfbE3X2Ss+Fj8nnXvKJS6sjRG4gzwPMsP+taZC+ZzEGjAYlvENixmt1sZ5Ca6tWls+BlKSGKPJ6OOXvXCbkFg==", + "version": "7.20.7", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.20.7.tgz", + "integrity": "sha512-WiWBIkeHKVOSYPO0pWkxGPfKeWrCJyD3NJ53+Lrp/QMSZbsVPovrVl2aWZ19D/LTVnaDv5Ap7GJ/B2CTOZdrfA==", "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.20.2" } }, "@babel/plugin-transform-property-literals": { @@ -953,15 +954,15 @@ } }, "@babel/plugin-transform-react-jsx": { - "version": "7.19.0", - "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.19.0.tgz", - "integrity": "sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.21.0.tgz", + "integrity": "sha512-6OAWljMvQrZjR2DaNhVfRz6dkCAVV+ymcLUmaf8bccGOHn2v5rHJK3tTpij0BuhdYWP4LLaqj5lwcdlpAAPuvg==", "requires": { "@babel/helper-annotate-as-pure": "^7.18.6", "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-plugin-utils": "^7.20.2", "@babel/plugin-syntax-jsx": "^7.18.6", - "@babel/types": "^7.19.0" + "@babel/types": "^7.21.0" } }, "@babel/plugin-transform-react-jsx-development": { @@ -982,12 +983,12 @@ } }, "@babel/plugin-transform-regenerator": { - "version": "7.18.6", - "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.6.tgz", - "integrity": "sha512-poqRI2+qiSdeldcz4wTSTXBRryoq3Gc70ye7m7UD5Ww0nE29IXqMl6r7Nd15WBgRd74vloEMlShtH6CKxVzfmQ==", + "version": "7.20.5", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.20.5.tgz", + "integrity": "sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ==", "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "regenerator-transform": "^0.15.0" + "@babel/helper-plugin-utils": "^7.20.2", + "regenerator-transform": "^0.15.1" } }, "@babel/plugin-transform-reserved-words": { @@ -999,12 +1000,12 @@ } }, "@babel/plugin-transform-runtime": { - "version": "7.19.1", - "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.19.1.tgz", - "integrity": "sha512-2nJjTUFIzBMP/f/miLxEK9vxwW/KUXsdvN4sR//TmuDhe6yU2h57WmIOE12Gng3MDP/xpjUV/ToZRdcf8Yj4fA==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.21.0.tgz", + "integrity": "sha512-ReY6pxwSzEU0b3r2/T/VhqMKg/AkceBT19X0UptA3/tYi5Pe2eXgEUH+NNMC5nok6c6XQz5tyVTUpuezRfSMSg==", "requires": { "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-plugin-utils": "^7.19.0", + "@babel/helper-plugin-utils": "^7.20.2", "babel-plugin-polyfill-corejs2": "^0.3.3", "babel-plugin-polyfill-corejs3": "^0.6.0", "babel-plugin-polyfill-regenerator": "^0.4.1", @@ -1020,12 +1021,12 @@ } }, "@babel/plugin-transform-spread": { - "version": "7.19.0", - "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz", - "integrity": "sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w==", + "version": "7.20.7", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.20.7.tgz", + "integrity": "sha512-ewBbHQ+1U/VnH1fxltbJqDeWBU1oNLG8Dj11uIv3xVf7nrQu0bPGe5Rf716r7K5Qz+SqtAOVswoVunoiBtGhxw==", "requires": { - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.18.9" + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0" } }, "@babel/plugin-transform-sticky-regex": { @@ -1053,13 +1054,13 @@ } }, "@babel/plugin-transform-typescript": { - "version": "7.19.1", - "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.19.1.tgz", - "integrity": "sha512-+ILcOU+6mWLlvCwnL920m2Ow3wWx3Wo8n2t5aROQmV55GZt+hOiLvBaa3DNzRjSEHa1aauRs4/YLmkCfFkhhRQ==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.21.0.tgz", + "integrity": "sha512-xo///XTPp3mDzTtrqXoBlK9eiAYW3wv9JXglcn/u1bi60RW11dEUxIgA8cbnDhutS1zacjMRmAwxE0gMklLnZg==", "requires": { - "@babel/helper-create-class-features-plugin": "^7.19.0", - "@babel/helper-plugin-utils": "^7.19.0", - "@babel/plugin-syntax-typescript": "^7.18.6" + "@babel/helper-create-class-features-plugin": "^7.21.0", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/plugin-syntax-typescript": "^7.20.0" } }, "@babel/plugin-transform-unicode-escapes": { @@ -1090,17 +1091,17 @@ } }, "@babel/preset-env": { - "version": "7.19.1", - "resolved": "https://registry.npmmirror.com/@babel/preset-env/-/preset-env-7.19.1.tgz", - "integrity": "sha512-c8B2c6D16Lp+Nt6HcD+nHl0VbPKVnNPTpszahuxJJnurfMtKeZ80A+qUv48Y7wqvS+dTFuLuaM9oYxyNHbCLWA==", + "version": "7.20.2", + "resolved": "https://registry.npmmirror.com/@babel/preset-env/-/preset-env-7.20.2.tgz", + "integrity": "sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg==", "requires": { - "@babel/compat-data": "^7.19.1", - "@babel/helper-compilation-targets": "^7.19.1", - "@babel/helper-plugin-utils": "^7.19.0", + "@babel/compat-data": "^7.20.1", + "@babel/helper-compilation-targets": "^7.20.0", + "@babel/helper-plugin-utils": "^7.20.2", "@babel/helper-validator-option": "^7.18.6", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9", - "@babel/plugin-proposal-async-generator-functions": "^7.19.1", + "@babel/plugin-proposal-async-generator-functions": "^7.20.1", "@babel/plugin-proposal-class-properties": "^7.18.6", "@babel/plugin-proposal-class-static-block": "^7.18.6", "@babel/plugin-proposal-dynamic-import": "^7.18.6", @@ -1109,7 +1110,7 @@ "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9", "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", "@babel/plugin-proposal-numeric-separator": "^7.18.6", - "@babel/plugin-proposal-object-rest-spread": "^7.18.9", + "@babel/plugin-proposal-object-rest-spread": "^7.20.2", "@babel/plugin-proposal-optional-catch-binding": "^7.18.6", "@babel/plugin-proposal-optional-chaining": "^7.18.9", "@babel/plugin-proposal-private-methods": "^7.18.6", @@ -1120,7 +1121,7 @@ "@babel/plugin-syntax-class-static-block": "^7.14.5", "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-import-assertions": "^7.18.6", + "@babel/plugin-syntax-import-assertions": "^7.20.0", "@babel/plugin-syntax-json-strings": "^7.8.3", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", @@ -1133,10 +1134,10 @@ "@babel/plugin-transform-arrow-functions": "^7.18.6", "@babel/plugin-transform-async-to-generator": "^7.18.6", "@babel/plugin-transform-block-scoped-functions": "^7.18.6", - "@babel/plugin-transform-block-scoping": "^7.18.9", - "@babel/plugin-transform-classes": "^7.19.0", + "@babel/plugin-transform-block-scoping": "^7.20.2", + "@babel/plugin-transform-classes": "^7.20.2", "@babel/plugin-transform-computed-properties": "^7.18.9", - "@babel/plugin-transform-destructuring": "^7.18.13", + "@babel/plugin-transform-destructuring": "^7.20.2", "@babel/plugin-transform-dotall-regex": "^7.18.6", "@babel/plugin-transform-duplicate-keys": "^7.18.9", "@babel/plugin-transform-exponentiation-operator": "^7.18.6", @@ -1144,14 +1145,14 @@ "@babel/plugin-transform-function-name": "^7.18.9", "@babel/plugin-transform-literals": "^7.18.9", "@babel/plugin-transform-member-expression-literals": "^7.18.6", - "@babel/plugin-transform-modules-amd": "^7.18.6", - "@babel/plugin-transform-modules-commonjs": "^7.18.6", - "@babel/plugin-transform-modules-systemjs": "^7.19.0", + "@babel/plugin-transform-modules-amd": "^7.19.6", + "@babel/plugin-transform-modules-commonjs": "^7.19.6", + "@babel/plugin-transform-modules-systemjs": "^7.19.6", "@babel/plugin-transform-modules-umd": "^7.18.6", "@babel/plugin-transform-named-capturing-groups-regex": "^7.19.1", "@babel/plugin-transform-new-target": "^7.18.6", "@babel/plugin-transform-object-super": "^7.18.6", - "@babel/plugin-transform-parameters": "^7.18.8", + "@babel/plugin-transform-parameters": "^7.20.1", "@babel/plugin-transform-property-literals": "^7.18.6", "@babel/plugin-transform-regenerator": "^7.18.6", "@babel/plugin-transform-reserved-words": "^7.18.6", @@ -1163,7 +1164,7 @@ "@babel/plugin-transform-unicode-escapes": "^7.18.10", "@babel/plugin-transform-unicode-regex": "^7.18.6", "@babel/preset-modules": "^0.1.5", - "@babel/types": "^7.19.0", + "@babel/types": "^7.20.2", "babel-plugin-polyfill-corejs2": "^0.3.3", "babel-plugin-polyfill-corejs3": "^0.6.0", "babel-plugin-polyfill-regenerator": "^0.4.1", @@ -1197,64 +1198,74 @@ } }, "@babel/preset-typescript": { - "version": "7.18.6", - "resolved": "https://registry.npmmirror.com/@babel/preset-typescript/-/preset-typescript-7.18.6.tgz", - "integrity": "sha512-s9ik86kXBAnD760aybBucdpnLsAt0jK1xqJn2juOn9lkOvSHV60os5hxoVJsPzMQxvnUJFAlkont2DvvaYEBtQ==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/preset-typescript/-/preset-typescript-7.21.0.tgz", + "integrity": "sha512-myc9mpoVA5m1rF8K8DgLEatOYFDpwC+RkMkjZ0Du6uI62YvDe8uxIEYVs/VCdSJ097nlALiU/yBC7//3nI+hNg==", "requires": { - "@babel/helper-plugin-utils": "^7.18.6", - "@babel/helper-validator-option": "^7.18.6", - "@babel/plugin-transform-typescript": "^7.18.6" + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/helper-validator-option": "^7.21.0", + "@babel/plugin-transform-typescript": "^7.21.0" } }, + "@babel/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmmirror.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==" + }, "@babel/runtime": { - "version": "7.19.0", - "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.19.0.tgz", - "integrity": "sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.21.0.tgz", + "integrity": "sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==", "requires": { - "regenerator-runtime": "^0.13.4" + "regenerator-runtime": "^0.13.11" } }, "@babel/template": { - "version": "7.18.10", - "resolved": "https://registry.npmmirror.com/@babel/template/-/template-7.18.10.tgz", - "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", + "version": "7.20.7", + "resolved": "https://registry.npmmirror.com/@babel/template/-/template-7.20.7.tgz", + "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", "requires": { "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.18.10", - "@babel/types": "^7.18.10" + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" } }, "@babel/traverse": { - "version": "7.19.1", - "resolved": "https://registry.npmmirror.com/@babel/traverse/-/traverse-7.19.1.tgz", - "integrity": "sha512-0j/ZfZMxKukDaag2PtOPDbwuELqIar6lLskVPPJDjXMXjfLb1Obo/1yjxIGqqAJrmfaTIY3z2wFLAQ7qSkLsuA==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/traverse/-/traverse-7.21.0.tgz", + "integrity": "sha512-Xdt2P1H4LKTO8ApPfnO1KmzYMFpp7D/EinoXzLYN/cHcBNrVCAkAtGUcXnHXrl/VGktureU6fkQrHSBE2URfoA==", "requires": { "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.19.0", + "@babel/generator": "^7.21.0", "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", + "@babel/helper-function-name": "^7.21.0", "@babel/helper-hoist-variables": "^7.18.6", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.19.1", - "@babel/types": "^7.19.0", + "@babel/parser": "^7.21.0", + "@babel/types": "^7.21.0", "debug": "^4.1.0", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.19.0", - "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.19.0.tgz", - "integrity": "sha512-YuGopBq3ke25BVSiS6fgF49Ul9gH1x70Bcr6bqRLjWCkcX8Hre1/5+z+IiWOIerRMSSEfGZVB9z9kyq7wVs9YA==", + "version": "7.21.0", + "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.21.0.tgz", + "integrity": "sha512-uR7NWq2VNFnDi7EYqiRz2Jv/VQIu38tu64Zy8TX2nQFQ6etJ9V/Rr2msW8BS132mum2rL645qpDrLtAJtVpuow==", "requires": { - "@babel/helper-string-parser": "^7.18.10", - "@babel/helper-validator-identifier": "^7.18.6", + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", "to-fast-properties": "^2.0.0" } }, "@ctrl/tinycolor": { - "version": "3.4.1", - "resolved": "https://registry.npmmirror.com/@ctrl/tinycolor/-/tinycolor-3.4.1.tgz", - "integrity": "sha512-ej5oVy6lykXsvieQtqZxCOaLT+xD4+QNarq78cIYISHmZXshCvROLudpQN3lfL8G0NL7plMSSK+zlyvCaIJ4Iw==" + "version": "3.6.0", + "resolved": "https://registry.npmmirror.com/@ctrl/tinycolor/-/tinycolor-3.6.0.tgz", + "integrity": "sha512-/Z3l6pXthq0JvMYdUFyX9j0MaCltlIn6mfh9jLyQwg5aPKxkyNa0PTHtU1AlFXLNk55ZuAeJRcpvq+tmLfKmaQ==" + }, + "@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmmirror.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==" }, "@eslint/eslintrc": { "version": "0.4.3", @@ -1274,9 +1285,9 @@ }, "dependencies": { "globals": { - "version": "13.17.0", - "resolved": "https://registry.npmmirror.com/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "version": "13.20.0", + "resolved": "https://registry.npmmirror.com/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -1379,12 +1390,12 @@ "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==" }, "@jridgewell/trace-mapping": { - "version": "0.3.15", - "resolved": "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz", - "integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==", + "version": "0.3.17", + "resolved": "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" } }, "@knowdesign/icons": { @@ -1424,26 +1435,26 @@ } }, "@pmmmwh/react-refresh-webpack-plugin": { - "version": "0.5.7", - "resolved": "https://registry.npmmirror.com/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.7.tgz", - "integrity": "sha512-bcKCAzF0DV2IIROp9ZHkRJa6O4jy7NlnHdWL3GmcUxYWNjLXkK5kfELELwEfSP5hXPfVL/qOGMAROuMQb9GG8Q==", + "version": "0.5.10", + "resolved": "https://registry.npmmirror.com/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.10.tgz", + "integrity": "sha512-j0Ya0hCFZPd4x40qLzbhGsh9TMtdb+CJQiso+WxLOPNasohq9cc5SNUcwsZaRH6++Xh91Xkm/xHCkuIiIu0LUA==", "dev": true, "requires": { "ansi-html-community": "^0.0.8", "common-path-prefix": "^3.0.0", - "core-js-pure": "^3.8.1", + "core-js-pure": "^3.23.3", "error-stack-parser": "^2.0.6", "find-up": "^5.0.0", "html-entities": "^2.1.0", - "loader-utils": "^2.0.0", + "loader-utils": "^2.0.4", "schema-utils": "^3.0.0", "source-map": "^0.7.3" }, "dependencies": { "loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", + "version": "2.0.4", + "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", "dev": true, "requires": { "big.js": "^5.2.2", @@ -1539,9 +1550,9 @@ "dev": true }, "@types/lodash": { - "version": "4.14.185", - "resolved": "https://registry.npmmirror.com/@types/lodash/-/lodash-4.14.185.tgz", - "integrity": "sha512-evMDG1bC4rgQg4ku9tKpuMh5iBNEwNa3tf9zRHdP1qlv+1WUg44xat4IxCE14gIpZRGUUWAx2VhItCZc25NfMA==", + "version": "4.14.191", + "resolved": "https://registry.npmmirror.com/@types/lodash/-/lodash-4.14.191.tgz", + "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==", "dev": true }, "@types/minimatch": { @@ -1584,9 +1595,9 @@ "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" }, "@types/react": { - "version": "17.0.50", - "resolved": "https://registry.npmmirror.com/@types/react/-/react-17.0.50.tgz", - "integrity": "sha512-ZCBHzpDb5skMnc1zFXAXnL3l1FAdi+xZvwxK+PkglMmBrwjpp9nKaWuEvrGnSifCJmBFGxZOOFuwC6KH/s0NuA==", + "version": "17.0.53", + "resolved": "https://registry.npmmirror.com/@types/react/-/react-17.0.53.tgz", + "integrity": "sha512-1yIpQR2zdYu1Z/dc1OxC+MA6GR240u3gcnP4l6mvj/PJiVaqHsQPmWttsvHsfnhfPbU2FuGmo0wSITPygjBmsw==", "requires": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -1602,9 +1613,9 @@ } }, "@types/react-dom": { - "version": "17.0.17", - "resolved": "https://registry.npmmirror.com/@types/react-dom/-/react-dom-17.0.17.tgz", - "integrity": "sha512-VjnqEmqGnasQKV0CWLevqMTXBYG9GbwuE6x3VetERLh0cq2LTptFE73MrQi2S7GkKXCf2GgwItB/melLnxfnsg==", + "version": "17.0.19", + "resolved": "https://registry.npmmirror.com/@types/react-dom/-/react-dom-17.0.19.tgz", + "integrity": "sha512-PiYG40pnQRdPHnlf7tZnp0aQ6q9tspYr72vD61saO6zFCybLfMqwUCN0va1/P+86DXn18ZWeW30Bk7xlC5eEAQ==", "requires": { "@types/react": "^17" } @@ -1669,9 +1680,9 @@ "integrity": "sha512-ipixuVrh2OdNmauvtT51o3d8z12p6LtFW9in7U79der/kwejjdNchQC5UMn5u/KxNoM7VHHOs/l8KS8uHxhODQ==" }, "@types/uglify-js": { - "version": "3.17.0", - "resolved": "https://registry.npmmirror.com/@types/uglify-js/-/uglify-js-3.17.0.tgz", - "integrity": "sha512-3HO6rm0y+/cqvOyA8xcYLweF0TKXlAxmQASjbOi49Co51A1N4nR4bEwBgRoD9kNM+rqFGArjKr654SLp2CoGmQ==", + "version": "3.17.1", + "resolved": "https://registry.npmmirror.com/@types/uglify-js/-/uglify-js-3.17.1.tgz", + "integrity": "sha512-GkewRA4i5oXacU/n4MA9+bLgt5/L3F1mKrYvFGm7r2ouLXhRKjuWwo9XHNnbx6WF3vlGW21S3fCvgqxvxXXc5g==", "requires": { "source-map": "^0.6.1" } @@ -1682,9 +1693,9 @@ "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==" }, "@types/webpack": { - "version": "4.41.32", - "resolved": "https://registry.npmmirror.com/@types/webpack/-/webpack-4.41.32.tgz", - "integrity": "sha512-cb+0ioil/7oz5//7tZUSwbrSAN/NWHrQylz5cW8G0dWTcF/g+/dSdMlKVZspBYuMAN1+WnwHrkxiRrLcwd0Heg==", + "version": "4.41.33", + "resolved": "https://registry.npmmirror.com/@types/webpack/-/webpack-4.41.33.tgz", + "integrity": "sha512-PPajH64Ft2vWevkerISMtnZ8rTs4YmRbs+23c402J0INmxDKCrhZNvwZYtzx96gY2wAtXdrK1BS2fiC8MlLr3g==", "requires": { "@types/node": "*", "@types/tapable": "^1", @@ -1695,9 +1706,9 @@ }, "dependencies": { "@types/node": { - "version": "18.7.18", - "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.7.18.tgz", - "integrity": "sha512-m+6nTEOadJZuTPkKR/SYK3A2d7FZrgElol9UP1Kae90VVU4a6mxnPuLiIW1m4Cq4gZ/nWb9GrdVXJCoCazDAbg==" + "version": "18.14.0", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.14.0.tgz", + "integrity": "sha512-5EWrvLmglK+imbCJY0+INViFWUHg1AHel1sq4ZVSfdcNqGy9Edv3UB9IIzzg+xPaUcAgZYcfVs2fBcwDeZzU0A==" } } }, @@ -1712,9 +1723,9 @@ }, "dependencies": { "@types/node": { - "version": "18.7.18", - "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.7.18.tgz", - "integrity": "sha512-m+6nTEOadJZuTPkKR/SYK3A2d7FZrgElol9UP1Kae90VVU4a6mxnPuLiIW1m4Cq4gZ/nWb9GrdVXJCoCazDAbg==" + "version": "18.14.0", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.14.0.tgz", + "integrity": "sha512-5EWrvLmglK+imbCJY0+INViFWUHg1AHel1sq4ZVSfdcNqGy9Edv3UB9IIzzg+xPaUcAgZYcfVs2fBcwDeZzU0A==" }, "source-map": { "version": "0.7.4", @@ -1739,14 +1750,29 @@ "tsutils": "^3.17.1" }, "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmmirror.com/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmmirror.com/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "requires": { "lru-cache": "^6.0.0" } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true } } }, @@ -1808,14 +1834,29 @@ "tsutils": "^3.17.1" }, "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmmirror.com/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmmirror.com/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "requires": { "lru-cache": "^6.0.0" } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true } } }, @@ -2027,9 +2068,9 @@ } }, "acorn": { - "version": "8.8.0", - "resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==" + "version": "8.8.2", + "resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==" }, "acorn-jsx": { "version": "5.3.2", @@ -2382,13 +2423,13 @@ }, "dependencies": { "rc-resize-observer": { - "version": "1.2.0", - "resolved": "https://registry.npmmirror.com/rc-resize-observer/-/rc-resize-observer-1.2.0.tgz", - "integrity": "sha512-6W+UzT3PyDM0wVCEHfoW3qTHPTvbdSgiA43buiy8PzmeMnfgnDeb9NjdimMXMl3/TcrvvWl5RRVdp+NqcR47pQ==", + "version": "1.3.1", + "resolved": "https://registry.npmmirror.com/rc-resize-observer/-/rc-resize-observer-1.3.1.tgz", + "integrity": "sha512-iFUdt3NNhflbY3mwySv5CA1TC06zdJ+pfo0oc27xpf4PIOvfZwZGtD9Kz41wGYqC4SLio93RVAirSSpYlV/uYg==", "requires": { - "@babel/runtime": "^7.10.1", + "@babel/runtime": "^7.20.7", "classnames": "^2.2.1", - "rc-util": "^5.15.0", + "rc-util": "^5.27.0", "resize-observer-polyfill": "^1.5.1" } } @@ -2438,13 +2479,12 @@ } }, "rc-util": { - "version": "5.24.2", - "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.24.2.tgz", - "integrity": "sha512-MWd0ZEV7xSwN4HM9jz9BwpnMzwCPjYJ7K90lePsrdgAkrmm8U7b4BOTIsv/84BQsaF7N3ejNkcrZ3AfEwc9HXA==", + "version": "5.28.0", + "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.28.0.tgz", + "integrity": "sha512-KYDjhGodswVj29v0TRciKTqRPgumIFvFDndbCD227pitQ+0Cei196rxk+OXb/blu6V8zdTRK5RjCJn+WmHLvBA==", "requires": { "@babel/runtime": "^7.18.3", - "react-is": "^16.12.0", - "shallowequal": "^1.1.0" + "react-is": "^16.12.0" } } } @@ -2459,9 +2499,9 @@ } }, "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "version": "3.1.3", + "resolved": "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "requires": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -2507,15 +2547,15 @@ "dev": true }, "array-includes": { - "version": "3.1.5", - "resolved": "https://registry.npmmirror.com/array-includes/-/array-includes-3.1.5.tgz", - "integrity": "sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==", + "version": "3.1.6", + "resolved": "https://registry.npmmirror.com/array-includes/-/array-includes-3.1.6.tgz", + "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", "dev": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", - "es-abstract": "^1.19.5", - "get-intrinsic": "^1.1.1", + "es-abstract": "^1.20.4", + "get-intrinsic": "^1.1.3", "is-string": "^1.0.7" } }, @@ -2548,25 +2588,25 @@ "dev": true }, "array.prototype.flatmap": { - "version": "1.3.0", - "resolved": "https://registry.npmmirror.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.0.tgz", - "integrity": "sha512-PZC9/8TKAIxcWKdyeb77EzULHPrIX/tIZebLJUQOMR1OwYosT8yggdfWScfTBCDj5utONvOuPQQumYsU2ULbkg==", + "version": "1.3.1", + "resolved": "https://registry.npmmirror.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", + "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", "es-shim-unscopables": "^1.0.0" } }, "array.prototype.reduce": { - "version": "1.0.4", - "resolved": "https://registry.npmmirror.com/array.prototype.reduce/-/array.prototype.reduce-1.0.4.tgz", - "integrity": "sha512-WnM+AjG/DvLRLo4DDl+r+SvCzYtD2Jd9oeBYMcEaI7t3fFrHY9M53/wdLcTvmZNQ70IU6Htj0emFkZ5TS+lrdw==", + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/array.prototype.reduce/-/array.prototype.reduce-1.0.5.tgz", + "integrity": "sha512-kDdugMl7id9COE8R7MHF5jWk7Dqt/fs4Pv+JXoICnYwqpjjjbUurz6w5fT5IG6brLdJhv6/VoHB0H7oyIBXd+Q==", "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", "es-array-method-boxes-properly": "^1.0.0", "is-string": "^1.0.7" } @@ -2645,9 +2685,9 @@ } }, "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmmirror.com/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", + "version": "1.0.6", + "resolved": "https://registry.npmmirror.com/async-each/-/async-each-1.0.6.tgz", + "integrity": "sha512-c646jH1avxr+aVpndVMeAfYw7wAa6idufrlN3LPA4PmKS0QEGp6PIC9nwz0WQkkvBGAMEki3pFdtxaF39J9vvg==", "dev": true }, "async-limiter": { @@ -2667,6 +2707,11 @@ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", "dev": true }, + "available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==" + }, "axios": { "version": "0.21.4", "resolved": "https://registry.npmmirror.com/axios/-/axios-0.21.4.tgz", @@ -2698,9 +2743,9 @@ } }, "babel-loader": { - "version": "8.2.5", - "resolved": "https://registry.npmmirror.com/babel-loader/-/babel-loader-8.2.5.tgz", - "integrity": "sha512-OSiFfH89LrEMiWd4pLNqGz4CwJDtbs2ZVc+iGu2HrkRfPxId9F2anQj38IxWpmRfsUY0aBZYi1EFcd3mhtRMLQ==", + "version": "8.3.0", + "resolved": "https://registry.npmmirror.com/babel-loader/-/babel-loader-8.3.0.tgz", + "integrity": "sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q==", "dev": true, "requires": { "find-cache-dir": "^3.3.1", @@ -2710,9 +2755,9 @@ }, "dependencies": { "loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", + "version": "2.0.4", + "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", "dev": true, "requires": { "big.js": "^5.2.2", @@ -2733,18 +2778,10 @@ } } }, - "babel-plugin-dynamic-import-node": { - "version": "2.3.3", - "resolved": "https://registry.npmmirror.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", - "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", - "requires": { - "object.assign": "^4.1.0" - } - }, "babel-plugin-import": { - "version": "1.13.5", - "resolved": "https://registry.npmmirror.com/babel-plugin-import/-/babel-plugin-import-1.13.5.tgz", - "integrity": "sha512-IkqnoV+ov1hdJVofly9pXRJmeDm9EtROfrc5i6eII0Hix2xMs5FEm8FG3ExMvazbnZBbgHIt6qdO8And6lCloQ==", + "version": "1.13.6", + "resolved": "https://registry.npmmirror.com/babel-plugin-import/-/babel-plugin-import-1.13.6.tgz", + "integrity": "sha512-N7FYnGh0DFsvDRkAPsvFq/metVfVD7P2h1rokOPpEH4cZbdRHCW+2jbXt0nnuqowkm/xhh2ww1anIdEpfYa7ZA==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.0.0" @@ -2939,9 +2976,9 @@ "dev": true }, "body-parser": { - "version": "1.20.0", - "resolved": "https://registry.npmmirror.com/body-parser/-/body-parser-1.20.0.tgz", - "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", + "version": "1.20.1", + "resolved": "https://registry.npmmirror.com/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", "dev": true, "requires": { "bytes": "3.1.2", @@ -2952,7 +2989,7 @@ "http-errors": "2.0.0", "iconv-lite": "0.4.24", "on-finished": "2.4.1", - "qs": "6.10.3", + "qs": "6.11.0", "raw-body": "2.5.1", "type-is": "~1.6.18", "unpipe": "1.0.0" @@ -2987,15 +3024,6 @@ "resolved": "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true - }, - "qs": { - "version": "6.10.3", - "resolved": "https://registry.npmmirror.com/qs/-/qs-6.10.3.tgz", - "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", - "dev": true, - "requires": { - "side-channel": "^1.0.4" - } } } }, @@ -3136,14 +3164,14 @@ } }, "browserslist": { - "version": "4.21.3", - "resolved": "https://registry.npmmirror.com/browserslist/-/browserslist-4.21.3.tgz", - "integrity": "sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ==", + "version": "4.21.5", + "resolved": "https://registry.npmmirror.com/browserslist/-/browserslist-4.21.5.tgz", + "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", "requires": { - "caniuse-lite": "^1.0.30001370", - "electron-to-chromium": "^1.4.202", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.5" + "caniuse-lite": "^1.0.30001449", + "electron-to-chromium": "^1.4.284", + "node-releases": "^2.0.8", + "update-browserslist-db": "^1.0.10" } }, "buffer": { @@ -3215,23 +3243,6 @@ "ssri": "^6.0.1", "unique-filename": "^1.1.1", "y18n": "^4.0.0" - }, - "dependencies": { - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmmirror.com/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - } } }, "cache-base": { @@ -3319,9 +3330,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001400", - "resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001400.tgz", - "integrity": "sha512-Mv659Hn65Z4LgZdJ7ge5JTVbE3rqbJaaXgW5LEI9/tOaXclfIZ8DW7D7FCWWWmWiiPS7AC48S8kf3DApSxQdgA==" + "version": "1.0.30001457", + "resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001457.tgz", + "integrity": "sha512-SDIV6bgE1aVbK6XyxdURbUE89zY7+k1BBBaOwYwkNCglXlel/E7mELiHC64HQ+W0xSKlqWhV9Wh7iHxUjMs4fA==" }, "case-sensitive-paths-webpack-plugin": { "version": "2.4.0", @@ -3592,9 +3603,9 @@ } }, "codemirror": { - "version": "5.65.8", - "resolved": "https://registry.npmmirror.com/codemirror/-/codemirror-5.65.8.tgz", - "integrity": "sha512-TNGkSkkoAsmZSf6W6g35LMVQJBHKasc2CKwhr/fTxSYun7cn6J+CbtyNjV/MYlFVkNTsqZoviegyCZimWhoMMA==" + "version": "5.65.12", + "resolved": "https://registry.npmmirror.com/codemirror/-/codemirror-5.65.12.tgz", + "integrity": "sha512-z2jlHBocElRnPYysN2HAuhXbO3DNB0bcSKmNz3hcWR2Js2Dkhc1bEOxG93Z3DeUrnm+qx56XOY5wQmbP5KY0sw==" }, "collection-visit": { "version": "1.0.0", @@ -3734,9 +3745,9 @@ } }, "compute-scroll-into-view": { - "version": "1.0.17", - "resolved": "https://registry.npmmirror.com/compute-scroll-into-view/-/compute-scroll-into-view-1.0.17.tgz", - "integrity": "sha512-j4dx+Fb0URmzbwwMUrhqWM2BEWHdFGx+qZ9qqASHRPqvTYdqvWnHg0H1hIbcyLnvgnoNAVMlwkepyqM3DaIFUg==" + "version": "1.0.20", + "resolved": "https://registry.npmmirror.com/compute-scroll-into-view/-/compute-scroll-into-view-1.0.20.tgz", + "integrity": "sha512-UCB0ioiyj8CRjtrvaceBLqqhZCVP+1B8+NWQhmdsm0VXOJtobBCf1dBQmebCCo34qZmUwZfIH2MZLqNHazrfjg==" }, "concat-map": { "version": "0.0.1", @@ -3792,18 +3803,15 @@ } }, "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmmirror.com/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "dev": true }, "convert-source-map": { - "version": "1.8.0", - "resolved": "https://registry.npmmirror.com/convert-source-map/-/convert-source-map-1.8.0.tgz", - "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", - "requires": { - "safe-buffer": "~5.1.1" - } + "version": "1.9.0", + "resolved": "https://registry.npmmirror.com/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" }, "cookie": { "version": "0.5.0", @@ -3847,9 +3855,9 @@ "dev": true }, "copy-to-clipboard": { - "version": "3.3.2", - "resolved": "https://registry.npmmirror.com/copy-to-clipboard/-/copy-to-clipboard-3.3.2.tgz", - "integrity": "sha512-Vme1Z6RUDzrb6xAI7EZlVZ5uvOk2F//GaxKUxajDqm9LhOVM1inxNAD2vy+UZDYsd0uyA9s7b3/FVZPSxqrCfg==", + "version": "3.3.3", + "resolved": "https://registry.npmmirror.com/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz", + "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==", "requires": { "toggle-selection": "^1.0.6" } @@ -4062,17 +4070,17 @@ "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==" }, "core-js-compat": { - "version": "3.25.1", - "resolved": "https://registry.npmmirror.com/core-js-compat/-/core-js-compat-3.25.1.tgz", - "integrity": "sha512-pOHS7O0i8Qt4zlPW/eIFjwp+NrTPx+wTL0ctgI2fHn31sZOq89rDsmtc/A2vAX7r6shl+bmVI+678He46jgBlw==", + "version": "3.28.0", + "resolved": "https://registry.npmmirror.com/core-js-compat/-/core-js-compat-3.28.0.tgz", + "integrity": "sha512-myzPgE7QodMg4nnd3K1TDoES/nADRStM8Gpz0D6nhkwbmwEnE0ZGJgoWsvQ722FR8D7xS0n0LV556RcEicjTyg==", "requires": { - "browserslist": "^4.21.3" + "browserslist": "^4.21.5" } }, "core-js-pure": { - "version": "3.25.1", - "resolved": "https://registry.npmmirror.com/core-js-pure/-/core-js-pure-3.25.1.tgz", - "integrity": "sha512-7Fr74bliUDdeJCBMxkkIuQ4xfxn/SwrVg+HkJUAoNEXVqYLv55l6Af0dJ5Lq2YBUW9yKqSkLXaS5SYPK6MGa/A==", + "version": "3.28.0", + "resolved": "https://registry.npmmirror.com/core-js-pure/-/core-js-pure-3.28.0.tgz", + "integrity": "sha512-DSOVleA9/v3LNj/vFxAPfUHttKTzrB2RXhAPvR5TPXn4vrra3Z2ssytvRyt8eruJwAfwAiFADEbrjcRdcvPLQQ==", "dev": true }, "core-util-is": { @@ -4082,9 +4090,9 @@ "dev": true }, "cosmiconfig": { - "version": "7.0.1", - "resolved": "https://registry.npmmirror.com/cosmiconfig/-/cosmiconfig-7.0.1.tgz", - "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", + "version": "7.1.0", + "resolved": "https://registry.npmmirror.com/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", "requires": { "@types/parse-json": "^4.0.0", "import-fresh": "^3.2.1", @@ -4453,9 +4461,9 @@ "integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==" }, "dayjs": { - "version": "1.11.5", - "resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.5.tgz", - "integrity": "sha512-CAdX5Q3YW3Gclyo5Vpqkgpj8fSdLQcRuzfX6mC6Phy0nfJ0eGYOeS7m4mt2plDWLAtA4TqTakvbboHvUxfe4iA==" + "version": "1.11.7", + "resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.7.tgz", + "integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==" }, "debug": { "version": "4.3.4", @@ -4472,9 +4480,9 @@ "dev": true }, "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmmirror.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==" + "version": "0.2.2", + "resolved": "https://registry.npmmirror.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz", + "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==" }, "dedent": { "version": "0.7.0", @@ -4503,9 +4511,9 @@ "dev": true }, "deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmmirror.com/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==" + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/deepmerge/-/deepmerge-4.3.0.tgz", + "integrity": "sha512-z2wJZXrmeHdvYJp/Ux55wIjqo81G5Bp4c+oELTW+7ar6SogWHajt5a9gO3s3IDaGSAXjDk0vlQKN3rms8ab3og==" }, "default-gateway": { "version": "4.2.0", @@ -4602,9 +4610,9 @@ } }, "define-properties": { - "version": "1.1.4", - "resolved": "https://registry.npmmirror.com/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/define-properties/-/define-properties-1.2.0.tgz", + "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", "requires": { "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" @@ -4811,9 +4819,9 @@ } }, "dom-align": { - "version": "1.12.3", - "resolved": "https://registry.npmmirror.com/dom-align/-/dom-align-1.12.3.tgz", - "integrity": "sha512-Gj9hZN3a07cbR6zviMUBOMPdWxYhbMI+x+WS0NAIu2zFZmbK8ys9R79g+iG9qLnlCwpFoaB+fKy8Pdv470GsPA==" + "version": "1.12.4", + "resolved": "https://registry.npmmirror.com/dom-align/-/dom-align-1.12.4.tgz", + "integrity": "sha512-R8LUSEay/68zE5c8/3BDxiTEvgb4xZTF0RKmAHfiEVN3klfIpXfi2/QCoiWPccVQ0J/ZGdz9OjzL4uJEP/MRAw==" }, "dom-converter": { "version": "0.2.0", @@ -4903,9 +4911,9 @@ } }, "dotenv": { - "version": "16.0.2", - "resolved": "https://registry.npmmirror.com/dotenv/-/dotenv-16.0.2.tgz", - "integrity": "sha512-JvpYKUmzQhYoIFgK2MOnF3bciIZoItIIoryihy0rIA+H4Jy0FmgyKYAHCTN98P5ybGSJcIFbh6QKeJdtZd1qhA==" + "version": "16.0.3", + "resolved": "https://registry.npmmirror.com/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==" }, "draft-js": { "version": "0.10.5", @@ -4935,12 +4943,12 @@ } }, "echarts": { - "version": "5.3.3", - "resolved": "https://registry.npmmirror.com/echarts/-/echarts-5.3.3.tgz", - "integrity": "sha512-BRw2serInRwO5SIwRviZ6Xgm5Lb7irgz+sLiFMmy/HOaf4SQ+7oYqxKzRHAKp4xHQ05AuHw1xvoQWJjDQq/FGw==", + "version": "5.4.1", + "resolved": "https://registry.npmmirror.com/echarts/-/echarts-5.4.1.tgz", + "integrity": "sha512-9ltS3M2JB0w2EhcYjCdmtrJ+6haZcW6acBolMGIuf01Hql1yrIV01L1aRj7jsaaIULJslEP9Z3vKlEmnJaWJVQ==", "requires": { "tslib": "2.3.0", - "zrender": "5.3.2" + "zrender": "5.4.1" }, "dependencies": { "tslib": { @@ -4966,9 +4974,9 @@ "dev": true }, "electron-to-chromium": { - "version": "1.4.251", - "resolved": "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.4.251.tgz", - "integrity": "sha512-k4o4cFrWPv4SoJGGAydd07GmlRVzmeDIJ6MaEChTUjk4Dmomn189tCicSzil2oyvbPoGgg2suwPDNWq4gWRhoQ==" + "version": "1.4.308", + "resolved": "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.4.308.tgz", + "integrity": "sha512-qyTx2aDFjEni4UnRWEME9ubd2Xc9c0zerTUl/ZinvD4QPsF0S7kJTV/Es/lPCTkNX6smyYar+z/n8Cl6pFr8yQ==" }, "elliptic": { "version": "6.5.4", @@ -5087,33 +5095,43 @@ } }, "es-abstract": { - "version": "1.20.2", - "resolved": "https://registry.npmmirror.com/es-abstract/-/es-abstract-1.20.2.tgz", - "integrity": "sha512-XxXQuVNrySBNlEkTYJoDNFe5+s2yIOpzq80sUHEdPdQr0S5nTLz4ZPPPswNIpKseDDUS5yghX1gfLIHQZ1iNuQ==", + "version": "1.21.1", + "resolved": "https://registry.npmmirror.com/es-abstract/-/es-abstract-1.21.1.tgz", + "integrity": "sha512-QudMsPOz86xYz/1dG1OuGBKOELjCh99IIWHLzy5znUB6j8xG2yMA7bfTV86VSqKF+Y/H08vQPR+9jyXpuC6hfg==", "requires": { + "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", + "es-set-tostringtag": "^2.0.1", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.1.2", + "get-intrinsic": "^1.1.3", "get-symbol-description": "^1.0.0", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", "has": "^1.0.3", "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", "has-symbols": "^1.0.3", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", + "internal-slot": "^1.0.4", + "is-array-buffer": "^3.0.1", + "is-callable": "^1.2.7", "is-negative-zero": "^2.0.2", "is-regex": "^1.1.4", "is-shared-array-buffer": "^1.0.2", "is-string": "^1.0.7", + "is-typed-array": "^1.1.10", "is-weakref": "^1.0.2", "object-inspect": "^1.12.2", "object-keys": "^1.1.1", "object.assign": "^4.1.4", "regexp.prototype.flags": "^1.4.3", - "string.prototype.trimend": "^1.0.5", - "string.prototype.trimstart": "^1.0.5", - "unbox-primitive": "^1.0.2" + "safe-regex-test": "^1.0.0", + "string.prototype.trimend": "^1.0.6", + "string.prototype.trimstart": "^1.0.6", + "typed-array-length": "^1.0.4", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.9" } }, "es-array-method-boxes-properly": { @@ -5121,6 +5139,16 @@ "resolved": "https://registry.npmmirror.com/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==" }, + "es-set-tostringtag": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", + "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", + "requires": { + "get-intrinsic": "^1.1.3", + "has": "^1.0.3", + "has-tostringtag": "^1.0.0" + } + }, "es-shim-unscopables": { "version": "1.0.0", "resolved": "https://registry.npmmirror.com/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", @@ -5260,9 +5288,9 @@ "dev": true }, "globals": { - "version": "13.17.0", - "resolved": "https://registry.npmmirror.com/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "version": "13.20.0", + "resolved": "https://registry.npmmirror.com/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -5280,10 +5308,19 @@ "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmmirror.com/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmmirror.com/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -5306,6 +5343,12 @@ "requires": { "has-flag": "^4.0.0" } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true } } }, @@ -5425,9 +5468,9 @@ "dev": true }, "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmmirror.com/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "version": "1.4.2", + "resolved": "https://registry.npmmirror.com/esquery/-/esquery-1.4.2.tgz", + "integrity": "sha512-JVSoLdTlTDkmjFmab7H/9SL9qGSyjElT3myyKp7krqjVFQCDLmj1QFaCLRFBszBKI0XVZaiiXvuPIX3ZwHe1Ng==", "dev": true, "requires": { "estraverse": "^5.1.0" @@ -5593,14 +5636,14 @@ } }, "express": { - "version": "4.18.1", - "resolved": "https://registry.npmmirror.com/express/-/express-4.18.1.tgz", - "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==", + "version": "4.18.2", + "resolved": "https://registry.npmmirror.com/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", "dev": true, "requires": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.0", + "body-parser": "1.20.1", "content-disposition": "0.5.4", "content-type": "~1.0.4", "cookie": "0.5.0", @@ -5619,7 +5662,7 @@ "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", "proxy-addr": "~2.0.7", - "qs": "6.10.3", + "qs": "6.11.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", "send": "0.18.0", @@ -5658,15 +5701,6 @@ "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", "dev": true }, - "qs": { - "version": "6.10.3", - "resolved": "https://registry.npmmirror.com/qs/-/qs-6.10.3.tgz", - "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", - "dev": true, - "requires": { - "side-channel": "^1.0.4" - } - }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -5798,9 +5832,9 @@ "dev": true }, "fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmmirror.com/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "version": "1.15.0", + "resolved": "https://registry.npmmirror.com/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", "dev": true, "requires": { "reusify": "^1.0.4" @@ -5875,9 +5909,9 @@ }, "dependencies": { "loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", + "version": "2.0.4", + "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", "dev": true, "requires": { "big.js": "^5.2.2", @@ -6034,12 +6068,6 @@ } } }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmmirror.com/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, "is-number": { "version": "3.0.0", "resolved": "https://registry.npmmirror.com/is-number/-/is-number-3.0.0.tgz", @@ -6135,6 +6163,14 @@ "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.2.tgz", "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" }, + "for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmmirror.com/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "requires": { + "is-callable": "^1.1.3" + } + }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmmirror.com/for-in/-/for-in-1.0.2.tgz", @@ -6241,9 +6277,9 @@ "dev": true }, "get-intrinsic": { - "version": "1.1.3", - "resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.1.3.tgz", - "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.2.0.tgz", + "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", "requires": { "function-bind": "^1.1.1", "has": "^1.0.3", @@ -6363,6 +6399,14 @@ "resolved": "https://registry.npmmirror.com/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" }, + "globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "requires": { + "define-properties": "^1.1.3" + } + }, "globby": { "version": "11.1.0", "resolved": "https://registry.npmmirror.com/globby/-/globby-11.1.0.tgz", @@ -6377,6 +6421,14 @@ "slash": "^3.0.0" } }, + "gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "requires": { + "get-intrinsic": "^1.1.3" + } + }, "graceful-fs": { "version": "4.2.10", "resolved": "https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.10.tgz", @@ -6544,6 +6596,11 @@ "get-intrinsic": "^1.1.1" } }, + "has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==" + }, "has-symbols": { "version": "1.0.3", "resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.0.3.tgz", @@ -6578,12 +6635,6 @@ "kind-of": "^4.0.0" }, "dependencies": { - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmmirror.com/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, "is-number": { "version": "3.0.0", "resolved": "https://registry.npmmirror.com/is-number/-/is-number-3.0.0.tgz", @@ -6660,6 +6711,18 @@ "resolved": "https://registry.npmmirror.com/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz", "integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==" }, + "hastscript": { + "version": "6.0.0", + "resolved": "https://registry.npmmirror.com/hastscript/-/hastscript-6.0.0.tgz", + "integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==", + "requires": { + "@types/hast": "^2.0.0", + "comma-separated-tokens": "^1.0.0", + "hast-util-parse-selector": "^2.0.0", + "property-information": "^5.0.0", + "space-separated-tokens": "^1.0.0" + } + }, "he": { "version": "1.2.0", "resolved": "https://registry.npmmirror.com/he/-/he-1.2.0.tgz", @@ -6676,6 +6739,11 @@ "resolved": "https://registry.npmmirror.com/highlight-words-core/-/highlight-words-core-1.2.2.tgz", "integrity": "sha512-BXUKIkUuh6cmmxzi5OIbUJxrG8OAk2MqoL1DtO3Wo9D2faJg2ph5ntyuQeLqaHJmzER6H5tllCDA9ZnNe9BVGg==" }, + "highlight.js": { + "version": "10.7.3", + "resolved": "https://registry.npmmirror.com/highlight.js/-/highlight.js-10.7.3.tgz", + "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==" + }, "history": { "version": "4.10.1", "resolved": "https://registry.npmmirror.com/history/-/history-4.10.1.tgz", @@ -6888,12 +6956,6 @@ } } }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmmirror.com/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, "is-number": { "version": "3.0.0", "resolved": "https://registry.npmmirror.com/is-number/-/is-number-3.0.0.tgz", @@ -7073,9 +7135,9 @@ "dev": true }, "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmmirror.com/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "version": "5.2.4", + "resolved": "https://registry.npmmirror.com/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", "dev": true }, "image-size": { @@ -7220,11 +7282,11 @@ } }, "internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmmirror.com/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/internal-slot/-/internal-slot-1.0.5.tgz", + "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", "requires": { - "get-intrinsic": "^1.1.0", + "get-intrinsic": "^1.2.0", "has": "^1.0.3", "side-channel": "^1.0.4" } @@ -7235,6 +7297,28 @@ "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", "dev": true }, + "intl-format-cache": { + "version": "4.3.1", + "resolved": "https://registry.npmmirror.com/intl-format-cache/-/intl-format-cache-4.3.1.tgz", + "integrity": "sha512-OEUYNA7D06agqPOYhbTkl0T8HA3QKSuwWh1HiClEnpd9vw7N+3XsQt5iZ0GUEchp5CW1fQk/tary+NsbF3yQ1Q==" + }, + "intl-messageformat": { + "version": "7.8.4", + "resolved": "https://registry.npmmirror.com/intl-messageformat/-/intl-messageformat-7.8.4.tgz", + "integrity": "sha512-yS0cLESCKCYjseCOGXuV4pxJm/buTfyCJ1nzQjryHmSehlptbZbn9fnlk1I9peLopZGGbjj46yHHiTAEZ1qOTA==", + "requires": { + "intl-format-cache": "^4.2.21", + "intl-messageformat-parser": "^3.6.4" + } + }, + "intl-messageformat-parser": { + "version": "3.6.4", + "resolved": "https://registry.npmmirror.com/intl-messageformat-parser/-/intl-messageformat-parser-3.6.4.tgz", + "integrity": "sha512-RgPGwue0mJtoX2Ax8EmMzJzttxjnva7gx0Q7mKJ4oALrTZvtmCeAw5Msz2PcjW4dtCh/h7vN/8GJCxZO1uv+OA==", + "requires": { + "@formatjs/intl-unified-numberformat": "^3.2.0" + } + }, "invariant": { "version": "2.2.4", "resolved": "https://registry.npmmirror.com/invariant/-/invariant-2.2.4.tgz", @@ -7276,12 +7360,6 @@ "kind-of": "^3.0.2" }, "dependencies": { - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmmirror.com/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmmirror.com/kind-of/-/kind-of-3.2.2.tgz", @@ -7317,6 +7395,16 @@ "has-tostringtag": "^1.0.0" } }, + "is-array-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/is-array-buffer/-/is-array-buffer-3.0.1.tgz", + "integrity": "sha512-ASfLknmY8Xa2XtB4wmbz13Wu202baeA18cJBCeCy0wXUHZF0IPyVEXqKEcd+t2fNSLLL1vC6k7lxZEojNbISXQ==", + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-typed-array": "^1.1.10" + } + }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmmirror.com/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -7349,10 +7437,16 @@ "has-tostringtag": "^1.0.0" } }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmmirror.com/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, "is-callable": { - "version": "1.2.6", - "resolved": "https://registry.npmmirror.com/is-callable/-/is-callable-1.2.6.tgz", - "integrity": "sha512-krO72EO2NptOGAX2KYyqbP9vYMlNAXdB53rq6f8LXY6RY7JdSR/3BD6wLUlPHSAesmY9vstNrjvqGaCiRK/91Q==" + "version": "1.2.7", + "resolved": "https://registry.npmmirror.com/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==" }, "is-color-stop": { "version": "1.1.0", @@ -7369,9 +7463,9 @@ } }, "is-core-module": { - "version": "2.10.0", - "resolved": "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.10.0.tgz", - "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", + "version": "2.11.0", + "resolved": "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", "requires": { "has": "^1.0.3" } @@ -7385,12 +7479,6 @@ "kind-of": "^3.0.2" }, "dependencies": { - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmmirror.com/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmmirror.com/kind-of/-/kind-of-3.2.2.tgz", @@ -7526,6 +7614,12 @@ "path-is-inside": "^1.0.2" } }, + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "dev": true + }, "is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmmirror.com/is-plain-object/-/is-plain-object-2.0.4.tgz", @@ -7585,6 +7679,18 @@ "has-symbols": "^1.0.2" } }, + "is-typed-array": { + "version": "1.1.10", + "resolved": "https://registry.npmmirror.com/is-typed-array/-/is-typed-array-1.1.10.tgz", + "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + } + }, "is-unicode-supported": { "version": "0.1.0", "resolved": "https://registry.npmmirror.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", @@ -7659,9 +7765,9 @@ } }, "jsencrypt": { - "version": "3.2.1", - "resolved": "https://registry.npmmirror.com/jsencrypt/-/jsencrypt-3.2.1.tgz", - "integrity": "sha512-k1sD5QV0KPn+D8uG9AdGzTQuamt82QZ3A3l6f7TRwMU6Oi2Vg0BsL+wZIQBONcraO1pc78ExMdvmBBJ8WhNYUA==" + "version": "3.3.1", + "resolved": "https://registry.npmmirror.com/jsencrypt/-/jsencrypt-3.3.1.tgz", + "integrity": "sha512-dVvV54GdFuJgmEKn+oBiaifDMen4p6o6j/lJh0OVMcouME8sST0bJ7bldIgKBQk4za0zyGn0/pm4vOznR25mLw==" }, "jsesc": { "version": "2.5.2", @@ -7700,9 +7806,9 @@ } }, "json5": { - "version": "2.2.1", - "resolved": "https://registry.npmmirror.com/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==" + "version": "2.2.3", + "resolved": "https://registry.npmmirror.com/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" }, "jsx-ast-utils": { "version": "3.3.3", @@ -7838,13 +7944,12 @@ }, "dependencies": { "rc-util": { - "version": "5.24.4", - "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.24.4.tgz", - "integrity": "sha512-2a4RQnycV9eV7lVZPEJ7QwJRPlZNc06J7CwcwZo4vIHr3PfUqtYgl1EkUV9ETAc6VRRi8XZOMFhYG63whlIC9Q==", + "version": "5.28.0", + "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.28.0.tgz", + "integrity": "sha512-KYDjhGodswVj29v0TRciKTqRPgumIFvFDndbCD227pitQ+0Cei196rxk+OXb/blu6V8zdTRK5RjCJn+WmHLvBA==", "requires": { "@babel/runtime": "^7.18.3", - "react-is": "^16.12.0", - "shallowequal": "^1.1.0" + "react-is": "^16.12.0" } } } @@ -8050,9 +8155,9 @@ "dev": true }, "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "version": "1.4.2", + "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-1.4.2.tgz", + "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", "requires": { "big.js": "^5.2.2", "emojis-list": "^3.0.0", @@ -8060,9 +8165,9 @@ }, "dependencies": { "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmmirror.com/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "requires": { "minimist": "^1.2.0" } @@ -8248,9 +8353,9 @@ } }, "loglevel": { - "version": "1.8.0", - "resolved": "https://registry.npmmirror.com/loglevel/-/loglevel-1.8.0.tgz", - "integrity": "sha512-G6A/nJLRgWOuuwdNuA6koovfEV1YpqqAG4pRUlFaz3jj2QNZ8M4vBqnVA+HBTmU/AMNUtlOsMmSpF6NyOjztbA==", + "version": "1.8.1", + "resolved": "https://registry.npmmirror.com/loglevel/-/loglevel-1.8.1.tgz", + "integrity": "sha512-tCRIJM51SHjAayKwC+QAg8hT8vg6z7GSgLJKGvzuPb1Wc+hLzqtuVLxp6/HzSPOozuK+8ErAhy7U/sVzw8Dgfg==", "dev": true }, "loose-envify": { @@ -8276,22 +8381,14 @@ "requires": { "fault": "^1.0.0", "highlight.js": "~10.7.0" - }, - "dependencies": { - "highlight.js": { - "version": "10.7.3", - "resolved": "https://registry.npmmirror.com/highlight.js/-/highlight.js-10.7.3.tgz", - "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==" - } } }, "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, + "version": "5.1.1", + "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "requires": { - "yallist": "^4.0.0" + "yallist": "^3.0.2" } }, "make-dir": { @@ -8386,9 +8483,9 @@ "dev": true }, "metismenujs": { - "version": "1.3.1", - "resolved": "https://registry.npmmirror.com/metismenujs/-/metismenujs-1.3.1.tgz", - "integrity": "sha512-bb2f78827KWj/zeY9ZmnEnuEU9kRaW/WL1r5jJ2ALAtY34qSIvygE/HzNw1QXWQrW6t4ILELZGS6CcDz6gr5mw==" + "version": "1.4.0", + "resolved": "https://registry.npmmirror.com/metismenujs/-/metismenujs-1.4.0.tgz", + "integrity": "sha512-a+3/XVkG8fVA6HBYu1yQkUkVpbh2n9po3vhSzu/Pu5k6s2hbteFZMRzUQyHt6FF28N8pLOpzcb47w4ErBHEsDQ==" }, "micromatch": { "version": "4.0.5", @@ -8466,9 +8563,9 @@ }, "dependencies": { "loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", + "version": "2.0.4", + "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", "dev": true, "requires": { "big.js": "^5.2.2", @@ -8509,9 +8606,9 @@ } }, "minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmmirror.com/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" + "version": "1.2.8", + "resolved": "https://registry.npmmirror.com/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==" }, "mississippi": { "version": "3.0.0", @@ -8607,9 +8704,9 @@ "dev": true }, "nan": { - "version": "2.16.0", - "resolved": "https://registry.npmmirror.com/nan/-/nan-2.16.0.tgz", - "integrity": "sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA==", + "version": "2.17.0", + "resolved": "https://registry.npmmirror.com/nan/-/nan-2.17.0.tgz", + "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==", "dev": true, "optional": true }, @@ -8733,9 +8830,9 @@ "dev": true }, "node-releases": { - "version": "2.0.6", - "resolved": "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.6.tgz", - "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==" + "version": "2.0.10", + "resolved": "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.10.tgz", + "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==" }, "normalize-path": { "version": "3.0.0", @@ -8795,12 +8892,6 @@ "is-descriptor": "^0.1.0" } }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmmirror.com/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmmirror.com/kind-of/-/kind-of-3.2.2.tgz", @@ -8813,9 +8904,9 @@ } }, "object-inspect": { - "version": "1.12.2", - "resolved": "https://registry.npmmirror.com/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==" + "version": "1.12.3", + "resolved": "https://registry.npmmirror.com/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==" }, "object-is": { "version": "1.1.5", @@ -8853,36 +8944,36 @@ } }, "object.entries": { - "version": "1.1.5", - "resolved": "https://registry.npmmirror.com/object.entries/-/object.entries-1.1.5.tgz", - "integrity": "sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==", + "version": "1.1.6", + "resolved": "https://registry.npmmirror.com/object.entries/-/object.entries-1.1.6.tgz", + "integrity": "sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" } }, "object.fromentries": { - "version": "2.0.5", - "resolved": "https://registry.npmmirror.com/object.fromentries/-/object.fromentries-2.0.5.tgz", - "integrity": "sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw==", + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/object.fromentries/-/object.fromentries-2.0.6.tgz", + "integrity": "sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" } }, "object.getownpropertydescriptors": { - "version": "2.1.4", - "resolved": "https://registry.npmmirror.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.4.tgz", - "integrity": "sha512-sccv3L/pMModT6dJAYF3fzGMVcb38ysQ0tEE6ixv2yXJDtEIPph268OlAdJj5/qZMZDq2g/jqvwppt36uS/uQQ==", + "version": "2.1.5", + "resolved": "https://registry.npmmirror.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.5.tgz", + "integrity": "sha512-yDNzckpM6ntyQiGTik1fKV1DcVDRS+w8bvpWNCBanvH5LfRX9O8WTHqQzG4RZwRAM4I0oU7TV11Lj5v0g20ibw==", "requires": { - "array.prototype.reduce": "^1.0.4", + "array.prototype.reduce": "^1.0.5", "call-bind": "^1.0.2", "define-properties": "^1.1.4", - "es-abstract": "^1.20.1" + "es-abstract": "^1.20.4" } }, "object.pick": { @@ -8895,14 +8986,14 @@ } }, "object.values": { - "version": "1.1.5", - "resolved": "https://registry.npmmirror.com/object.values/-/object.values-1.1.5.tgz", - "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", + "version": "1.1.6", + "resolved": "https://registry.npmmirror.com/object.values/-/object.values-1.1.6.tgz", + "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" } }, "obuf": { @@ -9094,6 +9185,19 @@ "safe-buffer": "^5.1.1" } }, + "parse-entities": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/parse-entities/-/parse-entities-2.0.0.tgz", + "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", + "requires": { + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" + } + }, "parse-json": { "version": "5.2.0", "resolved": "https://registry.npmmirror.com/parse-json/-/parse-json-5.2.0.tgz", @@ -9696,9 +9800,9 @@ } }, "postcss-selector-parser": { - "version": "6.0.10", - "resolved": "https://registry.npmmirror.com/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", - "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", + "version": "6.0.11", + "resolved": "https://registry.npmmirror.com/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz", + "integrity": "sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==", "dev": true, "requires": { "cssesc": "^3.0.0", @@ -9934,9 +10038,9 @@ } }, "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmmirror.com/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "version": "2.3.0", + "resolved": "https://registry.npmmirror.com/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", "dev": true }, "q": { @@ -9954,11 +10058,11 @@ } }, "query-string": { - "version": "7.1.1", - "resolved": "https://registry.npmmirror.com/query-string/-/query-string-7.1.1.tgz", - "integrity": "sha512-MplouLRDHBZSG9z7fpuAAcI7aAYjDLhtsiVZsevsfaHWDS2IDdORKbSd1kWUA+V4zyva/HZoSfpwnYMMQDhb0w==", + "version": "7.1.3", + "resolved": "https://registry.npmmirror.com/query-string/-/query-string-7.1.3.tgz", + "integrity": "sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==", "requires": { - "decode-uri-component": "^0.2.0", + "decode-uri-component": "^0.2.2", "filter-obj": "^1.1.0", "split-on-first": "^1.0.0", "strict-uri-encode": "^2.0.0" @@ -10051,26 +10155,24 @@ } }, "rc-align": { - "version": "4.0.12", - "resolved": "https://registry.npmmirror.com/rc-align/-/rc-align-4.0.12.tgz", - "integrity": "sha512-3DuwSJp8iC/dgHzwreOQl52soj40LchlfUHtgACOUtwGuoFIOVh6n/sCpfqCU8kO5+iz6qR0YKvjgB8iPdE3aQ==", + "version": "4.0.15", + "resolved": "https://registry.npmmirror.com/rc-align/-/rc-align-4.0.15.tgz", + "integrity": "sha512-wqJtVH60pka/nOX7/IspElA8gjPNQKIx/ZqJ6heATCkXpe1Zg4cPVrMD2vC96wjsFFL8WsmhPbx9tdMo1qqlIA==", "requires": { "@babel/runtime": "^7.10.1", "classnames": "2.x", "dom-align": "^1.7.0", - "lodash": "^4.17.21", - "rc-util": "^5.3.0", + "rc-util": "^5.26.0", "resize-observer-polyfill": "^1.5.1" }, "dependencies": { "rc-util": { - "version": "5.24.2", - "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.24.2.tgz", - "integrity": "sha512-MWd0ZEV7xSwN4HM9jz9BwpnMzwCPjYJ7K90lePsrdgAkrmm8U7b4BOTIsv/84BQsaF7N3ejNkcrZ3AfEwc9HXA==", + "version": "5.28.0", + "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.28.0.tgz", + "integrity": "sha512-KYDjhGodswVj29v0TRciKTqRPgumIFvFDndbCD227pitQ+0Cei196rxk+OXb/blu6V8zdTRK5RjCJn+WmHLvBA==", "requires": { "@babel/runtime": "^7.18.3", - "react-is": "^16.12.0", - "shallowequal": "^1.1.0" + "react-is": "^16.12.0" } } } @@ -10104,13 +10206,12 @@ }, "dependencies": { "rc-util": { - "version": "5.24.2", - "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.24.2.tgz", - "integrity": "sha512-MWd0ZEV7xSwN4HM9jz9BwpnMzwCPjYJ7K90lePsrdgAkrmm8U7b4BOTIsv/84BQsaF7N3ejNkcrZ3AfEwc9HXA==", + "version": "5.28.0", + "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.28.0.tgz", + "integrity": "sha512-KYDjhGodswVj29v0TRciKTqRPgumIFvFDndbCD227pitQ+0Cei196rxk+OXb/blu6V8zdTRK5RjCJn+WmHLvBA==", "requires": { "@babel/runtime": "^7.18.3", - "react-is": "^16.12.0", - "shallowequal": "^1.1.0" + "react-is": "^16.12.0" } } } @@ -10137,13 +10238,12 @@ }, "dependencies": { "rc-util": { - "version": "5.24.2", - "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.24.2.tgz", - "integrity": "sha512-MWd0ZEV7xSwN4HM9jz9BwpnMzwCPjYJ7K90lePsrdgAkrmm8U7b4BOTIsv/84BQsaF7N3ejNkcrZ3AfEwc9HXA==", + "version": "5.28.0", + "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.28.0.tgz", + "integrity": "sha512-KYDjhGodswVj29v0TRciKTqRPgumIFvFDndbCD227pitQ+0Cei196rxk+OXb/blu6V8zdTRK5RjCJn+WmHLvBA==", "requires": { "@babel/runtime": "^7.18.3", - "react-is": "^16.12.0", - "shallowequal": "^1.1.0" + "react-is": "^16.12.0" } } } @@ -10160,13 +10260,12 @@ }, "dependencies": { "rc-util": { - "version": "5.24.2", - "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.24.2.tgz", - "integrity": "sha512-MWd0ZEV7xSwN4HM9jz9BwpnMzwCPjYJ7K90lePsrdgAkrmm8U7b4BOTIsv/84BQsaF7N3ejNkcrZ3AfEwc9HXA==", + "version": "5.28.0", + "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.28.0.tgz", + "integrity": "sha512-KYDjhGodswVj29v0TRciKTqRPgumIFvFDndbCD227pitQ+0Cei196rxk+OXb/blu6V8zdTRK5RjCJn+WmHLvBA==", "requires": { "@babel/runtime": "^7.18.3", - "react-is": "^16.12.0", - "shallowequal": "^1.1.0" + "react-is": "^16.12.0" } } } @@ -10182,13 +10281,12 @@ }, "dependencies": { "rc-util": { - "version": "5.24.2", - "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.24.2.tgz", - "integrity": "sha512-MWd0ZEV7xSwN4HM9jz9BwpnMzwCPjYJ7K90lePsrdgAkrmm8U7b4BOTIsv/84BQsaF7N3ejNkcrZ3AfEwc9HXA==", + "version": "5.28.0", + "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.28.0.tgz", + "integrity": "sha512-KYDjhGodswVj29v0TRciKTqRPgumIFvFDndbCD227pitQ+0Cei196rxk+OXb/blu6V8zdTRK5RjCJn+WmHLvBA==", "requires": { "@babel/runtime": "^7.18.3", - "react-is": "^16.12.0", - "shallowequal": "^1.1.0" + "react-is": "^16.12.0" } } } @@ -10248,13 +10346,12 @@ "integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==" }, "rc-util": { - "version": "5.24.4", - "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.24.4.tgz", - "integrity": "sha512-2a4RQnycV9eV7lVZPEJ7QwJRPlZNc06J7CwcwZo4vIHr3PfUqtYgl1EkUV9ETAc6VRRi8XZOMFhYG63whlIC9Q==", + "version": "5.28.0", + "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.28.0.tgz", + "integrity": "sha512-KYDjhGodswVj29v0TRciKTqRPgumIFvFDndbCD227pitQ+0Cei196rxk+OXb/blu6V8zdTRK5RjCJn+WmHLvBA==", "requires": { "@babel/runtime": "^7.18.3", - "react-is": "^16.12.0", - "shallowequal": "^1.1.0" + "react-is": "^16.12.0" } } } @@ -10287,21 +10384,20 @@ }, "dependencies": { "rc-util": { - "version": "5.24.2", - "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.24.2.tgz", - "integrity": "sha512-MWd0ZEV7xSwN4HM9jz9BwpnMzwCPjYJ7K90lePsrdgAkrmm8U7b4BOTIsv/84BQsaF7N3ejNkcrZ3AfEwc9HXA==", + "version": "5.28.0", + "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.28.0.tgz", + "integrity": "sha512-KYDjhGodswVj29v0TRciKTqRPgumIFvFDndbCD227pitQ+0Cei196rxk+OXb/blu6V8zdTRK5RjCJn+WmHLvBA==", "requires": { "@babel/runtime": "^7.18.3", - "react-is": "^16.12.0", - "shallowequal": "^1.1.0" + "react-is": "^16.12.0" } } } }, "rc-input-number": { - "version": "7.3.7", - "resolved": "https://registry.npmmirror.com/rc-input-number/-/rc-input-number-7.3.7.tgz", - "integrity": "sha512-W9jDwfhJyNjg0iZX401r0GctTGX4ETURzF6SisC42GR0AkJxtaPD89eGwbTdAudUjEx0Pkn2rGmfvVGGdQACKA==", + "version": "7.3.11", + "resolved": "https://registry.npmmirror.com/rc-input-number/-/rc-input-number-7.3.11.tgz", + "integrity": "sha512-aMWPEjFeles6PQnMqP5eWpxzsvHm9rh1jQOWXExUEIxhX62Fyl/ptifLHOn17+waDG1T/YUb6flfJbvwRhHrbA==", "requires": { "@babel/runtime": "^7.10.1", "classnames": "^2.2.5", @@ -10309,13 +10405,12 @@ }, "dependencies": { "rc-util": { - "version": "5.24.2", - "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.24.2.tgz", - "integrity": "sha512-MWd0ZEV7xSwN4HM9jz9BwpnMzwCPjYJ7K90lePsrdgAkrmm8U7b4BOTIsv/84BQsaF7N3ejNkcrZ3AfEwc9HXA==", + "version": "5.28.0", + "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.28.0.tgz", + "integrity": "sha512-KYDjhGodswVj29v0TRciKTqRPgumIFvFDndbCD227pitQ+0Cei196rxk+OXb/blu6V8zdTRK5RjCJn+WmHLvBA==", "requires": { "@babel/runtime": "^7.18.3", - "react-is": "^16.12.0", - "shallowequal": "^1.1.0" + "react-is": "^16.12.0" } } } @@ -10348,13 +10443,12 @@ } }, "rc-util": { - "version": "5.24.2", - "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.24.2.tgz", - "integrity": "sha512-MWd0ZEV7xSwN4HM9jz9BwpnMzwCPjYJ7K90lePsrdgAkrmm8U7b4BOTIsv/84BQsaF7N3ejNkcrZ3AfEwc9HXA==", + "version": "5.28.0", + "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.28.0.tgz", + "integrity": "sha512-KYDjhGodswVj29v0TRciKTqRPgumIFvFDndbCD227pitQ+0Cei196rxk+OXb/blu6V8zdTRK5RjCJn+WmHLvBA==", "requires": { "@babel/runtime": "^7.18.3", - "react-is": "^16.12.0", - "shallowequal": "^1.1.0" + "react-is": "^16.12.0" } } } @@ -10374,21 +10468,20 @@ }, "dependencies": { "rc-util": { - "version": "5.24.4", - "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.24.4.tgz", - "integrity": "sha512-2a4RQnycV9eV7lVZPEJ7QwJRPlZNc06J7CwcwZo4vIHr3PfUqtYgl1EkUV9ETAc6VRRi8XZOMFhYG63whlIC9Q==", + "version": "5.28.0", + "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.28.0.tgz", + "integrity": "sha512-KYDjhGodswVj29v0TRciKTqRPgumIFvFDndbCD227pitQ+0Cei196rxk+OXb/blu6V8zdTRK5RjCJn+WmHLvBA==", "requires": { "@babel/runtime": "^7.18.3", - "react-is": "^16.12.0", - "shallowequal": "^1.1.0" + "react-is": "^16.12.0" } } } }, "rc-motion": { - "version": "2.6.2", - "resolved": "https://registry.npmmirror.com/rc-motion/-/rc-motion-2.6.2.tgz", - "integrity": "sha512-4w1FaX3dtV749P8GwfS4fYnFG4Rb9pxvCYPc/b2fw1cmlHJWNNgOFIz7ysiD+eOrzJSvnLJWlNQQncpNMXwwpg==", + "version": "2.6.3", + "resolved": "https://registry.npmmirror.com/rc-motion/-/rc-motion-2.6.3.tgz", + "integrity": "sha512-xFLkes3/7VL/J+ah9jJruEW/Akbx5F6jVa2wG5o/ApGKQKSOd5FR3rseHLL9+xtJg4PmCwo6/1tqhDO/T+jFHA==", "requires": { "@babel/runtime": "^7.11.1", "classnames": "^2.2.1", @@ -10396,13 +10489,12 @@ }, "dependencies": { "rc-util": { - "version": "5.24.2", - "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.24.2.tgz", - "integrity": "sha512-MWd0ZEV7xSwN4HM9jz9BwpnMzwCPjYJ7K90lePsrdgAkrmm8U7b4BOTIsv/84BQsaF7N3ejNkcrZ3AfEwc9HXA==", + "version": "5.28.0", + "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.28.0.tgz", + "integrity": "sha512-KYDjhGodswVj29v0TRciKTqRPgumIFvFDndbCD227pitQ+0Cei196rxk+OXb/blu6V8zdTRK5RjCJn+WmHLvBA==", "requires": { "@babel/runtime": "^7.18.3", - "react-is": "^16.12.0", - "shallowequal": "^1.1.0" + "react-is": "^16.12.0" } } } @@ -10419,13 +10511,12 @@ }, "dependencies": { "rc-util": { - "version": "5.24.2", - "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.24.2.tgz", - "integrity": "sha512-MWd0ZEV7xSwN4HM9jz9BwpnMzwCPjYJ7K90lePsrdgAkrmm8U7b4BOTIsv/84BQsaF7N3ejNkcrZ3AfEwc9HXA==", + "version": "5.28.0", + "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.28.0.tgz", + "integrity": "sha512-KYDjhGodswVj29v0TRciKTqRPgumIFvFDndbCD227pitQ+0Cei196rxk+OXb/blu6V8zdTRK5RjCJn+WmHLvBA==", "requires": { "@babel/runtime": "^7.18.3", - "react-is": "^16.12.0", - "shallowequal": "^1.1.0" + "react-is": "^16.12.0" } } } @@ -10442,13 +10533,12 @@ }, "dependencies": { "rc-util": { - "version": "5.24.2", - "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.24.2.tgz", - "integrity": "sha512-MWd0ZEV7xSwN4HM9jz9BwpnMzwCPjYJ7K90lePsrdgAkrmm8U7b4BOTIsv/84BQsaF7N3ejNkcrZ3AfEwc9HXA==", + "version": "5.28.0", + "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.28.0.tgz", + "integrity": "sha512-KYDjhGodswVj29v0TRciKTqRPgumIFvFDndbCD227pitQ+0Cei196rxk+OXb/blu6V8zdTRK5RjCJn+WmHLvBA==", "requires": { "@babel/runtime": "^7.18.3", - "react-is": "^16.12.0", - "shallowequal": "^1.1.0" + "react-is": "^16.12.0" } } } @@ -10478,13 +10568,12 @@ }, "dependencies": { "rc-util": { - "version": "5.24.2", - "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.24.2.tgz", - "integrity": "sha512-MWd0ZEV7xSwN4HM9jz9BwpnMzwCPjYJ7K90lePsrdgAkrmm8U7b4BOTIsv/84BQsaF7N3ejNkcrZ3AfEwc9HXA==", + "version": "5.28.0", + "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.28.0.tgz", + "integrity": "sha512-KYDjhGodswVj29v0TRciKTqRPgumIFvFDndbCD227pitQ+0Cei196rxk+OXb/blu6V8zdTRK5RjCJn+WmHLvBA==", "requires": { "@babel/runtime": "^7.18.3", - "react-is": "^16.12.0", - "shallowequal": "^1.1.0" + "react-is": "^16.12.0" } } } @@ -10509,36 +10598,34 @@ }, "dependencies": { "rc-util": { - "version": "5.24.2", - "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.24.2.tgz", - "integrity": "sha512-MWd0ZEV7xSwN4HM9jz9BwpnMzwCPjYJ7K90lePsrdgAkrmm8U7b4BOTIsv/84BQsaF7N3ejNkcrZ3AfEwc9HXA==", + "version": "5.28.0", + "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.28.0.tgz", + "integrity": "sha512-KYDjhGodswVj29v0TRciKTqRPgumIFvFDndbCD227pitQ+0Cei196rxk+OXb/blu6V8zdTRK5RjCJn+WmHLvBA==", "requires": { "@babel/runtime": "^7.18.3", - "react-is": "^16.12.0", - "shallowequal": "^1.1.0" + "react-is": "^16.12.0" } } } }, "rc-resize-observer": { - "version": "1.2.0", - "resolved": "https://registry.npmmirror.com/rc-resize-observer/-/rc-resize-observer-1.2.0.tgz", - "integrity": "sha512-6W+UzT3PyDM0wVCEHfoW3qTHPTvbdSgiA43buiy8PzmeMnfgnDeb9NjdimMXMl3/TcrvvWl5RRVdp+NqcR47pQ==", + "version": "1.3.1", + "resolved": "https://registry.npmmirror.com/rc-resize-observer/-/rc-resize-observer-1.3.1.tgz", + "integrity": "sha512-iFUdt3NNhflbY3mwySv5CA1TC06zdJ+pfo0oc27xpf4PIOvfZwZGtD9Kz41wGYqC4SLio93RVAirSSpYlV/uYg==", "requires": { - "@babel/runtime": "^7.10.1", + "@babel/runtime": "^7.20.7", "classnames": "^2.2.1", - "rc-util": "^5.15.0", + "rc-util": "^5.27.0", "resize-observer-polyfill": "^1.5.1" }, "dependencies": { "rc-util": { - "version": "5.24.2", - "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.24.2.tgz", - "integrity": "sha512-MWd0ZEV7xSwN4HM9jz9BwpnMzwCPjYJ7K90lePsrdgAkrmm8U7b4BOTIsv/84BQsaF7N3ejNkcrZ3AfEwc9HXA==", + "version": "5.28.0", + "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.28.0.tgz", + "integrity": "sha512-KYDjhGodswVj29v0TRciKTqRPgumIFvFDndbCD227pitQ+0Cei196rxk+OXb/blu6V8zdTRK5RjCJn+WmHLvBA==", "requires": { "@babel/runtime": "^7.18.3", - "react-is": "^16.12.0", - "shallowequal": "^1.1.0" + "react-is": "^16.12.0" } } } @@ -10558,13 +10645,12 @@ }, "dependencies": { "rc-util": { - "version": "5.24.2", - "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.24.2.tgz", - "integrity": "sha512-MWd0ZEV7xSwN4HM9jz9BwpnMzwCPjYJ7K90lePsrdgAkrmm8U7b4BOTIsv/84BQsaF7N3ejNkcrZ3AfEwc9HXA==", + "version": "5.28.0", + "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.28.0.tgz", + "integrity": "sha512-KYDjhGodswVj29v0TRciKTqRPgumIFvFDndbCD227pitQ+0Cei196rxk+OXb/blu6V8zdTRK5RjCJn+WmHLvBA==", "requires": { "@babel/runtime": "^7.18.3", - "react-is": "^16.12.0", - "shallowequal": "^1.1.0" + "react-is": "^16.12.0" } } } @@ -10582,13 +10668,12 @@ }, "dependencies": { "rc-util": { - "version": "5.24.2", - "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.24.2.tgz", - "integrity": "sha512-MWd0ZEV7xSwN4HM9jz9BwpnMzwCPjYJ7K90lePsrdgAkrmm8U7b4BOTIsv/84BQsaF7N3ejNkcrZ3AfEwc9HXA==", + "version": "5.28.0", + "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.28.0.tgz", + "integrity": "sha512-KYDjhGodswVj29v0TRciKTqRPgumIFvFDndbCD227pitQ+0Cei196rxk+OXb/blu6V8zdTRK5RjCJn+WmHLvBA==", "requires": { "@babel/runtime": "^7.18.3", - "react-is": "^16.12.0", - "shallowequal": "^1.1.0" + "react-is": "^16.12.0" } } } @@ -10604,13 +10689,12 @@ }, "dependencies": { "rc-util": { - "version": "5.24.2", - "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.24.2.tgz", - "integrity": "sha512-MWd0ZEV7xSwN4HM9jz9BwpnMzwCPjYJ7K90lePsrdgAkrmm8U7b4BOTIsv/84BQsaF7N3ejNkcrZ3AfEwc9HXA==", + "version": "5.28.0", + "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.28.0.tgz", + "integrity": "sha512-KYDjhGodswVj29v0TRciKTqRPgumIFvFDndbCD227pitQ+0Cei196rxk+OXb/blu6V8zdTRK5RjCJn+WmHLvBA==", "requires": { "@babel/runtime": "^7.18.3", - "react-is": "^16.12.0", - "shallowequal": "^1.1.0" + "react-is": "^16.12.0" } } } @@ -10626,13 +10710,12 @@ }, "dependencies": { "rc-util": { - "version": "5.24.2", - "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.24.2.tgz", - "integrity": "sha512-MWd0ZEV7xSwN4HM9jz9BwpnMzwCPjYJ7K90lePsrdgAkrmm8U7b4BOTIsv/84BQsaF7N3ejNkcrZ3AfEwc9HXA==", + "version": "5.28.0", + "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.28.0.tgz", + "integrity": "sha512-KYDjhGodswVj29v0TRciKTqRPgumIFvFDndbCD227pitQ+0Cei196rxk+OXb/blu6V8zdTRK5RjCJn+WmHLvBA==", "requires": { "@babel/runtime": "^7.18.3", - "react-is": "^16.12.0", - "shallowequal": "^1.1.0" + "react-is": "^16.12.0" } } } @@ -10650,13 +10733,12 @@ }, "dependencies": { "rc-util": { - "version": "5.24.4", - "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.24.4.tgz", - "integrity": "sha512-2a4RQnycV9eV7lVZPEJ7QwJRPlZNc06J7CwcwZo4vIHr3PfUqtYgl1EkUV9ETAc6VRRi8XZOMFhYG63whlIC9Q==", + "version": "5.28.0", + "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.28.0.tgz", + "integrity": "sha512-KYDjhGodswVj29v0TRciKTqRPgumIFvFDndbCD227pitQ+0Cei196rxk+OXb/blu6V8zdTRK5RjCJn+WmHLvBA==", "requires": { "@babel/runtime": "^7.18.3", - "react-is": "^16.12.0", - "shallowequal": "^1.1.0" + "react-is": "^16.12.0" } } } @@ -10689,13 +10771,12 @@ } }, "rc-util": { - "version": "5.24.2", - "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.24.2.tgz", - "integrity": "sha512-MWd0ZEV7xSwN4HM9jz9BwpnMzwCPjYJ7K90lePsrdgAkrmm8U7b4BOTIsv/84BQsaF7N3ejNkcrZ3AfEwc9HXA==", + "version": "5.28.0", + "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.28.0.tgz", + "integrity": "sha512-KYDjhGodswVj29v0TRciKTqRPgumIFvFDndbCD227pitQ+0Cei196rxk+OXb/blu6V8zdTRK5RjCJn+WmHLvBA==", "requires": { "@babel/runtime": "^7.18.3", - "react-is": "^16.12.0", - "shallowequal": "^1.1.0" + "react-is": "^16.12.0" } } } @@ -10713,13 +10794,12 @@ }, "dependencies": { "rc-util": { - "version": "5.24.2", - "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.24.2.tgz", - "integrity": "sha512-MWd0ZEV7xSwN4HM9jz9BwpnMzwCPjYJ7K90lePsrdgAkrmm8U7b4BOTIsv/84BQsaF7N3ejNkcrZ3AfEwc9HXA==", + "version": "5.28.0", + "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.28.0.tgz", + "integrity": "sha512-KYDjhGodswVj29v0TRciKTqRPgumIFvFDndbCD227pitQ+0Cei196rxk+OXb/blu6V8zdTRK5RjCJn+WmHLvBA==", "requires": { "@babel/runtime": "^7.18.3", - "react-is": "^16.12.0", - "shallowequal": "^1.1.0" + "react-is": "^16.12.0" } } } @@ -10746,13 +10826,12 @@ }, "dependencies": { "rc-util": { - "version": "5.24.4", - "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.24.4.tgz", - "integrity": "sha512-2a4RQnycV9eV7lVZPEJ7QwJRPlZNc06J7CwcwZo4vIHr3PfUqtYgl1EkUV9ETAc6VRRi8XZOMFhYG63whlIC9Q==", + "version": "5.28.0", + "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.28.0.tgz", + "integrity": "sha512-KYDjhGodswVj29v0TRciKTqRPgumIFvFDndbCD227pitQ+0Cei196rxk+OXb/blu6V8zdTRK5RjCJn+WmHLvBA==", "requires": { "@babel/runtime": "^7.18.3", - "react-is": "^16.12.0", - "shallowequal": "^1.1.0" + "react-is": "^16.12.0" } } } @@ -10769,34 +10848,21 @@ "rc-util": "^5.7.0" }, "dependencies": { - "rc-tree": { - "version": "5.3.8", - "resolved": "https://registry.npmmirror.com/rc-tree/-/rc-tree-5.3.8.tgz", - "integrity": "sha512-YuobEryPymqPmHFUOvsoOrYdm24psaj0CrGEUuDUQUeG/nNcTGw6FA2YmF4NsEaNBvNSJUSzwfZnFHrKa/xv0A==", - "requires": { - "@babel/runtime": "^7.10.1", - "classnames": "2.x", - "rc-motion": "^2.0.1", - "rc-util": "^5.16.1", - "rc-virtual-list": "^3.4.1" - } - }, "rc-util": { - "version": "5.24.2", - "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.24.2.tgz", - "integrity": "sha512-MWd0ZEV7xSwN4HM9jz9BwpnMzwCPjYJ7K90lePsrdgAkrmm8U7b4BOTIsv/84BQsaF7N3ejNkcrZ3AfEwc9HXA==", + "version": "5.28.0", + "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.28.0.tgz", + "integrity": "sha512-KYDjhGodswVj29v0TRciKTqRPgumIFvFDndbCD227pitQ+0Cei196rxk+OXb/blu6V8zdTRK5RjCJn+WmHLvBA==", "requires": { "@babel/runtime": "^7.18.3", - "react-is": "^16.12.0", - "shallowequal": "^1.1.0" + "react-is": "^16.12.0" } } } }, "rc-trigger": { - "version": "5.3.1", - "resolved": "https://registry.npmmirror.com/rc-trigger/-/rc-trigger-5.3.1.tgz", - "integrity": "sha512-5gaFbDkYSefZ14j2AdzucXzlWgU2ri5uEjkHvsf1ynRhdJbKxNOnw4PBZ9+FVULNGFiDzzlVF8RJnR9P/xrnKQ==", + "version": "5.3.4", + "resolved": "https://registry.npmmirror.com/rc-trigger/-/rc-trigger-5.3.4.tgz", + "integrity": "sha512-mQv+vas0TwKcjAO2izNPkqR4j86OemLRmvL2nOzdP9OWNWA1ivoTt5hzFqYNW9zACwmTezRiN8bttrC7cZzYSw==", "requires": { "@babel/runtime": "^7.18.3", "classnames": "^2.2.6", @@ -10806,13 +10872,12 @@ }, "dependencies": { "rc-util": { - "version": "5.24.2", - "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.24.2.tgz", - "integrity": "sha512-MWd0ZEV7xSwN4HM9jz9BwpnMzwCPjYJ7K90lePsrdgAkrmm8U7b4BOTIsv/84BQsaF7N3ejNkcrZ3AfEwc9HXA==", + "version": "5.28.0", + "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.28.0.tgz", + "integrity": "sha512-KYDjhGodswVj29v0TRciKTqRPgumIFvFDndbCD227pitQ+0Cei196rxk+OXb/blu6V8zdTRK5RjCJn+WmHLvBA==", "requires": { "@babel/runtime": "^7.18.3", - "react-is": "^16.12.0", - "shallowequal": "^1.1.0" + "react-is": "^16.12.0" } } } @@ -10828,13 +10893,12 @@ }, "dependencies": { "rc-util": { - "version": "5.24.2", - "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.24.2.tgz", - "integrity": "sha512-MWd0ZEV7xSwN4HM9jz9BwpnMzwCPjYJ7K90lePsrdgAkrmm8U7b4BOTIsv/84BQsaF7N3ejNkcrZ3AfEwc9HXA==", + "version": "5.28.0", + "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.28.0.tgz", + "integrity": "sha512-KYDjhGodswVj29v0TRciKTqRPgumIFvFDndbCD227pitQ+0Cei196rxk+OXb/blu6V8zdTRK5RjCJn+WmHLvBA==", "requires": { "@babel/runtime": "^7.18.3", - "react-is": "^16.12.0", - "shallowequal": "^1.1.0" + "react-is": "^16.12.0" } } } @@ -10852,23 +10916,23 @@ } }, "rc-virtual-list": { - "version": "3.4.8", - "resolved": "https://registry.npmmirror.com/rc-virtual-list/-/rc-virtual-list-3.4.8.tgz", - "integrity": "sha512-qSN+Rv4i/E7RCTvTMr1uZo7f3crJJg/5DekoCagydo9zsXrxj07zsFSxqizqW+ldGA16lwa8So/bIbV9Ofjddg==", + "version": "3.4.13", + "resolved": "https://registry.npmmirror.com/rc-virtual-list/-/rc-virtual-list-3.4.13.tgz", + "integrity": "sha512-cPOVDmcNM7rH6ANotanMDilW/55XnFPw0Jh/GQYtrzZSy3AmWvCnqVNyNC/pgg3lfVmX2994dlzAhuUrd4jG7w==", "requires": { + "@babel/runtime": "^7.20.0", "classnames": "^2.2.6", "rc-resize-observer": "^1.0.0", "rc-util": "^5.15.0" }, "dependencies": { "rc-util": { - "version": "5.24.2", - "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.24.2.tgz", - "integrity": "sha512-MWd0ZEV7xSwN4HM9jz9BwpnMzwCPjYJ7K90lePsrdgAkrmm8U7b4BOTIsv/84BQsaF7N3ejNkcrZ3AfEwc9HXA==", + "version": "5.28.0", + "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.28.0.tgz", + "integrity": "sha512-KYDjhGodswVj29v0TRciKTqRPgumIFvFDndbCD227pitQ+0Cei196rxk+OXb/blu6V8zdTRK5RjCJn+WmHLvBA==", "requires": { "@babel/runtime": "^7.18.3", - "react-is": "^16.12.0", - "shallowequal": "^1.1.0" + "react-is": "^16.12.0" } } } @@ -11130,30 +11194,6 @@ "intl-messageformat": "^7.8.4", "intl-messageformat-parser": "^3.6.4", "shallow-equal": "^1.2.1" - }, - "dependencies": { - "intl-format-cache": { - "version": "4.3.1", - "resolved": "https://registry.npmmirror.com/intl-format-cache/-/intl-format-cache-4.3.1.tgz", - "integrity": "sha512-OEUYNA7D06agqPOYhbTkl0T8HA3QKSuwWh1HiClEnpd9vw7N+3XsQt5iZ0GUEchp5CW1fQk/tary+NsbF3yQ1Q==" - }, - "intl-messageformat": { - "version": "7.8.4", - "resolved": "https://registry.npmmirror.com/intl-messageformat/-/intl-messageformat-7.8.4.tgz", - "integrity": "sha512-yS0cLESCKCYjseCOGXuV4pxJm/buTfyCJ1nzQjryHmSehlptbZbn9fnlk1I9peLopZGGbjj46yHHiTAEZ1qOTA==", - "requires": { - "intl-format-cache": "^4.2.21", - "intl-messageformat-parser": "^3.6.4" - } - }, - "intl-messageformat-parser": { - "version": "3.6.4", - "resolved": "https://registry.npmmirror.com/intl-messageformat-parser/-/intl-messageformat-parser-3.6.4.tgz", - "integrity": "sha512-RgPGwue0mJtoX2Ax8EmMzJzttxjnva7gx0Q7mKJ4oALrTZvtmCeAw5Msz2PcjW4dtCh/h7vN/8GJCxZO1uv+OA==", - "requires": { - "@formatjs/intl-unified-numberformat": "^3.2.0" - } - } } }, "react-is": { @@ -11314,13 +11354,6 @@ "lowlight": "^1.14.0", "prismjs": "^1.21.0", "refractor": "^3.0.0" - }, - "dependencies": { - "highlight.js": { - "version": "10.7.3", - "resolved": "https://registry.npmmirror.com/highlight.js/-/highlight.js-10.7.3.tgz", - "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==" - } } }, "react-test-renderer": { @@ -11401,9 +11434,9 @@ } }, "react-window": { - "version": "1.8.7", - "resolved": "https://registry.npmmirror.com/react-window/-/react-window-1.8.7.tgz", - "integrity": "sha512-JHEZbPXBpKMmoNO1bNhoXOOLg/ujhL/BU4IqVU9r8eQPcy5KQnGHIHDRkJ0ns9IM5+Aq5LNwt3j8t3tIrePQzA==", + "version": "1.8.8", + "resolved": "https://registry.npmmirror.com/react-window/-/react-window-1.8.8.tgz", + "integrity": "sha512-D4IiBeRtGXziZ1n0XklnFGu7h9gU684zepqyKzgPNzrsrk7xOCxni+TCckjg2Nr/DiaEEGVVmnhYSlT2rB47dQ==", "requires": { "@babel/runtime": "^7.0.0", "memoize-one": ">=3.1.1 <6" @@ -11425,9 +11458,9 @@ } }, "reactstrap": { - "version": "9.1.4", - "resolved": "https://registry.npmmirror.com/reactstrap/-/reactstrap-9.1.4.tgz", - "integrity": "sha512-kn+Ex58V4tZatogn472n5fkgvCkXwhQvlqCRGTjpM1MzkD9wv0rp5W0VcM60purpdtzkud2ku6KHvJrqYqnv0w==", + "version": "9.1.6", + "resolved": "https://registry.npmmirror.com/reactstrap/-/reactstrap-9.1.6.tgz", + "integrity": "sha512-79h/L/pvMJIz198VULMpLbEyXFeArFTLAnEtk5anppJhAnZnfyM1pNuQWZNGXy6cUlgsaEy2gBziAw4tockOnw==", "requires": { "@babel/runtime": "^7.12.5", "@popperjs/core": "^2.6.0", @@ -11471,9 +11504,9 @@ } }, "redux": { - "version": "4.2.0", - "resolved": "https://registry.npmmirror.com/redux/-/redux-4.2.0.tgz", - "integrity": "sha512-oSBmcKKIuIR4ME29/AeNUnl5L+hvBq7OaJWzaptTQJAntaPvxIJqfnjbaEiCzzaIz+XmVILfqAM3Ob0aXLPfjA==", + "version": "4.2.1", + "resolved": "https://registry.npmmirror.com/redux/-/redux-4.2.1.tgz", + "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", "requires": { "@babel/runtime": "^7.9.2" } @@ -11488,31 +11521,6 @@ "prismjs": "~1.27.0" }, "dependencies": { - "hastscript": { - "version": "6.0.0", - "resolved": "https://registry.npmmirror.com/hastscript/-/hastscript-6.0.0.tgz", - "integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==", - "requires": { - "@types/hast": "^2.0.0", - "comma-separated-tokens": "^1.0.0", - "hast-util-parse-selector": "^2.0.0", - "property-information": "^5.0.0", - "space-separated-tokens": "^1.0.0" - } - }, - "parse-entities": { - "version": "2.0.0", - "resolved": "https://registry.npmmirror.com/parse-entities/-/parse-entities-2.0.0.tgz", - "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", - "requires": { - "character-entities": "^1.0.0", - "character-entities-legacy": "^1.0.0", - "character-reference-invalid": "^1.0.0", - "is-alphanumerical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-hexadecimal": "^1.0.0" - } - }, "prismjs": { "version": "1.27.0", "resolved": "https://registry.npmmirror.com/prismjs/-/prismjs-1.27.0.tgz", @@ -11534,14 +11542,14 @@ } }, "regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" + "version": "0.13.11", + "resolved": "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" }, "regenerator-transform": { - "version": "0.15.0", - "resolved": "https://registry.npmmirror.com/regenerator-transform/-/regenerator-transform-0.15.0.tgz", - "integrity": "sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg==", + "version": "0.15.1", + "resolved": "https://registry.npmmirror.com/regenerator-transform/-/regenerator-transform-0.15.1.tgz", + "integrity": "sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==", "requires": { "@babel/runtime": "^7.8.4" } @@ -11573,23 +11581,18 @@ "dev": true }, "regexpu-core": { - "version": "5.2.1", - "resolved": "https://registry.npmmirror.com/regexpu-core/-/regexpu-core-5.2.1.tgz", - "integrity": "sha512-HrnlNtpvqP1Xkb28tMhBUO2EbyUHdQlsnlAhzWcwHy8WJR53UWr7/MAvqrsQKMbV4qdpv03oTMG8iIhfsPFktQ==", + "version": "5.3.1", + "resolved": "https://registry.npmmirror.com/regexpu-core/-/regexpu-core-5.3.1.tgz", + "integrity": "sha512-nCOzW2V/X15XpLsK2rlgdwrysrBq+AauCn+omItIz4R1pIcmeot5zvjdmOBRLzEH/CkC6IxMJVmxDe3QcMuNVQ==", "requires": { + "@babel/regjsgen": "^0.8.0", "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.1.0", - "regjsgen": "^0.7.1", "regjsparser": "^0.9.1", "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.0.0" + "unicode-match-property-value-ecmascript": "^2.1.0" } }, - "regjsgen": { - "version": "0.7.1", - "resolved": "https://registry.npmmirror.com/regjsgen/-/regjsgen-0.7.1.tgz", - "integrity": "sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA==" - }, "regjsparser": { "version": "0.9.1", "resolved": "https://registry.npmmirror.com/regjsparser/-/regjsparser-0.9.1.tgz", @@ -11819,9 +11822,9 @@ } }, "rxjs": { - "version": "7.5.6", - "resolved": "https://registry.npmmirror.com/rxjs/-/rxjs-7.5.6.tgz", - "integrity": "sha512-dnyv2/YsXhnm461G+R/Pe5bWP41Nm6LBXEYWI6eiFP4fiwx6WRI/CD0zbdVAudd9xwLEF2IDcKXLHit0FYjUzw==", + "version": "7.8.0", + "resolved": "https://registry.npmmirror.com/rxjs/-/rxjs-7.8.0.tgz", + "integrity": "sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==", "dev": true, "requires": { "tslib": "^2.1.0" @@ -11830,7 +11833,8 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true }, "safe-regex": { "version": "1.1.0", @@ -11841,6 +11845,16 @@ "ret": "~0.1.10" } }, + "safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + } + }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -11878,11 +11892,11 @@ "integrity": "sha512-pz7y517OVls1maEzlirKO5nPYle9AXsFzTMNJrRGmT951mzpIBy7sNHOg5o/0MQd/NqliCiWnAi0kZneMPFLcg==" }, "scroll-into-view-if-needed": { - "version": "2.2.29", - "resolved": "https://registry.npmmirror.com/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.29.tgz", - "integrity": "sha512-hxpAR6AN+Gh53AdAimHM6C8oTN1ppwVZITihix+WqalywBeFcQ6LdQP5ABNl26nX8GTEL7VT+b8lKpdqq65wXg==", + "version": "2.2.31", + "resolved": "https://registry.npmmirror.com/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.31.tgz", + "integrity": "sha512-dGCXy99wZQivjmjIqihaBQNjryrz5rueJY7eHfTdyWEiR4ttYpsajb14rn9s5d4DY4EcY6+4+U/maARBXJedkA==", "requires": { - "compute-scroll-into-view": "^1.0.17" + "compute-scroll-into-view": "^1.0.20" } }, "scrollparent": { @@ -12350,12 +12364,6 @@ "kind-of": "^3.2.0" }, "dependencies": { - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmmirror.com/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmmirror.com/kind-of/-/kind-of-3.2.2.tgz", @@ -12417,14 +12425,6 @@ "dev": true, "requires": { "is-plain-obj": "^1.0.0" - }, - "dependencies": { - "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmmirror.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", - "dev": true - } } }, "source-list-map": { @@ -12663,39 +12663,39 @@ } }, "string.prototype.matchall": { - "version": "4.0.7", - "resolved": "https://registry.npmmirror.com/string.prototype.matchall/-/string.prototype.matchall-4.0.7.tgz", - "integrity": "sha512-f48okCX7JiwVi1NXCVWcFnZgADDC/n2vePlQ/KUCNqCikLLilQvwjMO8+BHVKvgzH0JB0J9LEPgxOGT02RoETg==", + "version": "4.0.8", + "resolved": "https://registry.npmmirror.com/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz", + "integrity": "sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1", - "get-intrinsic": "^1.1.1", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "get-intrinsic": "^1.1.3", "has-symbols": "^1.0.3", "internal-slot": "^1.0.3", - "regexp.prototype.flags": "^1.4.1", + "regexp.prototype.flags": "^1.4.3", "side-channel": "^1.0.4" } }, "string.prototype.trimend": { - "version": "1.0.5", - "resolved": "https://registry.npmmirror.com/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", - "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", + "version": "1.0.6", + "resolved": "https://registry.npmmirror.com/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", + "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" + "es-abstract": "^1.20.4" } }, "string.prototype.trimstart": { - "version": "1.0.5", - "resolved": "https://registry.npmmirror.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", - "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", + "version": "1.0.6", + "resolved": "https://registry.npmmirror.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", + "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" + "es-abstract": "^1.20.4" } }, "string_decoder": { @@ -12866,9 +12866,9 @@ } }, "table": { - "version": "6.8.0", - "resolved": "https://registry.npmmirror.com/table/-/table-6.8.0.tgz", - "integrity": "sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==", + "version": "6.8.1", + "resolved": "https://registry.npmmirror.com/table/-/table-6.8.1.tgz", + "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", "dev": true, "requires": { "ajv": "^8.0.1", @@ -12879,9 +12879,9 @@ }, "dependencies": { "ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmmirror.com/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "version": "8.12.0", + "resolved": "https://registry.npmmirror.com/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -13093,9 +13093,9 @@ "dev": true }, "tiny-invariant": { - "version": "1.2.0", - "resolved": "https://registry.npmmirror.com/tiny-invariant/-/tiny-invariant-1.2.0.tgz", - "integrity": "sha512-1Uhn/aqw5C6RI4KejVeTg6mIS7IqxnLJ8Mv2tV5rTc0qWobay7pDUz6Wi392Cnc8ak1H0F2cjoRzb2/AW4+Fvg==" + "version": "1.3.1", + "resolved": "https://registry.npmmirror.com/tiny-invariant/-/tiny-invariant-1.3.1.tgz", + "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==" }, "tiny-warning": { "version": "1.0.3", @@ -13103,9 +13103,9 @@ "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" }, "tinycolor2": { - "version": "1.4.2", - "resolved": "https://registry.npmmirror.com/tinycolor2/-/tinycolor2-1.4.2.tgz", - "integrity": "sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA==" + "version": "1.6.0", + "resolved": "https://registry.npmmirror.com/tinycolor2/-/tinycolor2-1.6.0.tgz", + "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==" }, "to-arraybuffer": { "version": "1.0.1", @@ -13127,12 +13127,6 @@ "kind-of": "^3.0.2" }, "dependencies": { - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmmirror.com/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmmirror.com/kind-of/-/kind-of-3.2.2.tgz", @@ -13251,9 +13245,9 @@ "dev": true }, "loader-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-2.0.2.tgz", - "integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==", + "version": "2.0.4", + "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", "dev": true, "requires": { "big.js": "^5.2.2", @@ -13261,10 +13255,19 @@ "json5": "^2.1.2" } }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmmirror.com/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmmirror.com/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -13278,13 +13281,19 @@ "requires": { "has-flag": "^4.0.0" } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true } } }, "tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + "version": "2.5.0", + "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.5.0.tgz", + "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==" }, "tsutils": { "version": "3.21.0", @@ -13334,6 +13343,16 @@ "mime-types": "~2.1.24" } }, + "typed-array-length": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/typed-array-length/-/typed-array-length-1.0.4.tgz", + "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "requires": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "is-typed-array": "^1.1.9" + } + }, "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmmirror.com/typedarray/-/typedarray-0.0.6.tgz", @@ -13347,9 +13366,9 @@ "dev": true }, "ua-parser-js": { - "version": "0.7.31", - "resolved": "https://registry.npmmirror.com/ua-parser-js/-/ua-parser-js-0.7.31.tgz", - "integrity": "sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ==" + "version": "0.7.33", + "resolved": "https://registry.npmmirror.com/ua-parser-js/-/ua-parser-js-0.7.33.tgz", + "integrity": "sha512-s8ax/CeZdK9R/56Sui0WM6y9OFREJarMRHqLB2EwkovemBxNQ+Bqu8GAsUnVcXKgphb++ghr/B2BZx4mahujPw==" }, "unbox-primitive": { "version": "1.0.2", @@ -13377,9 +13396,9 @@ } }, "unicode-match-property-value-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmmirror.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz", - "integrity": "sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==" + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", + "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==" }, "unicode-property-aliases-ecmascript": { "version": "2.1.0", @@ -13493,9 +13512,9 @@ "dev": true }, "update-browserslist-db": { - "version": "1.0.9", - "resolved": "https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.0.9.tgz", - "integrity": "sha512-/xsqn21EGVdXI3EXSum1Yckj3ZVZugqyOZQ/CxYPBD/R+ko9NSUScf8tFF4dOKY+2pvSSJA/S+5B8s4Zr4kyvg==", + "version": "1.0.10", + "resolved": "https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", "requires": { "escalade": "^3.1.1", "picocolors": "^1.0.0" @@ -13593,6 +13612,12 @@ "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", "dev": true }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmmirror.com/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + }, "v8-compile-cache": { "version": "2.3.0", "resolved": "https://registry.npmmirror.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", @@ -13803,13 +13828,6 @@ "binary-extensions": "^1.0.0" } }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmmirror.com/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true, - "optional": true - }, "is-number": { "version": "3.0.0", "resolved": "https://registry.npmmirror.com/is-number/-/is-number-3.0.0.tgz", @@ -13987,12 +14005,6 @@ } } }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmmirror.com/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, "is-number": { "version": "3.0.0", "resolved": "https://registry.npmmirror.com/is-number/-/is-number-3.0.0.tgz", @@ -14068,10 +14080,11 @@ } }, "webpack-bundle-analyzer": { - "version": "4.6.1", - "resolved": "https://registry.npmmirror.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.6.1.tgz", - "integrity": "sha512-oKz9Oz9j3rUciLNfpGFjOb49/jEpXNmWdVH8Ls//zNcnLlQdTGXQQMsBbb/gR7Zl8WNLxVCq+0Hqbx3zv6twBw==", + "version": "4.8.0", + "resolved": "https://registry.npmmirror.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.8.0.tgz", + "integrity": "sha512-ZzoSBePshOKhr+hd8u6oCkZVwpVaXgpw23ScGLFpR6SjYI7+7iIWYarjN6OEYOfRt8o7ZyZZQk0DuMizJ+LEIg==", "requires": { + "@discoveryjs/json-ext": "0.5.7", "acorn": "^8.0.4", "acorn-walk": "^8.0.0", "chalk": "^4.1.0", @@ -14436,12 +14449,6 @@ "binary-extensions": "^1.0.0" } }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmmirror.com/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, "is-number": { "version": "3.0.0", "resolved": "https://registry.npmmirror.com/is-number/-/is-number-3.0.0.tgz", @@ -14543,14 +14550,6 @@ "requires": { "ansi-colors": "^3.0.0", "uuid": "^3.3.2" - }, - "dependencies": { - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmmirror.com/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true - } } }, "webpack-merge": { @@ -14627,6 +14626,19 @@ "integrity": "sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==", "dev": true }, + "which-typed-array": { + "version": "1.1.9", + "resolved": "https://registry.npmmirror.com/which-typed-array/-/which-typed-array-1.1.9.tgz", + "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0", + "is-typed-array": "^1.1.10" + } + }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmmirror.com/word-wrap/-/word-wrap-1.2.3.tgz", @@ -14759,10 +14771,9 @@ "dev": true }, "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" }, "yaml": { "version": "1.10.2", @@ -14887,9 +14898,9 @@ "dev": true }, "zrender": { - "version": "5.3.2", - "resolved": "https://registry.npmmirror.com/zrender/-/zrender-5.3.2.tgz", - "integrity": "sha512-8IiYdfwHj2rx0UeIGZGGU4WEVSDEdeVCaIg/fomejg1Xu6OifAL1GVzIPHg2D+MyUkbNgPWji90t0a8IDk+39w==", + "version": "5.4.1", + "resolved": "https://registry.npmmirror.com/zrender/-/zrender-5.4.1.tgz", + "integrity": "sha512-M4Z05BHWtajY2241EmMPHglDQAJ1UyHQcYsxDNzD9XLSkPDqMq4bB28v9Pb4mvHnVQ0GxyTklZ/69xCFP6RXBA==", "requires": { "tslib": "2.3.0" }, diff --git a/km-console/packages/layout-clusters-fe/package.json b/km-console/packages/layout-clusters-fe/package.json index af1faf35..62fe6f9c 100644 --- a/km-console/packages/layout-clusters-fe/package.json +++ b/km-console/packages/layout-clusters-fe/package.json @@ -50,7 +50,7 @@ "crypto-js": "^4.1.1", "dotenv": "^16.0.1", "html-webpack-plugin": "^4.0.0", - "knowdesign": "^1.3.7", + "knowdesign": "1.3.7", "lodash": "^4.17.21", "moment": "^2.24.0", "react": "16.12.0", diff --git a/km-console/packages/layout-clusters-fe/src/api/index.ts b/km-console/packages/layout-clusters-fe/src/api/index.ts index 0dcc912a..1c6bc77e 100755 --- a/km-console/packages/layout-clusters-fe/src/api/index.ts +++ b/km-console/packages/layout-clusters-fe/src/api/index.ts @@ -15,7 +15,10 @@ export enum MetricType { Partition = 104, Replication = 105, Zookeeper = 110, + Connect = 120, + Connectors = 121, Controls = 901, + MM2 = 122, } const api = { @@ -163,7 +166,7 @@ const api = { getApi(`/clusters/${clusterPhyId}/${MetricType[type].toLowerCase()}s-metadata`), // 集群节点信息 getDashboardMetricList: (clusterPhyId: string, type: MetricType) => getApi(`/clusters/${clusterPhyId}/types/${type}/user-metric-config`), // 默认选中的指标项 getDashboardMetricChartData: (clusterPhyId: string, type: MetricType) => - getApi(`/clusters/${clusterPhyId}/${MetricType[type].toLowerCase()}-metrics`), // 图表数据Z + getApi(`/clusters/${clusterPhyId}/${MetricType[type].toLowerCase()}-metrics`), // 图表数据 // ! Jobs 集群任务相关接口 getJobsList: (clusterPhyId: string) => getApi(`/clusters/${clusterPhyId}/jobs-overview`), @@ -211,6 +214,77 @@ const api = { getZookeeperNodeData: (clusterPhyId: number) => getApi(`/clusters/${clusterPhyId}/znode-data`), getZookeeperMetricsInfo: (clusterPhyId: number) => getApi(`/clusters/${clusterPhyId}/zookeeper-latest-metrics`), getZookeeperMetrics: (clusterPhyId: string) => getApi(`/clusters/${clusterPhyId}/zookeeper-metrics`), + + // Connector 接口 + getConnectState: (clusterPhyId: string) => getApi(`/kafka-clusters/${clusterPhyId}/connect-state`), + getConnectorsList: (clusterPhyId: number) => getApi(`/clusters/${clusterPhyId}/connectors-overview`), + // Connector 详情 + getConnectDetailMetricPoints: (connectorName: number | string, connectClusterId: number | string) => + getApi(`/kafka-connect/clusters/${connectClusterId}/connectors/${connectorName}/latest-metrics`), + getConnectDetailTasks: (connectorName: number | string, connectClusterId: number | string) => + getApi(`/kafka-connect/clusters/${connectClusterId}/connectors/${connectorName}/tasks`), + getConnectDetailState: (connectorName: number | string, connectClusterId: number | string) => + getApi(`/kafka-connect/clusters/${connectClusterId}/connectors/${connectorName}/state`), + optionTasks: () => getApi(`/kafka-connect/tasks`), + // Workers 接口 + getWorkersList: (clusterPhyId: number) => getApi(`/clusters/${clusterPhyId}/workers-overview`), + // Connector + getConnectClusters: (clusterPhyId: string) => getApi(`/kafka-clusters/${clusterPhyId}/connect-clusters-basic`), + getConnectClusterMetrics: (clusterPhyId: string) => getApi(`/kafka-clusters/${clusterPhyId}/connect-cluster-metrics`), + getConnectors: (clusterPhyId: string) => getApi(`/clusters/${clusterPhyId}/connectors-basic`), + getConnectorMetrics: (clusterPhyId: string) => getApi(`/clusters/${clusterPhyId}/connectors-metrics`), + getConnectorPlugins: (connectClusterId: number) => getApi(`/kafka-connect/clusters/${connectClusterId}/connector-plugins`), + getConnectorPluginConfig: (connectClusterId: number | string, pluginName: string) => + getApi(`/kafka-connect/clusters/${connectClusterId}/connector-plugins/${pluginName}/config`), + getCurPluginConfig: (connectClusterId: number | string, connectorName: string) => + getApi(`/kafka-connect/clusters/${connectClusterId}/connectors/${connectorName}/config`), + isConnectorExist: (connectClusterId: number, connectorName: string) => + getApi(`/kafka-connect/clusters/${connectClusterId}/connectors/${connectorName}/basic-combine-exist`), + validateConnectorConfig: getApi('/kafka-connect/connectors-config/validate'), + // Connector 操作接口 新增、暂停、重启、删除 + connectorsOperates: getApi('/kafka-connect/connectors'), + // 修改 Connector 配置 + updateConnectorConfig: getApi('/kafka-connect/connectors-config'), + // Cluster首页修改Connect集群 + batchConnectClusters: getApi(`/kafka-connect/batch-connect-clusters`), + // Cluster首页删除Connect集群 + deleteConnectClusters: getApi(`/kafka-connect/connect-clusters`), + + getConnectClusterBasicExit: (clusterPhyId: string, clusterPhyName: string) => + getApi(`/kafka-clusters/${clusterPhyId}/connect-clusters/${clusterPhyName}/basic-combine-exist`), + + // MM2 列表 + getMirrorMakerList: (clusterPhyId: number) => getApi(`/clusters/${clusterPhyId}/mirror-makers-overview`), + // MM2 状态卡片 + getMirrorMakerState: (clusterPhyId: string) => getApi(`/kafka-clusters/${clusterPhyId}/mirror-makers-state`), + // MM2 指标卡片 + getMirrorMakerMetrics: (clusterPhyId: string) => getApi(`/clusters/${clusterPhyId}/mirror-makers-metrics`), + // MM2 筛选 + getMirrorMakerMetadata: (clusterPhyId: string) => getApi(`/clusters/${clusterPhyId}/mirror-makers-basic`), + // MM2 详情列表 + getMM2DetailTasks: (connectorName: number | string, connectClusterId: number | string) => + getApi(`/kafka-mm2/clusters/${connectClusterId}/connectors/${connectorName}/tasks`), + // MM2 详情状态卡片 + getMM2DetailState: (connectorName: number | string, connectClusterId: number | string) => + getApi(`/kafka-mm2/clusters/${connectClusterId}/connectors/${connectorName}/state`), + // MM2 操作接口 新增、暂停、重启、删除 + mirrorMakerOperates: getApi('/kafka-mm2/mirror-makers'), + // MM2 操作接口 新增、编辑校验 + validateMM2Config: getApi('/kafka-mm2/mirror-makers-config/validate'), + // 修改 Connector 配置 + updateMM2Config: getApi('/kafka-mm2/mirror-makers-config'), + // MM2 详情 + getMirrorMakerMetricPoints: (mirrorMakerName: number | string, connectClusterId: number | string) => + getApi(`/kafka-mm2/clusters/${connectClusterId}/connectors/${mirrorMakerName}/latest-metrics`), + getSourceKafkaClusterBasic: getApi(`/physical-clusters/basic`), + getGroupBasic: (clusterPhyId: string) => getApi(`/clusters/${clusterPhyId}/groups-basic`), + // Topic复制 + getMirrorClusterList: () => getApi(`/ha-mirror/physical-clusters/basic`), + handleTopicMirror: () => getApi(`/ha-mirror/topics`), + getTopicMirrorList: (clusterPhyId: number, topicName: string) => + getApi(`/ha-mirror/clusters/${clusterPhyId}/topics/${topicName}/mirror-info`), + getMirrorMakerConfig: (connectClusterId: number | string, connectorName: string) => + getApi(`/kafka-mm2/clusters/${connectClusterId}/connectors/${connectorName}/config`), }; export default api; diff --git a/km-console/packages/layout-clusters-fe/src/assets/no-data.png b/km-console/packages/layout-clusters-fe/src/assets/no-data.png new file mode 100644 index 00000000..2dac47ab Binary files /dev/null and b/km-console/packages/layout-clusters-fe/src/assets/no-data.png differ diff --git a/km-console/packages/layout-clusters-fe/src/components/CardBar/BrokerHealthCheck.tsx b/km-console/packages/layout-clusters-fe/src/components/CardBar/BrokerHealthCheck.tsx index 31531c15..eda43287 100644 --- a/km-console/packages/layout-clusters-fe/src/components/CardBar/BrokerHealthCheck.tsx +++ b/km-console/packages/layout-clusters-fe/src/components/CardBar/BrokerHealthCheck.tsx @@ -7,7 +7,6 @@ import { Tag, Tooltip, Utils } from 'knowdesign'; import api from '@src/api'; import { QuestionCircleOutlined } from '@ant-design/icons'; import { HealthStateEnum } from '../HealthState'; - export default () => { const routeParams = useParams<{ clusterId: string; @@ -112,5 +111,5 @@ export default () => { }); }, [routeParams.clusterId]); - return ; + return ; }; diff --git a/km-console/packages/layout-clusters-fe/src/components/CardBar/ConnectCard.tsx b/km-console/packages/layout-clusters-fe/src/components/CardBar/ConnectCard.tsx new file mode 100644 index 00000000..9992ccbf --- /dev/null +++ b/km-console/packages/layout-clusters-fe/src/components/CardBar/ConnectCard.tsx @@ -0,0 +1,119 @@ +import React, { useState, useEffect } from 'react'; +import { useParams } from 'react-router-dom'; +import CardBar, { healthDataProps } from './index'; +import { Tooltip, Utils } from 'knowdesign'; +import api from '@src/api'; +import { HealthStateEnum } from '../HealthState'; +import { InfoCircleOutlined } from '@ant-design/icons'; + +interface ConnectState { + connectClusterCount: number; + workerCount: number; + aliveConnectorCount: number; + aliveTaskCount: number; + healthCheckPassed: number; + healthCheckTotal: number; + healthState: number; + totalConnectorCount: string; + totalTaskCount: number; + totalServerCount: number; +} + +const getVal = (val: string | number | undefined | null) => { + return val === undefined || val === null || val === '' ? '0' : val; +}; + +const ConnectCard = ({ state }: { state?: boolean }) => { + const { clusterId } = useParams<{ + clusterId: string; + }>(); + const [loading, setLoading] = useState(false); + const [cardData, setCardData] = useState([]); + const [healthData, setHealthData] = useState({ + state: HealthStateEnum.UNKNOWN, + passed: 0, + total: 0, + }); + + const getHealthData = () => { + return Utils.post(api.getMetricPointsLatest(Number(clusterId)), [ + 'HealthCheckPassed_Connector', + 'HealthCheckTotal_Connector', + 'HealthState_Connector', + ]).then((data: any) => { + setHealthData({ + state: data?.metrics?.['HealthState_Connector'], + passed: data?.metrics?.['HealthCheckPassed_Connector'] || 0, + total: data?.metrics?.['HealthCheckTotal_Connector'] || 0, + }); + }); + }; + + const getCardInfo = () => { + return Utils.request(api.getConnectState(clusterId)).then((res: ConnectState) => { + const { connectClusterCount, aliveConnectorCount, aliveTaskCount, totalConnectorCount, totalTaskCount, workerCount } = res || {}; + const cardMap = [ + { + title: 'Connect集群数', + value: getVal(connectClusterCount), + customStyle: { + // 自定义cardbar样式 + marginLeft: 0, + }, + }, + { + title: 'Workers', + value: getVal(workerCount), + }, + { + title() { + return ( +
+ Connectors + + + +
+ ); + }, + value() { + return ( + + {getVal(aliveConnectorCount)}/{getVal(totalConnectorCount)} + + ); + }, + }, + { + title() { + return ( +
+ Tasks + + + +
+ ); + }, + value() { + return ( + + {getVal(aliveTaskCount)}/{getVal(totalTaskCount)} + + ); + }, + }, + ]; + setCardData(cardMap); + }); + }; + useEffect(() => { + setLoading(true); + Promise.all([getHealthData(), getCardInfo()]).finally(() => { + setLoading(false); + }); + }, [clusterId, state]); + return ; +}; + +export default ConnectCard; diff --git a/km-console/packages/layout-clusters-fe/src/components/CardBar/ConnectDetailCard.tsx b/km-console/packages/layout-clusters-fe/src/components/CardBar/ConnectDetailCard.tsx new file mode 100644 index 00000000..f3f9f545 --- /dev/null +++ b/km-console/packages/layout-clusters-fe/src/components/CardBar/ConnectDetailCard.tsx @@ -0,0 +1,122 @@ +/* eslint-disable react/display-name */ +import React, { useState, useEffect } from 'react'; +import { useLocation, useParams } from 'react-router-dom'; +import CardBar from '@src/components/CardBar'; +import { healthDataProps } from '.'; +import { Tooltip, Utils } from 'knowdesign'; +import Api from '@src/api'; +import { hashDataParse } from '@src/constants/common'; +import { HealthStateEnum } from '../HealthState'; +import { InfoCircleOutlined } from '@ant-design/icons'; +import { stateEnum } from '@src/pages/Connect/config'; +const getVal = (val: string | number | undefined | null) => { + return val === undefined || val === null || val === '' ? '0' : val; +}; + +const ConnectDetailCard = (props: { record: any }) => { + const { record } = props; + const urlParams = useParams<{ clusterId: string; brokerId: string }>(); + const urlLocation = useLocation(); + const [loading, setLoading] = useState(false); + const [cardData, setCardData] = useState([]); + const [healthData, setHealthData] = useState({ + state: HealthStateEnum.UNKNOWN, + passed: 0, + total: 0, + }); + + const getHealthData = () => { + return Utils.post(Api.getConnectDetailMetricPoints(record.connectorName, record?.connectClusterId), [ + 'HealthCheckPassed', + 'HealthCheckTotal', + 'HealthState', + ]).then((data: any) => { + setHealthData({ + state: data?.metrics?.['HealthState'], + passed: data?.metrics?.['HealthCheckPassed'] || 0, + total: data?.metrics?.['HealthCheckTotal'] || 0, + }); + }); + }; + + const getCardInfo = () => { + return Utils.request(Api.getConnectDetailState(record.connectorName, record?.connectClusterId)).then((res: any) => { + const { type, aliveTaskCount, state, totalTaskCount, totalWorkerCount } = res || {}; + const cordRightMap = [ + { + title: 'Type', + value: () => { + return ( + <> + { + + {Utils.firstCharUppercase(type) || '-'} + + } + + ); + }, + }, + { + title: 'Status', + // value: Utils.firstCharUppercase(state) || '-', + value: () => { + return ( + <> + { + + {Utils.firstCharUppercase(state) || '-'} + + } + + ); + }, + }, + + { + title() { + return ( +
+ Tasks + + + +
+ ); + }, + value() { + return ( + + {getVal(aliveTaskCount)}/{getVal(totalTaskCount)} + + ); + }, + }, + { + title: 'Workers', + value: getVal(totalWorkerCount), + }, + ]; + setCardData(cordRightMap); + }); + }; + + useEffect(() => { + setLoading(true); + Promise.all([getHealthData(), getCardInfo()]).finally(() => { + setLoading(false); + }); + }, [record]); + return ( + + ); +}; + +export default ConnectDetailCard; diff --git a/km-console/packages/layout-clusters-fe/src/components/CardBar/MirrorMakerCard.tsx b/km-console/packages/layout-clusters-fe/src/components/CardBar/MirrorMakerCard.tsx new file mode 100644 index 00000000..f7489e75 --- /dev/null +++ b/km-console/packages/layout-clusters-fe/src/components/CardBar/MirrorMakerCard.tsx @@ -0,0 +1,119 @@ +import React, { useState, useEffect } from 'react'; +import { useParams } from 'react-router-dom'; +import CardBar, { healthDataProps } from './index'; +import { Tooltip, Utils } from 'knowdesign'; +import api from '@src/api'; +import { HealthStateEnum } from '../HealthState'; +import { InfoCircleOutlined } from '@ant-design/icons'; + +interface MM2State { + workerCount: number; + aliveConnectorCount: number; + aliveTaskCount: number; + healthCheckPassed: number; + healthCheckTotal: number; + healthState: number; + totalConnectorCount: string; + totalTaskCount: number; + totalServerCount: number; + mirrorMakerCount: number; +} + +const getVal = (val: string | number | undefined | null) => { + return val === undefined || val === null || val === '' ? '0' : val; +}; + +const ConnectCard = ({ state }: { state?: boolean }) => { + const { clusterId } = useParams<{ + clusterId: string; + }>(); + const [loading, setLoading] = useState(false); + const [cardData, setCardData] = useState([]); + const [healthData, setHealthData] = useState({ + state: HealthStateEnum.UNKNOWN, + passed: 0, + total: 0, + }); + + const getHealthData = () => { + return Utils.post(api.getMetricPointsLatest(Number(clusterId)), [ + 'HealthCheckPassed_MirrorMaker', + 'HealthCheckTotal_MirrorMaker', + 'HealthState_MirrorMaker', + ]).then((data: any) => { + setHealthData({ + state: data?.metrics?.['HealthState_MirrorMaker'], + passed: data?.metrics?.['HealthCheckPassed_MirrorMaker'] || 0, + total: data?.metrics?.['HealthCheckTotal_MirrorMaker'] || 0, + }); + }); + }; + + const getCardInfo = () => { + return Utils.request(api.getMirrorMakerState(clusterId)).then((res: MM2State) => { + const { mirrorMakerCount, aliveConnectorCount, aliveTaskCount, totalConnectorCount, totalTaskCount, workerCount } = res || {}; + const cardMap = [ + { + title: 'MM2s', + value: getVal(mirrorMakerCount), + customStyle: { + // 自定义cardbar样式 + marginLeft: 0, + }, + }, + { + title: 'Workers', + value: getVal(workerCount), + }, + { + title() { + return ( +
+ Connectors + + + +
+ ); + }, + value() { + return ( + + {getVal(aliveConnectorCount)}/{getVal(totalConnectorCount)} + + ); + }, + }, + { + title() { + return ( +
+ Tasks + + + +
+ ); + }, + value() { + return ( + + {getVal(aliveTaskCount)}/{getVal(totalTaskCount)} + + ); + }, + }, + ]; + setCardData(cardMap); + }); + }; + useEffect(() => { + setLoading(true); + Promise.all([getHealthData(), getCardInfo()]).finally(() => { + setLoading(false); + }); + }, [clusterId, state]); + return ; +}; + +export default ConnectCard; diff --git a/km-console/packages/layout-clusters-fe/src/components/CardBar/MirrorMakerDetailCard.tsx b/km-console/packages/layout-clusters-fe/src/components/CardBar/MirrorMakerDetailCard.tsx new file mode 100644 index 00000000..743e2e12 --- /dev/null +++ b/km-console/packages/layout-clusters-fe/src/components/CardBar/MirrorMakerDetailCard.tsx @@ -0,0 +1,145 @@ +/* eslint-disable react/display-name */ +import React, { useState, useEffect } from 'react'; +import { useLocation, useParams } from 'react-router-dom'; +import CardBar from '@src/components/CardBar'; +import { healthDataProps } from '.'; +import { Tooltip, Utils } from 'knowdesign'; +import Api from '@src/api'; +import { hashDataParse } from '@src/constants/common'; +import { HealthStateEnum } from '../HealthState'; +import { InfoCircleOutlined } from '@ant-design/icons'; +import { stateEnum } from '@src/pages/Connect/config'; +const getVal = (val: string | number | undefined | null) => { + return val === undefined || val === null || val === '' ? '0' : val; +}; + +const ConnectDetailCard = (props: { record: any; tabSelectType: string }) => { + const { record, tabSelectType } = props; + const urlParams = useParams<{ clusterId: string; brokerId: string }>(); + const urlLocation = useLocation(); + const [loading, setLoading] = useState(false); + const [cardData, setCardData] = useState([]); + const [healthData, setHealthData] = useState({ + state: HealthStateEnum.UNKNOWN, + passed: 0, + total: 0, + }); + + const getHealthData = (tabSelectTypeName: string) => { + return Utils.post(Api.getMirrorMakerMetricPoints(tabSelectTypeName, record?.connectClusterId), [ + 'HealthState', + 'HealthCheckPassed', + 'HealthCheckTotal', + ]).then((data: any) => { + setHealthData({ + state: data?.metrics?.['HealthState'], + passed: data?.metrics?.['HealthCheckPassed'] || 0, + total: data?.metrics?.['HealthCheckTotal'] || 0, + }); + }); + }; + + const getCardInfo = (tabSelectTypeName: string) => { + return Utils.request(Api.getConnectDetailState(tabSelectTypeName, record?.connectClusterId)).then((res: any) => { + const { type, aliveTaskCount, state, totalTaskCount, totalWorkerCount } = res || {}; + const cordRightMap = [ + { + title: 'Status', + // value: Utils.firstCharUppercase(state) || '-', + value: () => { + return ( + <> + { + + {Utils.firstCharUppercase(state) || '-'} + + } + + ); + }, + }, + + { + title() { + return ( +
+ Tasks + + + +
+ ); + }, + value() { + return ( + + {getVal(aliveTaskCount)}/{getVal(totalTaskCount)} + + ); + }, + }, + { + title: 'Workers', + value: getVal(totalWorkerCount), + }, + ]; + setCardData(cordRightMap); + }); + }; + + const noDataCardInfo = () => { + const cordRightMap = [ + { + title: 'Status', + // value: Utils.firstCharUppercase(state) || '-', + value() { + return -; + }, + }, + + { + title() { + return ( +
+ Tasks + + + +
+ ); + }, + value() { + return -/-; + }, + }, + { + title: 'Workers', + value() { + return -; + }, + }, + ]; + setCardData(cordRightMap); + }; + + useEffect(() => { + setLoading(true); + + const filterCardInfo = + tabSelectType === 'MirrorCheckpoint' && record.checkpointConnector + ? getCardInfo(record.checkpointConnector) + : tabSelectType === 'MirrorHeatbeat' && record.heartbeatConnector + ? getCardInfo(record.heartbeatConnector) + : tabSelectType === 'MirrorSource' && record.connectorName + ? getCardInfo(record.connectorName) + : noDataCardInfo(); + Promise.all([getHealthData(record.connectorName), filterCardInfo]).finally(() => { + setLoading(false); + }); + }, [record, tabSelectType]); + return ( + + ); +}; + +export default ConnectDetailCard; diff --git a/km-console/packages/layout-clusters-fe/src/components/CardBar/TopicHealthCheck.tsx b/km-console/packages/layout-clusters-fe/src/components/CardBar/TopicHealthCheck.tsx index 38da5b03..cb0dbf28 100644 --- a/km-console/packages/layout-clusters-fe/src/components/CardBar/TopicHealthCheck.tsx +++ b/km-console/packages/layout-clusters-fe/src/components/CardBar/TopicHealthCheck.tsx @@ -66,5 +66,5 @@ export default () => { }); }); }, []); - return ; + return ; }; diff --git a/km-console/packages/layout-clusters-fe/src/components/CardBar/ZookeeperCard.tsx b/km-console/packages/layout-clusters-fe/src/components/CardBar/ZookeeperCard.tsx index 8f6c65ed..cc837349 100644 --- a/km-console/packages/layout-clusters-fe/src/components/CardBar/ZookeeperCard.tsx +++ b/km-console/packages/layout-clusters-fe/src/components/CardBar/ZookeeperCard.tsx @@ -1,7 +1,7 @@ import React, { useState, useEffect } from 'react'; import { useParams } from 'react-router-dom'; import CardBar, { healthDataProps } from './index'; -import { Utils } from 'knowdesign'; +import { Tooltip, Utils } from 'knowdesign'; import api from '@src/api'; import { HealthStateEnum } from '../HealthState'; @@ -81,7 +81,22 @@ const ZookeeperCard = () => { { title: 'Leader', value() { - return {leaderNode || '-'}; + return ( + + + {leaderNode || '-'} + + + ); }, }, { diff --git a/km-console/packages/layout-clusters-fe/src/components/CardBar/index.less b/km-console/packages/layout-clusters-fe/src/components/CardBar/index.less index 6474a929..e5302338 100644 --- a/km-console/packages/layout-clusters-fe/src/components/CardBar/index.less +++ b/km-console/packages/layout-clusters-fe/src/components/CardBar/index.less @@ -12,7 +12,8 @@ display: flex; align-items: center; .card-bar-health { - width: 240px; + // width: 240px; // 去掉固定宽度自适应 + margin-right: 10px; height: 70px; display: flex; align-items: center; @@ -68,6 +69,15 @@ letter-spacing: 0; text-align: justify; line-height: 20px; + .anticon-question-circle { + padding: 3px 3px 2px 3px; + margin-left: -3px; + font-size: 14px; + border-radius: 50%; + &:hover { + background: rgba(33, 37, 41, 0.04); + } + } } .card-bar-colunms-body { font-size: 40px; @@ -79,6 +89,7 @@ margin-top: 5px; .num { font-family: DIDIFD-Medium; + overflow: hidden; } .sub-title { font-family: @font-family; diff --git a/km-console/packages/layout-clusters-fe/src/components/CardBar/index.tsx b/km-console/packages/layout-clusters-fe/src/components/CardBar/index.tsx index 51fc9057..4fb4121e 100644 --- a/km-console/packages/layout-clusters-fe/src/components/CardBar/index.tsx +++ b/km-console/packages/layout-clusters-fe/src/components/CardBar/index.tsx @@ -18,7 +18,7 @@ export interface CardBarProps { cardColumns?: any[]; healthData?: healthDataProps; showCardBg?: boolean; - scene: 'topic' | 'broker' | 'group' | 'zookeeper'; + scene: 'topics' | 'brokers' | 'topic' | 'broker' | 'group' | 'zookeeper' | 'connect' | 'connector' | 'mm2'; record?: any; loading?: boolean; needProgress?: boolean; @@ -27,16 +27,26 @@ const renderValue = (v: string | number | ((visibleType?: boolean) => JSX.Elemen return typeof v === 'function' ? v(visibleType) : v; }; const sceneCodeMap = { - broker: { + brokers: { code: 1, fieldName: 'brokerId', alias: 'Brokers', }, - topic: { + broker: { + code: 1, + fieldName: 'brokerId', + alias: 'Broker', + }, + topics: { code: 2, fieldName: 'topicName', alias: 'Topics', }, + topic: { + code: 2, + fieldName: 'topicName', + alias: 'Topic', + }, group: { code: 3, fieldName: 'groupName', @@ -47,6 +57,21 @@ const sceneCodeMap = { fieldName: 'zookeeperId', alias: 'Zookeeper', }, + connect: { + code: 5, + fieldName: 'connectClusterId', + alias: 'Connect', + }, + connector: { + code: 6, + fieldName: 'connectorName', + alias: 'Connector', + }, + mm2: { + code: 7, + fieldName: 'connectorName', + alias: 'MM2', + }, }; const CardColumnsItem: any = (cardItem: any) => { const { cardColumnsItemData, showCardBg } = cardItem; @@ -87,12 +112,17 @@ const CardBar = (props: CardBarProps) => { useEffect(() => { const sceneObj = sceneCodeMap[scene]; const path = record - ? api.getResourceHealthDetail(Number(routeParams.clusterId), sceneObj.code, record[sceneObj.fieldName]) + ? api.getResourceHealthDetail( + scene === 'connector' || scene === 'mm2' ? Number(record?.connectClusterId) : Number(routeParams.clusterId), + sceneObj.code, + record[sceneObj.fieldName] + ) : api.getResourceListHealthDetail(Number(routeParams.clusterId)); const promise = record ? Utils.request(path) : Utils.request(path, { - params: { dimensionCode: sceneObj.code }, + method: 'POST', + data: scene === 'connect' ? JSON.parse(JSON.stringify([5, 6])) : JSON.parse(JSON.stringify([sceneObj.code])), }); promise.then((data: any[]) => { setHealthCheckDetailList(data); @@ -102,6 +132,7 @@ const CardBar = (props: CardBarProps) => { { title: '检查项', dataIndex: 'checkConfig', + width: '40%', render(config: any, record: any) { let valueGroup = {}; try { @@ -109,7 +140,12 @@ const CardBar = (props: CardBarProps) => { } catch (e) { // } - return getConfigItemDetailDesc(record.configItem, valueGroup) || record.configDesc || '-'; + return ( + getConfigItemDetailDesc(record.configItem, valueGroup) || + getConfigItemDetailDesc(config.configItem, valueGroup) || + record.configDesc || + '-' + ); }, }, // { @@ -119,25 +155,31 @@ const CardBar = (props: CardBarProps) => { { title: '检查时间', dataIndex: 'updateTime', + width: '30%', render: (value: number) => { - return moment(value).format('YYYY-MM-DD HH:mm:ss'); + return value ? moment(value).format('YYYY-MM-DD HH:mm:ss') : '-'; }, }, { title: '检查结果', dataIndex: 'passed', + width: '30%', render(value: boolean, record: any) { - const icon = value ? : ; - const txt = value ? '已通过' : '未通过'; - const notPassedResNameList = record.notPassedResNameList || []; - return ( -
-
- {icon} {txt} + if (record?.updateTime) { + const icon = value ? : ; + const txt = value ? '已通过' : '未通过'; + const notPassedResNameList = record.notPassedResNameList || []; + return ( +
+
+ {icon} {txt} +
+ {}
- {} -
- ); + ); + } else { + return '-'; + } }, }, ]; @@ -145,7 +187,7 @@ const CardBar = (props: CardBarProps) => {
- {!loading && healthData && needProgress && ( + {healthData && needProgress && (
@@ -181,7 +223,7 @@ const CardBar = (props: CardBarProps) => { onClose={(_) => setDetailDrawerVisible(false)} visible={detailDrawerVisible} > - +
); diff --git a/km-console/packages/layout-clusters-fe/src/components/ChartOperateBar/MetricSelect.tsx b/km-console/packages/layout-clusters-fe/src/components/ChartOperateBar/MetricSelect.tsx index badae226..3ce20f3c 100644 --- a/km-console/packages/layout-clusters-fe/src/components/ChartOperateBar/MetricSelect.tsx +++ b/km-console/packages/layout-clusters-fe/src/components/ChartOperateBar/MetricSelect.tsx @@ -1,18 +1,25 @@ -import React, { useState, useEffect, forwardRef, useImperativeHandle } from 'react'; +import React, { useState, useEffect, forwardRef, useImperativeHandle, useRef } from 'react'; import { Drawer, Button, Space, Divider, AppContainer, ProTable, Utils } from 'knowdesign'; import { IconFont } from '@knowdesign/icons'; -import { MetricSelect } from './index'; +import { arrayMoveImmutable } from 'array-move'; import './style/indicator-drawer.less'; -import { useLocation } from 'react-router-dom'; +import { useLocation, useParams } from 'react-router-dom'; +import api, { MetricType } from '@src/api'; +import { MetricInfo, resolveMetricsRank } from '@src/constants/chartConfig'; -interface PropsType extends React.HTMLAttributes { - metricSelect: MetricSelect; +export interface Inode { + name: string; + desc: string; } -interface MetricInfo { - name: string; - unit: string; - desc: string; +export interface MetricSelectProps extends React.HTMLAttributes { + metricType: MetricType; + hide?: boolean; + drawerTitle?: string; + selectedRows: (string | number)[]; + checkboxProps?: (record: any) => { [props: string]: any }; + tableData?: Inode[]; + submitCallback?: (value: (string | number)[]) => Promise; } interface SelectedMetrics { @@ -21,10 +28,14 @@ interface SelectedMetrics { type CategoryData = { category: string; - metrics: MetricInfo[]; + metrics: { + name: string; + unit: string; + desc: string; + }[]; }; -const expandedRowColumns = [ +export const expandedRowColumns = [ { title: '指标名称', dataIndex: 'name', @@ -44,16 +55,7 @@ const expandedRowColumns = [ const ExpandedRow = ({ metrics, category, selectedMetrics, selectedMetricChange }: any) => { return ( -
+
{ +export const MetricSelect = forwardRef((metricSelect: MetricSelectProps, ref) => { const [global] = AppContainer.useGlobalValue(); const { pathname } = useLocation(); const [confirmLoading, setConfirmLoading] = useState(false); @@ -87,7 +89,15 @@ const MetricSelect = forwardRef(({ metricSelect }: PropsType, ref) => { const columns = [ { - title: `${pathname.endsWith('/broker') ? 'Broker' : pathname.endsWith('/topic') ? 'Topic' : 'Cluster'} Metrics`, + title: `${ + pathname.endsWith('/broker') + ? 'Broker' + : pathname.endsWith('/topic') + ? 'Topic' + : pathname.endsWith('/replication') + ? 'MM2' + : 'Cluster' + } Metrics`, dataIndex: 'category', key: 'category', }, @@ -96,7 +106,11 @@ const MetricSelect = forwardRef(({ metricSelect }: PropsType, ref) => { const formateTableData = () => { const tableData = metricSelect.tableData; const categoryData: { - [category: string]: MetricInfo[]; + [category: string]: { + name: string; + unit: string; + desc: string; + }[]; } = {}; tableData.forEach(({ name, desc }) => { @@ -106,7 +120,7 @@ const MetricSelect = forwardRef(({ metricSelect }: PropsType, ref) => { desc, unit: metricDefine?.unit, }; - if (metricDefine.category) { + if (metricDefine?.category) { if (!categoryData[metricDefine.category]) { categoryData[metricDefine.category] = [returnData]; } else { @@ -123,11 +137,11 @@ const MetricSelect = forwardRef(({ metricSelect }: PropsType, ref) => { }; const formateSelectedKeys = () => { - const newKeys = metricSelect.selectedRows; + const newKeys = metricSelect?.selectedRows; const result: SelectedMetrics = {}; const selectedCategories: string[] = []; - newKeys.forEach((name: string) => { + newKeys?.forEach((name: string) => { const metricDefine = global.getMetricDefine(metricSelect?.metricType, name); if (metricDefine) { if (!result[metricDefine.category]) { @@ -328,4 +342,106 @@ const MetricSelect = forwardRef(({ metricSelect }: PropsType, ref) => { ); }); -export default MetricSelect; +interface MetricsFilterProps { + metricType: MetricType; + onSelectChange: (list: (string | number)[], rankList: string[]) => void; +} + +const MetricsFilter = forwardRef((props: MetricsFilterProps, ref) => { + const { metricType, onSelectChange } = props; + const { clusterId } = useParams<{ + clusterId: string; + }>(); + const [metricsList, setMetricsList] = useState([]); // 指标列表 + const [metricRankList, setMetricRankList] = useState([]); + const [selectedMetricNames, setSelectedMetricNames] = useState<(string | number)[]>(undefined); // 默认选中的指标的列表 + const metricSelectRef = useRef(null); + + // 更新指标 + const setMetricList = (metricDetailDTOList: { metric: string; rank: number; set: boolean }[]) => { + return Utils.request(api.getDashboardMetricList(clusterId, metricType), { + method: 'POST', + data: { + metricDetailDTOList, + }, + }); + }; + + // 图表展示顺序变更 + const rankChange = (oldIndex: number, newIndex: number) => { + const newList = arrayMoveImmutable(metricRankList, oldIndex, newIndex); + setMetricRankList(newList); + setMetricList(newList.map((metric, rank) => ({ metric, rank, set: metricsList.find(({ name }) => metric === name)?.set || false }))); + }; + + // 更新 rank + const updateRank = (metricList: MetricInfo[]) => { + const { list, listInfo, shouldUpdate } = resolveMetricsRank(metricList); + setMetricRankList(list); + if (shouldUpdate) { + setMetricList(listInfo); + } + }; + + // 获取指标列表 + const getMetricList = () => { + Utils.request(api.getDashboardMetricList(clusterId, metricType)).then((res: MetricInfo[] | null) => { + if (!res) return; + const supportMetrics = res.filter((metric) => metric.support); + const selectedMetrics = supportMetrics.filter((metric) => metric.set).map((metric) => metric.name); + updateRank([...supportMetrics]); + setMetricsList(supportMetrics); + setSelectedMetricNames(selectedMetrics); + }); + }; + + // 指标选中项更新回调 + const metricSelectCallback = (newMetricNames: (string | number)[]) => { + const updateMetrics: { metric: string; set: boolean; rank: number }[] = []; + // 需要选中的指标 + newMetricNames.forEach( + (name) => + !selectedMetricNames.includes(name) && + updateMetrics.push({ metric: name as string, set: true, rank: metricsList.find(({ name: metric }) => metric === name)?.rank }) + ); + // 取消选中的指标 + selectedMetricNames.forEach( + (name) => + !newMetricNames.includes(name) && + updateMetrics.push({ metric: name as string, set: false, rank: metricsList.find(({ name: metric }) => metric === name)?.rank }) + ); + + const requestPromise = Object.keys(updateMetrics).length ? setMetricList(updateMetrics) : Promise.resolve(); + requestPromise.then( + () => getMetricList(), + () => getMetricList() + ); + + return requestPromise; + }; + + useEffect(() => { + onSelectChange(selectedMetricNames, metricRankList); + }, [selectedMetricNames, metricRankList]); + + useEffect(() => { + getMetricList(); + }, []); + + useImperativeHandle(ref, () => ({ + rankChange, + open: () => metricSelectRef.current?.open(), + })); + + return ( + + ); +}); + +export default MetricsFilter; diff --git a/km-console/packages/layout-clusters-fe/src/components/ChartOperateBar/NodeScope.tsx b/km-console/packages/layout-clusters-fe/src/components/ChartOperateBar/NodeScope.tsx deleted file mode 100644 index 80f160c3..00000000 --- a/km-console/packages/layout-clusters-fe/src/components/ChartOperateBar/NodeScope.tsx +++ /dev/null @@ -1,203 +0,0 @@ -import React, { useState, useEffect } from 'react'; -import { Radio, Input, Popover, Space, Checkbox, Row, Col, Button } from 'knowdesign'; -import { IconFont } from '@knowdesign/icons'; -import { InodeScopeModule } from './index'; -import './style/node-scope.less'; - -interface propsType { - change: Function; - nodeScopeModule: InodeScopeModule; -} - -const OptionsDefault = [ - { - label: 'Top 5', - value: 5, - }, - { - label: 'Top 10', - value: 10, - }, - { - label: 'Top 15', - value: 15, - }, -]; - -const NodeScope = ({ nodeScopeModule, change }: propsType) => { - const { - customScopeList: customList, - scopeName = '', - scopeLabel = '自定义范围', - searchPlaceholder = '输入内容进行搜索', - } = nodeScopeModule; - const [topNum, setTopNum] = useState(5); - const [isTop, setIsTop] = useState(true); - const [audioOptions, setAudioOptions] = useState(OptionsDefault); - const [scopeSearchValue, setScopeSearchValue] = useState(''); - const [inputValue, setInputValue] = useState(null); - const [indeterminate, setIndeterminate] = useState(false); - const [popVisible, setPopVisible] = useState(false); - const [checkAll, setCheckAll] = useState(false); - const [checkedListTemp, setCheckedListTemp] = useState([]); - const [checkedList, setCheckedList] = useState([]); - const [allCheckedList, setAllCheckedList] = useState([]); - - useEffect(() => { - const all = customList?.map((item) => item.value) || []; - setAllCheckedList(all); - }, [customList]); - - useEffect(() => { - if (topNum) { - const timeOption = audioOptions.find((item) => item.value === topNum); - - setInputValue(timeOption?.label); - setCheckedListTemp([]); - setCheckedList([]); - - setPopVisible(false); - } - }, [topNum]); - - useEffect(() => { - setIndeterminate(!!checkedListTemp.length && checkedListTemp.length < allCheckedList.length); - setCheckAll(checkedListTemp?.length === allCheckedList.length); - }, [checkedListTemp]); - - const customSure = () => { - if (checkedListTemp?.length > 0) { - setCheckedList(checkedListTemp); - change(checkedListTemp, false); - setIsTop(false); - setTopNum(null); - setInputValue(`${checkedListTemp?.length}项`); - setPopVisible(false); - } - }; - - const customCancel = () => { - setCheckedListTemp(checkedList); - setPopVisible(false); - }; - - const visibleChange = (visible: any) => { - setCheckedListTemp(checkedList); - setPopVisible(visible); - }; - - const periodtimeChange = (e: any) => { - const topNum = e.target.value; - setTopNum(topNum); - change(topNum, true); - setIsTop(true); - }; - - const onCheckAllChange = (e: any) => { - setCheckedListTemp(e.target.checked ? allCheckedList : []); - setIndeterminate(false); - setCheckAll(e.target.checked); - }; - - const checkChange = (val: any) => { - setCheckedListTemp(val); - // setIndeterminate(!!val.length && val.length < allCheckedList.length); - // setCheckAll(val?.length === allCheckedList.length); - }; - - const clickContent = ( -
- {/* 时间: */} -
-
-
选择 top 范围
- - - {audioOptions.map((item, index) => ( - - {item.label} - - ))} - - -
-
-
{scopeLabel}
-
-
- - 全选 - - } - size="small" - placeholder={searchPlaceholder} - onChange={(e) => setScopeSearchValue(e.target.value)} - /> -
-
- - - {customList - .filter((item) => item.label.includes(scopeSearchValue)) - .map((item) => ( -
- {item.label} - - ))} - - - - -
- - -
- - - - - ); - return ( -
-
{scopeName}筛选:
- - - } - /> - - -
- ); -}; - -export default NodeScope; diff --git a/km-console/packages/layout-clusters-fe/src/components/ChartOperateBar/NodeSelect.tsx b/km-console/packages/layout-clusters-fe/src/components/ChartOperateBar/NodeSelect.tsx new file mode 100644 index 00000000..0268c32e --- /dev/null +++ b/km-console/packages/layout-clusters-fe/src/components/ChartOperateBar/NodeSelect.tsx @@ -0,0 +1,115 @@ +import React, { useState, useEffect, useRef, PropsWithChildren } from 'react'; +import { Radio, Input, Popover, Space, Checkbox, Row, Col, Button } from 'knowdesign'; +import { IconFont } from '@knowdesign/icons'; +import './style/node-scope.less'; + +interface NodeSelectProps { + name?: string; + onChange: (data: any, isTop: boolean) => void; +} + +const TOP_SELECT_OPTIONS = [ + { + label: 'Top 5', + value: 5, + }, + { + label: 'Top 10', + value: 10, + }, + { + label: 'Top 15', + value: 15, + }, +]; + +const NodeSelect = ({ name, onChange, children }: PropsWithChildren) => { + const [topNum, setTopNum] = useState(5); + const [isTop, setIsTop] = useState(true); + const [audioOptions] = useState(TOP_SELECT_OPTIONS); + const [inputValue, setInputValue] = useState(null); + const [popVisible, setPopVisible] = useState(false); + + useEffect(() => { + if (topNum) { + const timeOption = audioOptions.find((item) => item.value === topNum); + + setInputValue(timeOption?.label); + + setPopVisible(false); + } + }, [topNum]); + + const visibleChange = (visible: any) => { + setPopVisible(visible); + }; + + const periodtimeChange = (e: any) => { + const topNum = e.target.value; + setTopNum(topNum); + onChange(topNum, true); + setIsTop(true); + }; + + const clickContent = ( +
+
+
+
选择 top 范围
+ + + {audioOptions.map((item, index) => ( + + {item.label} + + ))} + + +
+
+ {children ? ( + React.Children.map(children, (child) => { + return React.cloneElement(child as React.ReactElement, { + isTop, + visibleChange: visibleChange, + onChange: (data: any, inputValue: string) => { + onChange(data, false); + setIsTop(false); + setTopNum(null); + setInputValue(inputValue); + setPopVisible(false); + }, + }); + }) + ) : ( + <> + )} +
+
+
+ ); + return ( +
+
{name}筛选:
+ + + } + /> + + +
+ ); +}; + +export default NodeSelect; diff --git a/km-console/packages/layout-clusters-fe/src/components/ChartOperateBar/index.tsx b/km-console/packages/layout-clusters-fe/src/components/ChartOperateBar/index.tsx index af8cdd61..bfff9b4b 100644 --- a/km-console/packages/layout-clusters-fe/src/components/ChartOperateBar/index.tsx +++ b/km-console/packages/layout-clusters-fe/src/components/ChartOperateBar/index.tsx @@ -3,16 +3,8 @@ import { Select, Divider, Button } from 'knowdesign'; import { IconFont } from '@knowdesign/icons'; import moment from 'moment'; import { DRangeTime } from 'knowdesign'; -import MetricSelect from './MetricSelect'; -import NodeScope from './NodeScope'; - +import NodeSelect from './NodeSelect'; import './style/index.less'; -import { MetricType } from 'src/api'; - -export interface Inode { - name: string; - desc: string; -} export interface KsHeaderOptions { rangeTime: [number, number]; @@ -21,18 +13,9 @@ export interface KsHeaderOptions { gridNum?: number; scopeData?: { isTop: boolean; - data: number | number[]; + data: any; }; } -export interface MetricSelect { - metricType: MetricType; - hide?: boolean; - drawerTitle?: string; - selectedRows: (string | number)[]; - checkboxProps?: (record: any) => { [props: string]: any }; - tableData?: Inode[]; - submitCallback?: (value: (string | number)[]) => Promise; -} export interface IfilterData { hostName?: string; @@ -41,25 +24,15 @@ export interface IfilterData { agent?: string; } -export interface IcustomScope { - label: string; - value: string | number; -} - -export interface InodeScopeModule { - customScopeList: IcustomScope[]; - scopeName?: string; - scopeLabel?: string; - searchPlaceholder?: string; - change?: () => void; -} - interface PropsType { - metricSelect?: MetricSelect; hideNodeScope?: boolean; hideGridSelect?: boolean; - nodeScopeModule?: InodeScopeModule; + nodeSelect?: { + name?: string; + customContent?: React.ReactElement; + }; onChange: (options: KsHeaderOptions) => void; + openMetricFilter: () => void; } interface ScopeData { @@ -84,15 +57,12 @@ const GRID_SIZE_OPTIONS = [ ]; const MetricOperateBar = ({ - metricSelect, - nodeScopeModule = { - customScopeList: [], - }, + nodeSelect = {}, hideNodeScope = false, hideGridSelect = false, onChange: onChangeCallback, + openMetricFilter, }: PropsType): JSX.Element => { - const metricSelectRef = useRef(null); const [gridNum, setGridNum] = useState(GRID_SIZE_OPTIONS[1].value); const [rangeTime, setRangeTime] = useState<[number, number]>(() => { const curTimeStamp = moment().valueOf(); @@ -170,20 +140,22 @@ const MetricOperateBar = ({
{/* 节点范围 */} - {!hideNodeScope && } + {!hideNodeScope && ( + + {nodeSelect.customContent} + + )} {/* 分栏 */} {!hideGridSelect && ( } + size="small" + placeholder={searchPlaceholder} + onChange={(e) => setScopeSearchValue(e.target.value)} + /> +
+
+ + + {list + .filter((item) => item.label.includes(scopeSearchValue)) + .map((item) => ( +
+ {item.label} + + ))} + + + + +
+ + +
+ + + ); +}; const DraggableCharts = (props: PropsType): JSX.Element => { const [global] = AppContainer.useGlobalValue(); @@ -35,66 +139,49 @@ const DraggableCharts = (props: PropsType): JSX.Element => { }>(); const [loading, setLoading] = useState(true); const [scopeList, setScopeList] = useState([]); // 节点范围列表 - const [metricsList, setMetricsList] = useState([]); // 指标列表 - const [selectedMetricNames, setSelectedMetricNames] = useState<(string | number)[]>([]); // 默认选中的指标的列表 const [curHeaderOptions, setCurHeaderOptions] = useState(); + const [metricList, setMetricList] = useState<(string | number)[]>([]); const [metricChartData, setMetricChartData] = useState([]); // 指标图表数据列表 const [gridNum, setGridNum] = useState(12); // 图表列布局 - const metricRankList = useRef([]); - const chartDetailRef = useRef(null); const curFetchingTimestamp = useRef(0); + const metricRankList = useRef([]); + const metricFilterRef = useRef(null); + const chartDetailRef = useRef(null); // 获取节点范围列表 const getScopeList = async () => { - const res: any = await Utils.request(api.getDashboardMetadata(clusterId, dashboardType)); - const list = res.map((item: any) => { - return dashboardType === MetricType.Broker - ? { - label: item.host, - value: item.brokerId, - } - : { - label: item.topicName, - value: item.topicName, - }; - }); + const res: any = await Utils.request( + dashboardType !== MetricType.MM2 ? api.getDashboardMetadata(clusterId, dashboardType) : api.getMirrorMakerMetadata(clusterId) + ); + const mockRes = [{ connectClusterId: 1, connectClusterName: 'connectClusterName', connectorName: 'connectorName' }]; + const list = + res.length > 0 + ? res.map((item: any) => { + return dashboardType === MetricType.Broker + ? { + label: item.host, + value: item.brokerId, + } + : dashboardType === MetricType.MM2 + ? { + label: item.connectorName, + value: JSON.stringify({ connectClusterId: item.connectClusterId, connectorName: item.connectorName }), + } + : { + label: item.topicName, + value: item.topicName, + }; + }) + : mockRes.map((item) => { + return { + label: item.connectorName, + value: JSON.stringify(item), + }; + }); + setScopeList(list); }; - // 更新 rank - const updateRank = (metricList: MetricInfo[]) => { - const { list, listInfo, shouldUpdate } = resolveMetricsRank(metricList); - metricRankList.current = list; - if (shouldUpdate) { - setMetricList(listInfo); - } - }; - - // 获取指标列表 - const getMetricList = () => { - Utils.request(api.getDashboardMetricList(clusterId, dashboardType)).then((res: MetricInfo[] | null) => { - if (!res) return; - const supportMetrics = res.filter((metric) => metric.support); - const selectedMetrics = supportMetrics.filter((metric) => metric.set).map((metric) => metric.name); - updateRank([...supportMetrics]); - setMetricsList(supportMetrics); - setSelectedMetricNames(selectedMetrics); - if (!selectedMetrics.length) { - setLoading(false); - } - }); - }; - - // 更新指标 - const setMetricList = (metricDetailDTOList: { metric: string; rank: number; set: boolean }[]) => { - return Utils.request(api.getDashboardMetricList(clusterId, dashboardType), { - method: 'POST', - data: { - metricDetailDTOList, - }, - }); - }; - // 根据筛选项获取图表信息 const getMetricChartData = () => { !curHeaderOptions.isAutoReload && setLoading(true); @@ -102,19 +189,23 @@ const DraggableCharts = (props: PropsType): JSX.Element => { const [startTime, endTime] = curHeaderOptions.rangeTime; const curTimestamp = Date.now(); curFetchingTimestamp.current = curTimestamp; - const reqBody = Object.assign( { startTime, endTime, - metricsNames: selectedMetricNames, + metricsNames: metricList || [], }, - dashboardType === MetricType.Broker || dashboardType === MetricType.Topic + dashboardType === MetricType.Broker || dashboardType === MetricType.Topic || dashboardType === MetricType.MM2 ? { topNu: curHeaderOptions?.scopeData?.isTop ? curHeaderOptions.scopeData.data : null, - [dashboardType === MetricType.Broker ? 'brokerIds' : 'topics']: curHeaderOptions?.scopeData?.isTop - ? null - : curHeaderOptions.scopeData.data, + [dashboardType === MetricType.Broker ? 'brokerIds' : dashboardType === MetricType.MM2 ? 'connectorNameList' : 'topics']: + curHeaderOptions?.scopeData?.isTop + ? null + : dashboardType === MetricType.MM2 + ? curHeaderOptions.scopeData.data?.map((item: any) => { + return JSON.parse(item); + }) + : curHeaderOptions.scopeData.data, } : {} ); @@ -137,10 +228,31 @@ const DraggableCharts = (props: PropsType): JSX.Element => { dashboardType, curHeaderOptions.rangeTime ) as FormattedMetricData[]; + // todo 将指标筛选选中但是没有返回的指标插入chartData中 + const nullformattedMetricData: any = []; + + metricList?.forEach((item) => { + if (formattedMetricData && formattedMetricData.some((key) => item === key.metricName)) { + nullformattedMetricData.push(null); + } else { + const chartData: any = { + metricName: item, + metricType: dashboardType, + metricUnit: global.getMetricDefine(dashboardType, item)?.unit || '', + metricLines: [], + showLegend: false, + targetUnit: undefined, + }; + nullformattedMetricData.push(chartData); + } + }); // 指标排序 formattedMetricData.sort((a, b) => metricRankList.current.indexOf(a.metricName) - metricRankList.current.indexOf(b.metricName)); - - setMetricChartData(formattedMetricData); + const filterNullformattedMetricData = nullformattedMetricData.filter((item: any) => item !== null); + filterNullformattedMetricData.sort( + (a: any, b: any) => metricRankList.current.indexOf(a?.metricName) - metricRankList.current.indexOf(b?.metricName) + ); + setMetricChartData([...formattedMetricData, ...filterNullformattedMetricData]); } setLoading(false); }, @@ -168,65 +280,32 @@ const DraggableCharts = (props: PropsType): JSX.Element => { } }; - // 指标选中项更新回调 - const metricSelectCallback = (newMetricNames: (string | number)[]) => { - const updateMetrics: { metric: string; set: boolean; rank: number }[] = []; - // 需要选中的指标 - newMetricNames.forEach( - (name) => - !selectedMetricNames.includes(name) && - updateMetrics.push({ metric: name as string, set: true, rank: metricsList.find(({ name: metric }) => metric === name)?.rank }) - ); - // 取消选中的指标 - selectedMetricNames.forEach( - (name) => - !newMetricNames.includes(name) && - updateMetrics.push({ metric: name as string, set: false, rank: metricsList.find(({ name: metric }) => metric === name)?.rank }) - ); - - const requestPromise = Object.keys(updateMetrics).length ? setMetricList(updateMetrics) : Promise.resolve(); - requestPromise.then( - () => getMetricList(), - () => getMetricList() - ); - - return requestPromise; - }; - - // 拖拽开始回调,触发图表的 onDrag 事件( 设置为 true ),禁止同步展示图表的 tooltip - const dragStart = () => { - busInstance.emit('onDrag', true); - }; - - // 拖拽结束回调,更新图表顺序,并触发图表的 onDrag 事件( 设置为 false ),允许同步展示图表的 tooltip - const dragEnd = ({ oldIndex, newIndex }: { oldIndex: number; newIndex: number }) => { - busInstance.emit('onDrag', false); + // 图表拖拽 + const dragCallback = (oldIndex: number, newIndex: number) => { const originFrom = metricRankList.current.indexOf(metricChartData[oldIndex].metricName); const originTarget = metricRankList.current.indexOf(metricChartData[newIndex].metricName); - const newList = arrayMoveImmutable(metricRankList.current, originFrom, originTarget); - metricRankList.current = newList; - setMetricList(newList.map((metric, rank) => ({ metric, rank, set: metricsList.find(({ name }) => metric === name)?.set || false }))); - setMetricChartData(arrayMoveImmutable(metricChartData, oldIndex, newIndex)); + metricFilterRef.current?.rankChange(originFrom, originTarget); }; - // 监听盒子宽度变化,重置图表宽度 - const observeDashboardWidthChange = () => { - const targetNode = document.getElementsByClassName('dcd-two-columns-layout-sider-footer')[0]; - targetNode && targetNode.addEventListener('click', () => busInstance.emit('chartResize')); + // 展开图表详情 + const onExpand = (metricName: string) => { + const linesName = scopeList.map((item) => item.value); + chartDetailRef.current.onOpen(dashboardType, metricName, linesName); }; + // 获取图表指标 useEffect(() => { - if (selectedMetricNames.length && curHeaderOptions) { + if (metricList?.length && curHeaderOptions) { getMetricChartData(); + } else { + setMetricChartData([]); + setLoading(false); } - }, [curHeaderOptions, selectedMetricNames]); + }, [curHeaderOptions, metricList]); useEffect(() => { // 初始化页面,获取 scope 和 metric 信息 - (dashboardType === MetricType.Broker || dashboardType === MetricType.Topic) && getScopeList(); - getMetricList(); - - setTimeout(() => observeDashboardWidthChange()); + (dashboardType === MetricType.Broker || dashboardType === MetricType.Topic || dashboardType === MetricType.MM2) && getScopeList(); }, []); return ( @@ -234,95 +313,49 @@ const DraggableCharts = (props: PropsType): JSX.Element => { metricFilterRef.current?.open()} + nodeSelect={{ + name: + dashboardType === MetricType.Broker + ? 'Broker' + : dashboardType === MetricType.Topic + ? 'Topic' + : dashboardType === MetricType.MM2 + ? 'MM2' + : 'Zookeeper', + customContent: ( + + ), }} /> -
- - {metricChartData && metricChartData.length ? ( -
- - {metricChartData.map((data) => { - const { metricName, metricUnit, metricLines, showLegend } = data; - - return ( -
-
- { - let content = ''; - const metricDefine = global.getMetricDefine(dashboardType, metricName); - if (metricDefine) { - content = metricDefine.desc; - } - return content; - }} - > - - {metricName} - ({metricUnit}) - - -
-
{ - const linesName = scopeList.map((item) => item.value); - chartDetailRef.current.onOpen(dashboardType, metricName, linesName); - }} - > - -
- -
- ); - })} -
-
- ) : loading ? ( - <> - ) : ( - - )} -
-
+ { + metricRankList.current = rankList; + setMetricList(list); + }} + /> + {/* 图表详情 */} diff --git a/km-console/packages/layout-clusters-fe/src/components/SwitchTab/index.tsx b/km-console/packages/layout-clusters-fe/src/components/SwitchTab/index.tsx index ae4008c9..e7d21688 100644 --- a/km-console/packages/layout-clusters-fe/src/components/SwitchTab/index.tsx +++ b/km-console/packages/layout-clusters-fe/src/components/SwitchTab/index.tsx @@ -2,7 +2,8 @@ import React, { useLayoutEffect, useRef, useState } from 'react'; import './index.less'; interface SwitchTabProps { - defaultKey: string; + defaultKey?: string; + activeKey?: string | number; onChange: (key: string) => void; children: any; } @@ -18,9 +19,9 @@ const TabItem = (props: TabItemProps) => { }; const SwitchTab = (props: SwitchTabProps) => { - const { defaultKey, onChange, children } = props; + const { defaultKey, activeKey, onChange, children } = props; const tabRef = useRef(); - const [activeKey, setActiveKey] = useState(defaultKey); + const [active, setActive] = useState(activeKey || defaultKey); const [pos, setPos] = useState({ left: 0, width: 0, @@ -39,6 +40,10 @@ const SwitchTab = (props: SwitchTabProps) => { return false; }); } + }, [active]); + + useLayoutEffect(() => { + activeKey && setActive(activeKey); }, [activeKey]); return ( @@ -48,9 +53,10 @@ const SwitchTab = (props: SwitchTabProps) => { return (
{ - setActiveKey(key); + // 受控模式下不自动更新状态 + !activeKey && setActive(key); onChange(key); }} > diff --git a/km-console/packages/layout-clusters-fe/src/components/TopicJob/TopicMirror.tsx b/km-console/packages/layout-clusters-fe/src/components/TopicJob/TopicMirror.tsx new file mode 100644 index 00000000..2845dcae --- /dev/null +++ b/km-console/packages/layout-clusters-fe/src/components/TopicJob/TopicMirror.tsx @@ -0,0 +1,289 @@ +// 批量Topic复制 +import React, { useState, useEffect } from 'react'; +import { useParams } from 'react-router-dom'; +import { Button, Drawer, Form, Select, Utils, AppContainer, Space, Divider, Transfer, Checkbox, Tooltip } from 'knowdesign'; +import message from '@src/components/Message'; +import { IconFont } from '@knowdesign/icons'; +import { QuestionCircleOutlined } from '@ant-design/icons'; +import './index.less'; +import Api from '@src/api/index'; + +const { Option } = Select; +const CheckboxGroup = Checkbox.Group; + +interface DefaultConfig { + drawerVisible: boolean; + onClose: () => void; + genData?: () => any; +} + +export default (props: DefaultConfig) => { + const { drawerVisible, onClose, genData } = props; + const routeParams = useParams<{ clusterId: string }>(); + const [visible, setVisible] = useState(drawerVisible); + const [topicList, setTopicList] = useState([]); + const [clusterList, setClusterList] = useState([]); + const [selectTopicList, setSelectTopicList] = useState([]); + const [form] = Form.useForm(); + const topicsPerCluster = React.useRef({} as any); + + const mirrorScopeOptions = [ + { + label: '数据', + value: 'syncData', + }, + { + label: 'Topic配置', + value: 'syncConfig', + }, + { + label: 'kafkauser+Acls', + value: 'kafkauserAcls', + disabled: true, + }, + { + label: 'Group Offset', + value: 'groupOffset', + disabled: true, + }, + ]; + + const getTopicList = () => { + Utils.request(Api.getTopicMetaData(+routeParams.clusterId)).then((res: any) => { + const dataDe = res || []; + const dataHandle = dataDe.map((item: any) => { + return { + ...item, + key: item.topicName, + title: item.topicName, + }; + }); + setTopicList(dataHandle); + }); + }; + + const getTopicsPerCluster = (clusterId: number) => { + Utils.request(Api.getTopicMetaData(clusterId)).then((res: any) => { + const dataDe = res || []; + const dataHandle = dataDe.map((item: any) => item.topicName); + topicsPerCluster.current = { ...topicsPerCluster.current, [clusterId]: dataHandle }; + setTimeout(() => { + form.validateFields(['topicNames']); + }, 1000); + }); + }; + + const getClusterList = () => { + Utils.request(Api.getMirrorClusterList()).then((res: any) => { + const dataDe = res || []; + const dataHandle = dataDe.map((item: any) => { + return { + label: item.name, + value: item.id, + }; + }); + setClusterList(dataHandle); + }); + }; + + const checkTopic = (_: any, value: any[]) => { + const clusters = form.getFieldValue('destClusterPhyIds'); + if (!value || !value.length) { + return Promise.reject('请选择需要复制的Topic'); + } else { + if (clusters && clusters.length) { + // 验证Topic是否存在 + const existTopics = {} as any; + clusters.forEach((cluster: number) => { + if (cluster && topicsPerCluster.current[cluster]) { + existTopics[cluster] = []; + value.forEach((topic) => { + if (topicsPerCluster.current[cluster].indexOf(topic) > -1) { + existTopics[cluster].push(topic); + } + }); + if (!existTopics[cluster].length) delete existTopics[cluster]; + } else { + getTopicsPerCluster(cluster); + } + }); + if (Object.keys(existTopics).length) { + let errorInfo = ''; + Object.keys(existTopics).forEach((key) => { + const clusterName = clusterList.find((item) => item.value == key)?.label; + errorInfo = errorInfo.concat(`${existTopics[key].join('、')}在集群【${clusterName}】中已存在,`); + }); + errorInfo = errorInfo.concat('请重新选择'); + return Promise.reject(errorInfo); + } else { + return Promise.resolve(); + } + } else { + return Promise.resolve(); + } + } + }; + + const topicChange = (val: string[]) => { + setSelectTopicList(val); + }; + + const clusterChange = (val: number[]) => { + if (val && val.length) { + val.forEach((item) => { + if (item && !topicsPerCluster.current[item]) { + getTopicsPerCluster(item); + } else { + form.validateFields(['topicNames']); + } + }); + } else { + form.validateFields(['topicNames']); + } + }; + + const onDrawerClose = () => { + form.resetFields(); + setSelectTopicList([]); + topicsPerCluster.current = {}; + setVisible(false); + onClose(); + }; + + useEffect(() => { + if (!drawerVisible) return; + setVisible(true); + getTopicList(); + getClusterList(); + }, [drawerVisible]); + + const addTopicMirror = () => { + form.validateFields().then((e) => { + const formData = form.getFieldsValue(); + const handledData = [] as any; + formData.destClusterPhyIds.forEach((cluster: number) => { + formData.topicNames.forEach((topic: string) => { + handledData.push({ + destClusterPhyId: cluster, + sourceClusterPhyId: +routeParams.clusterId, + syncData: formData.mirrorScope.indexOf('syncData') > -1, + syncConfig: formData.mirrorScope.indexOf('syncConfig') > -1, + topicName: topic, + }); + }); + }); + Utils.post(Api.handleTopicMirror(), handledData).then(() => { + message.success('成功复制Topic'); + onDrawerClose(); + genData(); + }); + }); + }; + + return ( + + + + + + } + > +
+
+ + option.topicName.indexOf(inputValue) > -1} + targetKeys={selectTopicList} + onChange={topicChange} + render={(item) => item.title} + titles={['待选Topic', '已选Topic']} + customHeader + showSelectedCount + locale={{ itemUnit: '', itemsUnit: '' }} + suffix={} + /> + + + 选择目标集群 + + + + + } + rules={[{ required: true, message: '请选择目标集群' }]} + > + + + { + if (!value || !value.length) { + return Promise.reject('请选择Topic复制范围'); + } else if (value.indexOf('syncData') === -1) { + return Promise.reject('Topic复制范围必须选择[数据]'); + } else { + return Promise.resolve(); + } + }, + }, + ]} + initialValue={['syncData']} + > + + {mirrorScopeOptions.map((option) => { + return option.disabled ? ( + + + {option.label} + + + ) : ( + + {option.label} + + ); + })} + + + +
+
+ ); +}; diff --git a/km-console/packages/layout-clusters-fe/src/components/TopicJob/index.less b/km-console/packages/layout-clusters-fe/src/components/TopicJob/index.less index 794a252e..31c5914c 100644 --- a/km-console/packages/layout-clusters-fe/src/components/TopicJob/index.less +++ b/km-console/packages/layout-clusters-fe/src/components/TopicJob/index.less @@ -89,4 +89,10 @@ background: #F8F9FA; } } +} + +.checkbox-content-margin { + .dcloud-checkbox-wrapper { + margin-right: 20px; + } } \ No newline at end of file diff --git a/km-console/packages/layout-clusters-fe/src/constants/chartConfig.ts b/km-console/packages/layout-clusters-fe/src/constants/chartConfig.ts index f566e850..4eb7fadf 100644 --- a/km-console/packages/layout-clusters-fe/src/constants/chartConfig.ts +++ b/km-console/packages/layout-clusters-fe/src/constants/chartConfig.ts @@ -38,6 +38,7 @@ export interface OriginMetricData { export interface FormattedMetricData { metricName: string; metricUnit: string; + metricType: MetricType; metricLines: { name: string; data: (string | number)[][]; @@ -240,6 +241,7 @@ export const formatChartData = ( // 初始化返回结构 const chartData: FormattedMetricData = { metricName, + metricType, metricUnit: curMetricInfo?.unit || '', metricLines: metricLines .sort((a, b) => Number(a.name < b.name) - 0.5) diff --git a/km-console/packages/layout-clusters-fe/src/constants/menu.tsx b/km-console/packages/layout-clusters-fe/src/constants/menu.tsx index 0bcfbb51..47d84df4 100755 --- a/km-console/packages/layout-clusters-fe/src/constants/menu.tsx +++ b/km-console/packages/layout-clusters-fe/src/constants/menu.tsx @@ -56,12 +56,7 @@ export const leftMenus = (clusterId?: string, clusterRunState?: number) => ({ clusterRunState && clusterRunState !== ClusterRunState.Raft ? { name: (intl: any) => { - return ( -
- {intl.formatMessage({ id: 'menu.cluster.zookeeper' })} -
-
- ); + return {intl.formatMessage({ id: 'menu.cluster.zookeeper' })}; }, path: 'zookeeper', icon: 'icon-Zookeeper', @@ -79,6 +74,58 @@ export const leftMenus = (clusterId?: string, clusterRunState?: number) => ({ ], } : undefined, + { + name: (intl: any) => { + return ( +
+ {intl.formatMessage({ id: 'menu.cluster.connect' })} +
+ ); + }, + path: 'connect', + icon: 'icon-Operation', + children: [ + { + name: (intl: any) => {intl.formatMessage({ id: 'menu.cluster.connect.dashboard' })}, + path: '', + icon: 'icon-luoji', + }, + { + name: (intl: any) => {intl.formatMessage({ id: 'menu.cluster.connect.connectors' })}, + path: 'connectors', + icon: '#icon-luoji', + }, + { + name: (intl: any) => {intl.formatMessage({ id: 'menu.cluster.connect.workers' })}, + path: 'workers', + icon: 'icon-Jobs', + }, + ].filter((m) => m), + }, + { + name: (intl: any) => { + return ( +
+ {intl.formatMessage({ id: 'menu.cluster.replication' })} +
+
+ ); + }, + path: 'replication', + icon: 'icon-Operation', + children: [ + { + name: (intl: any) => {intl.formatMessage({ id: 'menu.cluster.replication.dashboard' })}, + path: '', + icon: 'icon-luoji', + }, + { + name: (intl: any) => {intl.formatMessage({ id: 'menu.cluster.replication.mirror-maker' })}, + path: 'mirror-maker', + icon: '#icon-luoji', + }, + ].filter((m) => m), + }, { name: 'consumer-group', path: 'consumers', diff --git a/km-console/packages/layout-clusters-fe/src/constants/reg.ts b/km-console/packages/layout-clusters-fe/src/constants/reg.ts index 0fbd11c6..7463882a 100644 --- a/km-console/packages/layout-clusters-fe/src/constants/reg.ts +++ b/km-console/packages/layout-clusters-fe/src/constants/reg.ts @@ -2,9 +2,15 @@ export const regNonnegativeInteger = /^\d+$/g; // 非负正整数 export const regOddNumber = /^\d*[13579]$/; //奇数 -export const regClusterName = /^[\u4E00-\u9FA5A-Za-z0-9\_\-\!\"\#\$\%&'()\*\+,./\:\;\<=\>?\@\[\\\]^\`\{\|\}~]*$/im; // 大、小写字母、数字、-、_ new RegExp('\[a-z0-9_-]$', 'g') +export const regClusterName = /^[\u4E00-\u9FA5A-Za-z0-9\_\-\!\#\$\%&'()\*\+,./\:\;\<=\>?\@\[\\\]^\`\{\|\}~]*$/im; // 大、小写字母、数字、-、_ new RegExp('\[a-z0-9_-]$', 'g') export const regUsername = /^[_a-zA-Z-]*$/; // 大、小写字母、数字、-、_ new RegExp('\[a-z0-9_-]$', 'g') +export const regIpAddress = /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/; +export const regIpPort = /^((6553[0-5])|(655[0-2][0-9])|(65[0-4][0-9]{2})|(6[0-4][0-9]{3})|([1-5][0-9]{4})|([0-5]{1,5})|([0-9]{1,4}))$/; +export const regIpAndPort = + /^http(s|):\/\/(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(:((6553[0-5])|(655[0-2][0-9])|(65[0-4][0-9]{2})|(6[0-4][0-9]{3})|([1-5][0-9]{4})|([0-5]{1,5})|([0-9]{1,4})))?$/; +export const regHttpOrHttpsAddress = + /^http(s|):\/\/(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/; export const regExp = /^[ ]+$/; // 不能为空 export const regNonnegativeNumber = /^[+]{0,1}(\d+)$|^[+]{0,1}(\d+\.\d+)$/; // 非负数 diff --git a/km-console/packages/layout-clusters-fe/src/index.less b/km-console/packages/layout-clusters-fe/src/index.less index f7da736e..cba2f5d2 100644 --- a/km-console/packages/layout-clusters-fe/src/index.less +++ b/km-console/packages/layout-clusters-fe/src/index.less @@ -308,11 +308,18 @@ li { align-items: center; } &-left { - &-refresh{ - font-size: 20px; - color: #74788d; - cursor: pointer; - } + &-refresh { + font-size: 20px; + color: #74788d; + cursor: pointer; + &-icon { + border-radius: 50%; + padding: 3px; + } + &-icon:hover { + background: rgba(33, 37, 41, 0.04); + } + } } &-right{ diff --git a/km-console/packages/layout-clusters-fe/src/locales/zh.tsx b/km-console/packages/layout-clusters-fe/src/locales/zh.tsx index 99c6682d..493a4bd9 100755 --- a/km-console/packages/layout-clusters-fe/src/locales/zh.tsx +++ b/km-console/packages/layout-clusters-fe/src/locales/zh.tsx @@ -47,6 +47,15 @@ export default { [`menu.${systemKey}.operation.balance`]: 'Rebalance', [`menu.${systemKey}.operation.jobs`]: 'Job', + [`menu.${systemKey}.connect`]: 'Connect', + [`menu.${systemKey}.connect.dashboard`]: 'Overview', + [`menu.${systemKey}.connect.connectors`]: 'Connectors', + [`menu.${systemKey}.connect.workers`]: 'Workers', + + [`menu.${systemKey}.replication`]: 'Replication', + [`menu.${systemKey}.replication.dashboard`]: 'Overview', + [`menu.${systemKey}.replication.mirror-maker`]: 'Mirror Makers', + [`menu.${systemKey}.acls`]: 'ACLs', [`menu.${systemKey}.jobs`]: 'Job', diff --git a/km-console/packages/layout-clusters-fe/src/pages/BrokerControllerChangeLog/index.tsx b/km-console/packages/layout-clusters-fe/src/pages/BrokerControllerChangeLog/index.tsx index 7cd85c6a..9fb63190 100644 --- a/km-console/packages/layout-clusters-fe/src/pages/BrokerControllerChangeLog/index.tsx +++ b/km-console/packages/layout-clusters-fe/src/pages/BrokerControllerChangeLog/index.tsx @@ -90,7 +90,7 @@ const ControllerChangeLogList: React.FC = (props: any) => {
-
+
{
-
+
{ diff --git a/km-console/packages/layout-clusters-fe/src/pages/Connect/AddConnector.tsx b/km-console/packages/layout-clusters-fe/src/pages/Connect/AddConnector.tsx new file mode 100644 index 00000000..8724a029 --- /dev/null +++ b/km-console/packages/layout-clusters-fe/src/pages/Connect/AddConnector.tsx @@ -0,0 +1,1171 @@ +import React, { + createContext, + createElement, + forwardRef, + useContext, + useEffect, + useImperativeHandle, + useLayoutEffect, + useRef, + useState, +} from 'react'; +import { Alert, Button, Col, Collapse, Drawer, Form, Input, InputNumber, Row, Select, Steps, Switch, Table, Utils } from 'knowdesign'; +import { FormInstance } from 'knowdesign/es/basic/form/Form'; +import SwitchTab from '@src/components/SwitchTab'; +import message from '@src/components/Message'; +import api from '@src/api'; +import { useParams } from 'react-router-dom'; +import { regClusterName } from '@src/constants/reg'; +import { IconFont } from '@knowdesign/icons'; + +const { Step } = Steps; + +export interface ConnectCluster { + id: number; + name: string; + groupName: string; + state: number; + version: string; + jmxProperties: string; + clusterUrl: string; + memberLeaderUrl: string; +} + +export interface ConnectorPlugin { + type: 'source' | 'sink'; + version: string; + className: string; + helpDocLink: string; +} + +interface ConnectorPluginConfigDefinition { + name: string; + type: string; + required: boolean; + defaultValue: string | null; + importance: string; + documentation: string; + group: string; + orderInGroup: number; + width: string; + displayName: string; + dependents: string[]; +} + +interface ConnectorPluginConfigValue { + errors: string[]; + name: string; + recommendedValues: any[]; + value: any; + visible: boolean; +} + +export interface ConnectorPluginConfig { + name: string; + errorCount: number; + groups: string[]; + configs: { + definition: ConnectorPluginConfigDefinition; + value: ConnectorPluginConfigValue; + }[]; +} + +interface FormConnectorConfigs { + pluginConfig: { [key: string]: ConnectorPluginConfigDefinition[] }; + connectorConfig?: { [key: string]: any }; +} + +interface SubFormProps { + visible: boolean; + setSubmitLoading: (loading: boolean) => void; +} + +export interface OperateInfo { + type: 'create' | 'edit'; + errors: { + [key: string]: string[]; + }; + detail?: { + connectClusterId: number; + connectorName: string; + connectorClassName: string; + connectorType: 'source' | 'sink'; + }; +} + +const existFormItems = { + basic: ['name', 'connector.class', 'tasks.max', 'key.converter', 'value.converter', 'header.converter'], + transforms: ['transforms'], + errorHandling: [ + 'errors.retry.timeout', + 'errors.retry.delay.max.ms', + 'errors.tolerance', + 'errors.log.enable', + 'errors.log.include.messages', + ], +}; + +const getExistFormItems = (type: 'source' | 'sink') => { + return [...existFormItems.basic, ...existFormItems.transforms, ...existFormItems.errorHandling, type === 'sink' ? 'topics' : ''].filter( + (k) => k + ); +}; + +const StepsFormContent = createContext< + OperateInfo & { + forms: { current: { [key: string]: FormInstance } }; + } +>({ + type: 'create', + errors: {}, + forms: { current: {} }, +}); + +function useStepForm(key: string | number) { + const { forms } = useContext(StepsFormContent); + const [form] = Form.useForm(); + let formInstace = form; + + if (forms.current[key]) { + formInstace = forms.current[key] as FormInstance; + } else { + forms.current[key] = formInstace; + } + + return [formInstace]; +} + +// 步骤一:设置插件类型 +const StepFormFirst = (props: SubFormProps) => { + const { clusterId } = useParams<{ + clusterId: string; + }>(); + const [form] = useStepForm(0); + const { type, detail } = useContext(StepsFormContent); + const isEdit = type === 'edit'; + const [connectClusters, setConnectClusters] = useState<{ label: string; value: number }[]>([]); + const [selectedConnectClusterId, setSelectedConnectClusterId] = useState(detail?.connectClusterId); + const [input, setInput] = useState(''); + const [plugins, setPlugins] = useState([]); + const [selectedPlugin, setSelectedPlugin] = useState(detail?.connectorClassName); + const [pluginType, setPluginType] = useState<'source' | 'sink'>((detail?.connectorType.toLowerCase() as 'source' | 'sink') || 'source'); + const [loading, setLoading] = useState(false); + + const getConnectClusters = () => { + return Utils.request(api.getConnectClusters(clusterId)).then((res: ConnectCluster[]) => { + const arr = res.map(({ name, id }) => ({ + label: name || '-', + value: id, + })); + setConnectClusters(arr); + form.setFieldsValue({ + connectClusters: arr, + }); + }); + }; + + const getConnectorPlugins = () => { + setLoading(true); + return Utils.request(api.getConnectorPlugins(selectedConnectClusterId)) + .then((res: ConnectorPlugin[]) => { + setPlugins(res); + }) + .finally(() => setLoading(false)); + }; + + const getConnectorPluginConfig = (pluginName: string) => { + props.setSubmitLoading(true); + + Promise.all( + [ + Utils.request(api.getConnectorPluginConfig(selectedConnectClusterId, pluginName)), + isEdit ? Utils.request(api.getCurPluginConfig(selectedConnectClusterId, detail.connectorName)) : undefined, + ].filter((r) => r) + ) + .then((res: [ConnectorPluginConfig, { [key: string]: any }]) => { + const [pluginConfig, connectorConfigs] = res; + + // 格式化插件配置 + const result: FormConnectorConfigs = { + pluginConfig: {}, + }; + pluginConfig.configs.forEach(({ definition }) => { + if (!getExistFormItems(pluginType).includes(definition.name)) { + const pluginConfigs = result.pluginConfig; + const group = definition.group || 'Others'; + pluginConfigs[group] ? pluginConfigs[group].push(definition) : (pluginConfigs[group] = [definition]); + } + }); + Object.values(result.pluginConfig).forEach((arr) => arr.sort((a, b) => a.orderInGroup - b.orderInGroup)); + + // 加入当前 connector 的配置 + if (isEdit) { + result.connectorConfig = connectorConfigs; + } + + Object.keys(result).length && + form.setFieldsValue({ + configs: result, + }); + }) + .finally(() => props.setSubmitLoading(false)); + }; + + useEffect(() => { + if (selectedPlugin) { + getConnectorPluginConfig(selectedPlugin); + } + }, [selectedPlugin]); + + useEffect(() => { + if (selectedConnectClusterId) { + getConnectorPlugins(); + } + }, [selectedConnectClusterId]); + + useEffect(() => { + getConnectClusters(); + }, []); + + return ( +
+
+ + { + setInput(e.target.value); + }} + /> +
+
{ + return ( + + {value} + {record?.helpDocLink && ( + window.open(record.helpDocLink)} + > + help + + )} + + ); + }, + }, + ]} + dataSource={plugins.filter((plugin) => plugin.type === pluginType && (!input || plugin.className.includes(input)))} + pagination={false} + rowSelection={{ + type: 'radio', + preserveSelectedRowKeys: false, + selectedRowKeys: [selectedPlugin], + getCheckboxProps: (record) => { + return { + disabled: isEdit && record.className !== selectedPlugin, + }; + }, + onChange: (keys) => { + setSelectedPlugin(keys[0] as string); + form.setFieldsValue({ + connectorClassName: keys[0], + }); + }, + }} + /> +
+ + + { + if (!value) { + return Promise.reject('请选择 Connector 插件'); + } + return Promise.resolve(); + }, + }, + ]} + /> + { + if (!form.getFieldValue('connectorClassName')) { + return Promise.resolve(true); + } + if (!value) { + return Promise.reject(isEdit ? '插件或 connector 配置获取失败' : '插件配置获取失败,请重新选择插件'); + } + return Promise.resolve(); + }, + }, + ]} + /> +
+ + ) : ( + <> + ); + }} + + + + ); +}; + +// 步骤二:基础设置 +const StepFormSecond = (props: SubFormProps) => { + const { clusterId } = useParams<{ + clusterId: string; + }>(); + const [prevForm] = useStepForm(0); + const [form] = useStepForm(1); + const [topicData, setTopicData] = useState([]); + const { type, detail, errors } = useContext(StepsFormContent); + const isEdit = type === 'edit'; + const connectorConfig = (prevForm.getFieldValue('configs') as FormConnectorConfigs)?.connectorConfig; + + const getTopicList = () => { + Utils.request(api.getTopicMetaList(Number(clusterId)), { + method: 'GET', + }).then((res: any) => { + const dataDe = res || []; + const dataHandle = dataDe.map((item: any) => { + return { + ...item, + key: item.topicName, + label: item.topicName, + value: item.topicName, + }; + }); + setTopicData(dataHandle); + }); + }; + + useEffect(() => { + getTopicList(); + }, []); + + useEffect(() => { + connectorConfig && + form.setFieldsValue({ + topics: + typeof connectorConfig['topics'] === 'string' ? connectorConfig['topics'].split(',').map((i: string) => i.trim()) : undefined, + }); + }, [topicData, connectorConfig]); + + useEffect(() => { + const curConfig = connectorConfig || {}; + form.setFieldsValue({ + 'connector.class': curConfig['connector.class'] || prevForm.getFieldValue('connectorClassName'), + 'tasks.max': curConfig['tasks.max'] || 1, + 'key.converter': curConfig['key.converter'], + 'value.converter': curConfig['value.converter'], + 'header.converter': curConfig['header.converter'], + }); + }, [connectorConfig]); + + useEffect(() => { + form.setFieldsValue({ + 'connector.class': prevForm.getFieldValue('connectorClassName'), + }); + }, [prevForm.getFieldValue('connectorClassName')]); + + useEffect(() => { + form.setFields([ + ...existFormItems.basic.map((name) => ({ name, errors: errors[name] || [] })), + { name: 'topics', errors: prevForm.getFieldValue('connectorType') === 'sink' ? errors['topics'] || [] : [] }, + ]); + }, [errors]); + + return ( +
+
+ 64) { + return Promise.reject('Connector 名称长度限制在1~128字符'); + } + if (!new RegExp(regClusterName).test(value)) { + return Promise.reject( + "Connector 名称支持中英文、数字、特殊字符 ! # $ % & ' ( ) * + , - . / : ; < = > ? @ [ ] ^ _ ` { | } ~" + ); + } + return Utils.request(api.isConnectorExist(prevForm.getFieldValue('connectClusterId'), value)).then( + (res: any) => { + const data = res || {}; + return data?.exist ? Promise.reject('Connector 名称重复') : Promise.resolve(); + }, + () => Promise.reject('连接超时! 请重试或检查服务') + ); + }, + }, + ]} + > + + + +
+ Connector 插件类型: {form.getFieldValue('connector.class') || '-'} +
+
+ + + + value || null} + > + + + value || null} + > + + + value || null} + > + + + {/* Connector 类型为 Sink 时才有 */} + {prevForm.getFieldValue('connectorType') === 'sink' && ( + + */} + + ) : type.toUpperCase() === 'INT' || type.toUpperCase() === 'LONG' ? ( + + ) : type.toUpperCase() === 'BOOLEAN' ? ( + + ) : ( + + )} + + ); + })} + + ); + })} + + )} + +
+ ); +}; + +const steps = [ + { + title: '设置插件类型', + content: StepFormFirst, + }, + { + title: '基础设置', + content: StepFormSecond, + }, + { + title: 'Transforms', + content: StepFormThird, + }, + { + title: 'Error Handling', + content: StepFormForth, + }, + { + title: '高级设置', + content: StepFormFifth, + }, +]; + +export default forwardRef( + ( + props: { + refresh: () => void; + }, + ref + ) => { + const [visible, setVisible] = useState(false); + const [jsonRef, setJsonRef] = useState({}); + const [currentStep, setCurrentStep] = useState(0); + const [stepInitState, setStepInitState] = useState([1]); + const [submitLoading, setSubmitLoading] = useState(false); + const [operateInfo, setOperateInfo] = useState({ + type: undefined, + errors: {}, + }); + const stepsFormRef = useRef<{ + [key: string]: FormInstance; + }>({}); + + const onOpen = (type: OperateInfo['type'], jsonRef: any, detail?: OperateInfo['detail']) => { + if (type === 'create') { + setStepInitState([1]); + } else { + setStepInitState([1, 2, 3, 4]); + } + setOperateInfo({ + type, + detail, + errors: {}, + }); + setJsonRef(jsonRef); + setVisible(true); + }; + + const onClose = () => { + Object.values(stepsFormRef.current).forEach((form) => { + form.resetFields(); + }); + stepsFormRef.current = {}; + setVisible(false); + setCurrentStep(0); + setStepInitState([]); + }; + + const turnTo = (jumpStep: number) => { + if (submitLoading) { + message.warning('加载中,请稍后重试'); + return; + } + if (jumpStep > currentStep) { + const prevInit = stepInitState[jumpStep - 1]; + if (!prevInit) { + message.warning('请按照顺序填写'); + } else { + stepsFormRef.current[currentStep].validateFields().then(() => { + const prevStep = jumpStep - 1; + if (currentStep < prevStep) { + stepsFormRef.current[prevStep] + .validateFields() + .then(() => { + setStepInitState((prev) => { + const cur = [...prev]; + cur[jumpStep] = 1; + return cur; + }); + setCurrentStep(jumpStep); + }) + .catch(() => { + setCurrentStep(prevStep); + }); + } else { + setStepInitState((prev) => { + const cur = [...prev]; + cur[jumpStep] = 1; + return cur; + }); + setCurrentStep(jumpStep); + } + }); + } + } else { + setCurrentStep(jumpStep); + } + }; + + // 校验所有表单 + const validateForms = ( + callback: (info: { + success?: { + connectClusterId: number; + connectorName: string; + configs: { + [key: string]: any; + }; + }; + error?: any; + }) => void + ) => { + const promises: Promise[] = []; + Object.values(stepsFormRef.current).forEach((form, i) => { + const promise = form + .validateFields() + .then((res) => { + return res; + }) + .catch(() => { + return Promise.reject(i); + }); + promises.push(promise); + }); + + Promise.all(promises).then( + (res) => { + const result = { + ...res[1], + ...res[3], + ...res[4], + }; + // topics 配置格式化 + res[1].topics && (result.topics = (res[1].topics as string[]).join(', ')); + // transforms 配置格式化 + res[2].transforms && + (res[2].transforms as string) + .split('\n') + .filter((l) => l) + .forEach((l) => { + const [k, ...v] = l.split('='); + result[k] = v.join('='); + }); + callback({ + success: { + connectClusterId: res[0].connectClusterId, + connectorName: result['name'], + configs: result, + }, + }); + }, + (error) => { + callback({ + error, + }); + } + ); + }; + + const toJsonMode = () => { + validateForms((info) => { + if (info.error) { + message.warning('校验失败,请检查填写内容'); + setCurrentStep(info.error); + } else { + let curClusterName = ''; + stepsFormRef.current[0].getFieldValue('connectClusters').some((cluster: { label: string; value: number }) => { + if (cluster.value === info.success.connectClusterId) { + curClusterName = cluster.label; + } + }); + (jsonRef as any)?.onOpen(operateInfo.type, curClusterName, info.success.configs); + onClose(); + } + }); + }; + + const onSubmit = () => { + validateForms((info) => { + if (info.error) { + message.warning('校验失败,请检查填写内容'); + setCurrentStep(info.error); + } else { + setSubmitLoading(true); + Object.entries(info.success.configs).forEach(([key, val]) => { + if (val === null) { + delete info.success.configs[key]; + } + }); + Utils.put(api.validateConnectorConfig, info.success).then( + (res: ConnectorPluginConfig) => { + if (res) { + if (res?.errorCount > 0) { + const errors: OperateInfo['errors'] = {}; + res?.configs + ?.filter((config) => config.value.errors.length !== 0) + .forEach(({ value }) => { + if (value.name.includes('transforms.')) { + errors['transforms'] = (errors['transforms'] || []).concat(value.errors); + } else { + errors[value.name] = value.errors; + } + }); + setOperateInfo((cur) => ({ + ...cur, + errors, + })); + + // 步骤跳转 + const items = getExistFormItems(stepsFormRef.current[0].getFieldValue('connectorType')); + const keys = Object.keys(errors).filter((key) => items.includes(key)); + let jumpStep = 4; + keys.forEach((key) => { + Object.values(existFormItems).some((items, i) => { + if (items.includes(key)) { + jumpStep > i + 1 && (jumpStep = i + 1); + return true; + } + return false; + }); + }); + setCurrentStep(jumpStep); + setSubmitLoading(false); + message.warning('字段校验失败,请检查'); + } else { + if (operateInfo.type === 'create') { + Utils.post(api.connectorsOperates, info.success) + .then(() => { + message.success('新建成功'); + onClose(); + props?.refresh(); + }) + .finally(() => setSubmitLoading(false)); + } else { + Utils.put(api.updateConnectorConfig, info.success) + .then(() => { + message.success('编辑成功'); + props?.refresh(); + onClose(); + }) + .finally(() => setSubmitLoading(false)); + } + } + } else { + setSubmitLoading(false); + message.error('接口校验出错,请重新提交'); + } + }, + () => setSubmitLoading(false) + ); + } + }); + }; + + useImperativeHandle(ref, () => ({ + onOpen, + onClose, + })); + + return ( + + {operateInfo.type && visible && ( + <> + turnTo(cur)}> + {steps.map(({ title }) => ( + + ))} + +
+ + {steps.map((step, i) => { + return createElement(step.content, { + visible: i === currentStep, + setSubmitLoading, + }); + })} + + {currentStep === steps.length - 1 && ( + + 如果你想自定义更多配置,可以点击 + + 继续补充 + + } + /> + )} +
+ {currentStep > 0 && ( + + )} + {currentStep < steps.length - 1 && ( + + )} + {currentStep === steps.length - 1 && ( + + )} +
+
+ + )} +
+ ); + } +); diff --git a/km-console/packages/layout-clusters-fe/src/pages/Connect/AddConnectorUseJSON.tsx b/km-console/packages/layout-clusters-fe/src/pages/Connect/AddConnectorUseJSON.tsx new file mode 100644 index 00000000..b9351346 --- /dev/null +++ b/km-console/packages/layout-clusters-fe/src/pages/Connect/AddConnectorUseJSON.tsx @@ -0,0 +1,262 @@ +import api from '@src/api'; +import CodeMirrorFormItem from '@src/components/CodeMirrorFormItem'; +import customMessage from '@src/components/Message'; +import { Button, Divider, Drawer, Form, message, Space, Utils } from 'knowdesign'; +import React, { forwardRef, useEffect, useImperativeHandle, useState } from 'react'; +import { useParams } from 'react-router-dom'; +import { ConnectCluster, ConnectorPlugin, ConnectorPluginConfig, OperateInfo } from './AddConnector'; + +const PLACEHOLDER = `配置格式如下 + +{ + "connectClusterName": "", // Connect Cluster 名称 + "configs": { // 具体配置项 + "name": "", + "connector.class": "", + "tasks.max": 1, + ... + } +}`; + +export default forwardRef((props: any, ref) => { + const { clusterId } = useParams<{ + clusterId: string; + }>(); + const [visible, setVisible] = useState(false); + const [form] = Form.useForm(); + const [type, setType] = useState('create'); + const [connectClusters, setConnectClusters] = useState<{ label: string; value: number }[]>([]); + const [defaultConfigs, setDefaultConfigs] = useState<{ [key: string]: any }>({}); + const [submitLoading, setSubmitLoading] = useState(false); + + const getConnectClusters = () => { + return Utils.request(api.getConnectClusters(clusterId)).then((res: ConnectCluster[]) => { + setConnectClusters( + res.map(({ name, id }) => ({ + label: name || '-', + value: id, + })) + ); + }); + }; + + const onOpen = (type: 'create' | 'edit', connectClusterName?: string, defaultConfigs?: { [key: string]: any }) => { + if (defaultConfigs) { + setDefaultConfigs({ ...defaultConfigs, connectClusterName }); + form.setFieldsValue({ + configs: JSON.stringify( + { + connectClusterName, + configs: defaultConfigs, + }, + null, + 2 + ), + }); + } + setType(type); + setVisible(true); + }; + + const onSubmit = () => { + setSubmitLoading(true); + form.validateFields().then( + (data) => { + const postData = JSON.parse(data.configs); + postData.connectorName = postData.configs.name; + postData.connectClusterId = connectClusters.find((cluster) => cluster.label === postData.connectClusterName).value; + delete postData.connectClusterName; + + Object.entries(postData.configs).forEach(([key, val]) => { + if (val === null) { + delete postData.configs[key]; + } + }); + Utils.put(api.validateConnectorConfig, postData).then( + (res: ConnectorPluginConfig) => { + if (res) { + if (res?.errorCount > 0) { + const errors: OperateInfo['errors'] = {}; + res?.configs + ?.filter((config) => config.value.errors.length !== 0) + .forEach(({ value }) => { + if (value.name.includes('transforms.')) { + errors['transforms'] = (errors['transforms'] || []).concat(value.errors); + } else { + errors[value.name] = value.errors; + } + }); + form.setFields([ + { + name: 'configs', + errors: Object.entries(errors).map(([name, errorArr]) => `${name}: ${errorArr.join('; ')}\n`), + }, + ]); + setSubmitLoading(false); + } else { + if (type === 'create') { + Utils.post(api.connectorsOperates, postData) + .then(() => { + customMessage.success('新建成功'); + onClose(); + props?.refresh(); + }) + .finally(() => setSubmitLoading(false)); + } else { + Utils.put(api.updateConnectorConfig, postData) + .then(() => { + customMessage.success('编辑成功'); + props?.refresh(); + onClose(); + }) + .finally(() => setSubmitLoading(false)); + } + } + } else { + setSubmitLoading(false); + message.error('接口校验出错,请重新提交'); + } + }, + () => setSubmitLoading(false) + ); + }, + () => setSubmitLoading(false) + ); + }; + + const onClose = () => { + setVisible(false); + form.resetFields(); + }; + + useEffect(() => { + getConnectClusters(); + }, []); + + useImperativeHandle(ref, () => ({ + onOpen, + onClose, + })); + + return ( + + + + + + + + } + > +
+ cluster.label === v.connectClusterName); + if (!targetConnectCluster) { + return Promise.reject('connectClusterName 不存在,请检查'); + } else { + connectClusterId = targetConnectCluster.value; + } + } + } + + if (!v.configs || typeof v.configs !== 'object') { + return Promise.reject('内容缺少 configs 字段或字段格式错误'); + } else { + // 校验 connectorName 字段 + if (!v.configs.name) { + return Promise.reject('configs 字段下缺少 name 项'); + } else { + if (type === 'edit' && v.configs.name !== defaultConfigs.name) { + return Promise.reject('编辑模式下不允许修改 name 字段'); + } + } + if (!v.configs['connector.class']) { + return Promise.reject('configs 字段下缺少 connector.class 项'); + } else if (type === 'edit' && v.configs['connector.class'] !== defaultConfigs['connector.class']) { + return Promise.reject('编辑模式下不允许修改 connector.class 字段'); + } + } + + if (type === 'create') { + // 异步校验 connector 名称是否重复 以及 className 是否存在 + return Promise.all([ + Utils.request(api.isConnectorExist(connectClusterId, v.configs.name)), + Utils.request(api.getConnectorPlugins(connectClusterId)), + ]).then( + ([data, plugins]: [any, ConnectorPlugin[]]) => { + return data?.exist + ? Promise.reject('name 与已有 Connector 重复') + : plugins.every((plugin) => plugin.className !== v.configs['connector.class']) + ? Promise.reject('该 connectCluster 下不存在 connector.class 项配置的插件') + : Promise.resolve(); + }, + () => { + return Promise.reject('接口校验出错,请重试'); + } + ); + } else { + return Promise.resolve(); + } + } catch (e) { + return Promise.reject('输入内容必须为 JSON'); + } + }, + }, + ]} + > + {visible && ( +
+ { + form.setFieldsValue({ configs }); + }} + /> +
+ )} +
+ +
+ ); +}); diff --git a/km-console/packages/layout-clusters-fe/src/pages/Connect/Delete.tsx b/km-console/packages/layout-clusters-fe/src/pages/Connect/Delete.tsx new file mode 100644 index 00000000..ef6b58fe --- /dev/null +++ b/km-console/packages/layout-clusters-fe/src/pages/Connect/Delete.tsx @@ -0,0 +1,99 @@ +import React, { useState } from 'react'; +import { useParams } from 'react-router-dom'; +import { Button, Form, Input, Modal, Utils } from 'knowdesign'; +import notification from '@src/components/Notification'; +import { IconFont } from '@knowdesign/icons'; +import Api from '@src/api/index'; + +// eslint-disable-next-line react/display-name +const DeleteConnector = (props: { record: any; onConfirm?: () => void }) => { + const { record, onConfirm } = props; + const [form] = Form.useForm(); + const [delDialogVisible, setDelDialogVisble] = useState(false); + const handleDelOk = () => { + form.validateFields().then((e) => { + const formVal = form.getFieldsValue(); + formVal.connectClusterId = Number(record.connectClusterId); + Utils.delete(Api.connectorsOperates, { data: formVal }).then((res: any) => { + if (res === null) { + notification.success({ + message: '删除成功', + }); + setDelDialogVisble(false); + onConfirm && onConfirm(); + } else { + notification.error({ + message: '删除失败', + }); + } + }); + }); + }; + return ( + <> + + { + setDelDialogVisble(false); + }} + okText="删除" + okButtonProps={{ + danger: true, + size: 'small', + style: { + paddingLeft: '16px', + paddingRight: '16px', + }, + }} + cancelButtonProps={{ + size: 'small', + style: { + paddingLeft: '16px', + paddingRight: '16px', + }, + }} + > +
+ {record.connectorName} + ({ + validator(_, value) { + if (!value) { + return Promise.reject(new Error('请输入ConnectorName名称')); + } else if (value !== record.connectorName) { + return Promise.reject(new Error('请输入正确的ConnectorName名称')); + } + return Promise.resolve(); + }, + }), + ]} + > + + + +
+ + ); +}; + +export default DeleteConnector; diff --git a/km-console/packages/layout-clusters-fe/src/pages/Connect/Detail.tsx b/km-console/packages/layout-clusters-fe/src/pages/Connect/Detail.tsx new file mode 100644 index 00000000..d3f6b42e --- /dev/null +++ b/km-console/packages/layout-clusters-fe/src/pages/Connect/Detail.tsx @@ -0,0 +1,111 @@ +import React, { useState, useEffect } from 'react'; +import { Drawer, Utils, AppContainer, ProTable } from 'knowdesign'; +import API from '@src/api'; +import ConnectDetailCard from '@src/components/CardBar/ConnectDetailCard'; +import { defaultPagination, getConnectorsDetailColumns } from './config'; +import notification from '@src/components/Notification'; +import './index.less'; + +const prefix = 'connect-detail'; +const { request } = Utils; +const ConnectorDetail = (props: any) => { + const { visible, setVisible, record } = props; + const [global] = AppContainer.useGlobalValue(); + const [loading, setLoading] = useState(false); + const [data, setData] = useState([]); + const [pagination, setPagination] = useState(defaultPagination); + const onClose = () => { + setVisible(false); + setPagination(defaultPagination); + // clean hash + }; + + // 请求接口获取数据 + const genData = async () => { + if (global?.clusterInfo?.id === undefined) return; + + setLoading(true); + + request(API.getConnectDetailTasks(record.connectorName, record.connectClusterId)) + .then((res: any) => { + setData(res || []); + setLoading(false); + }) + .catch((err) => { + setLoading(false); + }); + }; + + const onTableChange = (pagination: any, filters: any, sorter: any) => { + setPagination(pagination); + }; + + const optionFn: any = (taskId: any) => { + const params = { + action: 'restart', + connectClusterId: record?.connectClusterId, + connectorName: record?.connectorName, + taskId, + }; + + request(API.optionTasks(), { method: 'PUT', data: params }).then((res: any) => { + if (res === null) { + notification.success({ + message: `任务重试成功`, + }); + genData(); + } else { + notification.error({ + message: `任务重试失败`, + }); + } + }); + }; + + const retryOption = Utils.useDebounce(optionFn, 500); + + useEffect(() => { + visible && record && genData(); + }, [visible]); + + return ( + + {record.connectorName ?? '-'} + + } + width={1080} + placement="right" + onClose={onClose} + visible={visible} + className={`${prefix}-drawer`} + destroyOnClose + maskClosable={false} + > + +
Tasks
+ + {/* */} +
+ ); +}; + +export default ConnectorDetail; diff --git a/km-console/packages/layout-clusters-fe/src/pages/Connect/HasConnector.tsx b/km-console/packages/layout-clusters-fe/src/pages/Connect/HasConnector.tsx new file mode 100644 index 00000000..d2deaeea --- /dev/null +++ b/km-console/packages/layout-clusters-fe/src/pages/Connect/HasConnector.tsx @@ -0,0 +1,51 @@ +import React, { useLayoutEffect, useState } from 'react'; +import api from '@src/api'; +import { Spin, Utils } from 'knowdesign'; +import { useParams } from 'react-router-dom'; +import NodataImg from '@src/assets/no-data.png'; + +interface Props { + children: any; +} + +const NoConnector = () => { + return ( +
+ + 暂无数据,请先接入 Connect 集群 +
+ ); +}; + +export default (props: Props) => { + const { clusterId } = useParams<{ + clusterId: string; + }>(); + const [loading, setLoading] = useState(true); + const [disabled, setDisabled] = useState(true); + + useLayoutEffect(() => { + Utils.request(api.getConnectClusters(clusterId)) + .then((res: any[]) => { + res?.length && setDisabled(false); + }) + .finally(() => setLoading(false)); + }, []); + + return disabled ? ( + {loading ?
: } + ) : ( + props.children + ); +}; diff --git a/km-console/packages/layout-clusters-fe/src/pages/Connect/Workers.tsx b/km-console/packages/layout-clusters-fe/src/pages/Connect/Workers.tsx new file mode 100644 index 00000000..1ac89fb6 --- /dev/null +++ b/km-console/packages/layout-clusters-fe/src/pages/Connect/Workers.tsx @@ -0,0 +1,120 @@ +import React, { useState, useEffect, memo } from 'react'; +import { useParams, useHistory, useLocation } from 'react-router-dom'; +import { ProTable, Button, Utils, AppContainer, SearchInput } from 'knowdesign'; +import { IconFont } from '@knowdesign/icons'; +import API from '../../api'; +import { getWorkersColumns, defaultPagination } from './config'; +import { tableHeaderPrefix } from '@src/constants/common'; +import ConnectCard from '@src/components/CardBar/ConnectCard'; +import DBreadcrumb from 'knowdesign/es/extend/d-breadcrumb'; +import './index.less'; +import HasConnector from './HasConnector'; +const { request } = Utils; + +const Workers: React.FC = () => { + const [global] = AppContainer.useGlobalValue(); + const [loading, setLoading] = useState(false); + const [data, setData] = useState([]); + const [searchKeywords, setSearchKeywords] = useState(''); + const [pagination, setPagination] = useState(defaultPagination); + + // 请求接口获取数据 + const genData = async ({ pageNo, pageSize, filters, sorter }: any) => { + if (global?.clusterInfo?.id === undefined) return; + + setLoading(true); + const params = { + searchKeywords: searchKeywords.slice(0, 128), + pageNo, + pageSize, + }; + + request(API.getWorkersList(global?.clusterInfo?.id), { params }) + .then((res: any) => { + setPagination({ + current: res.pagination?.pageNo, + pageSize: res.pagination?.pageSize, + total: res.pagination?.total, + }); + setData(res?.bizData || []); + setLoading(false); + }) + .catch((err) => { + setLoading(false); + }); + }; + + const onTableChange = (pagination: any, filters: any, sorter: any) => { + genData({ pageNo: pagination.current, pageSize: pagination.pageSize, filters, sorter }); + }; + + useEffect(() => { + genData({ + pageNo: 1, + pageSize: pagination.pageSize, + }); + }, [searchKeywords]); + + return ( + <> +
+ +
+ + <> +
+ +
+
+
+
+
genData({ pageNo: pagination.current, pageSize: pagination.pageSize })} + > + +
+
+
+ +
+
+ +
+ +
+ + ); +}; + +export default Workers; diff --git a/km-console/packages/layout-clusters-fe/src/pages/Connect/config.tsx b/km-console/packages/layout-clusters-fe/src/pages/Connect/config.tsx new file mode 100644 index 00000000..67691d74 --- /dev/null +++ b/km-console/packages/layout-clusters-fe/src/pages/Connect/config.tsx @@ -0,0 +1,365 @@ +import SmallChart from '@src/components/SmallChart'; +import TagsWithHide from '@src/components/TagsWithHide'; +import { Button, Tag, Tooltip, Utils, Popconfirm } from 'knowdesign'; +import React from 'react'; +import Delete from './Delete'; +export const defaultPagination = { + current: 1, + pageSize: 10, + position: 'bottomRight', + showSizeChanger: true, + pageSizeOptions: ['10', '20', '50', '100', '200', '500'], +}; + +export const optionType: { [name: string]: string } = { + ['stop']: '暂停', + ['restart']: '重启', + ['resume']: '继续', +}; + +export const stateEnum: any = { + ['UNASSIGNED']: { + // 未分配 + name: 'Unassigned', + color: '#556EE6', + bgColor: '#EBEEFA', + }, + ['RUNNING']: { + // 运行 + name: 'Running', + color: '#00C0A2', + bgColor: 'rgba(0,192,162,0.10)', + }, + ['PAUSED']: { + // 暂停 + name: 'Paused', + color: '#495057', + bgColor: '#ECECF6', + }, + ['FAILED']: { + // 失败 + name: 'Failed', + color: '#F58342', + bgColor: '#fef3e5', + }, + ['DESTROYED']: { + // 销毁 + name: 'Destroyed', + color: '#FF7066', + bgColor: '#fdefee', + }, + ['RESTARTING']: { + // 重新启动 + name: 'Restarting', + color: '#3991FF', + bgColor: '#e9f5ff', + }, +}; + +const calcCurValue = (record: any, metricName: string) => { + // const item = (record.metricPoints || []).find((item: any) => item.metricName === metricName); + // return item?.value || ''; + // TODO 替换record + const orgVal = record?.latestMetrics?.metrics?.[metricName]; + if (orgVal !== undefined) { + if (metricName === 'TotalRecordErrors') { + return Math.round(orgVal).toLocaleString(); + } else { + return Number(Utils.formatAssignSize(orgVal, 'KB', orgVal > 1000 ? 2 : 3)).toLocaleString(); + // return Utils.formatAssignSize(orgVal, 'KB'); + } + } + return '-'; + // return orgVal !== undefined ? (metricName !== 'HealthScore' ? formatAssignSize(orgVal, 'KB') : orgVal) : '-'; +}; + +const renderLine = (record: any, metricName: string) => { + const points = record.metricLines?.find((item: any) => item.metricName === metricName)?.metricPoints || []; + return points.length ? ( +
+ ({ time: item.timeStamp, value: item.value })), + }} + /> + {calcCurValue(record, metricName)} +
+ ) : ( + {calcCurValue(record, metricName)} + ); +}; + +export const getConnectorsColumns = (arg?: any) => { + const columns = [ + { + title: 'Connector Name', + dataIndex: 'connectorName', + key: 'connectorName', + width: 160, + fixed: 'left', + lineClampOne: true, + render: (t: string, r: any) => { + return t ? ( + <> + + { + arg.getDetailInfo(r); + }} + > + {t} + + + + ) : ( + '-' + ); + }, + }, + { + title: 'Connect集群', + dataIndex: 'connectClusterName', + key: 'connectClusterName', + width: 200, + lineClampOne: true, + needTooltip: true, + // render: (t: string, r: any) => { + // return ( + // + // {t} + // {r?.status ? Live : Down} + // + // ); + // }, + }, + + { + title: 'State', + dataIndex: 'state', + key: 'state', + width: 120, + render: (t: string, r: any) => { + return t ? ( + + {stateEnum[t]?.name} + + ) : ( + '-' + ); + }, + }, + { + title: 'Class', + dataIndex: 'connectorClassName', + key: 'connectorClassName', + width: 150, + lineClampOne: true, + needTooltip: true, + }, + { + title: 'Type', + dataIndex: 'connectorType', + key: 'connectorType', + width: 100, + render: (value: any, record: any) => Utils.firstCharUppercase(value), + }, + { + title: 'Tasks', + dataIndex: 'taskCount', + key: 'taskCount', + width: 100, + }, + { + title: '消息读取速率(KB/s)', + dataIndex: 'readRate', + key: 'readRate', + sorter: true, + width: 170, + render: (value: any, record: any) => + renderLine(record, record.connectorType === 'SINK' ? 'SinkRecordReadRate' : 'SourceRecordPollRate'), + }, + { + title: '消息写入速率(KB/s)', + dataIndex: 'writeRate', + key: 'writeRate', + sorter: true, + width: 170, + render: (value: any, record: any) => + renderLine(record, record.connectorType === 'SINK' ? 'SinkRecordSendRate' : 'SourceRecordWriteRate'), + }, + { + title: '消息处理错误次数(次)', + dataIndex: 'recordErrors', + key: 'recordErrors', + sorter: true, + width: 170, + render: (value: any, record: any) => renderLine(record, 'TotalRecordErrors'), + }, + { + title: 'Topics', + dataIndex: 'topicNameList', + key: 'topicNameList', + width: 200, + render(t: any, r: any) { + return t && t.length > 0 ? `共有${num}个`} /> : '-'; + }, + }, + { + title: '操作', + dataIndex: 'options', + key: 'options', + width: 200, + filterTitle: true, + fixed: 'right', + // eslint-disable-next-line react/display-name + render: (_t: any, r: any) => { + return ( +
+ arg?.optionConnect(r, 'restart')} + // onCancel={cancel} + okText="是" + cancelText="否" + overlayClassName="connect-popconfirm" + > + + + + {(r.state === 'RUNNING' || r.state === 'PAUSED') && ( + arg?.optionConnect(r, r.state === 'RUNNING' ? 'stop' : 'resume')} + // onCancel={cancel} + okText="是" + cancelText="否" + overlayClassName="connect-popconfirm" + > + + + )} + + + +
+ ); + }, + }, + ]; + return columns; +}; + +// Workers +export const getWorkersColumns = (arg?: any) => { + const columns = [ + { + title: 'Worker Host', + dataIndex: 'workerHost', + key: 'workerHost', + width: 200, + }, + { + title: '所属集群', + dataIndex: 'connectClusterName', + key: 'connectClusterName', + width: 200, + }, + { + title: 'Connectors', + dataIndex: 'connectorCount', + key: 'connectorCount', + width: 200, + }, + { + title: 'Tasks', + dataIndex: 'taskCount', + key: 'taskCount', + width: 200, + }, + ]; + return columns; +}; + +// Detail +export const getConnectorsDetailColumns = (arg?: any) => { + const columns = [ + { + title: 'Task ID', + dataIndex: 'taskId', + key: 'taskId', + width: 240, + render: (t: any, r: any) => { + return ( + + {t} + { + + {Utils.firstCharUppercase(r?.state as string)} + + } + + ); + }, + }, + { + title: 'Worker', + dataIndex: 'workerId', + key: 'workerId', + width: 240, + }, + { + title: '错误原因', + dataIndex: 'trace', + key: 'trace', + width: 400, + needTooltip: true, + lineClampOne: true, + }, + { + title: '操作', + dataIndex: 'role', + key: 'role', + width: 100, + render: (_t: any, r: any) => { + return ( +
+ arg?.retryOption(r.taskId)} + // onCancel={cancel} + okText="是" + cancelText="否" + overlayClassName="connect-popconfirm" + > + 重试 + +
+ ); + }, + }, + ]; + return columns; +}; diff --git a/km-console/packages/layout-clusters-fe/src/pages/Connect/index.less b/km-console/packages/layout-clusters-fe/src/pages/Connect/index.less new file mode 100644 index 00000000..c4e23094 --- /dev/null +++ b/km-console/packages/layout-clusters-fe/src/pages/Connect/index.less @@ -0,0 +1,193 @@ +// connect列表 图表 +.metric-data-wrap { + // display: flex; + // align-items: center; + width: 100%; + .cur-val { + display: block; + text-align: right; + } + .dcloud-spin-nested-loading { + flex: 1; + } +} + +// 新增按钮 +.add-connect { + .dcloud-btn-primary:hover, + .dcloud-btn-primary:focus { + // 可以控制新增按钮的hover和focus的样式 + // background: #556ee6; + // border-color: #556ee6; + } + &-btn { + border-top-right-radius: 0 !important; + border-bottom-right-radius: 0 !important; + border-right: none; + } + &-dropdown-menu { + .dcloud-dropdown-menu { + border-radius: 8px; + &-item { + font-size: 13px; + } + } + } + &-json { + padding: 8px 12px !important; + border-top-left-radius: 0 !important; + border-bottom-left-radius: 0 !important; + border-left: none; + } +} + +// connect详情 +.connect-detail-drawer { + .card-bar-container { + background: rgba(86, 110, 230, 0.04) !important; + + .card-bar-colunms { + background-color: rgba(86, 110, 230, 0); + } + } + &-title { + margin: 20px 0 8px; + font-family: @font-family-bold; + font-size: 16px; + font-weight: 500; + } +} + +// 删除 +.del-connect-modal { + .tip-info { + display: flex; + color: #592d00; + padding: 6px 14px; + font-size: 13px; + background: #fffae0; + border-radius: 4px; + .anticon { + color: #ffc300; + margin-right: 4px; + margin-top: 3px; + } + .test-right-away { + color: #556ee6; + cursor: pointer; + } + .dcloud-alert-content { + flex: none; + } + } +} + +// 重启、继续/暂停 气泡卡片 +.connect-popconfirm { + .dcloud-popover-inner-content { + padding: 6px 16px; + } + .dcloud-popover-inner { + border-radius: 8px; + } + .dcloud-popover-message, + .dcloud-btn { + font-size: 12px !important; + } +} + +.operate-connector-drawer { + .connector-plugin-desc { + font-size: 13px; + .connector-plugin-title { + font-family: @font-family-bold; + } + } + .dcloud-collapse.add-connector-collapse { + .add-connector-collapse-panel, + .add-connector-collapse-panel:last-child { + margin-bottom: 8px; + overflow: hidden; + background: #f8f9fa; + border: 0px; + border-radius: 8px; + .dcloud-collapse-header { + padding: 8px 12px; + font-size: 14px; + color: #495057; + .dcloud-collapse-arrow { + margin-right: 8px !important; + font-size: 10px; + } + } + &:hover .dcloud-collapse-extra { + opacity: 1; + } + &:not(.dcloud-collapse-item-active) { + .dcloud-collapse-header:hover { + background: #f1f3ff; + } + } + .dcloud-collapse-content-box { + display: flex; + flex-flow: row wrap; + justify-content: space-between; + padding: 20px 14px 0 14px; + .dcloud-form-item { + flex: 1 0 50%; + .dcloud-input-number { + width: 100%; + } + &:nth-child(2n) { + padding-left: 6px; + } + &:nth-child(2n + 1) { + padding-right: 6px; + } + .dcloud-form-item-control-input { + height: 100%; + } + } + } + } + } + + .add-container-plugin-select { + height: 27px; + margin: 4px 0; + position: relative; + .dcloud-form-item { + position: absolute; + top: 0; + left: 0; + .dcloud-form-item-control-input { + min-height: 0; + } + } + } + + .dcloud-alert { + margin: 16px 0 24px 0; + padding: 0 12px; + border: unset; + border-radius: 8px; + background: #fffae0; + .dcloud-alert-message { + font-size: 13px; + color: #592d00; + .dcloud-btn { + padding: 0 4px; + font-size: 13px; + } + } + } +} + +.operate-connector-drawer-use-json { + .CodeMirror.cm-s-default { + height: calc(100vh - 146px); + } + .dcloud-form-item { + margin-bottom: 0 !important; + } +} diff --git a/km-console/packages/layout-clusters-fe/src/pages/Connect/index.tsx b/km-console/packages/layout-clusters-fe/src/pages/Connect/index.tsx new file mode 100644 index 00000000..4c8dbb88 --- /dev/null +++ b/km-console/packages/layout-clusters-fe/src/pages/Connect/index.tsx @@ -0,0 +1,228 @@ +import React, { useState, useEffect, useRef } from 'react'; +import { ProTable, Dropdown, Button, Utils, AppContainer, SearchInput, Menu } from 'knowdesign'; +import { IconFont } from '@knowdesign/icons'; +import API from '../../api'; +import { getConnectorsColumns, defaultPagination, optionType } from './config'; +import { tableHeaderPrefix } from '@src/constants/common'; +import ConnectCard from '@src/components/CardBar/ConnectCard'; +import DBreadcrumb from 'knowdesign/es/extend/d-breadcrumb'; +import AddConnector, { OperateInfo } from './AddConnector'; +import ConnectorDetail from './Detail'; +import notification from '@src/components/Notification'; +import './index.less'; +import AddConnectorUseJSON from './AddConnectorUseJSON'; +import HasConnector from './HasConnector'; +const { request } = Utils; + +const rateMap: any = { + readRate: ['SinkRecordReadRate', 'SourceRecordPollRate'], + writeRate: ['SinkRecordSendRate', 'SourceRecordWriteRate'], + recordErrors: ['TotalRecordErrors'], +}; + +const Connectors: React.FC = () => { + const [global] = AppContainer.useGlobalValue(); + const [loading, setLoading] = useState(false); + const [detailVisible, setDetailVisible] = useState(false); + const [data, setData] = useState([]); + const [searchKeywords, setSearchKeywords] = useState(''); + const [pagination, setPagination] = useState(defaultPagination); + const [sortInfo, setSortInfo] = useState({}); + const [detailRecord, setDetailRecord] = useState(''); + const [healthType, setHealthType] = useState(true); + const addConnectorRef = useRef(null); + const addConnectorJsonRef = useRef(null); + + const getRecent1DayTimeStamp = () => [Date.now() - 24 * 60 * 60 * 1000, Date.now()]; + // 请求接口获取数据 + const genData = async ({ pageNo, pageSize, filters, sorter }: any) => { + const [startStamp, endStamp] = getRecent1DayTimeStamp(); + if (global?.clusterInfo?.id === undefined) return; + setLoading(true); + const params = { + metricLines: { + aggType: 'avg', + endTime: endStamp, + metricsNames: ['SourceRecordPollRate', 'SourceRecordWriteRate', 'SinkRecordReadRate', 'SinkRecordSendRate', 'TotalRecordErrors'], + startTime: startStamp, + topNu: 0, + }, + searchKeywords: searchKeywords.slice(0, 128), + pageNo, + pageSize, + latestMetricNames: ['SourceRecordPollRate', 'SourceRecordWriteRate', 'SinkRecordReadRate', 'SinkRecordSendRate', 'TotalRecordErrors'], + sortType: sorter?.order ? sorter.order.substring(0, sorter.order.indexOf('end')) : 'desc', + sortMetricNameList: rateMap[sorter?.field] || [], + }; + + request(API.getConnectorsList(global?.clusterInfo?.id), { method: 'POST', data: params }) + .then((res: any) => { + setPagination({ + current: res.pagination?.pageNo, + pageSize: res.pagination?.pageSize, + total: res.pagination?.total, + }); + const newData = + res?.bizData.map((item: any) => { + return { + ...item, + ...item?.latestMetrics?.metrics, + key: item.connectClusterName + item.connectorName, + }; + }) || []; + setData(newData); + setLoading(false); + }) + .catch((err) => { + setLoading(false); + }); + }; + + const onTableChange = (pagination: any, filters: any, sorter: any) => { + setSortInfo(sorter); + genData({ pageNo: pagination.current, pageSize: pagination.pageSize, filters, sorter }); + }; + + const menu = ( + + + addConnectorJsonRef.current?.onOpen('create')}>JSON 新增Connector + + + ); + + const getDetailInfo = (record: any) => { + setDetailRecord(record); + setDetailVisible(true); + }; + + // 编辑 + const editConnector = (detail: OperateInfo['detail']) => { + addConnectorRef.current?.onOpen('edit', addConnectorJsonRef.current, detail); + }; + + // 重启、暂停/继续 操作 + const optionConnect = (record: any, action: string) => { + const params = { + action, + connectClusterId: record?.connectClusterId, + connectorName: record?.connectorName, + }; + + request(API.connectorsOperates, { method: 'PUT', data: params }).then((res: any) => { + if (res === null) { + notification.success({ + message: `任务已${optionType[params.action]}`, + description: `任务状态更新会有至多1min延迟`, + }); + genData({ pageNo: pagination.current, pageSize: pagination.pageSize, sorter: sortInfo }); + setHealthType(!healthType); + } else { + notification.error({ + message: `${optionType[params.action]}任务失败`, + }); + } + }); + }; + + // 删除任务 + const deleteTesk = () => { + genData({ pageNo: 1, pageSize: pagination.pageSize }); + }; + + useEffect(() => { + genData({ + pageNo: 1, + pageSize: pagination.pageSize, + sorter: sortInfo, + }); + }, [searchKeywords]); + + return ( + <> +
+ +
+ + <> +
+ +
+
+
+
+
genData({ pageNo: pagination.current, pageSize: pagination.pageSize })} + > + +
+
+
+ + + + + + + +
+
+ +
+ +
+ + + genData({ pageNo: pagination.current, pageSize: pagination.pageSize, sorter: sortInfo })} + /> + genData({ pageNo: pagination.current, pageSize: pagination.pageSize, sorter: sortInfo })} + /> + + ); +}; + +export default Connectors; diff --git a/km-console/packages/layout-clusters-fe/src/pages/ConnectDashboard/MetricSelect.tsx b/km-console/packages/layout-clusters-fe/src/pages/ConnectDashboard/MetricSelect.tsx new file mode 100644 index 00000000..09d68652 --- /dev/null +++ b/km-console/packages/layout-clusters-fe/src/pages/ConnectDashboard/MetricSelect.tsx @@ -0,0 +1,298 @@ +import React, { useState, useEffect, forwardRef, useImperativeHandle, useRef } from 'react'; +import { Drawer, Button, Space, Divider, ProTable } from 'knowdesign'; +import { IconFont } from '@knowdesign/icons'; +import { ITableColumnsType } from 'knowdesign/lib/extend/d-table'; +import { cloneDeep } from 'lodash'; +import { MetricType } from '@src/api'; +import '../../components/ChartOperateBar/style/indicator-drawer.less'; + +export interface TreeTableDataSourceType { + set?: boolean; + children?: TreeTableData; + [key: string]: any; +} + +export interface TreeTableData { + showHeader: boolean; + rowKey: string; + columns: ITableColumnsType[]; + dataSource: TreeTableDataSourceType[]; +} + +export interface CheckboxStatus { + type: MetricType; + key: string; + status: boolean | 'indeterminate'; + children?: CheckboxStatus[]; +} + +export interface TreeTableProps { + tree: TreeTableData; + checkField: string; + submitCallback: ([leafs, checkboxData]: [any[], CheckboxStatus]) => Promise; +} + +const TreeTableItem = (props: { + treeData: TreeTableData; + checkboxData: CheckboxStatus[]; + keyTrace: (string | number)[]; + onKeyChange: any; +}) => { + const { treeData, checkboxData: data, keyTrace, onKeyChange } = props; + return ( + item.status === true).map((item) => item.key), + onChange: (keys: string[]) => { + onKeyChange(keyTrace, keys); + }, + getCheckboxProps: (record: TreeTableDataSourceType) => { + return { + indeterminate: data.some((item) => item.key === record[treeData.rowKey] && item.status === 'indeterminate'), + }; + }, + }, + }, + treeData.dataSource.some((item) => item.children) + ? { + expandable: { + childrenColumnName: 'notExist', + expandRowByClick: true, + expandedRowRender: (record: TreeTableDataSourceType) => { + return record?.children ? ( + record[treeData.rowKey] === item.key)?.children} + onKeyChange={onKeyChange} + /> + ) : ( + <> + ); + }, + rowExpandable: (record: TreeTableDataSourceType) => { + return !!record?.children; + }, + expandIcon: ({ expanded, onExpand, record }: { expanded: boolean; onExpand: any; record: TreeTableDataSourceType }) => { + return record?.children ? ( + expanded ? ( + { + onExpand(record, e); + }} + /> + ) : ( + { + onExpand(record, e); + }} + /> + ) + ) : ( + <> + ); + }, + }, + } + : {} + ), + }} + /> + ); +}; + +export const TreeTable = forwardRef((props: TreeTableProps, ref) => { + const [treeData, setTreeData] = useState(props.tree); + const [checkboxData, setCheckboxData] = useState(); + + // 根据链条查找指定选择框 + const findTargetCheckbox = (checkboxData: CheckboxStatus, keyTrace: (string | number)[]) => { + if (keyTrace.length === 0) { + return checkboxData; + } + + let targetCheckbox: CheckboxStatus = checkboxData; + keyTrace.forEach((key) => { + Object.values(targetCheckbox?.children).some((checkbox) => { + if (key === checkbox.key) { + targetCheckbox = checkbox; + return true; + } else { + return false; + } + }); + }); + return targetCheckbox; + }; + + const changeStatus = (checkbox: CheckboxStatus, type: CheckboxStatus['status']) => { + checkbox.status = type; + (checkbox?.children || []).forEach((c) => changeStatus(c, type)); + }; + + // 更新节点状态 + const updateCheckStatus = (data: CheckboxStatus, keyTrace: (string | number)[], keys: string[]) => { + // 1. 设置更新元素及其子元素的状态 + const targetCheckbox = findTargetCheckbox(data, keyTrace); + (targetCheckbox?.children || []).forEach((checkbox) => { + if (keys.includes(checkbox.key)) { + changeStatus(checkbox, true); + } else if (checkbox.status === true) { + changeStatus(checkbox, false); + } + }); + + // 2. 更新自身状态 + targetCheckbox.status = keys?.length ? (keys.length === targetCheckbox?.children?.length ? true : 'indeterminate') : false; + + // 3. 更新父级选中状态 + for (let i = 1; i < keyTrace.length; i++) { + const newTrace = keyTrace.slice(0, keyTrace.length - i); + const newCheckbox = findTargetCheckbox(data, newTrace); + const trueLen = newCheckbox?.children.map((item) => item.status === true).filter((s) => s).length; + newCheckbox.status = trueLen === 0 ? false : trueLen === newCheckbox?.children.length ? true : 'indeterminate'; + } + }; + + const onKeyChange = (keyTrace: (string | number)[], keys: string[]) => { + const clonedCheckboxData = cloneDeep(checkboxData); + updateCheckStatus(clonedCheckboxData, keyTrace, keys); + setCheckboxData(clonedCheckboxData); + }; + + // 生成初始选中结构 + const renderInitCheckboxData = ( + tree: TreeTableData, + curCheckboxData: CheckboxStatus, + wholeCheckboxData: CheckboxStatus, + keyTrace: (string | number)[], + callbacks: (() => void)[] + ) => { + curCheckboxData.children = []; + const selectedKeys: string[] = []; + + tree.dataSource.forEach((item) => { + const data = { + type: item.type, + key: item[tree.rowKey], + status: false, + }; + curCheckboxData.children.push(data); + if (item.children) { + renderInitCheckboxData(item.children, data, wholeCheckboxData, [...keyTrace, item[tree.rowKey]], callbacks); + } else if (item.set) { + selectedKeys.push(item[tree.rowKey]); + } + }); + + if (selectedKeys.length) { + callbacks.push(() => updateCheckStatus(wholeCheckboxData, keyTrace, selectedKeys)); + } + }; + + // 获取叶子节点状态数组 + const getLeafNodes = (checkboxData: CheckboxStatus, arr: any[]) => { + checkboxData?.children.forEach((item) => { + if (item?.children) { + getLeafNodes(item, arr); + } else { + arr.push({ ...item }); + } + }); + }; + + const getLeafCheckboxData = () => { + const leafs: any[] = []; + getLeafNodes(checkboxData, leafs); + return [leafs, checkboxData]; + }; + + // 初始化选中状态数据结构 + useEffect(() => { + const initCheckbox: CheckboxStatus = { + type: undefined, + key: undefined, + status: false, + }; + const callbacks: (() => void)[] = []; + renderInitCheckboxData(treeData, initCheckbox, initCheckbox, [], callbacks); + callbacks.forEach((cb) => cb()); + setCheckboxData(initCheckbox); + }, [treeData]); + + useEffect(() => { + setTreeData(props.tree); + }, [props.tree]); + + useImperativeHandle(ref, () => ({ + getLeafCheckboxData, + })); + + return checkboxData ? ( + + ) : ( + <> + ); +}); + +export const TreeTableDrawer = forwardRef((props: TreeTableProps, ref) => { + const [visible, setVisible] = useState(false); + const [confirmLoading, setConfirmLoading] = useState(false); + const treeTableRef = useRef(null); + + const onSubmit = () => { + setConfirmLoading(true); + props + .submitCallback(treeTableRef.current?.getLeafCheckboxData()) + .then(() => { + setVisible(false); + }) + .finally(() => { + setConfirmLoading(false); + }); + }; + + useImperativeHandle(ref, () => ({ + open: () => setVisible(true), + })); + + return ( + setVisible(false)} + visible={visible} + maskClosable={false} + destroyOnClose + extra={ + + + + + + } + > + + + ); +}); diff --git a/km-console/packages/layout-clusters-fe/src/pages/ConnectDashboard/MetricsFilter.tsx b/km-console/packages/layout-clusters-fe/src/pages/ConnectDashboard/MetricsFilter.tsx new file mode 100644 index 00000000..a4d9088a --- /dev/null +++ b/km-console/packages/layout-clusters-fe/src/pages/ConnectDashboard/MetricsFilter.tsx @@ -0,0 +1,235 @@ +import React, { useEffect, useImperativeHandle, useRef, useState } from 'react'; +import api, { MetricType } from '@src/api'; +import { arrayMoveImmutable } from 'array-move'; +import { expandedRowColumns } from '@src/components/ChartOperateBar/MetricSelect'; +import { TreeTableDataSourceType, TreeTableDrawer, TreeTableData, CheckboxStatus } from './MetricSelect'; +import { MetricInfo } from '@src/constants/chartConfig'; +import { forwardRef } from 'react'; +import { AppContainer, Utils } from 'knowdesign'; +import { useParams } from 'react-router-dom'; + +interface MetricsFilterProps { + metricType: MetricType[]; + onSelectChange: (list: MetricInfo[]) => void; + onRankChange: (rankList: string[]) => void; +} + +// 处理图表排序 +const resolveMetricsRank = (metricList: MetricInfo[]) => { + const isRanked = metricList.some(({ rank }) => rank !== null); + const listInfo: { [key: string]: { metric: string; rank: number; set: boolean }[] } = {}; + let shouldUpdate = false; + let sortedList: MetricInfo[] = []; + + if (isRanked) { + const rankedMetrics = metricList.filter(({ rank }) => rank !== null).sort((a, b) => a.rank - b.rank); + const unRankedMetrics = metricList.filter(({ rank }) => rank === null); + // 如果有新增/删除指标的情况,需要触发更新 + if (unRankedMetrics.length || rankedMetrics.some(({ rank }, i) => rank !== i)) { + shouldUpdate = true; + } + sortedList = [...rankedMetrics, ...unRankedMetrics.sort((a, b) => Number(a.name > b.name) - 0.5)]; + } else { + shouldUpdate = true; + // 按字母先后顺序初始化指标排序 + sortedList = metricList.sort((a, b) => a.type - b.type).sort((a, b) => (a.type !== b.type ? 1 : Number(a.name > b.name) - 0.5)); + } + + sortedList.forEach((metric, rank) => { + !listInfo[metric.type] && (listInfo[metric.type] = []); + listInfo[metric.type].push({ metric: metric.name, rank, set: metricList.find(({ name }) => metric.name === name)?.set || false }); + }); + + return { + list: sortedList.map(({ name }) => name), + listInfo, + shouldUpdate, + }; +}; + +const MetricsFilter = forwardRef((props: MetricsFilterProps, ref) => { + const [global] = AppContainer.useGlobalValue(); + const { metricType, onSelectChange, onRankChange } = props; + const { clusterId } = useParams<{ + clusterId: string; + }>(); + const [metricsList, setMetricsList] = useState([]); // 指标列表 + const [metricRankList, setMetricRankList] = useState([]); + const [tree, setTree] = useState(); + const metricSelectRef = useRef(null); + + // 更新指标 + const setMetricList = (list: { [key: string]: { metric: string; rank: number; set: boolean }[] }) => { + const reqArr: Promise[] = []; + Object.entries(list).forEach(([type, metricDetailDTOList]) => { + reqArr.push( + Utils.request(api.getDashboardMetricList(clusterId, type as unknown as MetricType), { + method: 'POST', + data: { + metricDetailDTOList, + }, + }) + ); + }); + return Promise.all(reqArr); + }; + + // TODO: 图表展示顺序变更 + const rankChange = (oldIndex: number, newIndex: number) => { + const newList = arrayMoveImmutable(metricRankList, oldIndex, newIndex); + setMetricRankList(newList); + const updates: { [key: string]: { metric: string; rank: number; set: boolean }[] } = {}; + newList.forEach((metric, rank) => { + const targetMetric = metricsList.find(({ name }) => metric === name); + if (targetMetric) { + const info = { metric, rank, set: targetMetric?.set || false }; + updates[targetMetric.type] ? updates[targetMetric.type].push(info) : (updates[targetMetric.type] = [info]); + } + }); + setMetricList(updates); + }; + + // 更新 rank + const updateRank = (metricList: MetricInfo[]) => { + const { list, listInfo, shouldUpdate } = resolveMetricsRank(metricList); + setMetricRankList(list); + if (shouldUpdate) { + setMetricList(listInfo); + } + }; + + // 获取指标列表 + const getMetricList = () => { + Promise.all(metricType.map((type) => Utils.request(api.getDashboardMetricList(clusterId, type)))).then((list) => { + let allSupportMetrics: MetricInfo[] = []; + + const treeData: TreeTableData = { + showHeader: true, + rowKey: 'category', + columns: [{ title: '分类', dataIndex: 'category' }], + dataSource: [], + }; + + (list as unknown as (MetricInfo[] | null)[]).forEach((res, i) => { + if (!res) return; + const supportMetrics = res.filter((metric) => metric.support); + allSupportMetrics = allSupportMetrics.concat(supportMetrics); + + // 处理结构 + const data: TreeTableDataSourceType = { + category: metricType[i] === MetricType.Connect ? 'Connect Cluster' : 'Connector', + }; + const categoryData: { + [category: string]: { + name: string; + unit: string; + desc: string; + }[]; + } = {}; + supportMetrics.forEach(({ name, desc, set }) => { + const metricDefine = global.getMetricDefine(metricType[i], name); + const returnData = { + type: metricType[i], + set, + name, + desc, + unit: metricDefine?.unit, + }; + if (metricDefine.category) { + if (!categoryData[metricDefine.category]) { + categoryData[metricDefine.category] = [returnData]; + } else { + categoryData[metricDefine.category].push(returnData); + } + } else { + if (!categoryData['Other']) { + categoryData['Other'] = [returnData]; + } else { + categoryData['Other'].push(returnData); + } + } + }); + + if (Object.keys(categoryData).length > 1) { + const returnData: TreeTableData = { + showHeader: false, + rowKey: 'category', + columns: [{ title: '分类', dataIndex: 'category' }], + dataSource: [], + }; + Object.entries(categoryData).forEach(([category, data]) => { + returnData.dataSource.push({ + category, + children: { + showHeader: true, + rowKey: 'name', + columns: expandedRowColumns, + dataSource: data, + }, + }); + }); + data.children = returnData; + } else { + data.children = { + showHeader: true, + rowKey: 'name', + columns: expandedRowColumns, + dataSource: Object.values(categoryData)[0] || [], + }; + } + treeData.dataSource.push(data); + }); + setTree(treeData); + + updateRank([...allSupportMetrics]); + setMetricsList(allSupportMetrics); + }); + }; + + // TODO: 指标选中项更新回调 + const metricSelectCallback = ([newMetrics]: [CheckboxStatus[], any]) => { + const updateMetrics: { [key: string]: { metric: string; set: boolean; rank: number }[] } = {}; + + newMetrics.forEach((metric) => { + const oldMetric = metricsList.find(({ type, name }) => type === metric.type && name === metric.key); + + if (oldMetric) { + if (oldMetric.set !== metric.status) { + if (updateMetrics[metric.type]) { + updateMetrics[metric.type].push({ metric: oldMetric.name, set: !oldMetric.set, rank: oldMetric.rank }); + } else { + updateMetrics[metric.type] = [{ metric: oldMetric.name, set: !oldMetric.set, rank: oldMetric.rank }]; + } + } + } + }); + + const requestPromise = Object.keys(updateMetrics).length ? setMetricList(updateMetrics) : Promise.resolve(); + requestPromise.then( + () => getMetricList(), + () => getMetricList() + ); + return requestPromise; + }; + + useEffect(() => { + onSelectChange(metricsList); + }, [metricsList]); + + useEffect(() => { + onRankChange(metricRankList); + }, [metricRankList]); + + useEffect(() => { + getMetricList(); + }, []); + + useImperativeHandle(ref, () => ({ + rankChange, + open: () => metricSelectRef.current?.open(), + })); + + return tree && ; +}); + +export default MetricsFilter; diff --git a/km-console/packages/layout-clusters-fe/src/pages/ConnectDashboard/SelectContent.tsx b/km-console/packages/layout-clusters-fe/src/pages/ConnectDashboard/SelectContent.tsx new file mode 100644 index 00000000..145bcb34 --- /dev/null +++ b/km-console/packages/layout-clusters-fe/src/pages/ConnectDashboard/SelectContent.tsx @@ -0,0 +1,233 @@ +import React, { useEffect, useMemo, useRef, useState } from 'react'; +import { DataNode } from 'knowdesign/lib/basic/tree'; +import { useParams } from 'react-router-dom'; +import { Tree, Input, Utils, Button } from 'knowdesign'; +import api from '@src/api'; +import type { ConnectCluster } from '../Connect/AddConnector'; + +export interface Connector { + connectClusterId: number; + connectClusterName: string; + connectorName: string; +} + +interface SelectContentProps { + title: string; + scopeList: { + connectClusters: ConnectCluster[]; + connectors: Connector[]; + }; + isTop?: boolean; + visibleChange?: (v: boolean) => void; + onChange?: (list: any, inputValue: string) => void; +} + +interface CheckedNodes { + connectClusters: number[]; + connectors: { connectClusterId: number; connectorName: string }[]; +} + +interface CheckedKeysProps { + checked: React.Key[]; + halfChecked: React.Key[]; +} + +const getParentKey = (key: React.Key, tree: DataNode[]): React.Key => { + let parentKey: React.Key; + for (let i = 0; i < tree.length; i++) { + const node = tree[i]; + if (node.children) { + if (node.children.some((item) => item.key === key)) { + parentKey = node.key; + } else if (getParentKey(key, node.children)) { + parentKey = getParentKey(key, node.children); + } + } + } + return parentKey; +}; + +const SelectContent = (props: SelectContentProps) => { + const { isTop, visibleChange, onChange } = props; + const { clusterId } = useParams<{ + clusterId: string; + }>(); + const [treeData, setTreeData] = useState([]); + const [expandedKeys, setExpandedKeys] = useState([]); + const [searchValue, setSearchValue] = useState(''); + const [autoExpandParent, setAutoExpandParent] = useState(true); + const [checkedKeys, setCheckedKeys] = useState({ + checked: [], + halfChecked: [], + }); + const [checkedNodes, setCheckedNodes] = useState({ + connectClusters: [], + connectors: [], + }); + const defaultChecked = useRef({ + checked: [], + halfChecked: [], + }); + + const onExpand = (newExpandedKeys: string[]) => { + setExpandedKeys(newExpandedKeys); + setAutoExpandParent(false); + }; + + const onCheck = (keys: CheckedKeysProps, { checkedNodes }: { checkedNodes: DataNode[] }) => { + const returnData: CheckedNodes = { + connectClusters: [], + connectors: [], + }; + checkedNodes.map((node) => { + if (node.children) { + returnData.connectClusters.push(node.key as number); + } else { + const [id, ...rest] = (node.key as string).split(':'); + returnData.connectors.push({ + connectClusterId: Number(id), + connectorName: rest.join(':'), + }); + } + }); + setCheckedNodes(returnData); + setCheckedKeys( + keys as { + checked: any[]; + halfChecked: any[]; + } + ); + }; + + const onSubmit = () => { + onChange(checkedNodes, `${checkedNodes.connectClusters.length + checkedNodes.connectors.length}项`); + }; + + const onCancel = () => { + visibleChange(false); + setCheckedKeys(defaultChecked.current); + }; + + const onInputChange = (e: React.ChangeEvent) => { + const { value } = e.target; + let newExpandedKeys: React.Key[] = []; + treeData.forEach((item) => { + if (String(item.title).indexOf(value) > -1) { + newExpandedKeys.push(getParentKey(item.key, treeData)); + } + item.children?.forEach((item) => { + if (String(item.title).indexOf(value) > -1) { + newExpandedKeys.push(getParentKey(item.key, treeData)); + } + }); + }); + newExpandedKeys = newExpandedKeys.filter((item, i, self) => item && self.indexOf(item) === i); + setExpandedKeys(newExpandedKeys as React.Key[]); + setSearchValue(value); + setAutoExpandParent(true); + }; + + const filterTreeData = useMemo(() => { + const loop = (data: DataNode[]): DataNode[] => + data.map((item) => { + const strTitle = item.title as string; + const index = strTitle.indexOf(searchValue); + const beforeStr = strTitle.substring(0, index); + const afterStr = strTitle.slice(index + searchValue.length); + const title = + index > -1 ? ( + + {beforeStr} + {searchValue} + {afterStr} + + ) : ( + {strTitle} + ); + if (item.children) { + return { title, key: item.key, children: loop(item.children) }; + } + + return { + title, + key: item.key, + }; + }); + return loop(treeData); + }, [treeData, searchValue]); + + // 获取节点范围列表 + const getScopeList = async () => { + const clustersMap: { [key: string]: DataNode } = {}; + props.scopeList.connectClusters.forEach((connectCluster) => { + clustersMap[connectCluster.id] = { + title: connectCluster.name, + key: connectCluster.id, + children: [], + }; + }); + props.scopeList.connectors.forEach((connector) => { + const targetConnectCluster = clustersMap[connector.connectClusterId]; + if (targetConnectCluster) { + targetConnectCluster.children.push({ + title: connector.connectorName, + key: `${connector.connectClusterId}:${connector.connectorName}`, + }); + } + }); + setTreeData(Object.values(clustersMap)); + }; + + useEffect(() => { + if (isTop) { + setCheckedKeys({ + checked: [], + halfChecked: [], + }); + setCheckedNodes({ + connectClusters: [], + connectors: [], + }); + defaultChecked.current = { + checked: [], + halfChecked: [], + }; + } + }, [isTop]); + + useEffect(() => { + getScopeList(); + }, [props.scopeList]); + + return ( + <> +
{props.title}
+
+
+ +
+ +
+ + +
+
+ + ); +}; + +export default SelectContent; diff --git a/km-console/packages/layout-clusters-fe/src/pages/ConnectDashboard/index.less b/km-console/packages/layout-clusters-fe/src/pages/ConnectDashboard/index.less new file mode 100644 index 00000000..52259ae2 --- /dev/null +++ b/km-console/packages/layout-clusters-fe/src/pages/ConnectDashboard/index.less @@ -0,0 +1,13 @@ +.dcloud-tree.connect-dashboard-option-tree { + background: transparent; + height: 198px; + padding: 0 10px; + overflow: auto; + .site-tree-search-value { + color: #f50; + } +} + +.dd-node-scope-module .flx_con .flx_r .custom-scope.dashboard-custom-scope { + height: 292px; +} diff --git a/km-console/packages/layout-clusters-fe/src/pages/ConnectDashboard/index.tsx b/km-console/packages/layout-clusters-fe/src/pages/ConnectDashboard/index.tsx new file mode 100644 index 00000000..74009716 --- /dev/null +++ b/km-console/packages/layout-clusters-fe/src/pages/ConnectDashboard/index.tsx @@ -0,0 +1,307 @@ +import React, { useState, useEffect, useRef } from 'react'; +import { Utils, AppContainer } from 'knowdesign'; +import api, { MetricType } from '@src/api'; +import DBreadcrumb from 'knowdesign/es/extend/d-breadcrumb'; +import ConnectCard from '@src/components/CardBar/ConnectCard'; +import { useParams } from 'react-router-dom'; +import { FormattedMetricData, formatChartData, MetricInfo } from '@src/constants/chartConfig'; +import ChartOperateBar, { KsHeaderOptions } from '@src/components/ChartOperateBar'; +import ChartDetail from '@src/components/DraggableCharts/Detail'; +import ChartList from '@src/components/DraggableCharts/ChartList'; +import MetricsFilter from './MetricsFilter'; +import SelectContent, { Connector } from './SelectContent'; +import './index.less'; +import { ConnectCluster } from '../Connect/AddConnector'; +import HasConnector from '../Connect/HasConnector'; + +type ChartFilterOptions = Omit; + +const { EventBus } = Utils; +const busInstance = new EventBus(); + +const DraggableCharts = (): JSX.Element => { + const [global] = AppContainer.useGlobalValue(); + const { clusterId } = useParams<{ + clusterId: string; + }>(); + const [loading, setLoading] = useState(true); + // const [scopeList, setScopeList] = useState([]); // 节点范围列表 + const [curHeaderOptions, setCurHeaderOptions] = useState(); + const [metricList, setMetricList] = useState<{ [key: string]: (string | number)[] }>({}); + const [metricChartData, setMetricChartData] = useState([]); // 指标图表数据列表 + const [gridNum, setGridNum] = useState(12); // 图表列布局 + const [scopeList, setScopeList] = useState<{ + connectClusters: ConnectCluster[]; + connectors: Connector[]; + }>({ + connectClusters: [], + connectors: [], + }); + const [screenType, setScreenType] = useState('all'); + const curFetchingTimestamp = useRef(0); + const metricRankList = useRef([]); + const metricFilterRef = useRef(null); + const chartDetailRef = useRef(null); + + // 根据筛选项获取图表信息 + const getMetricChartData = () => { + !curHeaderOptions.isAutoReload && setLoading(true); + const curTimestamp = Date.now(); + curFetchingTimestamp.current = curTimestamp; + + const [startTime, endTime] = curHeaderOptions.rangeTime; + const { connectClusters, connectors } = curHeaderOptions.scopeData.data; + const isTop = curHeaderOptions?.scopeData?.isTop; + const reqBasicBody = { + startTime, + endTime, + topNu: isTop ? curHeaderOptions.scopeData.data : null, + }; + + const getConnectClusterMetrics = + metricList[MetricType.Connect] && (isTop || connectClusters?.length) + ? Utils.post( + api.getConnectClusterMetrics(clusterId), + Object.assign( + { + ...reqBasicBody, + metricsNames: metricList[MetricType.Connect], + }, + isTop + ? {} + : { + connectClusterIdList: connectClusters, + } + ) + ) + : Promise.resolve([]); + const getConnectorMetrics = + metricList[MetricType.Connectors] && (isTop || connectors?.length) + ? Utils.post( + api.getConnectorMetrics(clusterId), + Object.assign( + { + ...reqBasicBody, + metricsNames: metricList[MetricType.Connectors], + }, + isTop ? {} : { connectorNameList: connectors } + ) + ) + : Promise.resolve([]); + + Promise.all([getConnectClusterMetrics, getConnectorMetrics]).then( + (res: any) => { + // 如果当前请求不是最新请求,则不做任何操作 + if (curFetchingTimestamp.current !== curTimestamp) { + return; + } + + // 为保证指标排序结果正确,当指标全部返回后才展示图表 + if (res.length === 1 || (res.length === 2 && res[0] && res[1])) { + const connectClusterData = formatChartData( + res[0], + global.getMetricDefine || {}, + MetricType.Connect, + curHeaderOptions.rangeTime + ) as FormattedMetricData[]; + // todo 将指标筛选选中但是没有返回的指标插入chartData中 + const newConnectClusterData: any = []; + metricList[MetricType.Connect]?.forEach((item) => { + if (connectClusterData && connectClusterData.some((key) => item === key.metricName)) { + newConnectClusterData.push(null); + } else { + const chartData: any = { + metricName: item, + metricType: MetricType.Connect, + metricUnit: global.getMetricDefine(MetricType.Connect, item)?.unit || '', + metricLines: [], + showLegend: false, + targetUnit: undefined, + }; + newConnectClusterData.push(chartData); + } + }); + const connectorData = formatChartData( + res[1], + global.getMetricDefine || {}, + MetricType.Connectors, + curHeaderOptions.rangeTime + ) as FormattedMetricData[]; + // todo 将指标筛选选中但是没有返回的指标插入chartData中 + const newConnectorData: any = []; + + metricList[MetricType.Connectors]?.forEach((item) => { + if (connectorData && connectorData.some((key) => item === key.metricName)) { + newConnectorData.push(null); + } else { + const chartData: any = { + metricName: item, + metricType: MetricType.Connectors, + metricUnit: global.getMetricDefine(MetricType.Connectors, item)?.unit || '', + metricLines: [], + showLegend: false, + targetUnit: undefined, + }; + newConnectorData.push(chartData); + } + }); + // 指标排序 + const formattedMetricData = [...connectClusterData, ...connectorData]; + const nullDataMetricData = [...newConnectClusterData, ...newConnectorData].filter((item) => item !== null); + formattedMetricData.sort((a, b) => metricRankList.current.indexOf(a.metricName) - metricRankList.current.indexOf(b.metricName)); + nullDataMetricData.sort((a, b) => metricRankList.current.indexOf(a.metricName) - metricRankList.current.indexOf(b.metricName)); + const filterMetricData = [...formattedMetricData, ...nullDataMetricData]; + setMetricChartData( + screenType === 'Connect' + ? filterMetricData.filter((item) => item.metricType === MetricType.Connect) + : screenType === 'Connector' + ? filterMetricData.filter((item) => item.metricType === MetricType.Connectors) + : filterMetricData + ); + } else { + setMetricChartData([]); + } + setLoading(false); + }, + () => curFetchingTimestamp.current === curTimestamp && setLoading(false) + ); + }; + + const getScopeList = () => { + const getConnectClusters = Utils.request(api.getConnectClusters(clusterId)); + const getConnectors = Utils.request(api.getConnectors(clusterId)); + Promise.all([getConnectClusters, getConnectors]).then(([connectClusters, connectors]: [ConnectCluster[], Connector[]]) => { + setScopeList({ + connectClusters, + connectors, + }); + }); + }; + + // 筛选项变化或者点击刷新按钮 + const ksHeaderChange = (ksOptions: KsHeaderOptions) => { + const { isAutoReload, gridNum: newGridNum, isRelativeRangeTime, rangeTime, scopeData } = ksOptions; + let newRangeTime = rangeTime; + // 重新渲染图表 + if (newGridNum !== gridNum) { + setGridNum(newGridNum || 12); + busInstance.emit('chartResize'); + } else { + // 如果为相对时间,则当前时间减去 1 分钟,避免最近一分钟的数据还没采集到时前端多补一个点 + if (isRelativeRangeTime) { + newRangeTime = rangeTime.map((timestamp) => timestamp - 60 * 1000) as [number, number]; + } + setCurHeaderOptions({ + isRelativeRangeTime: isRelativeRangeTime, + isAutoReload: isAutoReload, + rangeTime: newRangeTime, + scopeData: scopeData, + }); + } + }; + + // 图表拖拽 + const dragCallback = (oldIndex: number, newIndex: number) => { + const originFrom = metricRankList.current.indexOf(metricChartData[oldIndex].metricName); + const originTarget = metricRankList.current.indexOf(metricChartData[newIndex].metricName); + metricFilterRef.current?.rankChange(originFrom, originTarget); + }; + + // 展开图表详情 + const onExpand = (metricName: string, metricType: MetricType) => { + const linesName = + metricType === MetricType.Connect + ? scopeList.connectClusters.map((cluster) => cluster.id) + : scopeList.connectors.map((connector) => ({ + connectClusterId: connector.connectClusterId, + connectorName: connector.connectorName, + })); + chartDetailRef.current.onOpen(metricType, metricName, linesName); + }; + + // 获取图表指标 + useEffect(() => { + if (Object.values(metricList).some((list) => list.length) && curHeaderOptions) { + getMetricChartData(); + } + }, [curHeaderOptions, screenType]); + + useEffect(() => { + if (Object.values(metricList).some((list) => list.length) && curHeaderOptions) { + setLoading(true); + getMetricChartData(); + } else { + setMetricChartData([]); + setLoading(false); + } + }, [metricList]); + + useEffect(() => { + getScopeList(); + }, []); + + return ( +
+ metricFilterRef.current?.open()} + nodeSelect={{ + name: 'Connect', + customContent: , + }} + // setScreenType={setScreenType} // 3.3.1小版本发布 + /> + { + const res: { [key: string]: (string | number)[] } = {}; + list.forEach(({ type, name, set }) => { + set && (res[type] ? res[type].push(name) : (res[type] = [name])); + }); + setMetricList(res); + }} + onRankChange={(rankList) => { + metricRankList.current = rankList; + }} + /> + + {/* 图表详情 */} + +
+ ); +}; + +const ConnectDashboard = (): JSX.Element => { + const [global] = AppContainer.useGlobalValue(); + return ( + <> +
+ +
+ + <> + + + + + + ); +}; + +export default ConnectDashboard; diff --git a/km-console/packages/layout-clusters-fe/src/pages/ConsumerGroup/ExpandedRow.tsx b/km-console/packages/layout-clusters-fe/src/pages/ConsumerGroup/ExpandedRow.tsx index fac1e99a..3e951943 100644 --- a/km-console/packages/layout-clusters-fe/src/pages/ConsumerGroup/ExpandedRow.tsx +++ b/km-console/packages/layout-clusters-fe/src/pages/ConsumerGroup/ExpandedRow.tsx @@ -167,8 +167,11 @@ export const ExpandedRow: any = ({ record, groupName }: any) => { ) .then((data: any) => { if (!data) return; - setPagination((origin: any) => { - return { ...origin, current: data.pagination?.pageNo, pageSize: data.pagination?.pageSize }; + + setPagination({ + current: data.pagination?.pageNo, + pageSize: data.pagination?.pageSize, + total: data.pagination?.total, }); setConsumerList(data?.bizData || []); }) diff --git a/km-console/packages/layout-clusters-fe/src/pages/ConsumerGroup/index.tsx b/km-console/packages/layout-clusters-fe/src/pages/ConsumerGroup/index.tsx index 55647ae0..8e0bb6fb 100644 --- a/km-console/packages/layout-clusters-fe/src/pages/ConsumerGroup/index.tsx +++ b/km-console/packages/layout-clusters-fe/src/pages/ConsumerGroup/index.tsx @@ -79,7 +79,7 @@ const BrokerList: React.FC = (props: any) => {
-
+
{
)} -
+
{/* */} {scene !== 'topicDetail' && (
-
searchFn()}> - -
+ +
searchFn()}> + +
+
{
{/*
*/} -
+
{
-
+
Github: - 5.4K - + Star的项目 Know Streaming + 5.8K + + Star的的实时流处理平台
从开源至今社区内已经超过 2000+ 用户使用,从新创公司到巨头,尤其是得到各行业一线企业开发者的信赖。 diff --git a/km-console/packages/layout-clusters-fe/src/pages/MirrorMaker2/AddMM2.tsx b/km-console/packages/layout-clusters-fe/src/pages/MirrorMaker2/AddMM2.tsx new file mode 100644 index 00000000..1e46a8e2 --- /dev/null +++ b/km-console/packages/layout-clusters-fe/src/pages/MirrorMaker2/AddMM2.tsx @@ -0,0 +1,1263 @@ +import React, { createContext, createElement, forwardRef, useContext, useEffect, useImperativeHandle, useRef, useState } from 'react'; +import { Alert, Button, Drawer, Form, Input, InputNumber, Radio, Select, Spin, Steps, Switch, Table, Transfer, Utils } from 'knowdesign'; +import { FormInstance } from 'knowdesign/es/basic/form/Form'; +import message from '@src/components/Message'; +import api from '@src/api'; +import { useParams } from 'react-router-dom'; +import { IconFont } from '@knowdesign/icons'; +import { regClusterName } from '@src/constants/reg'; + +const { Step } = Steps; + +export interface ConnectCluster { + id: number; + name: string; + groupName: string; + state: number; + version: string; + jmxProperties: string; + clusterUrl: string; + memberLeaderUrl: string; +} + +export interface ConnectorPlugin { + type: 'source' | 'sink'; + version: string; + className: string; + helpDocLink: string; +} + +interface ConnectorPluginConfigDefinition { + name: string; + type: string; + required: boolean; + defaultValue: string | null; + importance: string; + documentation: string; + group: string; + orderInGroup: number; + width: string; + displayName: string; + dependents: string[]; +} + +interface ConnectorPluginConfigValue { + errors: string[]; + name: string; + recommendedValues: any[]; + value: any; + visible: boolean; +} + +export interface ConnectorPluginConfig { + name: string; + errorCount: number; + groups: string[]; + configs: { + definition: ConnectorPluginConfigDefinition; + value: ConnectorPluginConfigValue; + }[]; +} + +interface FormConnectorConfigs { + pluginConfig: { [key: string]: ConnectorPluginConfigDefinition[] }; + connectorConfig?: { [key: string]: any }; +} + +interface SubFormProps { + visible: boolean; + setSubmitLoading: (loading: boolean) => void; +} + +export interface OperateInfo { + type: 'create' | 'edit'; + errors: { + [key: string]: string[]; + }; + detail?: { + connectClusterId: number; + connectorName: string; + connectorClassName: string; + connectorType: 'source' | 'sink'; + }; + setSourceKafkaClusterId?: any; + setBootstrapServers?: any; + setSourceDetailConfigs?: any; + setCheckoutPointDetailConfigs?: any; + setHeartbeatDetailConfigs?: any; +} + +const existConfigItems = { + sourceConfigs: [ + 'sync.topic.configs.enabled', + 'sync.topic.configs.interval.seconds', + 'sync.topic.acls.enabled', + 'sync.topic.acls.interval.seconds', + 'refresh.topics.enabled', + 'refresh.topics.interval.seconds', + 'refresh.groups.enabled', + 'refresh.groups.interval.seconds', + 'replication.policy.separator', + 'replication.policy.class', + 'topics', + ], + checkpointConfig: ['emit.checkpoints.enabled', 'emit.checkpoints.interval.seconds', 'checkpoints.topic.replication.factor'], + heartbeatConfig: ['heartbeats.topic.replication.factor', 'emit.heartbeats.interval.seconds'], +}; + +const StepsFormContent = createContext< + OperateInfo & { + forms: { current: { [key: string]: FormInstance } }; + } +>({ + type: 'create', + errors: {}, + forms: { current: {} }, +}); + +function useStepForm(key: string | number) { + const { forms } = useContext(StepsFormContent); + const [form] = Form.useForm(); + let formInstace = form; + + if (forms.current[key]) { + formInstace = forms.current[key] as FormInstance; + } else { + forms.current[key] = formInstace; + } + + return [formInstace]; +} + +// 步骤一 +const StepFormFirst = (props: SubFormProps) => { + const { clusterId } = useParams<{ + clusterId: string; + }>(); + const [form] = useStepForm(0); + const [topicData, setTopicData] = useState([]); + const [topicDataLoading, setTopicDataLoading] = useState(false); + const [givenSourceKafkaId, setGivenSourceKafkaId] = useState(clusterId); + const { type, detail, setSourceKafkaClusterId, setBootstrapServers, setSourceDetailConfigs, setCheckoutPointDetailConfigs } = + useContext(StepsFormContent); + const isEdit = type === 'edit'; + const [seniorConfig, setSeniorConfig] = useState(false); + const [topicTargetKeys, setTopicTargetKeys] = useState([]); + const [connectClusters, setConnectClusters] = useState<{ label: string; value: number }[]>([]); + const [sourcekafkaClusters, setSourcekafkaClusters] = useState<{ label: string; value: number }[]>([]); + const [headSourcekafkaClusters, setHeadSourcekafkaClusters] = useState([]); + const [formItemValues, setFormItemValues] = useState([]); + const [formItemValue, setFormItemValue] = useState({}); + const [sourcekafkaClustersId, setSourcekafkaClustersId] = useState(null); + + const topicChange = (val: any) => { + setTopicTargetKeys(val); + }; + + // 获取Connect基本信息列表 + const getConnectClustersList = () => { + Utils.request(api.getConnectClusters(clusterId)).then((res: any) => { + const arr = res.map(({ name, id }: any) => ({ + label: name || '-', + value: id, + })); + setConnectClusters(arr); + }); + }; + + // 获取 Source Kafka 集群列表 + const getSourceKafkaClustersList = () => { + Utils.request(api.getSourceKafkaClusterBasic).then((res: any) => { + setHeadSourcekafkaClusters(res || []); + const arr = res + .filter((o: any) => o.id !== +clusterId) + .map(({ name, id }: any) => ({ + label: name || '-', + value: id, + })); + setSourcekafkaClusters(arr); + }); + }; + + // 获取Topic列表 + const getTopicList = (givenSourceKafkaId: any) => { + // ! 需整理 + setTopicDataLoading(true); + Utils.request(api.getTopicMetaList(Number(givenSourceKafkaId))) + .then((res: any) => { + const dataDe = res || []; + const dataHandle = dataDe.map((item: any) => { + return { + ...item, + key: item.topicName, + label: item.topicName, + value: item.topicName, + title: item.topicName, + }; + }); + setTopicData(dataHandle); + }) + .finally(() => { + setTopicDataLoading(false); + }); + }; + + const getMM2Config = (connectClusterId: string | number) => { + Promise.all( + [ + Utils.request(api.getConnectorPluginConfig(connectClusterId, 'org.apache.kafka.connect.mirror.MirrorSourceConnector')), + Utils.request(api.getConnectorPluginConfig(connectClusterId, 'org.apache.kafka.connect.mirror.MirrorCheckpointConnector')), + isEdit ? Utils.request(api.getMirrorMakerConfig(connectClusterId, detail.connectorName)) : undefined, + ].filter((r) => r) + ) + .then((res: any) => { + const detailConfigs: any[] = isEdit && res.length > 1 ? res?.[2] : []; + let sourceConfigs: any; + let checkpointConfigs: any; + detailConfigs?.forEach((config) => { + if (config['connector.class'] === 'org.apache.kafka.connect.mirror.MirrorCheckpointConnector') { + checkpointConfigs = config; + setCheckoutPointDetailConfigs(config); + } else if (config['connector.class'] === 'org.apache.kafka.connect.mirror.MirrorSourceConnector') { + sourceConfigs = config; + setSourceDetailConfigs(config); + setGivenSourceKafkaId(sourceConfigs['source.cluster.alias']); + } + }); + const formItemValue: any = {}; + const formItemValues: any = []; + res?.[0].configs.forEach(({ definition }: any) => { + if (existConfigItems.sourceConfigs.includes(definition.name)) { + if (isEdit && sourceConfigs[definition.name]) { + if (definition.name === 'topics') { + formItemValue[definition.name] = topicTargetKeys || sourceConfigs[definition.name]; + if (sourceConfigs[definition.name] === '.*' && topicTargetKeys.length < 1) { + formItemValues.push({ + name: 'priority', + value: 'allTopic', + }); + } else { + formItemValues.push( + { + name: 'topics', + value: topicTargetKeys.length > 0 ? topicTargetKeys : sourceConfigs[definition.name].split(','), + }, + { name: 'priority', value: 'givenTopic' } + ); + topicTargetKeys.length < 1 && setTopicTargetKeys(sourceConfigs[definition.name].split(',')); + } + } else { + formItemValue[definition.name] = sourceConfigs[definition.name]; + formItemValues.push({ + name: definition.name, + value: sourceConfigs[definition.name] || null, + }); + } + } else { + if (definition.name === 'topics') { + formItemValue['topics'] = topicTargetKeys || definition.defaultValue.split(','); + definition.defaultValue === '.*' && topicTargetKeys.length < 1 + ? formItemValues.push({ + name: 'priority', + value: 'allTopic', + }) + : formItemValues.push( + { + name: 'topics', + value: topicTargetKeys || definition.defaultValue, + }, + { name: 'priority', value: 'givenTopic' } + ); + } else { + formItemValue[definition.name] = definition.defaultValue; + formItemValues.push({ + name: definition.name, + value: definition.defaultValue || null, + }); + } + } + } + }); + res?.[1].configs.forEach(({ definition }: any) => { + if (existConfigItems.checkpointConfig.includes(definition.name)) { + if (isEdit && checkpointConfigs[definition.name]) { + formItemValue[definition.name] = checkpointConfigs[definition.name]; + formItemValues.push({ + name: definition.name, + value: checkpointConfigs[definition.name] || null, + }); + } else { + formItemValue[definition.name] = definition.defaultValue; + formItemValues.push({ + name: definition.name, + value: definition.defaultValue || null, + }); + } + // formItemValue[definition.name] = + // definition.type === 'BOOLEAN' ? Boolean(definition.defaultValue) : definition.defaultValue || null; + // formItemValues.push({ + // name: definition.name, + // value: definition.type === 'BOOLEAN' ? Boolean(definition.defaultValue) : definition.defaultValue || null, + // }); + } + }); + setFormItemValue(formItemValue); + setFormItemValues(formItemValues); + }) + .finally(() => props.setSubmitLoading(false)); + }; + + useEffect(() => { + getConnectClustersList(); + getSourceKafkaClustersList(); + }, []); + + useEffect(() => { + getTopicList(givenSourceKafkaId); + }, [givenSourceKafkaId]); + + useEffect(() => { + form.resetFields(existConfigItems.sourceConfigs); + form.setFields(formItemValues); + }, [formItemValues]); + + useEffect(() => { + const bootstrapServers = + headSourcekafkaClusters.length && headSourcekafkaClusters.find((item) => item.id === sourcekafkaClustersId)?.bootstrapServers; + setBootstrapServers(bootstrapServers); + }, [sourcekafkaClustersId]); + + useEffect(() => { + form.setFieldsValue({ topics: topicTargetKeys }); + }, [topicTargetKeys]); + // useEffect(() => { + // connectorConfig && + // form.setFieldsValue({ + // topics: + // typeof connectorConfig['topics'] === 'string' ? connectorConfig['topics'].split(',').map((i: string) => i.trim()) : undefined, + // }); + // }, [topicData, connectorConfig]); + + useEffect(() => { + // 需要处理Topic和config配置,还需要考虑编辑时的回显问题 + isEdit && getMM2Config(detail.connectClusterId); + const config = isEdit + ? detail + : { + 'sync.topic.configs.enabled': false, + 'sync.topic.configs.interval.seconds': 0, + 'sync.topic.acls.enabled': false, + 'sync.topic.acls.interval.seconds': 600, + 'refresh.topics.enabled': false, + 'refresh.topics.interval.seconds': 600, + 'refresh.groups.enabled': false, + 'refresh.groups.interval.seconds': 600, + 'emit.checkpoints.enabled': false, + 'emit.checkpoints.interval.seconds': 60, + 'checkpoints.topic.replication.factor': false, + 'replication.policy.separator': '.', + }; + form.setFieldsValue(config); + setFormItemValue((state: any) => { + return { ...state, ...config }; + }); + }, [isEdit, detail]); + + const onConnectClusterChange = (value: string) => { + value && getMM2Config(value); + }; + + return ( +
+ + 64) { + return Promise.reject('MM2任务名称长度限制在1~64字符'); + } + if (!new RegExp(regClusterName).test(value)) { + return Promise.reject("MM2 名称支持中英文、数字、特殊字符 ! # $ % & ' ( ) * + , - . / : ; < = > ? @ [ ] ^ _ ` { | } ~"); + } + return Promise.resolve(); + // return Utils.request(api.isConnectorExist(prevForm.getFieldValue('connectClusterId'), value)).then( + // (res: any) => { + // const data = res || {}; + // return data?.exist ? Promise.reject('MM2 名称重复') : Promise.resolve(); + // }, + // () => Promise.reject('连接超时! 请重试或检查服务') + // ); + }, + }, + ]} + > + + + + + + {!seniorConfig && ( +
setSeniorConfig(true)}> + 高级配置 + +
+ )} +
+
+
+ + + setFormItemValue((state: any) => { + return { ...state, 'sync.topic.configs.enabled': e }; + }) + } + /> + + {formItemValue['sync.topic.configs.enabled'] ? ( + + + + ) : null} +
+
+ + + setFormItemValue((state: any) => { + return { ...state, 'sync.topic.acls.enabled': e }; + }) + } + /> + + {formItemValue['sync.topic.acls.enabled'] ? ( + + + + ) : null} +
+
+ + + setFormItemValue((state: any) => { + return { ...state, 'refresh.topics.enabled': e }; + }) + } + /> + + {formItemValue['refresh.topics.enabled'] ? ( + + + + ) : null} +
+
+ + + setFormItemValue((state: any) => { + return { ...state, 'refresh.groups.enabled': e }; + }) + } + /> + + {formItemValue['refresh.groups.enabled'] ? ( + + + + ) : null} +
+
+ + + setFormItemValue((state: any) => { + return { ...state, 'emit.checkpoints.enabled': e }; + }) + } + /> + + {formItemValue['emit.checkpoints.enabled'] ? ( +
+ + + + + + +
+ ) : null} +
+
+ + + +
+ {seniorConfig && ( +
setSeniorConfig(false)}> + 收起 + +
+ )} + +
+ ); +}; + +// 步骤二 +const StepFormSecond = (props: SubFormProps) => { + const { clusterId } = useParams<{ + clusterId: string; + }>(); + const [form] = useStepForm(1); + const [firstForm] = useStepForm(0); + const connectClusterId = firstForm.getFieldValue('connectClusterId'); + const [activeKey, setActiveKey] = useState([]); + const { type, detail, errors, setHeartbeatDetailConfigs } = useContext(StepsFormContent); + const isEdit = type === 'edit'; + const [groupOffset, setGroupOffset] = useState(false); // 控制是否同步开关 + const [heartbeat, setHeartbeat] = useState(true); // 控制是否同步开关 + const [groupLoading, setGroupLoading] = useState(false); + const [groupBasicData, setGroupBasicData] = useState([]); + + const [formItemValues, setFormItemValues] = useState([]); + const [formItemValue, setFormItemValue] = useState({}); + const columns = [ + { + title: 'ConsumerGroup', + dataIndex: 'groupName', + key: 'groupName', + width: 200, + lineClampOne: true, + needTooltip: true, + }, + { + title: 'Topic', + dataIndex: 'topicName', + key: 'topicName', + width: 200, + lineClampOne: true, + needTooltip: true, + }, + { + title: '状态', + dataIndex: 'state', + key: 'state', + width: 60, + lineClampOne: true, + needTooltip: true, + }, + ]; + + const getGroupBasicData = () => { + setGroupLoading(true); + Utils.request(api.getGroupBasic(clusterId)) + .then((res: any) => { + setGroupBasicData(res || []); + }) + .finally(() => { + setGroupLoading(false); + }); + }; + + const getMM2Config = async (connectClusterId: string | number) => { + const formItemValue: any = {}; + const formItemValues: any = []; + const result: any = await Utils.request( + api.getConnectorPluginConfig(connectClusterId, 'org.apache.kafka.connect.mirror.MirrorHeartbeatConnector') + ); + const editResult: any = isEdit ? await Utils.request(api.getMirrorMakerConfig(connectClusterId, detail.connectorName)) : undefined; + let heartbeatConfigs: any; + editResult?.forEach((config: any) => { + if (config['connector.class'] === 'org.apache.kafka.connect.mirror.MirrorCheckpointConnector') { + heartbeatConfigs = config; + setHeartbeatDetailConfigs(config); + } + }); + result?.configs.forEach(({ definition }: any) => { + if (existConfigItems.heartbeatConfig.includes(definition.name)) { + if (isEdit && heartbeatConfigs[definition.name]) { + formItemValue[definition.name] = heartbeatConfigs[definition.name]; + formItemValues.push({ + name: definition.name, + value: heartbeatConfigs[definition.name] || null, + }); + } else { + formItemValue[definition.name] = definition.defaultValue; + formItemValues.push({ + name: definition.name, + value: definition.defaultValue || null, + }); + } + // formItemValue[definition.name] = definition.type === 'BOOLEAN' ? Boolean(definition.defaultValue) : definition.defaultValue || null; + // formItemValues.push({ + // name: definition.name, + // value: definition.type === 'BOOLEAN' ? Boolean(definition.defaultValue) : definition.defaultValue || null, + // }); + } + }); + if (formItemValue['heartbeats.topic.replication.factor'] || formItemValue['emit.heartbeats.interval.seconds']) { + formItemValue['heartbeat'] = true; + formItemValues.push({ + name: 'heartbeat', + value: true, + }); + } + setFormItemValue(formItemValue); + setFormItemValues(formItemValues); + }; + + useEffect(() => { + form.resetFields(existConfigItems.sourceConfigs); + form.setFields(formItemValues); + }, [formItemValues]); + + useEffect(() => { + connectClusterId + ? getMM2Config(connectClusterId) + : form.setFieldsValue({ + groupOffset: false, + heartbeat: true, + 'offset-syncs.topic.replication.factor': 3, + 'sync.group.offsets.interval.seconds': 60, + 'heartbeats.topic.replication.factor': 3, + 'emit.heartbeats.interval.seconds': 1, + }); + }, [connectClusterId]); + + useEffect(() => { + groupOffset && getGroupBasicData(); + }, [groupOffset]); + + return ( +
+
+ + setGroupOffset(e)} size="small" /> + + {groupOffset && ( +
+ + + + + + +
+ + )} + + + setFormItemValue((state: any) => { + return { ...state, heartbeat: e }; + }) + } + size="small" + /> + + {formItemValue['heartbeat'] ? ( +
+ + + + + + +
+ ) : null} + {/* {heartbeat && ( +
+ + + + + + +
+ )} */} + + + ); +}; + +const steps = [ + { + title: '步骤一', + content: StepFormFirst, + }, + { + title: '步骤二', + content: StepFormSecond, + }, +]; + +export default forwardRef( + ( + props: { + refresh: () => void; + }, + ref + ) => { + const [visible, setVisible] = useState(false); + const [jsonRef, setJsonRef] = useState({}); + const [currentStep, setCurrentStep] = useState(0); + const [stepInitState, setStepInitState] = useState([1]); + const [submitLoading, setSubmitLoading] = useState(false); + const [operateInfo, setOperateInfo] = useState({ + type: undefined, + errors: {}, + }); + const stepsFormRef = useRef<{ + [key: string]: FormInstance; + }>({}); + const [sourceKafkaClusterId, setSourceKafkaClusterId] = useState(''); + const [bootstrapServers, setBootstrapServers] = useState(null); + const [sourceDetailConfigs, setSourceDetailConfigs] = useState({}); + const [checkoutPointDetailConfigs, setCheckoutPointDetailConfigs] = useState({}); + const [heartbeatDetailConfigs, setHeartbeatDetailConfigs] = useState({}); + const onOpen = (type: OperateInfo['type'], jsonRef: any, detail?: OperateInfo['detail']) => { + if (type === 'create') { + setStepInitState([1]); + } else { + setStepInitState([1, 2, 3, 4]); + } + setOperateInfo({ + type, + detail, + errors: {}, + }); + setJsonRef(jsonRef); + setVisible(true); + }; + + const onClose = () => { + Object.values(stepsFormRef.current).forEach((form) => { + form.resetFields(); + }); + stepsFormRef.current = {}; + setVisible(false); + setCurrentStep(0); + setStepInitState([]); + }; + + const turnTo = (jumpStep: number) => { + if (submitLoading) { + message.warning('加载中,请稍后重试'); + return; + } + if (jumpStep > currentStep) { + const prevInit = stepInitState[jumpStep - 1]; + if (!prevInit) { + message.warning('请按照顺序填写'); + } else { + stepsFormRef.current[currentStep].validateFields().then(() => { + const prevStep = jumpStep - 1; + if (currentStep < prevStep) { + stepsFormRef.current[prevStep] + .validateFields() + .then(() => { + setStepInitState((prev) => { + const cur = [...prev]; + cur[jumpStep] = 1; + return cur; + }); + setCurrentStep(jumpStep); + }) + .catch(() => { + setCurrentStep(prevStep); + }); + } else { + setStepInitState((prev) => { + const cur = [...prev]; + cur[jumpStep] = 1; + return cur; + }); + setCurrentStep(jumpStep); + } + }); + } + } else { + setCurrentStep(jumpStep); + } + }; + + // 校验所有表单 + const validateForms = ( + callback: (info: { + success?: + | { + connectClusterId: number; + connectorName: string; + configs: { + [key: string]: any; + }; + sourceKafkaClusterId: number; + heartbeatConnectorConfigs: { + [key: string]: any; + }; + checkpointConnectorConfigs: { + [key: string]: any; + }; + } + | any; + error?: any; + }) => void + ) => { + const promises: Promise[] = []; + Object.values(stepsFormRef.current).forEach((form, i) => { + const promise = form + .validateFields() + .then((res) => { + return res; + }) + .catch(() => { + return Promise.reject(i); + }); + promises.push(promise); + }); + + Promise.all(promises).then( + (res) => { + const result = { + ...res[0], + ...res[1], + // ...res[4], + }; + const { detail } = operateInfo as any; + const checkpointConnectorConfigs = result['emit.checkpoints.enabled'] && { + ...checkoutPointDetailConfigs, + 'connector.class': 'org.apache.kafka.connect.mirror.MirrorCheckpointConnector', + 'emit.checkpoints.enabled': result['emit.checkpoints.enabled'], + 'emit.checkpoints.interval.seconds': result['emit.checkpoints.interval.seconds'], + 'checkpoints.topic.replication.factor': result['checkpoints.topic.replication.factor'], + 'source.cluster.alias': sourceKafkaClusterId || res[0].sourceKafkaClusterId, + name: detail?.checkpointConnector || result.name, + 'source.cluster.bootstrap.servers': bootstrapServers || checkoutPointDetailConfigs?.['source.cluster.bootstrap.servers'], + }; + const heartbeatConnectorConfigs = result['heartbeat'] && { + ...heartbeatDetailConfigs, + 'connector.class': 'org.apache.kafka.connect.mirror.MirrorHeartbeatConnector', + 'heartbeats.topic.replication.factor': result['heartbeats.topic.replication.factor'], + 'emit.heartbeats.interval.seconds': result['emit.heartbeats.interval.seconds'], + 'source.cluster.alias': sourceKafkaClusterId || res[0].sourceKafkaClusterId, + name: detail?.heartbeatConnector || result.name, + 'source.cluster.bootstrap.servers': bootstrapServers || heartbeatDetailConfigs?.['source.cluster.bootstrap.servers'], + }; + const configs = { + ...sourceDetailConfigs, + 'connector.class': 'org.apache.kafka.connect.mirror.MirrorSourceConnector', + 'sync.topic.configs.enabled': result['sync.topic.configs.enabled'], + 'sync.topic.configs.interval.seconds': result['sync.topic.configs.interval.seconds'], + + 'sync.topic.acls.enabled': result['sync.topic.acls.enabled'], + 'sync.topic.acls.interval.seconds': result['sync.topic.acls.interval.seconds'], + + 'refresh.topics.enabled': result['refresh.topics.enabled'], + 'refresh.topics.interval.seconds': result['refresh.topics.interval.seconds'], + + 'refresh.groups.enabled': result['refresh.groups.enabled'], + 'refresh.groups.interval.seconds': result['refresh.groups.interval.seconds'], + 'replication.policy.class': result['replication.policy.class'], + 'replication.policy.separator': result['replication.policy.separator'], + topics: result['priority'] === 'givenTopic' ? result['topics'].join() : '.*', + 'source.cluster.alias': sourceKafkaClusterId || res[0].sourceKafkaClusterId, + name: result.name, + 'source.cluster.bootstrap.servers': bootstrapServers || sourceDetailConfigs?.['source.cluster.bootstrap.servers'], + }; + // topics 配置格式化 + // res[1].topics && (result.topics = (res[1].topics as string[]).join(', ')); + // // transforms 配置格式化 + // res[2].transforms && + // (res[2].transforms as string) + // .split('\n') + // .filter((l) => l) + // .forEach((l) => { + // const [k, ...v] = l.split('='); + // result[k] = v.join('='); + // }); + callback({ + success: { + connectClusterId: res[0].connectClusterId, + connectorName: result['name'], + sourceKafkaClusterId: res[0].sourceKafkaClusterId, + configs, + heartbeatConnectorConfigs: heartbeatConnectorConfigs || undefined, + checkpointConnectorConfigs: checkpointConnectorConfigs || undefined, + }, + }); + }, + (error) => { + callback({ + error, + }); + } + ); + }; + + const toJsonMode = () => { + validateForms((info) => { + if (info.error) { + message.warning('校验失败,请检查填写内容'); + setCurrentStep(info.error); + } else { + (jsonRef as any)?.onOpen(operateInfo.type, info.success); + onClose(); + } + }); + }; + + const onSubmit = () => { + validateForms((info) => { + if (info.error) { + message.warning('校验失败,请检查填写内容'); + setCurrentStep(info.error); + } else { + setSubmitLoading(true); + Object.entries(info.success).forEach(([key, val]) => { + if (val === null) { + delete info.success[key]; + } + }); + Utils.put(api.validateMM2Config, info.success).then( + (res: ConnectorPluginConfig) => { + if (res) { + if (res?.errorCount > 0) { + const errors: OperateInfo['errors'] = {}; + res?.configs + ?.filter((config) => config.value.errors.length !== 0) + .forEach(({ value }) => { + if (value.name.includes('transforms.')) { + errors['transforms'] = (errors['transforms'] || []).concat(value.errors); + } else { + errors[value.name] = value.errors; + } + }); + setOperateInfo((cur) => ({ + ...cur, + errors, + })); + + // 步骤跳转 + // const items = getExistFormItems(stepsFormRef.current[0].getFieldValue('connectorType')); + // const keys = Object.keys(errors).filter((key) => items.includes(key)); + // let jumpStep = 4; + // keys.forEach((key) => { + // Object.values(existFormItems).some((items, i) => { + // if (items.includes(key)) { + // jumpStep > i + 1 && (jumpStep = i + 1); + // return true; + // } + // return false; + // }); + // }); + // setCurrentStep(jumpStep); + setSubmitLoading(false); + message.warning('字段校验失败,请检查'); + } else { + if (operateInfo.type === 'create') { + Utils.post(api.mirrorMakerOperates, info.success) + .then(() => { + message.success('新建成功'); + onClose(); + props?.refresh(); + }) + .finally(() => setSubmitLoading(false)); + } else { + Utils.put(api.updateMM2Config, info.success) + .then(() => { + message.success('编辑成功'); + props?.refresh(); + onClose(); + }) + .finally(() => setSubmitLoading(false)); + } + } + } else { + setSubmitLoading(false); + message.error('接口校验出错,请重新提交'); + } + }, + () => setSubmitLoading(false) + ); + } + }); + }; + + useImperativeHandle(ref, () => ({ + onOpen, + onClose, + })); + + return ( + + {operateInfo.type && visible && ( + <> + turnTo(cur)}> + {steps.map(({ title }) => ( + + ))} + +
+ + {steps.map((step, i) => { + return createElement(step.content, { + visible: i === currentStep, + setSubmitLoading, + }); + })} + + {currentStep === steps.length - 1 && ( + + 如果你想自定义更多配置,可以点击 + + 继续补充 + + } + /> + )} +
+ {currentStep > 0 && ( + + )} + {currentStep < steps.length - 1 && ( + + )} + {currentStep === steps.length - 1 && ( + + )} +
+
+ + )} +
+ ); + } +); diff --git a/km-console/packages/layout-clusters-fe/src/pages/MirrorMaker2/AddMM2JSON.tsx b/km-console/packages/layout-clusters-fe/src/pages/MirrorMaker2/AddMM2JSON.tsx new file mode 100644 index 00000000..eb58aa2c --- /dev/null +++ b/km-console/packages/layout-clusters-fe/src/pages/MirrorMaker2/AddMM2JSON.tsx @@ -0,0 +1,266 @@ +import api from '@src/api'; +import CodeMirrorFormItem from '@src/components/CodeMirrorFormItem'; +import customMessage from '@src/components/Message'; +import { Button, Divider, Drawer, Form, message, Space, Utils } from 'knowdesign'; +import React, { forwardRef, useEffect, useImperativeHandle, useState } from 'react'; +import { useParams } from 'react-router-dom'; +import { ConnectCluster, ConnectorPlugin, ConnectorPluginConfig, OperateInfo } from './AddMM2'; + +const PLACEHOLDER = `配置格式如下 + +{ + "connectClusterId": 1, // ConnectID + "connectorName": "", // MM2 名称 + "sourceKafkaClusterId": 1, // SourceKafka集群 ID + "configs": { // Source 相关配置 + "name": "", // MM2 名称 + "source.cluster.alias": "", // SourceKafka集群 ID + ... + }, + "heartbeatConnectorConfigs": { // Heartbeat 相关配置 + "name": "", // Heartbeat 对应的Connector名称 + "source.cluster.alias": "", // SourceKafka集群 ID + ... + }, + "checkpointConnectorConfigs": { // Checkpoint 相关配置 + "name": "", // Checkpoint 对应的Connector名称 + "source.cluster.alias": "", // SourceKafka集群 ID + ... + } +}`; + +export default forwardRef((props: any, ref) => { + // const { clusterId } = useParams<{ + // clusterId: string; + // }>(); + const [visible, setVisible] = useState(false); + const [form] = Form.useForm(); + const [type, setType] = useState('create'); + // const [connectClusters, setConnectClusters] = useState<{ label: string; value: number }[]>([]); + const [defaultConfigs, setDefaultConfigs] = useState<{ [key: string]: any }>({}); + const [submitLoading, setSubmitLoading] = useState(false); + + // const getConnectClusters = () => { + // return Utils.request(api.getConnectClusters(clusterId)).then((res: ConnectCluster[]) => { + // setConnectClusters( + // res.map(({ name, id }) => ({ + // label: name || '-', + // value: id, + // })) + // ); + // }); + // }; + + const onOpen = (type: 'create' | 'edit', defaultConfigs?: { [key: string]: any }) => { + if (defaultConfigs) { + setDefaultConfigs({ ...defaultConfigs }); + form.setFieldsValue({ + configs: JSON.stringify(defaultConfigs, null, 2), + }); + } + setType(type); + setVisible(true); + }; + + const onSubmit = () => { + setSubmitLoading(true); + form.validateFields().then( + (data) => { + const postData = JSON.parse(data.configs); + + Object.entries(postData.configs).forEach(([key, val]) => { + if (val === null) { + delete postData.configs[key]; + } + }); + Utils.put(api.validateMM2Config, postData).then( + (res: ConnectorPluginConfig) => { + if (res) { + if (res?.errorCount > 0) { + const errors: OperateInfo['errors'] = {}; + res?.configs + ?.filter((config) => config.value.errors.length !== 0) + .forEach(({ value }) => { + if (value.name.includes('transforms.')) { + errors['transforms'] = (errors['transforms'] || []).concat(value.errors); + } else { + errors[value.name] = value.errors; + } + }); + form.setFields([ + { + name: 'configs', + errors: Object.entries(errors).map(([name, errorArr]) => `${name}: ${errorArr.join('; ')}\n`), + }, + ]); + setSubmitLoading(false); + } else { + if (type === 'create') { + Utils.post(api.mirrorMakerOperates, postData) + .then(() => { + customMessage.success('新建成功'); + onClose(); + props?.refresh(); + }) + .finally(() => setSubmitLoading(false)); + } else { + Utils.put(api.updateMM2Config, postData) + .then(() => { + customMessage.success('编辑成功'); + props?.refresh(); + onClose(); + }) + .finally(() => setSubmitLoading(false)); + } + } + } else { + setSubmitLoading(false); + message.error('接口校验出错,请重新提交'); + } + }, + () => setSubmitLoading(false) + ); + }, + () => setSubmitLoading(false) + ); + }; + + const onClose = () => { + setVisible(false); + form.resetFields(); + }; + + // useEffect(() => { + // getConnectClusters(); + // }, []); + + useImperativeHandle(ref, () => ({ + onOpen, + onClose, + })); + + return ( + + + + + + + + } + > +
+ { + // return data?.exist + // ? Promise.reject('name 与已有 Connector 重复') + // : plugins.every((plugin) => plugin.className !== v.configs['connector.class']) + // ? Promise.reject('该 connectCluster 下不存在 connector.class 项配置的插件') + // : Promise.resolve(); + // }, + // () => { + // return Promise.reject('接口校验出错,请重试'); + // } + // ); + // } else { + // return Promise.resolve(); + // } + } catch (e) { + return Promise.reject('输入内容必须为 JSON'); + } + }, + }, + ]} + > + {visible && ( +
+ { + form.setFieldsValue({ configs }); + }} + /> +
+ )} +
+ +
+ ); +}); diff --git a/km-console/packages/layout-clusters-fe/src/pages/MirrorMaker2/Delete.tsx b/km-console/packages/layout-clusters-fe/src/pages/MirrorMaker2/Delete.tsx new file mode 100644 index 00000000..3ef93e6e --- /dev/null +++ b/km-console/packages/layout-clusters-fe/src/pages/MirrorMaker2/Delete.tsx @@ -0,0 +1,99 @@ +import React, { useState } from 'react'; +import { useParams } from 'react-router-dom'; +import { Button, Form, Input, Modal, Utils } from 'knowdesign'; +import notification from '@src/components/Notification'; +import { IconFont } from '@knowdesign/icons'; +import Api from '@src/api/index'; + +// eslint-disable-next-line react/display-name +const DeleteConnector = (props: { record: any; onConfirm?: () => void }) => { + const { record, onConfirm } = props; + const [form] = Form.useForm(); + const [delDialogVisible, setDelDialogVisble] = useState(false); + const handleDelOk = () => { + form.validateFields().then((e) => { + const formVal = form.getFieldsValue(); + formVal.connectClusterId = Number(record.connectClusterId); + Utils.delete(Api.mirrorMakerOperates, { data: formVal }).then((res: any) => { + if (res === null) { + notification.success({ + message: '删除成功', + }); + setDelDialogVisble(false); + onConfirm && onConfirm(); + } else { + notification.error({ + message: '删除失败', + }); + } + }); + }); + }; + return ( + <> + + { + setDelDialogVisble(false); + }} + okText="删除" + okButtonProps={{ + danger: true, + size: 'small', + style: { + paddingLeft: '16px', + paddingRight: '16px', + }, + }} + cancelButtonProps={{ + size: 'small', + style: { + paddingLeft: '16px', + paddingRight: '16px', + }, + }} + > +
+ {record.connectorName} + ({ + validator(_, value) { + if (!value) { + return Promise.reject(new Error('请输入MM2 Name名称')); + } else if (value !== record.connectorName) { + return Promise.reject(new Error('请输入正确的MM2 Name名称')); + } + return Promise.resolve(); + }, + }), + ]} + > + + + +
+ + ); +}; + +export default DeleteConnector; diff --git a/km-console/packages/layout-clusters-fe/src/pages/MirrorMaker2/Detail.tsx b/km-console/packages/layout-clusters-fe/src/pages/MirrorMaker2/Detail.tsx new file mode 100644 index 00000000..a5b12902 --- /dev/null +++ b/km-console/packages/layout-clusters-fe/src/pages/MirrorMaker2/Detail.tsx @@ -0,0 +1,185 @@ +import React, { useState, useEffect } from 'react'; +import { Drawer, Utils, AppContainer, ProTable, Tabs, Empty, Spin } from 'knowdesign'; +import API from '@src/api'; +import MirrorMakerDetailCard from '@src/components/CardBar/MirrorMakerDetailCard'; +import { defaultPagination, getMM2DetailColumns } from './config'; +import notification from '@src/components/Notification'; +import './index.less'; +const { TabPane } = Tabs; +const prefix = 'mm2-detail'; +const { request } = Utils; + +const DetailTable = ({ loading, retryOption, data }: { loading: boolean; retryOption: any; data: any[] }) => { + const [pagination, setPagination] = useState(defaultPagination); + const onTableChange = (pagination: any, filters: any, sorter: any) => { + setPagination(pagination); + }; + return ( + + {data.length ? ( + + ) : ( + + )} + + ); +}; + +const MM2Detail = (props: any) => { + const { visible, setVisible, record } = props; + const [global] = AppContainer.useGlobalValue(); + const [loading, setLoading] = useState(false); + const [data, setData] = useState([]); + + const [tabSelectType, setTabSelectType] = useState('MirrorSource'); + const onClose = () => { + setVisible(false); + setTabSelectType('MirrorSource'); + // setPagination(defaultPagination); + // clean hash + }; + const callback = (key: any) => { + setTabSelectType(key); + }; + + const genData: any = { + MirrorSource: async () => { + if (global?.clusterInfo?.id === undefined) return; + setData([]); + setLoading(true); + if (record.connectorName) { + request(API.getConnectDetailTasks(record.connectorName, record.connectClusterId)) + .then((res: any) => { + setData(res || []); + setLoading(false); + }) + .catch((err) => { + setLoading(false); + }); + } else { + setLoading(false); + } + }, + MirrorCheckpoint: async () => { + if (global?.clusterInfo?.id === undefined) return; + setData([]); + setLoading(true); + if (record.checkpointConnector) { + request(API.getConnectDetailTasks(record.checkpointConnector, record.connectClusterId)) + .then((res: any) => { + setData(res || []); + setLoading(false); + }) + .catch((err) => { + setLoading(false); + }); + } else { + setLoading(false); + } + }, + MirrorHeatbeat: async () => { + if (global?.clusterInfo?.id === undefined) return; + setData([]); + setLoading(true); + if (record.heartbeatConnector) { + request(API.getConnectDetailTasks(record.heartbeatConnector, record.connectClusterId)) + .then((res: any) => { + setData(res || []); + setLoading(false); + }) + .catch((err) => { + setLoading(false); + }); + } else { + setLoading(false); + } + }, + }; + + const retryOption = (taskId: any) => { + const params = { + action: 'restart', + connectClusterId: record?.connectClusterId, + connectorName: record?.connectorName, + taskId, + }; + // 需要区分 tabSelectType + request(API.optionTasks(), { method: 'PUT', data: params }).then((res: any) => { + if (res === null) { + notification.success({ + message: `任务重试成功`, + }); + genData[tabSelectType](); + } else { + notification.error({ + message: `任务重试失败`, + }); + } + }); + }; + + useEffect(() => { + visible && record && genData[tabSelectType](); + }, [visible, tabSelectType]); + + return ( + + {record.connectorName ?? '-'} + + } + width={1080} + placement="right" + onClose={onClose} + visible={visible} + className={`${prefix}-drawer`} + destroyOnClose + maskClosable={false} + > + + + + + {/* {global.isShowControl && global.isShowControl(ControlStatusMap.BROKER_DETAIL_CONFIG) ? ( + + ) : ( + + )} */} + + + + + + + + + {/* */} + + ); +}; + +export default MM2Detail; diff --git a/km-console/packages/layout-clusters-fe/src/pages/MirrorMaker2/config.tsx b/km-console/packages/layout-clusters-fe/src/pages/MirrorMaker2/config.tsx new file mode 100644 index 00000000..b0e21d3b --- /dev/null +++ b/km-console/packages/layout-clusters-fe/src/pages/MirrorMaker2/config.tsx @@ -0,0 +1,344 @@ +import SmallChart from '@src/components/SmallChart'; +import { IconFont } from '@knowdesign/icons'; +import { Button, Tag, Tooltip, Utils, Popconfirm, AppContainer } from 'knowdesign'; +import React from 'react'; +import Delete from './Delete'; +import { ClustersPermissionMap } from '../CommonConfig'; +export const defaultPagination = { + current: 1, + pageSize: 10, + position: 'bottomRight', + showSizeChanger: true, + pageSizeOptions: ['10', '20', '50', '100', '200', '500'], +}; + +export const optionType: { [name: string]: string } = { + ['stop']: '暂停', + ['restart']: '重启', + ['resume']: '继续', +}; + +export const stateEnum: any = { + ['UNASSIGNED']: { + // 未分配 + name: 'Unassigned', + color: '#556EE6', + bgColor: '#EBEEFA', + }, + ['RUNNING']: { + // 运行 + name: 'Running', + color: '#00C0A2', + bgColor: 'rgba(0,192,162,0.10)', + }, + ['PAUSED']: { + // 暂停 + name: 'Paused', + color: '#495057', + bgColor: '#ECECF6', + }, + ['FAILED']: { + // 失败 + name: 'Failed', + color: '#F58342', + bgColor: '#fef3e5', + }, + ['DESTROYED']: { + // 销毁 + name: 'Destroyed', + color: '#FF7066', + bgColor: '#fdefee', + }, + ['RESTARTING']: { + // 重新启动 + name: 'Restarting', + color: '#3991FF', + bgColor: '#e9f5ff', + }, +}; + +const calcCurValue = (record: any, metricName: string) => { + // const item = (record.metricPoints || []).find((item: any) => item.metricName === metricName); + // return item?.value || ''; + // TODO 替换record + const orgVal = record?.latestMetrics?.metrics?.[metricName]; + if (orgVal !== undefined) { + if (metricName === 'TotalRecordErrors') { + return Math.round(orgVal).toLocaleString(); + } else { + return Number(Utils.formatAssignSize(orgVal, 'KB', orgVal > 1000 ? 2 : 3)).toLocaleString(); + // return Utils.formatAssignSize(orgVal, 'KB'); + } + } + return '-'; + // return orgVal !== undefined ? (metricName !== 'HealthScore' ? formatAssignSize(orgVal, 'KB') : orgVal) : '-'; +}; + +const renderLine = (record: any, metricName: string) => { + const points = record.metricLines?.find((item: any) => item.metricName === metricName)?.metricPoints || []; + return points.length ? ( +
+ ({ time: item.timeStamp, value: item.value })), + }} + /> + {calcCurValue(record, metricName)} +
+ ) : ( + {calcCurValue(record, metricName)} + ); +}; + +export const getMM2Columns = (arg?: any) => { + // eslint-disable-next-line react-hooks/rules-of-hooks + const [global] = AppContainer.useGlobalValue(); + const columns: any = [ + { + title: 'MM2 Name', + dataIndex: 'connectorName', + key: 'connectorName', + width: 160, + fixed: 'left', + lineClampOne: true, + render: (t: string, r: any) => { + return t ? ( + <> + + { + arg.getDetailInfo(r); + }} + > + {t} + + + + ) : ( + '-' + ); + }, + }, + { + title: 'Connect集群', + dataIndex: 'connectClusterName', + key: 'connectClusterName', + width: 200, + lineClampOne: true, + needTooltip: true, + }, + { + title: 'State', + dataIndex: 'state', + key: 'state', + width: 120, + render: (t: string, r: any) => { + return t ? ( + + {stateEnum[t]?.name} + + ) : ( + '-' + ); + }, + }, + { + // title: '集群(源-->目标)', + title: ( + + 集群(源{' '} + + + {' '} + 目标) + + ), + dataIndex: 'destKafkaClusterName', + key: 'destKafkaClusterName', + width: 200, + render: (t: string, r: any) => { + return r.sourceKafkaClusterName && r.destKafkaClusterName ? ( + + {r.sourceKafkaClusterName} + + {t} + + ) : ( + '-' + ); + }, + }, + { + title: 'Tasks', + dataIndex: 'taskCount', + key: 'taskCount', + width: 100, + }, + { + title: '复制流量速率', + dataIndex: 'byteRate', + key: 'byteRate', + sorter: true, + width: 170, + render: (value: any, record: any) => renderLine(record, 'ByteRate'), + }, + { + title: '消息复制速率', + dataIndex: 'recordRate', + key: 'recordRate', + sorter: true, + width: 170, + render: (value: any, record: any) => renderLine(record, 'RecordRate'), + }, + { + title: '最大延迟', + dataIndex: 'replicationLatencyMsMax', + key: 'replicationLatencyMsMax', + sorter: true, + width: 170, + render: (value: any, record: any) => renderLine(record, 'ReplicationLatencyMsMax'), + }, + ]; + if (global.hasPermission) { + columns.push({ + title: '操作', + dataIndex: 'options', + key: 'options', + width: 200, + filterTitle: true, + fixed: 'right', + // eslint-disable-next-line react/display-name + render: (_t: any, r: any) => { + return ( +
+ {global.hasPermission(ClustersPermissionMap.MM2_STOP_RESUME) && (r.state === 'RUNNING' || r.state === 'PAUSED') && ( + arg?.optionConnect(r, r.state === 'RUNNING' ? 'stop' : 'resume')} + // onCancel={cancel} + okText="是" + cancelText="否" + overlayClassName="connect-popconfirm" + > + + + )} + {global.hasPermission(ClustersPermissionMap.MM2_RESTART) ? ( + arg?.optionConnect(r, 'restart')} + // onCancel={cancel} + okText="是" + cancelText="否" + overlayClassName="connect-popconfirm" + > + + + ) : ( + <> + )} + {global.hasPermission(ClustersPermissionMap.MM2_CHANGE_CONFIG) ? ( + r.sourceKafkaClusterId ? ( + + ) : ( + + + + ) + ) : ( + <> + )} + {global.hasPermission(ClustersPermissionMap.MM2_DELETE) ? : <>} +
+ ); + }, + }); + } + return columns; +}; + +// Detail +export const getMM2DetailColumns = (arg?: any) => { + const columns = [ + { + title: 'Task ID', + dataIndex: 'taskId', + key: 'taskId', + width: 240, + render: (t: any, r: any) => { + return ( + + {t} + { + + {Utils.firstCharUppercase(r?.state as string)} + + } + + ); + }, + }, + { + title: 'Worker', + dataIndex: 'workerId', + key: 'workerId', + width: 240, + }, + { + title: '错误原因', + dataIndex: 'trace', + key: 'trace', + width: 400, + needTooltip: true, + lineClampOne: true, + }, + { + title: '操作', + dataIndex: 'role', + key: 'role', + width: 100, + render: (_t: any, r: any) => { + return ( +
+ arg?.retryOption(r.taskId)} + // onCancel={cancel} + okText="是" + cancelText="否" + overlayClassName="connect-popconfirm" + > + 重试 + +
+ ); + }, + }, + ]; + return columns; +}; diff --git a/km-console/packages/layout-clusters-fe/src/pages/MirrorMaker2/index.less b/km-console/packages/layout-clusters-fe/src/pages/MirrorMaker2/index.less new file mode 100644 index 00000000..82664902 --- /dev/null +++ b/km-console/packages/layout-clusters-fe/src/pages/MirrorMaker2/index.less @@ -0,0 +1,265 @@ +// mm2列表 图表 +.metric-data-wrap { + // display: flex; + // align-items: center; + width: 100%; + .cur-val { + display: block; + text-align: right; + } + .dcloud-spin-nested-loading { + flex: 1; + } +} + +// 新增按钮 +.add-connect { + .dcloud-btn-primary:hover, + .dcloud-btn-primary:focus { + // 可以控制新增按钮的hover和focus的样式 + // background: #556ee6; + // border-color: #556ee6; + } + &-btn { + border-top-right-radius: 0 !important; + border-bottom-right-radius: 0 !important; + border-right: none; + } + &-dropdown-menu { + .dcloud-dropdown-menu { + border-radius: 8px; + &-item { + font-size: 13px; + } + } + } + &-json { + padding: 8px 12px !important; + border-top-left-radius: 0 !important; + border-bottom-left-radius: 0 !important; + border-left: none; + } +} + +// connect详情 +.mm2-detail-drawer { + .card-bar-container { + background: rgba(86, 110, 230, 0.04) !important; + + .card-bar-colunms { + background-color: rgba(86, 110, 230, 0); + } + } + &-title { + margin: 20px 0 8px; + font-family: @font-family-bold; + font-size: 16px; + font-weight: 500; + } +} + +// 删除 +.del-connect-modal { + .tip-info { + display: flex; + color: #592d00; + padding: 6px 14px; + font-size: 13px; + background: #fffae0; + border-radius: 4px; + .anticon { + color: #ffc300; + margin-right: 4px; + margin-top: 3px; + } + .test-right-away { + color: #556ee6; + cursor: pointer; + } + .dcloud-alert-content { + flex: none; + } + } +} + +// 重启、继续/暂停 气泡卡片 +.connect-popconfirm { + .dcloud-popover-inner-content { + padding: 6px 16px; + } + .dcloud-popover-inner { + border-radius: 8px; + } + .dcloud-popover-message, + .dcloud-btn { + font-size: 12px !important; + } +} + +.operate-connector-drawer { + .connector-plugin-desc { + font-size: 13px; + .connector-plugin-title { + font-family: @font-family-bold; + } + } + .dcloud-collapse.add-connector-collapse { + .add-connector-collapse-panel, + .add-connector-collapse-panel:last-child { + margin-bottom: 8px; + overflow: hidden; + background: #f8f9fa; + border: 0px; + border-radius: 8px; + .dcloud-collapse-header { + padding: 8px 12px; + font-size: 14px; + color: #495057; + .dcloud-collapse-arrow { + margin-right: 8px !important; + font-size: 10px; + } + } + &:hover .dcloud-collapse-extra { + opacity: 1; + } + &:not(.dcloud-collapse-item-active) { + .dcloud-collapse-header:hover { + background: #f1f3ff; + } + } + .dcloud-collapse-content-box { + display: flex; + flex-flow: row wrap; + justify-content: space-between; + padding: 20px 14px 0 14px; + .dcloud-form-item { + flex: 1 0 50%; + .dcloud-input-number { + width: 100%; + } + &:nth-child(2n) { + padding-left: 6px; + } + &:nth-child(2n + 1) { + padding-right: 6px; + } + .dcloud-form-item-control-input { + height: 100%; + } + } + } + } + } + + .add-container-plugin-select { + height: 27px; + margin: 4px 0; + position: relative; + .dcloud-form-item { + position: absolute; + top: 0; + left: 0; + .dcloud-form-item-control-input { + min-height: 0; + } + } + } + + .dcloud-alert { + margin: 16px 0 24px 0; + padding: 0 12px; + border: unset; + border-radius: 8px; + background: #fffae0; + .dcloud-alert-message { + font-size: 13px; + color: #592d00; + .dcloud-btn { + padding: 0 4px; + font-size: 13px; + } + } + } +} + +.operate-connector-drawer-use-json { + .CodeMirror.cm-s-default { + height: calc(100vh - 146px); + } + .dcloud-form-item { + margin-bottom: 0 !important; + } +} + +.mirror-maker-steps { + width: 340px !important; + margin: 0 auto !important; +} + +.add-mm2-config-title { + color: #556ee6; + margin-bottom: 24px; + display: inline-block; + cursor: pointer; + &-text { + margin-right: 7px; + } + &-icon { + transform: rotate(180deg); + } +} + +.custom-form-item-27 { + padding: 0 16px; + .dcloud-form-item { + margin-bottom: 6px !important; + } + .dcloud-form-item-label > label { + height: 27px; + } + .group-offset-table { + margin-bottom: 40px; + margin-top: 12px; + } +} + +.custom-form-item-36 { + .dcloud-form-item-control-input { + min-height: 36px; + } +} + +.clear-topic-minHeight { + .dcloud-form-item-control-input { + min-height: 0; + } +} + +.add-mm2-flex-layout { + &-item { + display: flex; + justify-content: space-between; + } + .senior-config-left { + width: 228px !important; + margin-right: 10px; + // .dcloud-form-item-label { + // width: 190px !important; + // text-align: right !important; + // } + } + .dcloud-form-item { + width: 345px; + flex-direction: row !important; + height: 27px; + margin-bottom: 2px !important; + &-label { + display: flex; + align-items: center; + justify-content: flex-end; + padding: 0 !important; + margin-right: 10px; + } + } +} diff --git a/km-console/packages/layout-clusters-fe/src/pages/MirrorMaker2/index.tsx b/km-console/packages/layout-clusters-fe/src/pages/MirrorMaker2/index.tsx new file mode 100644 index 00000000..42f42694 --- /dev/null +++ b/km-console/packages/layout-clusters-fe/src/pages/MirrorMaker2/index.tsx @@ -0,0 +1,240 @@ +import React, { useState, useEffect, useRef } from 'react'; +import { ProTable, Dropdown, Button, Utils, AppContainer, SearchInput, Menu } from 'knowdesign'; +import { IconFont } from '@knowdesign/icons'; +import API from '../../api'; +import { getMM2Columns, defaultPagination, optionType } from './config'; +import { tableHeaderPrefix } from '@src/constants/common'; +import MirrorMakerCard from '@src/components/CardBar/MirrorMakerCard'; +import DBreadcrumb from 'knowdesign/es/extend/d-breadcrumb'; +import AddMM2, { OperateInfo } from './AddMM2'; +import MM2Detail from './Detail'; +import notification from '@src/components/Notification'; +import './index.less'; +import AddConnectorUseJSON from './AddMM2JSON'; +import { ClustersPermissionMap } from '../CommonConfig'; +const { request } = Utils; + +const rateMap: any = { + byteRate: ['ByteRate'], + recordRate: ['RecordRate'], + replicationLatencyMsMax: ['ReplicationLatencyMsMax'], +}; + +const MirrorMaker2: React.FC = () => { + const [global] = AppContainer.useGlobalValue(); + const [loading, setLoading] = useState(false); + const [detailVisible, setDetailVisible] = useState(false); + const [data, setData] = useState([]); + const [searchKeywords, setSearchKeywords] = useState(''); + const [pagination, setPagination] = useState(defaultPagination); + const [sortInfo, setSortInfo] = useState({}); + const [detailRecord, setDetailRecord] = useState(''); + const [healthType, setHealthType] = useState(true); + const addConnectorRef = useRef(null); + const addConnectorJsonRef = useRef(null); + + const getRecent1DayTimeStamp = () => [Date.now() - 24 * 60 * 60 * 1000, Date.now()]; + // 请求接口获取数据 + const genData = async ({ pageNo, pageSize, filters, sorter }: any) => { + const [startStamp, endStamp] = getRecent1DayTimeStamp(); + if (global?.clusterInfo?.id === undefined) return; + setLoading(true); + const params = { + metricLines: { + aggType: 'avg', + endTime: endStamp, + metricsNames: ['ByteRate', 'RecordRate', 'ReplicationLatencyMsMax'], + // metricsNames: ['SourceRecordPollRate', 'SourceRecordWriteRate', 'SinkRecordReadRate', 'SinkRecordSendRate', 'TotalRecordErrors'], + startTime: startStamp, + topNu: 0, + }, + searchKeywords: searchKeywords.slice(0, 128), + pageNo, + pageSize, + latestMetricNames: ['ByteRate', 'RecordRate', 'ReplicationLatencyMsMax'], + // latestMetricNames: ['SourceRecordPollRate', 'SourceRecordWriteRate', 'SinkRecordReadRate', 'SinkRecordSendRate', 'TotalRecordErrors'], + sortType: sorter?.order ? sorter.order.substring(0, sorter.order.indexOf('end')) : 'desc', + sortMetricNameList: rateMap[sorter?.field] || [], + }; + + request(API.getMirrorMakerList(global?.clusterInfo?.id), { method: 'POST', data: params }) + // request(API.getConnectorsList(global?.clusterInfo?.id), { method: 'POST', data: params }) + .then((res: any) => { + setPagination({ + current: res.pagination?.pageNo, + pageSize: res.pagination?.pageSize, + total: res.pagination?.total, + }); + const newData = + res?.bizData.map((item: any) => { + return { + ...item, + ...item?.latestMetrics?.metrics, + key: item.connectClusterName + item.connectorName, + }; + }) || []; + setData(newData); + setLoading(false); + }) + .catch((err) => { + setLoading(false); + }); + }; + + const onTableChange = (pagination: any, filters: any, sorter: any) => { + setSortInfo(sorter); + genData({ pageNo: pagination.current, pageSize: pagination.pageSize, filters, sorter }); + }; + + const menu = ( + + + addConnectorJsonRef.current?.onOpen('create')}>JSON 新增MM2 + + + ); + + const getDetailInfo = (record: any) => { + setDetailRecord(record); + setDetailVisible(true); + }; + + // 编辑 + const editConnector = (detail: OperateInfo['detail']) => { + addConnectorRef.current?.onOpen('edit', addConnectorJsonRef.current, detail); + }; + + // 重启、暂停/继续 操作 + const optionConnect = (record: any, action: string) => { + setLoading(true); + const params = { + action, + connectClusterId: record?.connectClusterId, + connectorName: record?.connectorName, + }; + + request(API.mirrorMakerOperates, { method: 'PUT', data: params }) + .then((res: any) => { + if (res === null) { + notification.success({ + message: `任务已${optionType[params.action]}`, + description: `任务状态更新会有至多1min延迟`, + }); + genData({ pageNo: pagination.current, pageSize: pagination.pageSize, sorter: sortInfo }); + setHealthType(!healthType); + } else { + notification.error({ + message: `${optionType[params.action]}任务失败`, + }); + } + }) + .catch((err) => { + setLoading(false); + }); + }; + + // 删除任务 + const deleteTesk = () => { + genData({ pageNo: 1, pageSize: pagination.pageSize }); + }; + + useEffect(() => { + genData({ + pageNo: 1, + pageSize: pagination.pageSize, + sorter: sortInfo, + }); + }, [searchKeywords]); + + return ( + <> +
+ +
+ {/* + <> + + + */} +
+ +
+
+
+
+
genData({ pageNo: pagination.current, pageSize: pagination.pageSize })} + > + +
+
+
+ + {global.hasPermission && global.hasPermission(ClustersPermissionMap.MM2_ADD) ? ( + + + + + + + ) : ( + <> + )} +
+
+ +
+ + genData({ pageNo: pagination.current, pageSize: pagination.pageSize, sorter: sortInfo })} + /> + genData({ pageNo: pagination.current, pageSize: pagination.pageSize, sorter: sortInfo })} + /> + + ); +}; + +export default MirrorMaker2; diff --git a/km-console/packages/layout-clusters-fe/src/pages/MirrorMakerDashBoard/HasConnector.tsx b/km-console/packages/layout-clusters-fe/src/pages/MirrorMakerDashBoard/HasConnector.tsx new file mode 100644 index 00000000..a8fffc76 --- /dev/null +++ b/km-console/packages/layout-clusters-fe/src/pages/MirrorMakerDashBoard/HasConnector.tsx @@ -0,0 +1,51 @@ +import React, { useLayoutEffect, useState } from 'react'; +import api from '@src/api'; +import { Spin, Utils } from 'knowdesign'; +import { useParams } from 'react-router-dom'; +import NodataImg from '@src/assets/no-data.png'; + +interface Props { + children: any; +} + +const NoConnector = () => { + return ( +
+ + 暂无数据,请先创建 MM2 任务 +
+ ); +}; + +export default (props: Props) => { + const { clusterId } = useParams<{ + clusterId: string; + }>(); + const [loading, setLoading] = useState(true); + const [disabled, setDisabled] = useState(true); + + useLayoutEffect(() => { + Utils.request(api.getMirrorMakerMetadata(clusterId)) + .then((res: any[]) => { + res?.length && setDisabled(false); + }) + .finally(() => setLoading(false)); + }, []); + + return disabled ? ( + {loading ?
: } + ) : ( + props.children + ); +}; diff --git a/km-console/packages/layout-clusters-fe/src/pages/MirrorMakerDashBoard/index.tsx b/km-console/packages/layout-clusters-fe/src/pages/MirrorMakerDashBoard/index.tsx new file mode 100644 index 00000000..b82e7dac --- /dev/null +++ b/km-console/packages/layout-clusters-fe/src/pages/MirrorMakerDashBoard/index.tsx @@ -0,0 +1,34 @@ +import React from 'react'; +import { MetricType } from '@src/api'; +import MirrorMakerCard from '@src/components/CardBar/MirrorMakerCard'; +import DraggableCharts from '@src/components/DraggableCharts'; +import DBreadcrumb from 'knowdesign/es/extend/d-breadcrumb'; +import { AppContainer } from 'knowdesign'; +import HasConnector from './HasConnector'; + +const MirrorMakerDashboard = (): JSX.Element => { + const [global] = AppContainer.useGlobalValue(); + return ( + <> +
+ +
+ + <> + + + + + + {/* */} + + ); +}; + +export default MirrorMakerDashboard; diff --git a/km-console/packages/layout-clusters-fe/src/pages/MutliClusterPage/AccessCluster.tsx b/km-console/packages/layout-clusters-fe/src/pages/MutliClusterPage/AccessCluster.tsx index e5c1f649..28992f47 100644 --- a/km-console/packages/layout-clusters-fe/src/pages/MutliClusterPage/AccessCluster.tsx +++ b/km-console/packages/layout-clusters-fe/src/pages/MutliClusterPage/AccessCluster.tsx @@ -1,12 +1,13 @@ -import { Button, Divider, Drawer, Form, Input, InputNumber, Radio, Select, Spin, Space, Utils } from 'knowdesign'; +import { Button, Divider, Drawer, Form, Input, InputNumber, Radio, Select, Spin, Space, Utils, Tabs, Collapse, Empty } from 'knowdesign'; import message from '@src/components/Message'; -import * as React from 'react'; +import React, { forwardRef, useEffect, useImperativeHandle, useLayoutEffect, useRef, useState } from 'react'; import { useIntl } from 'react-intl'; import api from '@src/api'; -import { regClusterName, regUsername } from '@src/constants/reg'; +import { regClusterName, regIpAndPort, regUsername } from '@src/constants/reg'; import { bootstrapServersErrCodes, jmxErrCodes, zkErrCodes } from './config'; import CodeMirrorFormItem from '@src/components/CodeMirrorFormItem'; - +import { IconFont } from '@knowdesign/icons'; +import notification from '@src/components/Notification'; const LOW_KAFKA_VERSION = '2.8.0'; const CLIENT_PROPERTIES_PLACEHOLDER = `用于创建Kafka客户端进行信息获取的相关配置, 例如开启SCRAM-SHA-256安全管控模式的集群需输入如下配置, @@ -20,13 +21,12 @@ word=\\"xxxxxx\\";" } `; -const AccessClusters = (props: any): JSX.Element => { - const { afterSubmitSuccess, clusterInfo, visible } = props; +const { Panel } = Collapse; +const ClusterTabContent = forwardRef((props: any, ref): JSX.Element => { + const { form, clusterInfo, visible } = props; const intl = useIntl(); - const [form] = Form.useForm(); const [loading, setLoading] = React.useState(false); - const [confirmLoading, setConfirmLoading] = React.useState(false); const [curClusterInfo, setCurClusterInfo] = React.useState({}); const [extra, setExtra] = React.useState({ versionExtra: '', @@ -66,6 +66,7 @@ const AccessClusters = (props: any): JSX.Element => { const onCancel = () => { form.resetFields(); setLoading(false); + setCurClusterInfo({}); setExtra({ versionExtra: '', zooKeeperExtra: '', @@ -73,60 +74,6 @@ const AccessClusters = (props: any): JSX.Element => { jmxExtra: '', }); lastFormItemValue.current = { bootstrapServers: '', zookeeper: '', clientProperties: {} }; - props.setVisible && props.setVisible(false); - }; - - const onSubmit = () => { - form.validateFields().then((res) => { - setConfirmLoading(true); - let clientProperties = null; - try { - clientProperties = res.clientProperties && JSON.parse(res.clientProperties); - } catch (err) { - console.error(err); - } - - const params = { - bootstrapServers: res.bootstrapServers, - clientProperties: clientProperties || {}, - description: res.description || '', - jmxProperties: { - jmxPort: res.jmxPort, - maxConn: res.maxConn, - openSSL: res.openSSL || false, - token: res.token, - username: res.username, - }, - kafkaVersion: res.kafkaVersion, - name: res.name, - zookeeper: res.zookeeper || '', - }; - - if (!isNaN(curClusterInfo?.id)) { - Utils.put(api.phyCluster, { - ...params, - id: curClusterInfo?.id, - }) - .then(() => { - message.success('编辑成功'); - afterSubmitSuccess && afterSubmitSuccess(); - onCancel(); - }) - .finally(() => { - setConfirmLoading(false); - }); - } else { - Utils.post(api.phyCluster, params) - .then(() => { - message.success('集群接入成功。注意:新接入集群数据稳定需要1-2分钟'); - afterSubmitSuccess && afterSubmitSuccess(); - onCancel(); - }) - .finally(() => { - setConfirmLoading(false); - }); - } - }); }; const connectTest = () => { @@ -144,7 +91,7 @@ const AccessClusters = (props: any): JSX.Element => { return Utils.post(api.kafkaValidator, { bootstrapServers: bootstrapServers || '', zookeeper: zookeeper || '', - clientProperties, + clientProperties: clientProperties || {}, }) .then( (res: { @@ -213,39 +160,37 @@ const AccessClusters = (props: any): JSX.Element => { // 获取集群详情数据 React.useEffect(() => { - if (visible) { - if (clusterInfo?.id) { - setLoading(true); + if (clusterInfo?.id && visible) { + setLoading(true); - const resolveJmxProperties = (obj: any) => { - const res = { ...obj }; - try { - const originValue = obj?.jmxProperties; - if (originValue) { - const jmxProperties = JSON.parse(originValue); - typeof jmxProperties === 'object' && jmxProperties !== null && Object.assign(res, jmxProperties); - } - } catch (err) { - console.error('jmxProperties not JSON: ', err); + const resolveJmxProperties = (obj: any) => { + const res = { ...obj }; + try { + const originValue = obj?.jmxProperties; + if (originValue) { + const jmxProperties = JSON.parse(originValue); + typeof jmxProperties === 'object' && jmxProperties !== null && Object.assign(res, jmxProperties); } - return res; - }; + } catch (err) { + console.error('jmxProperties not JSON: ', err); + } + return res; + }; - Utils.request(api.getPhyClusterBasic(clusterInfo.id)) - .then((res: any) => { - setCurClusterInfo(resolveJmxProperties(res)); - }) - .catch((err) => { - setCurClusterInfo(resolveJmxProperties(clusterInfo)); - }) - .finally(() => { - setLoading(false); - }); - } else { - setCurClusterInfo({}); - } + Utils.request(api.getPhyClusterBasic(clusterInfo.id)) + .then((res: any) => { + setCurClusterInfo(resolveJmxProperties(res)); + }) + .catch((err) => { + setCurClusterInfo(resolveJmxProperties(clusterInfo)); + }) + .finally(() => { + setLoading(false); + }); + } else { + setCurClusterInfo({}); } - }, [visible, clusterInfo]); + }, [clusterInfo, visible]); const validators = { name: async (_: any, value: string) => { @@ -259,7 +204,7 @@ const AccessClusters = (props: any): JSX.Element => { return Promise.reject('集群名称长度限制在1~128字符'); } if (!new RegExp(regClusterName).test(value)) { - return Promise.reject('集群名称支持中英文、数字、特殊字符 ! " # $ % & \' ( ) * + , - . / : ; < = > ? @ [ ] ^ _ ` { | } ~'); + return Promise.reject("集群名称支持中英文、数字、特殊字符 ! # $ % & ' ( ) * + , - . / : ; < = > ? @ [ ] ^ _ ` { | } ~"); } return Utils.request(api.getClusterBasicExit(value)) .then((res: any) => { @@ -358,13 +303,511 @@ const AccessClusters = (props: any): JSX.Element => { }, }; + useImperativeHandle(ref, () => ({ + onCancel, + })); + + return ( + +
+ + + + {extra.bootstrapExtra}} + validateTrigger={'onBlur'} + rules={[ + { + required: true, + validator: validators.bootstrapServers, + }, + ]} + > + + + {extra.zooKeeperExtra}} + validateTrigger={'onBlur'} + rules={[ + { + validator: validators.zookeeper, + }, + ]} + > + + + +
+
+ + + + + + +
+ + + None + Password Authentication + + + + {({ getFieldValue }) => { + return getFieldValue('openSSL') ? ( +
+ +
+ + + + + + +
+
+ ) : null; + }} +
+
+
+ {extra.versionExtra}} + rules={[ + { + required: true, + validator: validators.kafkaVersion, + }, + ]} + > + + + + +
+ { + form.setFieldsValue({ clientProperties }); + form.validateFields(['clientProperties']); + }} + onBlur={() => { + form.validateFields(['clientProperties']).then(() => { + const bootstrapServers = form.getFieldValue('bootstrapServers'); + const zookeeper = form.getFieldValue('zookeeper'); + const clientProperties = form.getFieldValue('clientProperties'); + + if ( + clientProperties && + clientProperties !== lastFormItemValue.current.clientProperties && + (!!bootstrapServers || !!zookeeper) + ) { + connectTest() + .then(() => { + lastFormItemValue.current.clientProperties = clientProperties; + }) + .catch(() => { + message.error('连接失败'); + }); + } + }); + }} + /> +
+
+ + + + +
+ ); +}); + +const ConnectorForm = (props: { + initFieldsValue: any; + kafkaVersion: string[]; + setSelectedTabKey: React.Dispatch>; + getConnectClustersList: any; + clusterInfo: any; +}) => { + const { initFieldsValue, kafkaVersion, setSelectedTabKey, getConnectClustersList, clusterInfo } = props; + const [form] = Form.useForm(); + + const validators = { + name: async (_: any, value: string) => { + if (!value) { + return Promise.reject('集群名称不能为空'); + } + if (value === initFieldsValue?.name) { + return Promise.resolve(); + } + if (!new RegExp(regClusterName).test(value)) { + return Promise.reject('集群名称支持中英文、数字、特殊字符 ! " # $ % & \' ( ) * + , - . / : ; < = > ? @ [ ] ^ _ ` { | } ~'); + } + return Utils.request(api.getConnectClusterBasicExit(clusterInfo.id, value)) + .then((res: any) => { + const data = res || {}; + return data?.exist ? Promise.reject('集群名称重复') : Promise.resolve(); + }) + .catch(() => Promise.reject('连接超时! 请重试或检查服务')); + }, + address: async (_: any, value: string) => { + if (!value) { + return Promise.reject('请输入集群地址'); + } + if (!new RegExp(regIpAndPort).test(value)) { + return Promise.reject('格式错误,正确示例:http://1.1.1.1, http://1.1.1.1:65535, https://1.1.1.1, https://1.1.1.1:65535'); + } + return Promise.resolve(); + }, + }; + + const onFinish = (values: any) => { + const params = { + ...values, + id: initFieldsValue?.id, + jmxProperties: values.jmxProperties ? `{ "jmxProperties": "${values.jmxProperties}" }` : undefined, + }; + Utils.put(api.batchConnectClusters, [params]) + .then((res) => { + // setSelectedTabKey(undefined); + getConnectClustersList(); + notification.success({ + message: '修改Connect集群成功', + }); + }) + .catch((error) => { + notification.success({ + message: '修改Connect集群失败', + }); + }); + }; + + const onCancel = () => { + setSelectedTabKey(undefined); + try { + const jmxPortInfo = JSON.parse(initFieldsValue.jmxProperties) || {}; + form.setFieldsValue({ ...initFieldsValue, jmxProperties: jmxPortInfo.jmxProperties }); + } catch { + form.setFieldsValue({ ...initFieldsValue }); + } + }; + + useLayoutEffect(() => { + try { + const jmxPortInfo = JSON.parse(initFieldsValue.jmxProperties) || {}; + form.setFieldsValue({ ...initFieldsValue, jmxProperties: jmxPortInfo.jmxProperties }); + } catch { + form.setFieldsValue({ ...initFieldsValue }); + } + }, []); + return ( <> - + + + + + + + + + + {/* + + + + + 应用于所有Broker + 应用于特定Broker + + + + {({ getFieldValue }) => + getFieldValue('priority') === 'allBroker' ? ( + + + + ) : ( + + + + ) + } + */} +
+ + + + + + +
+ + + + + + + + + ); +}; + +const ConnectTabContent = forwardRef((props: any, ref) => { + const { kafkaVersion, clusterInfo, visible } = props; + const [connectors, setConnectors] = useState([]); + const [selectedTabKey, setSelectedTabKey] = useState(undefined); + const [loading, setLoading] = useState(true); + const genExtra = (connector: any) => ( + { + e.stopPropagation(); + Utils.delete(api.deleteConnectClusters, { + params: { + connectClusterId: connector.id, + }, + }).then((res) => { + // setSelectedTabKey(undefined); + getConnectClustersList(); + notification.success({ + message: '删除Connect集群成功', + }); + }); + }} + /> + ); + + const getConnectClustersList = () => { + setLoading(true); + Utils.request(api.getConnectClusters(clusterInfo.id)) + .then((res: any) => { + setConnectors(res || []); + }) + .finally(() => { + setLoading(false); + }); + }; + + useEffect(() => { + visible && getConnectClustersList(); + }, [visible]); + + return ( + + {connectors?.length ? ( + } + onChange={(key: string) => { + setSelectedTabKey(key); + }} + > + {connectors.map((connector, i) => { + return ( + + + + ); + })} + + ) : ( + + )} + + ); +}); + +interface AccessClusterDrawerProps { + visible: boolean; + setVisible: (visible: boolean) => void; + clusterInfo: any; + afterSubmitSuccess: () => void; + kafkaVersion: string[]; + title?: string; +} + +const AccessClusterDrawer = (props: AccessClusterDrawerProps) => { + const { afterSubmitSuccess, clusterInfo, visible, setVisible, kafkaVersion } = props; + const intl = useIntl(); + const [form] = Form.useForm(); + const [confirmLoading, setConfirmLoading] = useState(false); + const clusterRef = useRef(null); + const [positionType, setPositionType] = useState('cluster'); + + const onCancel = () => { + setPositionType('cluster'); + form.resetFields(); + clusterRef.current.onCancel(); + setVisible && setVisible(false); + }; + + const callback = (key: any) => { + setPositionType(key); + }; + + const onSubmit = () => { + form.validateFields().then((res) => { + setConfirmLoading(true); + let clientProperties = null; + try { + clientProperties = res.clientProperties && JSON.parse(res.clientProperties); + } catch (err) { + console.error(err); + } + + const params = { + bootstrapServers: res.bootstrapServers, + clientProperties: clientProperties || {}, + description: res.description || '', + jmxProperties: { + jmxPort: res.jmxPort, + maxConn: res.maxConn, + openSSL: res.openSSL || false, + token: res.token, + username: res.username, + }, + kafkaVersion: res.kafkaVersion, + name: res.name, + zookeeper: res.zookeeper || '', + }; + + if (!isNaN(clusterInfo?.id)) { + Utils.put(api.phyCluster, { + ...params, + id: clusterInfo?.id, + }) + .then(() => { + message.success('编辑成功'); + afterSubmitSuccess && afterSubmitSuccess(); + onCancel(); + }) + .finally(() => { + setConfirmLoading(false); + }); + } else { + Utils.post(api.phyCluster, params) + .then(() => { + message.success('集群接入成功。注意:新接入集群数据稳定需要1-2分钟'); + afterSubmitSuccess && afterSubmitSuccess(); + onCancel(); + }) + .finally(() => { + setConfirmLoading(false); + }); + } + }); + }; + + return ( +
- } - title={intl.formatMessage({ id: props.title || clusterInfo?.id ? 'edit.cluster' : 'access.cluster' })} - visible={props.visible} - placement="right" - width={480} - > - -
- - - - {extra.bootstrapExtra}} - validateTrigger={'onBlur'} - rules={[ - { - required: true, - validator: validators.bootstrapServers, - }, - ]} - > - - - {extra.zooKeeperExtra}} - validateTrigger={'onBlur'} - rules={[ - { - validator: validators.zookeeper, - }, - ]} - > - - - -
-
- - - - - - -
- - - None - Password Authentication - - - - {({ getFieldValue }) => { - return getFieldValue('openSSL') ? ( -
- -
- - - - - - -
-
- ) : null; - }} -
-
-
- {extra.versionExtra}} - rules={[ - { - required: true, - validator: validators.kafkaVersion, - }, - ]} - > - - - - -
- { - form.setFieldsValue({ clientProperties }); - form.validateFields(['clientProperties']); - }} - onBlur={(value: any) => { - form.validateFields(['clientProperties']).then(() => { - const bootstrapServers = form.getFieldValue('bootstrapServers'); - const zookeeper = form.getFieldValue('zookeeper'); - const clientProperties = form.getFieldValue('clientProperties'); - - if ( - clientProperties && - clientProperties !== lastFormItemValue.current.clientProperties && - (!!bootstrapServers || !!zookeeper) - ) { - connectTest() - .then((res: any) => { - lastFormItemValue.current.clientProperties = clientProperties; - }) - .catch((err) => { - message.error('连接失败'); - }); - } - }); - }} - /> -
-
- - - - -
- - + ) : null + } + title={intl.formatMessage({ id: props.title || clusterInfo?.id ? 'edit.cluster' : 'access.cluster' })} + visible={visible} + placement="right" + width={480} + > + + + + + {clusterInfo?.id && ( + + + + )} + + ); }; -export default AccessClusters; +export default AccessClusterDrawer; diff --git a/km-console/packages/layout-clusters-fe/src/pages/MutliClusterPage/AccessClusterConfig.tsx b/km-console/packages/layout-clusters-fe/src/pages/MutliClusterPage/AccessClusterConfig.tsx new file mode 100644 index 00000000..4c73a8ae --- /dev/null +++ b/km-console/packages/layout-clusters-fe/src/pages/MutliClusterPage/AccessClusterConfig.tsx @@ -0,0 +1,23 @@ +import React, { useState } from 'react'; +import { message } from 'knowdesign'; +import { HeartTwoTone } from '@ant-design/icons'; + +const AccessClusterConfig = () => { + const [count, setCount] = useState(1); + + const setErgeModal = () => { + if (count >= 50) { + message.success({ + content: 'Erge', + icon: , + }); + setCount(1); + } else { + setCount(count + 1); + } + }; + + return
; +}; + +export default AccessClusterConfig; diff --git a/km-console/packages/layout-clusters-fe/src/pages/MutliClusterPage/HomePage.tsx b/km-console/packages/layout-clusters-fe/src/pages/MutliClusterPage/HomePage.tsx index 25e5cdfe..4f59ae90 100644 --- a/km-console/packages/layout-clusters-fe/src/pages/MutliClusterPage/HomePage.tsx +++ b/km-console/packages/layout-clusters-fe/src/pages/MutliClusterPage/HomePage.tsx @@ -6,6 +6,7 @@ import TourGuide, { MultiPageSteps } from '@src/components/TourGuide'; import { healthSorceList, sliderValueMap, sortFieldList, sortTypes, statusFilters } from './config'; import ClusterList from './List'; import AccessClusters from './AccessCluster'; +import AccessCluster from './AccessClusterConfig'; import CustomCheckGroup from './CustomCheckGroup'; import { ClustersPermissionMap } from '../CommonConfig'; import './index.less'; @@ -359,6 +360,7 @@ const MultiClusterPage = () => { />
+
diff --git a/km-console/packages/layout-clusters-fe/src/pages/MutliClusterPage/index.less b/km-console/packages/layout-clusters-fe/src/pages/MutliClusterPage/index.less index 83230504..f0dab4ba 100644 --- a/km-console/packages/layout-clusters-fe/src/pages/MutliClusterPage/index.less +++ b/km-console/packages/layout-clusters-fe/src/pages/MutliClusterPage/index.less @@ -343,6 +343,14 @@ } } } + .multi-cluster-erge { + position: absolute; + width: 15px; + height: 15px; + top: 100px; + left: 20px; + background-color: transparent; + } } &-dashboard { & > .dcloud-spin-nested-loading > .dcloud-spin-container::after { @@ -466,6 +474,7 @@ max-width: 180px; overflow: hidden; text-overflow: ellipsis; + white-space: nowrap; font-family: @font-family-bold; font-size: 18px; color: #495057; @@ -633,6 +642,12 @@ } } } +.drawer-access-cluster { + .dcloud-drawer-title { + height: 27px; + line-height: 27px; + } +} .drawer-content { .dcloud-form-item-extra { @@ -674,6 +689,41 @@ } } } + .cluster-connect-custom-collapse { + background-color: transparent; + .cluster-connect-custom-panel, + .cluster-connect-custom-panel:last-child { + margin-bottom: 8px; + overflow: hidden; + background: #f8f9fa; + border: 0px; + border-radius: 8px; + .dcloud-collapse-header { + padding: 8px 12px; + font-size: 14px; + color: #495057; + .dcloud-collapse-extra { + opacity: 0; + transition: opacity 0.2s ease; + } + } + &:hover .dcloud-collapse-extra { + opacity: 1; + } + &:not(.dcloud-collapse-item-active) { + .dcloud-collapse-header:hover { + background: #f1f3ff; + } + } + .dcloud-collapse-content-box { + padding: 12px; + } + } + .dcloud-collapse-header .dcloud-collapse-arrow { + margin-right: 8px !important; + font-size: 16px; + } + } } .empty-page { diff --git a/km-console/packages/layout-clusters-fe/src/pages/SecurityACLs/index.tsx b/km-console/packages/layout-clusters-fe/src/pages/SecurityACLs/index.tsx index d361f3e7..9919afdd 100644 --- a/km-console/packages/layout-clusters-fe/src/pages/SecurityACLs/index.tsx +++ b/km-console/packages/layout-clusters-fe/src/pages/SecurityACLs/index.tsx @@ -207,7 +207,7 @@ const SecurityACLs = (): JSX.Element => {
-
+
getACLs()}> diff --git a/km-console/packages/layout-clusters-fe/src/pages/SingleClusterDetail/CheckDetail.tsx b/km-console/packages/layout-clusters-fe/src/pages/SingleClusterDetail/CheckDetail.tsx index 29fc708a..83f78db4 100644 --- a/km-console/packages/layout-clusters-fe/src/pages/SingleClusterDetail/CheckDetail.tsx +++ b/km-console/packages/layout-clusters-fe/src/pages/SingleClusterDetail/CheckDetail.tsx @@ -19,6 +19,7 @@ const CheckDetail = forwardRef((props: any, ref): JSX.Element => { const getHealthDetail = () => { setLoading(true); return Utils.request(API.getResourceListHealthDetail(+clusterId)).then((res: any) => { + res.sort((a: any, b: any) => a.dimension - b.dimension); setData(res); setLoading(false); }); diff --git a/km-console/packages/layout-clusters-fe/src/pages/SingleClusterDetail/DetailChart/index.tsx b/km-console/packages/layout-clusters-fe/src/pages/SingleClusterDetail/DetailChart/index.tsx index b9337f09..63ab9bd6 100644 --- a/km-console/packages/layout-clusters-fe/src/pages/SingleClusterDetail/DetailChart/index.tsx +++ b/km-console/packages/layout-clusters-fe/src/pages/SingleClusterDetail/DetailChart/index.tsx @@ -1,20 +1,13 @@ -import { Col, Row, SingleChart, Utils, Modal, Spin, Empty, AppContainer, Tooltip } from 'knowdesign'; -import { IconFont } from '@knowdesign/icons'; +import { SingleChart, Utils, Spin, AppContainer, Tooltip } from 'knowdesign'; import React, { useEffect, useRef, useState } from 'react'; import { arrayMoveImmutable } from 'array-move'; import api from '@src/api'; import { useParams } from 'react-router-dom'; -import { - OriginMetricData, - FormattedMetricData, - formatChartData, - supplementaryPoints, - resolveMetricsRank, - MetricInfo, -} from '@src/constants/chartConfig'; +import { OriginMetricData, FormattedMetricData, formatChartData, supplementaryPoints } from '@src/constants/chartConfig'; import { MetricType } from '@src/api'; import { getDataUnit } from '@src/constants/chartConfig'; import ChartOperateBar, { KsHeaderOptions } from '@src/components/ChartOperateBar'; +import MetricsFilter from '@src/components/ChartOperateBar/MetricSelect'; import RenderEmpty from '@src/components/RenderEmpty'; import DragGroup from '@src/components/DragGroup'; import { getChartConfig } from './config'; @@ -56,7 +49,6 @@ const DEFUALT_METRIC_NEED_METRICS = [DEFAULT_METRIC, 'TotalLogSize', 'TotalProdu const DetailChart = (props: { children: JSX.Element }): JSX.Element => { const [global] = AppContainer.useGlobalValue(); const { clusterId } = useParams<{ clusterId: string }>(); - const [metricList, setMetricList] = useState([]); // 指标列表 const [selectedMetricNames, setSelectedMetricNames] = useState<(string | number)[]>([]); // 默认选中的指标的列表 const [metricDataList, setMetricDataList] = useState([]); const [messagesInMetricData, setMessagesInMetricData] = useState({ @@ -72,6 +64,7 @@ const DetailChart = (props: { children: JSX.Element }): JSX.Element => { messagesIn: 0, other: 0, }); + const metricFilterRef = useRef(null); // 筛选项变化或者点击刷新按钮 const ksHeaderChange = (ksOptions: KsHeaderOptions) => { @@ -86,65 +79,9 @@ const DetailChart = (props: { children: JSX.Element }): JSX.Element => { }); }; - // 更新 rank - const updateRank = (metricList: MetricInfo[]) => { - const { list, listInfo, shouldUpdate } = resolveMetricsRank(metricList); - metricRankList.current = list; - if (shouldUpdate) { - updateMetricList(listInfo); - } - }; - - // 获取指标列表 - const getMetricList = () => { - Utils.request(api.getDashboardMetricList(clusterId, MetricType.Cluster)).then((res: MetricInfo[] | null) => { - if (!res) return; - const supportMetrics = res.filter((metric) => metric.support); - const selectedMetrics = supportMetrics.filter((metric) => metric.set).map((metric) => metric.name); - !selectedMetrics.includes(DEFAULT_METRIC) && selectedMetrics.push(DEFAULT_METRIC); - updateRank([...supportMetrics]); - setMetricList(supportMetrics); - setSelectedMetricNames(selectedMetrics); - }); - }; - - // 更新指标 - const updateMetricList = (metricDetailDTOList: { metric: string; rank: number; set: boolean }[]) => { - return Utils.request(api.getDashboardMetricList(clusterId, MetricType.Cluster), { - method: 'POST', - data: { - metricDetailDTOList, - }, - }); - }; - - // 指标选中项更新回调 - const indicatorChangeCallback = (newMetricNames: (string | number)[]) => { - const updateMetrics: { metric: string; set: boolean; rank: number }[] = []; - // 需要选中的指标 - newMetricNames.forEach( - (name) => - !selectedMetricNames.includes(name) && - updateMetrics.push({ metric: name as string, set: true, rank: metricList.find(({ name: metric }) => metric === name)?.rank }) - ); - // 取消选中的指标 - selectedMetricNames.forEach( - (name) => - !newMetricNames.includes(name) && - updateMetrics.push({ metric: name as string, set: false, rank: metricList.find(({ name: metric }) => metric === name)?.rank }) - ); - const requestPromise = Object.keys(updateMetrics).length ? updateMetricList(updateMetrics) : Promise.resolve(); - requestPromise.then( - () => getMetricList(), - () => getMetricList() - ); - - return requestPromise; - }; - // 获取 metric 列表的图表数据 const getMetricData = () => { - if (!selectedMetricNames.length) return; + if (!selectedMetricNames?.length) return; !curHeaderOptions.isAutoReload && setChartLoading(true); const [startTime, endTime] = curHeaderOptions.rangeTime; @@ -286,7 +223,7 @@ const DetailChart = (props: { children: JSX.Element }): JSX.Element => { const originTarget = metricRankList.current.indexOf(metricDataList[newIndex].metricName); const newList = arrayMoveImmutable(metricRankList.current, originFrom, originTarget); metricRankList.current = newList; - updateMetricList(newList.map((metric, rank) => ({ metric, rank, set: metricList.find(({ name }) => metric === name)?.set || false }))); + metricFilterRef.current?.rankChange(originFrom, originTarget); setMetricDataList(arrayMoveImmutable(metricDataList, oldIndex, newIndex)); }; @@ -302,29 +239,23 @@ const DetailChart = (props: { children: JSX.Element }): JSX.Element => { }, [curHeaderOptions]); useEffect(() => { - getMetricList(); setTimeout(() => observeDashboardWidthChange()); }, []); return (
metricFilterRef.current?.open()} onChange={ksHeaderChange} hideNodeScope={true} hideGridSelect={true} - metricSelect={{ - hide: false, - metricType: MetricType.Cluster, - tableData: metricList, - selectedRows: selectedMetricNames, - checkboxProps: (record: MetricInfo) => { - return record.name === DEFAULT_METRIC - ? { - disabled: true, - } - : {}; - }, - submitCallback: indicatorChangeCallback, + /> + { + metricRankList.current = rankList; + setSelectedMetricNames(list); }} /> diff --git a/km-console/packages/layout-clusters-fe/src/pages/SingleClusterDetail/config.tsx b/km-console/packages/layout-clusters-fe/src/pages/SingleClusterDetail/config.tsx index deaaab4b..e72bae1d 100644 --- a/km-console/packages/layout-clusters-fe/src/pages/SingleClusterDetail/config.tsx +++ b/km-console/packages/layout-clusters-fe/src/pages/SingleClusterDetail/config.tsx @@ -32,6 +32,18 @@ export const dimensionMap = { label: 'Zookeeper', href: '/zookeeper', }, + 5: { + label: 'Connect', + href: '/connect', + }, + 6: { + label: 'Connector', + href: '/connect/connectors', + }, + 7: { + label: 'MirrorMaker', + href: '/replication', + }, } as any; const toLowerCase = (name = '') => { @@ -78,6 +90,27 @@ const CONFIG_ITEM_DETAIL_DESC = { SentRate: (valueGroup: any) => { return `Zookeeper 首发包数小于 ${valueGroup?.ratio * 100}% 总容量`; }, + TaskStartupFailurePercentage: (valueGroup: any) => { + return `任务启动失败概率 小于 ${valueGroup?.value * 100}%`; + }, + ConnectorFailedTaskCount: (valueGroup: any) => { + return `失败状态的任务数量 小于 ${valueGroup?.value}`; + }, + ConnectorUnassignedTaskCount: (valueGroup: any) => { + return `未被分配的任务数量 小于 ${valueGroup?.value}`; + }, + MirrorMakerFailedTaskCount: (valueGroup: any) => { + return `失败状态的任务数量 小于 ${valueGroup?.value}`; + }, + MirrorMakerUnassignedTaskCount: (valueGroup: any) => { + return `未被分配的任务数量 小于 ${valueGroup?.value}`; + }, + ReplicationLatencyMsMax: (valueGroup: any) => { + return `消息复制最大延迟时间 小于 ${valueGroup?.value}`; + }, + 'TotalRecord-errors': (valueGroup: any) => { + return `消息处理错误的次数 增量小于 ${valueGroup?.value}`; + }, }; export const getConfigItemDetailDesc = (item: keyof typeof CONFIG_ITEM_DETAIL_DESC, valueGroup: any) => { @@ -145,9 +178,9 @@ export const getDetailColumn = (clusterId: number) => [ // eslint-disable-next-line react/display-name render: (text: number, record: any) => { return dimensionMap[text] ? ( - {toLowerCase(record?.dimensionName)} + {record?.dimensionDisplayName} ) : ( - toLowerCase(record?.dimensionName) + record?.dimensionDisplayName ); }, }, @@ -182,7 +215,7 @@ export const getDetailColumn = (clusterId: number) => [ width: 190, dataIndex: 'updateTime', render: (text: string) => { - return moment(text).format(timeFormat); + return text ? moment(text).format(timeFormat) : '-'; }, }, { @@ -191,21 +224,25 @@ export const getDetailColumn = (clusterId: number) => [ width: 280, // eslint-disable-next-line react/display-name render: (passed: boolean, record: any) => { - if (passed) { + if (record?.updateTime) { + if (passed) { + return ( + <> + + 通过 + + ); + } return ( - <> - - 通过 - +
+ +
未通过
+ +
); + } else { + return '-'; } - return ( -
- -
未通过
- -
- ); }, }, ]; @@ -219,9 +256,9 @@ export const getHealthySettingColumn = (form: any, data: any, clusterId: string) // eslint-disable-next-line react/display-name render: (text: number, record: any) => { return dimensionMap[text] ? ( - {toLowerCase(record?.dimensionName)} + {record?.dimensionDisplayName} ) : ( - toLowerCase(record?.dimensionName) + record?.dimensionDisplayName ); }, }, @@ -365,6 +402,69 @@ export const getHealthySettingColumn = (form: any, data: any, clusterId: string)
); } + case 'TaskStartupFailurePercentage': { + return ( +
+ {'>'} + {getFormItem({ configItem, percent: true })} + 则不通过 +
+ ); + } + case 'ConnectorFailedTaskCount': { + return ( +
+ {'>'} + {getFormItem({ configItem, attrs: { min: 0, max: 99998 } })} + 则不通过 +
+ ); + } + case 'ConnectorUnassignedTaskCount': { + return ( +
+ {'>'} + {getFormItem({ configItem, attrs: { min: 0, max: 99998 } })} + 则不通过 +
+ ); + } + case 'MirrorMakerFailedTaskCount': { + return ( +
+ {'>'} + {getFormItem({ configItem, attrs: { min: 0, max: 99998 } })} + 则不通过 +
+ ); + } + case 'MirrorMakerUnassignedTaskCount': { + return ( +
+ {'>'} + {getFormItem({ configItem, attrs: { min: 0, max: 99998 } })} + 则不通过 +
+ ); + } + case 'ReplicationLatencyMsMax': { + return ( +
+ {'>'} + {getFormItem({ configItem, attrs: { min: 0, max: 99998 } })} + 则不通过 +
+ ); + } + case 'TotalRecord-errors': { + return ( +
+ {'>'} + {getFormItem({ configItem, attrs: { min: 0, max: 99998 } })} + 则不通过 +
+ ); + } default: { return <>; } diff --git a/km-console/packages/layout-clusters-fe/src/pages/SingleClusterDetail/index.less b/km-console/packages/layout-clusters-fe/src/pages/SingleClusterDetail/index.less index 4b098a72..7cb7ded4 100644 --- a/km-console/packages/layout-clusters-fe/src/pages/SingleClusterDetail/index.less +++ b/km-console/packages/layout-clusters-fe/src/pages/SingleClusterDetail/index.less @@ -35,14 +35,19 @@ } .edit-icon-box { position: relative; - width: 20px; + width: 24px; cursor: pointer; .edit-icon { - position: absolute; - bottom: 2px; - margin-left: 4px; - font-size: 16px; - color: #74788d; + position: absolute; + bottom: -2px; + padding: 3px; + margin-left: 4px; + font-size: 16px; + color: #74788d; + border-radius: 50%; + &:hover { + background: rgba(33, 37, 41, 0.04); + } } } } @@ -208,6 +213,13 @@ margin-left: 4px; font-size: 14px; cursor: pointer; + .anticon { + padding: 3px; + border-radius: 50%; + &:hover { + background: rgba(33, 37, 41, 0.04); + } + } } } diff --git a/km-console/packages/layout-clusters-fe/src/pages/TopicDetail/Messages.tsx b/km-console/packages/layout-clusters-fe/src/pages/TopicDetail/Messages.tsx index 450cb59b..374af706 100644 --- a/km-console/packages/layout-clusters-fe/src/pages/TopicDetail/Messages.tsx +++ b/km-console/packages/layout-clusters-fe/src/pages/TopicDetail/Messages.tsx @@ -173,7 +173,7 @@ const TopicMessages = (props: any) => { style={{ margin: '12px 0 4px', padding: '7px 12px', background: '#FFF9E6' }} message={
- 此处展示 Topic 最近的 100 条 messages。 + 此处展示 Topic 的 100 条 messages。 {process.env.BUSINESS_VERSION ? ( 若想获取其他 messages,可前往 Produce&Consume 进行操作 diff --git a/km-console/packages/layout-clusters-fe/src/pages/TopicDetail/Replicator.tsx b/km-console/packages/layout-clusters-fe/src/pages/TopicDetail/Replicator.tsx new file mode 100644 index 00000000..89e27479 --- /dev/null +++ b/km-console/packages/layout-clusters-fe/src/pages/TopicDetail/Replicator.tsx @@ -0,0 +1,173 @@ +import React, { useState, useEffect } from 'react'; +import { AppContainer, ProTable, Utils, Tag, Modal, Tooltip } from 'knowdesign'; +import Api from '@src/api'; +import { useParams } from 'react-router-dom'; +import { getDataUnit } from '@src/constants/chartConfig'; +import message from '@src/components/Message'; +import { ClustersPermissionMap } from '../CommonConfig'; +import { ControlStatusMap } from '../CommonRoute'; +const { request } = Utils; + +const getColmns = (arg: any) => { + const formattedBytes = (v: number) => { + const [unit, size] = getDataUnit['Memory'](v); + return `${(v / size).toFixed(2)}${unit}/s`; + }; + const tagEle = ( + + 当前集群 + + ); + const baseColumns: any = [ + { + title: '源集群', + dataIndex: 'sourceClusterName', + key: 'sourceClusterName', + render: (t: string, record: any) => ( + <> + {t || '-'} + {record.sourceClusterId == arg.clusterId && tagEle} + + ), + }, + { + title: '目标集群', + dataIndex: 'destClusterName', + key: 'destClusterName', + render: (t: string, record: any) => ( + <> + {t || '-'} + {record.destClusterId == arg.clusterId && tagEle} + + ), + }, + { + title: '消息写入速率', + dataIndex: 'bytesIn', + key: 'bytesIn', + width: 150, + render: (t: number) => (t !== null && t !== undefined ? formattedBytes(t) : '-'), + }, + { + title: '消息复制速率', + dataIndex: 'replicationBytesIn', + key: 'replicationBytesIn', + width: 150, + render: (t: number) => (t !== null && t !== undefined ? formattedBytes(t) : '-'), + }, + { + title: '延迟(个消息)', + dataIndex: 'lag', + key: 'lag', + width: 150, + }, + { + title: '操作', + dataIndex: 'option', + key: 'option', + width: 100, + render: (_t: any, r: any) => { + return arg.global.hasPermission(ClustersPermissionMap.TOPIC_CANCEL_REPLICATOR) ? ( + arg.cancelSync(r)}>取消同步 + ) : ( + '-' + ); + }, + }, + ]; + + return baseColumns; +}; + +const Replicator = (props: any) => { + const { hashData } = props; + const urlParams = useParams(); // 获取地址栏参数 + const [global] = AppContainer.useGlobalValue(); + const [loading, setLoading] = useState(false); + const [data, setData] = useState([]); + const [pagination, setPagination] = useState({ + current: 1, + pageSize: 10, + position: 'bottomRight', + showSizeChanger: true, + pageSizeOptions: ['10', '20', '50', '100', '200', '500'], + }); + + const genData = () => { + if (urlParams?.clusterId === undefined || hashData?.topicName === undefined) return; + setLoading(true); + request(Api.getTopicMirrorList(urlParams?.clusterId, hashData?.topicName)) + .then((res: any = []) => { + setData(res); + }) + .finally(() => setLoading(false)); + }; + + const cancelSync = (item: any) => { + Modal.confirm({ + title: `确认取消此Topic同步吗?`, + okType: 'primary', + centered: true, + okButtonProps: { + size: 'small', + danger: true, + }, + cancelButtonProps: { + size: 'small', + }, + maskClosable: false, + onOk(close) { + close(); + const data = [ + { + destClusterPhyId: item.destClusterId, + sourceClusterPhyId: item.sourceClusterId, + topicName: item.topicName, + }, + ]; + Utils.delete(Api.handleTopicMirror(), { data }).then(() => { + message.success('成功取消Topic同步'); + genData(); + }); + }, + }); + }; + + const onTableChange = (pagination: any, filters: any, sorter: any, extra: any) => { + setPagination(pagination); + }; + + useEffect(() => { + props.positionType === 'Replicator' && genData(); + }, []); + + return ( +
+ +
+ ); +}; + +export default Replicator; diff --git a/km-console/packages/layout-clusters-fe/src/pages/TopicDetail/index.tsx b/km-console/packages/layout-clusters-fe/src/pages/TopicDetail/index.tsx index bc3f6ed4..ea009bd4 100644 --- a/km-console/packages/layout-clusters-fe/src/pages/TopicDetail/index.tsx +++ b/km-console/packages/layout-clusters-fe/src/pages/TopicDetail/index.tsx @@ -10,6 +10,7 @@ import ConsumerGroups from './ConsumerGroups'; import ACLs from './ACLs'; import Configuration from './Configuration'; import Consumers from './ConsumerGroups'; +import Replicator from './Replicator'; // import Consumers from '@src/pages/Consumers'; import './index.less'; import TopicDetailHealthCheck from '@src/components/CardBar/TopicDetailHealthCheck'; @@ -206,6 +207,9 @@ const TopicDetail = (props: any) => { )} + + {positionType === 'Replicator' && } + ); diff --git a/km-console/packages/layout-clusters-fe/src/pages/TopicList/Create.tsx b/km-console/packages/layout-clusters-fe/src/pages/TopicList/Create.tsx index 6f1cb667..bf80fd74 100644 --- a/km-console/packages/layout-clusters-fe/src/pages/TopicList/Create.tsx +++ b/km-console/packages/layout-clusters-fe/src/pages/TopicList/Create.tsx @@ -1,11 +1,13 @@ import React, { useState, useEffect } from 'react'; import { useParams } from 'react-router-dom'; -import { Alert, Button, Checkbox, Divider, Drawer, Form, Input, InputNumber, Modal, Select, Utils } from 'knowdesign'; +import { Alert, Button, Checkbox, Divider, Drawer, Form, Input, InputNumber, Modal, Select, Utils, Radio, AppContainer } from 'knowdesign'; import notification from '@src/components/Notification'; import { PlusOutlined, DownOutlined, UpOutlined } from '@ant-design/icons'; import Api from '@src/api/index'; +import { ControlStatusMap } from '../CommonRoute'; const CheckboxGroup = Checkbox.Group; +const RadioGroup = Radio.Group; interface DefaultConfig { name: string; @@ -67,6 +69,8 @@ export default (props: any) => { const routeParams = useParams<{ clusterId: string; }>(); + const [global] = AppContainer.useGlobalValue(); + const multiCleanupPolicy = global.isShowControl && global.isShowControl(ControlStatusMap.CREATE_TOPIC_CLEANUP_POLICY); const confirm = () => { form.validateFields().then((e) => { const formVal = JSON.parse(JSON.stringify(form.getFieldsValue())); @@ -106,7 +110,7 @@ export default (props: any) => { let res: any; try { res = - item.name === 'cleanup.policy' + item.name === 'cleanup.policy' && multiCleanupPolicy ? item.defaultValue .replace(/\[|\]|\s+/g, '') .split(',') @@ -267,12 +271,21 @@ export default (props: any) => {
- - - delete - - compact - + {multiCleanupPolicy ? ( + + + delete + + compact + + ) : ( + + + delete + + compact + + )}
更多配置
diff --git a/km-console/packages/layout-clusters-fe/src/pages/TopicList/config.tsx b/km-console/packages/layout-clusters-fe/src/pages/TopicList/config.tsx index c424d44c..200e20aa 100644 --- a/km-console/packages/layout-clusters-fe/src/pages/TopicList/config.tsx +++ b/km-console/packages/layout-clusters-fe/src/pages/TopicList/config.tsx @@ -23,3 +23,11 @@ export const getChartConfig = (title: string) => { }, }; }; + +export const HealthStateMap: any = { + '-1': 'Unknown', + 0: '好', + 1: '中', + 2: '差', + 3: 'Down', +}; diff --git a/km-console/packages/layout-clusters-fe/src/pages/TopicList/index.less b/km-console/packages/layout-clusters-fe/src/pages/TopicList/index.less index 0fa44077..41a407b6 100644 --- a/km-console/packages/layout-clusters-fe/src/pages/TopicList/index.less +++ b/km-console/packages/layout-clusters-fe/src/pages/TopicList/index.less @@ -124,7 +124,7 @@ text-align: right; span { margin-left: 10px; - color: #adb5bc; + color: #74788D; } } } diff --git a/km-console/packages/layout-clusters-fe/src/pages/TopicList/index.tsx b/km-console/packages/layout-clusters-fe/src/pages/TopicList/index.tsx index 60d7dd72..4c3f8857 100644 --- a/km-console/packages/layout-clusters-fe/src/pages/TopicList/index.tsx +++ b/km-console/packages/layout-clusters-fe/src/pages/TopicList/index.tsx @@ -1,7 +1,7 @@ /* eslint-disable react/display-name */ import React, { useState, useEffect } from 'react'; import { useHistory, useParams } from 'react-router-dom'; -import { AppContainer, Input, ProTable, Select, Switch, Tooltip, Utils, Dropdown, Menu, Button, Divider } from 'knowdesign'; +import { AppContainer, Input, ProTable, Select, Switch, Tooltip, Utils, Dropdown, Menu, Button, Divider, Tag } from 'knowdesign'; import { IconFont } from '@knowdesign/icons'; import Create from './Create'; import './index.less'; @@ -15,9 +15,12 @@ import DBreadcrumb from 'knowdesign/es/extend/d-breadcrumb'; import ReplicaChange from '@src/components/TopicJob/ReplicaChange'; import SmallChart from '@src/components/SmallChart'; import ReplicaMove from '@src/components/TopicJob/ReplicaMove'; +import TopicMirror from '@src/components/TopicJob/TopicMirror'; import { formatAssignSize } from '../Jobs/config'; import { DownOutlined } from '@ant-design/icons'; import { tableHeaderPrefix } from '@src/constants/common'; +import { HealthStateMap } from './config'; +import { ControlStatusMap } from '../CommonRoute'; const { Option } = Select; @@ -38,6 +41,7 @@ const AutoPage = (props: any) => { const [type, setType] = useState(''); const [changeVisible, setChangeVisible] = useState(false); const [moveVisible, setMoveVisible] = useState(false); + const [mirrorVisible, setMirrorVisible] = useState(false); const [selectValue, setSelectValue] = useState('批量操作'); const [sortObj, setSortObj] = useState<{ @@ -90,8 +94,8 @@ const AutoPage = (props: any) => { // return item?.value || ''; const orgVal = record?.latestMetrics?.metrics?.[metricName]; if (orgVal !== undefined) { - if (metricName === 'HealthScore') { - return Math.round(orgVal).toLocaleString(); + if (metricName === 'HealthState') { + return HealthStateMap[orgVal] || '-'; } else if (metricName === 'LogSize') { return Number(Utils.formatAssignSize(orgVal, 'MB')).toLocaleString(); } else { @@ -130,17 +134,34 @@ const AutoPage = (props: any) => { className: 'clean-padding-left', lineClampOne: true, // eslint-disable-next-line react/display-name - render: (t: string, r: any) => { + render: (t: string, record: any) => { return ( - - { - window.location.hash = `topicName=${t}`; - }} - > - {t} - - + <> + + { + window.location.hash = `topicName=${t}`; + }} + > + {t} + + + {record.inMirror && ( +
+ + 复制中... + +
+ )} + ); }, }, @@ -148,22 +169,24 @@ const AutoPage = (props: any) => { title: 'Partitions', dataIndex: 'partitionNum', key: 'partitionNum', - width: 95, + width: 100, }, { title: 'Replications', dataIndex: 'replicaNum', key: 'replicaNum', - width: 95, + width: 100, }, { - title: '健康分', - dataIndex: 'HealthScore', - key: 'HealthScore', + title: '健康状态', + dataIndex: 'HealthState', + key: 'HealthState', sorter: true, // 设计图上量出来的是144,但做的时候发现写144 header部分的sort箭头不出来,所以临时调大些 - width: 170, - render: (value: any, record: any) => renderLine(record, 'HealthScore'), + width: 100, + render: (value: any, record: any) => { + return calcCurValue(record, 'HealthState'); + }, }, // { // title: '创建时间', @@ -253,6 +276,7 @@ const AutoPage = (props: any) => { const onclose = () => { setChangeVisible(false); setMoveVisible(false); + setMirrorVisible(false); setSelectValue('批量操作'); }; @@ -268,6 +292,11 @@ const AutoPage = (props: any) => { setMoveVisible(true)}>迁移副本 )} + {global.hasPermission(ClustersPermissionMap.TOPIC_REPLICATOR) && ( + + setMirrorVisible(true)}>Topic复制 + + )} ); @@ -286,13 +315,15 @@ const AutoPage = (props: any) => {
-
+
{/* 批量扩缩副本 */} {/* 批量迁移 */} + {/* Topic复制 */} +
getTopicsList()}> @@ -331,7 +362,8 @@ const AutoPage = (props: any) => { }} /> {(global.hasPermission(ClustersPermissionMap.TOPIC_CHANGE_REPLICA) || - global.hasPermission(ClustersPermissionMap.TOPIC_MOVE_REPLICA)) && ( + global.hasPermission(ClustersPermissionMap.TOPIC_MOVE_REPLICA) || + global.hasPermission(ClustersPermissionMap.TOPIC_REPLICATOR)) && (