Compare commits

...

108 Commits

Author SHA1 Message Date
c2726db8a1 logrus添加支持彩虹日志的配置字段force_colors 2025-07-17 03:18:31 +08:00
Bobo
47c72651db feat: database. 2025-06-29 18:36:43 +08:00
Bobo
f267c19c73 feat: database. 2025-06-29 14:17:03 +08:00
Bobo
8c017a34e0 feat: database. 2025-06-29 11:12:16 +08:00
Bobo
ac6f0d1987 feat: database. 2025-06-29 09:41:13 +08:00
Bobo
29a8782662 feat: database. 2025-06-29 09:29:47 +08:00
Bobo
d0e55cf372 feat: api. 2025-06-29 08:50:08 +08:00
Bobo
45d364280b feat: mongodb. 2025-06-26 21:53:55 +08:00
Bobo
fcd2a5ee43 feat: influxdb. 2025-06-26 18:07:24 +08:00
Bobo
989f5da01f feat: influxdb. 2025-06-26 16:58:49 +08:00
Bobo
d31ab9cdf3 feat: elasticsearch, influxdb. 2025-06-25 19:50:51 +08:00
Bobo
735ca567bf feat: api. 2025-06-25 10:06:15 +08:00
Bobo
2aeb7b823e feat: api. 2025-06-16 22:02:56 +08:00
Bobo
569df2b7bd Merge pull request #5 from gozbq/main
nacos做配置中心时,通常也需要指定用户名、密码、命令空间id
2025-06-16 21:56:35 +08:00
baoqiang
b7f9fa5807 nacos做配置中心时,通常也需要指定用户名、密码、命令空间id 2025-06-13 11:34:55 +08:00
Bobo
bda9c5e6bb feat: redis. 2025-06-09 16:26:15 +08:00
Bobo
c88687b033 feat: config. 2025-06-09 15:56:09 +08:00
Bobo
f3dbfdea77 feat: config. 2025-06-05 15:04:22 +08:00
Bobo
579ffd9848 feat: config. 2025-06-02 15:19:13 +08:00
Bobo
c5fc1a5b7d feat: config. 2025-06-02 15:19:01 +08:00
Bobo
13aa5042b4 feat: config. 2025-06-02 15:12:30 +08:00
Bobo
f7166c40b0 feat: config. 2025-06-02 15:03:26 +08:00
Bobo
dfa34e0f51 feat: config. 2025-06-02 14:40:47 +08:00
Bobo
405717ba70 feat: config. 2025-06-02 14:38:13 +08:00
Bobo
54e887034f feat: registry. 2025-06-02 14:09:11 +08:00
Bobo
0759f2d752 feat: registry. 2025-06-02 11:58:11 +08:00
Bobo
59c731904a feat: registry. 2025-06-02 11:53:18 +08:00
Bobo
b0e91998e1 feat: registry. 2025-06-02 10:33:44 +08:00
Bobo
45a51d01a7 feat: registry. 2025-06-02 09:54:53 +08:00
Bobo
a94b15f3f9 feat: registry. 2025-06-02 08:36:25 +08:00
Bobo
22a04344d4 feat: api. 2025-05-27 13:28:19 +08:00
Bobo
9e4e56bc2d feat: api. 2025-05-21 12:54:38 +08:00
Bobo
411aabf0fa feat: rpc. 2025-05-17 23:34:13 +08:00
Bobo
46bffc550a feat: api. 2025-05-12 22:07:43 +08:00
Bobo
3f27534f13 feat: api. 2025-05-12 14:02:04 +08:00
Bobo
8a4eb0c479 feat: api. 2025-05-12 14:00:08 +08:00
Bobo
0b7e6265f4 feat: fix bug. 2025-05-12 11:21:58 +08:00
Bobo
b54b4252d9 feat: upgrade go.mod. 2025-05-10 20:04:38 +08:00
Bobo
0804d46f69 feat: upgrade go.mod. 2025-05-10 18:30:42 +08:00
Bobo
984b5dbb9c feat: upgrade go.mod. 2025-05-10 17:10:33 +08:00
Bobo
9812fa1494 feat: upgrade go.mod. 2025-05-10 16:43:40 +08:00
Bobo
6099965d89 feat: api. 2025-05-10 15:44:51 +08:00
Bobo
03c605e139 feat: api. 2025-05-10 15:43:14 +08:00
Bobo
00e2881172 feat: api. 2025-05-06 16:47:23 +08:00
Bobo
5313e6862b feat: bootstrap. 2025-04-01 18:06:05 +08:00
tx7do
bccb4e1b90 feat: edit pagination api. 2024-12-15 13:05:22 +08:00
tx7do
a24d01286b feat: edit pagination api. 2024-12-15 12:12:46 +08:00
tx7do
612a81089c feat: api. 2024-11-19 22:43:51 +08:00
tx7do
4c3b801ae5 feat: api 2024-11-19 22:41:10 +08:00
tx7do
29e8e79d50 feat: rest pprof. 2024-11-19 17:29:52 +08:00
tx7do
ce77bd094d feat: rest pprof. 2024-11-19 17:29:27 +08:00
tx7do
6f251c9fb7 feat: refactor tls utils. 2024-11-19 13:56:22 +08:00
tx7do
c7f54ac1e2 feat: refactor tls utils. 2024-11-19 13:02:41 +08:00
tx7do
6b606eb032 feat: refactor tls utils. 2024-11-19 12:42:27 +08:00
tx7do
2d9e26ee1d feat: refactor tls utils. 2024-11-19 11:54:05 +08:00
tx7do
bdd869b5ab feat: refactor go.mod. 2024-11-14 17:04:29 +08:00
tx7do
2d04529a89 feat: refactor go.mod. 2024-11-14 16:53:47 +08:00
tx7do
16cccfe6ab feat: refactor go.mod. 2024-11-14 16:49:40 +08:00
tx7do
9e9d634935 feat: refactor go.mod. 2024-11-14 16:07:28 +08:00
tx7do
f65e647380 feat: refactor go.mod. 2024-11-14 16:03:35 +08:00
tx7do
be232fe811 feat: refactor go.mod. 2024-11-14 15:51:47 +08:00
tx7do
52fc752502 feat: refactor go.mod. 2024-11-14 15:48:38 +08:00
tx7do
120029bb01 feat: refactor go.mod. 2024-11-14 15:47:21 +08:00
tx7do
f3d17b9d34 feat: refactor go.mod. 2024-11-14 15:25:58 +08:00
tx7do
62ee65a36b feat: refactor go.mod. 2024-11-14 15:00:57 +08:00
tx7do
a28f55cb99 feat: refactor go.mod. 2024-11-14 14:56:51 +08:00
tx7do
9a4861eff2 feat: refactor go.mod. 2024-11-14 14:11:32 +08:00
tx7do
dd2b0f5156 feat: refactor go.mod. 2024-11-14 13:40:48 +08:00
tx7do
c506430ed7 feat: refactor go.mod. 2024-11-14 13:29:20 +08:00
tx7do
719fa01c8d feat: refactor go.mod. 2024-11-14 13:04:30 +08:00
tx7do
3ef28da068 feat: refactor go.mod. 2024-11-14 11:45:17 +08:00
tx7do
0e4d1aa6cb feat: add database. 2024-11-14 11:35:26 +08:00
tx7do
bef6bbc269 feat: refactor go.mod. 2024-11-14 10:32:27 +08:00
tx7do
8b79665a27 feat: refactor go.mod. 2024-11-14 09:08:30 +08:00
tx7do
da4a21ce62 feat: refactor go.mod. 2024-11-14 09:03:48 +08:00
tx7do
883b23dbbb feat: refactor go.mod. 2024-11-14 08:41:54 +08:00
tx7do
40ec693f17 feat: rpc. 2024-11-13 23:48:48 +08:00
tx7do
968f1b72b0 feat: upgrade go.mod. 2024-11-13 13:41:34 +08:00
tx7do
43da1db483 feat: upgrade go.mod. 2024-11-13 13:00:36 +08:00
tx7do
16f4462220 feat: upgrade go.mod. 2024-11-13 12:40:59 +08:00
tx7do
9e051505a1 feat: support tls config. 2024-11-13 11:27:13 +08:00
tx7do
e755b6cfc8 feat: upgrade go.mod. 2024-10-16 21:04:04 +08:00
tx7do
91b483ac9a feat: conf. 2024-06-08 14:21:00 +08:00
tx7do
01424e4387 feat: refactor. 2024-06-08 14:09:29 +08:00
tx7do
5e85934e35 feat: refactor. 2024-05-14 16:37:22 +08:00
tx7do
edbcad5973 feat: refactor. 2024-05-14 16:25:53 +08:00
tx7do
6711cb7613 feat: refactor. 2024-05-14 16:25:37 +08:00
tx7do
d7b7e9e8fd feat: refactor. 2024-05-06 13:15:31 +08:00
tx7do
ad13aafe69 feat: refactor. 2024-05-06 13:04:22 +08:00
tx7do
f1fa4176af feat: refactor. 2024-05-06 12:55:44 +08:00
tx7do
8044bb92b3 feat: refactor. 2024-05-06 12:51:50 +08:00
tx7do
3eb9f014bc feat: refactor. 2024-05-06 12:32:26 +08:00
tx7do
7eb628e676 feat: refactor. 2024-05-06 12:27:45 +08:00
tx7do
7b10a94188 feat: refactor. 2024-05-06 12:09:37 +08:00
tx7do
cf902efeca feat: refactor. 2024-05-06 12:05:57 +08:00
tx7do
e043284a58 feat: refactor. 2024-05-06 10:57:42 +08:00
tx7do
f4658eb5d9 feat: refactor. 2024-05-06 10:38:46 +08:00
tx7do
72daf43151 feat: refactor. 2024-05-06 10:26:59 +08:00
tx7do
7ce746e181 feat: refactor. 2024-05-06 10:07:22 +08:00
tx7do
9df72bbad8 feat: refactor. 2024-05-06 09:52:29 +08:00
tx7do
7471dbf968 feat: refactor. 2024-05-06 08:34:16 +08:00
tx7do
601a7e5545 feat: refactor. 2024-05-06 08:23:05 +08:00
tx7do
8e16b4309c feat: refactor. 2024-05-06 08:02:26 +08:00
tx7do
cfb5aefaf9 feat: edit. 2024-05-06 06:21:05 +08:00
tx7do
22382d11e0 feat: edit. 2024-04-18 13:47:24 +08:00
tx7do
f428916cd1 feat: edit. 2023-11-18 13:30:18 +08:00
tx7do
3fc082fef5 feat: edit. 2023-11-17 22:48:39 +08:00
tx7do
094a996690 feat: upgrade go-redis version. 2023-11-13 19:52:57 +08:00
265 changed files with 38094 additions and 11070 deletions

26
.gitignore vendored
View File

@@ -1,6 +1,4 @@
# If you prefer the allow list template instead of the deny list, see community template:
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
#
# Reference https://github.com/github/gitignore/blob/master/Go.gitignore
# Binaries for programs and plugins
*.exe
*.exe~
@@ -15,7 +13,23 @@
*.out
# Dependency directories (remove the comment below to include it)
# vendor/
vendor/
# Go workspace file
go.work
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
# OS General
Thumbs.db
.DS_Store
# project
*.cert
*.key
*.log
bin/
# Develop tools
.vscode/
.idea/
*.swp

View File

@@ -13,6 +13,7 @@ SRCS_MK := $(foreach dir, app, $(wildcard $(dir)/*/*/Makefile))
# generate protobuf api go code
api:
cd api && \
buf generate
# show help

View File

@@ -6,7 +6,7 @@ managed:
optimize_for: SPEED
go_package_prefix:
default: github.com/tx7do/kratos-bootstrap/gen/api/go
default: github.com/tx7do/kratos-bootstrap/api/gen/go
except:
- 'buf.build/googleapis/googleapis'
- 'buf.build/envoyproxy/protoc-gen-validate'
@@ -18,5 +18,5 @@ plugins:
# generate go struct code
#- plugin: buf.build/protocolbuffers/go
- name: go
out: gen/api/go
out: gen/go
opt: paths=source_relative

View File

@@ -1,28 +1,2 @@
# Generated by buf. DO NOT EDIT.
version: v1
deps:
- remote: buf.build
owner: envoyproxy
repository: protoc-gen-validate
commit: eac44469a7af47e7839a7f1f3d7ac004
digest: shake256:0feabcde01b6b11e3c75a5e3f807968d5995626546f39c37e5d4205892b3a59cced0ed83b35a2eb9e6dddd3309660ad46b737c9dcd224b425de0a6654ce04417
- remote: buf.build
owner: gnostic
repository: gnostic
commit: 087bc8072ce44e339f213209e4d57bf0
digest: shake256:4689c26f0460fea84c4c277c1b9c7e7d657388c5b4116d1065f907a92100ffbea87de05bbd138a0166411361e1f6ce063b4c0c6002358d39710f3c4a8de788d5
- remote: buf.build
owner: gogo
repository: protobuf
commit: 5461a3dfa9d941da82028ab185dc2a0e
digest: shake256:37c7c75224982038cb1abf45b481ef06716c1f806ffaa162018d0df092bd11a2a9b62c2d0dc0a2ae43beff86b6014fc0eb8c594ffd84d52ade4b08fca901eadc
- remote: buf.build
owner: googleapis
repository: googleapis
commit: 28151c0d0a1641bf938a7672c500e01d
digest: shake256:49215edf8ef57f7863004539deff8834cfb2195113f0b890dd1f67815d9353e28e668019165b9d872395871eeafcbab3ccfdb2b5f11734d3cca95be9e8d139de
- remote: buf.build
owner: kratos
repository: apis
commit: c2de25f14fa445a79a054214f31d17a8
digest: shake256:91c024935d46f7966667c29e4fc933435959f93c3f0e675e1227c99db09905d44f8ec275b770da7659df5a6b18f4710da157b6d8ad760a4a95f60365b231e637

View File

@@ -1,4 +1,4 @@
version: v1
directories:
- api
- protos

View File

@@ -1,28 +0,0 @@
syntax = "proto3";
package conf;
option go_package = "github.com/tx7do/kratos-bootstrap/gen/api/go/conf/v1;conf";
import "conf/v1/kratos_conf_tracer.proto";
import "conf/v1/kratos_conf_data.proto";
import "conf/v1/kratos_conf_server.proto";
import "conf/v1/kratos_conf_client.proto";
import "conf/v1/kratos_conf_logger.proto";
import "conf/v1/kratos_conf_registry.proto";
import "conf/v1/kratos_conf_oss.proto";
import "conf/v1/kratos_conf_config.proto";
import "conf/v1/kratos_conf_notify.proto";
// 引导信息
message Bootstrap {
Server server = 1;
Client client = 2;
Data data = 3;
Tracer trace = 4;
Logger logger = 5;
Registry registry = 6;
RemoteConfig config = 7;
OSS oss = 8;
Notification notify = 9;
}

View File

@@ -1,26 +0,0 @@
syntax = "proto3";
package conf;
option go_package = "github.com/tx7do/kratos-bootstrap/gen/api/go/conf/v1;conf";
import "google/protobuf/duration.proto";
import "conf/v1/kratos_conf_middleware.proto";
// 客户端
message Client {
// REST
message REST {
google.protobuf.Duration timeout = 1; // 超时时间
Middleware middleware = 2;
}
// gPRC
message GRPC {
google.protobuf.Duration timeout = 1; // 超时时间
Middleware middleware = 2;
}
REST rest = 1; // REST服务
GRPC grpc = 2; // gRPC服务
}

View File

@@ -1,53 +0,0 @@
syntax = "proto3";
package conf;
option go_package = "github.com/tx7do/kratos-bootstrap/gen/api/go/conf/v1;conf";
import "google/protobuf/duration.proto";
// 配置服务
message RemoteConfig {
message Nacos {
string address = 1; // 服务端地址
uint64 port = 2; // 服务端端口
string key = 3; //
}
message Etcd {
repeated string endpoints = 1;
google.protobuf.Duration timeout = 2;
string key = 3; //
}
message Consul {
string scheme = 1; // 网络样式
string address = 2; // 服务端地址
string key = 3; //
}
message Apollo {
string endpoint = 1;
string app_id = 2;
string cluster = 3;
string namespace = 4;
string secret = 5;
}
message Kubernetes {
string namespace = 1;
}
message Polaris {
}
string type = 1;
Etcd etcd = 2;
Consul consul = 3;
Nacos nacos = 4;
Apollo apollo = 6;
Kubernetes kubernetes = 7;
Polaris polaris = 8;
}

View File

@@ -1,76 +0,0 @@
syntax = "proto3";
package conf;
option go_package = "github.com/tx7do/kratos-bootstrap/gen/api/go/conf/v1;conf";
import "google/protobuf/duration.proto";
// 数据
message Data {
// 数据库
message Database {
string driver = 1; // 驱动名mysql、postgresql、mongodb、sqlite……
string source = 2; // 数据源DSN字符串
bool migrate = 3; // 数据迁移开关
bool debug = 4; // 调试开关
int32 max_idle_connections = 5; // 连接池最大空闲连接数
int32 max_open_connections = 6; // 连接池最大打开连接数
google.protobuf.Duration connection_max_lifetime = 7; // 连接可重用的最大时间长度
}
// redis
message Redis {
string network = 1; // 网络
string addr = 2; // 服务端地址
string password = 3; // 密码
int32 db = 4; // 数据库索引
google.protobuf.Duration dial_timeout = 5; // 连接超时时间
google.protobuf.Duration read_timeout = 6; // 读取超时时间
google.protobuf.Duration write_timeout = 7; // 写入超时时间
}
// MongoDB
message MongoDB {
string address = 1;
}
// ClickHouse
message ClickHouse {
string address = 1;
}
// InfluxDB
message InfluxDB {
string address = 1;
string token = 2;
string orgnization = 3;
string bucket = 4;
}
// Kafka
message Kafka {
repeated string addrs = 1; // 对端网络地址
string codec = 2; // 编解码器
}
message Doris {
string address = 1;
}
message ElasticSearch {
string address = 1;
}
Database database = 1; // 数据库DSN
Redis redis = 10; // Redis
MongoDB mongodb = 11; // MongoDB数据库
ElasticSearch elastic_search = 12; // ElasticSearch数据库
ClickHouse clickhouse = 20; // ClickHouse数据库
InfluxDB influxdb = 21; // InfluxDB数据库
Doris doris = 22; // Doris数据库
Kafka kafka = 30; // Kafka服务
}

View File

@@ -1,38 +0,0 @@
syntax = "proto3";
package conf;
option go_package = "github.com/tx7do/kratos-bootstrap/gen/api/go/conf/v1;conf";
import "google/protobuf/duration.proto";
message Middleware {
// JWT校验
message Auth {
string method = 1; // JWT签名的算法支持算法HS256
string key = 2; // JWT 秘钥
}
// 限流器
message RateLimiter {
string name = 1; // 限流器名字支持bbr。
}
// 性能指标
message Metrics {
bool histogram = 1; // 直方图
bool counter = 2; // 计数器
bool gauge = 3; // 仪表盘
bool summary = 4; // 摘要
}
bool enable_logging = 1; // 日志开关
bool enable_recovery = 2; // 异常恢复
bool enable_tracing = 3; // 链路追踪开关
bool enable_validate = 4; // 参数校验开关
bool enable_circuit_breaker = 5; // 熔断器
RateLimiter limiter = 6;
Metrics metrics = 7;
Auth auth = 8;
}

View File

@@ -1,20 +0,0 @@
syntax = "proto3";
package conf;
option go_package = "github.com/tx7do/kratos-bootstrap/gen/api/go/conf/v1;conf";
message OSS {
// MinIO
message MinIO {
string endpoint = 1; // 对端端口
string access_key = 2; // 访问密钥
string secret_key = 3; // 密钥
string token = 4; // 令牌
bool use_ssl = 5; // 使用SSL
string upload_host = 6; // 上传链接的主机名
string download_host = 7; // 下载链接的主机名
}
MinIO minio = 1;
}

View File

@@ -1,82 +0,0 @@
syntax = "proto3";
package conf;
option go_package = "github.com/tx7do/kratos-bootstrap/gen/api/go/conf/v1;conf";
import "google/protobuf/duration.proto";
// 注册发现中心
message Registry {
// Consul
message Consul {
string scheme = 1; // 网络样式
string address = 2; // 服务端地址
bool health_check = 3; // 健康检查
}
// Etcd
message Etcd {
repeated string endpoints = 1;
}
// ZooKeeper
message ZooKeeper {
repeated string endpoints = 1;
google.protobuf.Duration timeout = 2;
}
// Nacos
message Nacos {
string address = 1; // 服务端地址
uint64 port = 2; // 服务端端口
string namespace_id = 3; //
string log_level = 4; // 日志等级
string cache_dir = 5; // 缓存目录
string log_dir = 6; // 日志目录
int32 update_thread_num = 7; // 更新服务的线程数
google.protobuf.Duration timeout = 8; // http请求超时时间单位: 毫秒
google.protobuf.Duration beat_interval = 9; // 心跳间隔时间,单位: 毫秒
bool not_load_cache_at_start = 10; // 在启动时不读取本地缓存数据true: 不读取false: 读取
bool update_cache_when_empty = 11; // 当服务列表为空时是否更新本地缓存true: 更新,false: 不更新
}
// Kubernetes
message Kubernetes {
}
// Eureka
message Eureka {
repeated string endpoints = 1;
google.protobuf.Duration heartbeat_interval = 2;
google.protobuf.Duration refresh_interval = 3;
string path = 4;
}
// Polaris
message Polaris {
string address = 1; // 服务端地址
int32 port = 2; // 服务端端口
int32 instance_count = 3;
string namespace = 4;
string service = 5;
string token = 6;
}
// Servicecomb
message Servicecomb {
repeated string endpoints = 1;
}
string type = 1;
Consul consul = 2; // Consul
Etcd etcd = 3; // Etcd
ZooKeeper zookeeper = 4; // ZooKeeper
Nacos nacos = 5; // Nacos
Kubernetes kubernetes = 6; // Kubernetes
Eureka eureka = 7; // Eureka
Polaris polaris = 8; // Polaris
Servicecomb servicecomb = 9; // Servicecomb
}

View File

@@ -1,202 +0,0 @@
syntax = "proto3";
package conf;
option go_package = "github.com/tx7do/kratos-bootstrap/gen/api/go/conf/v1;conf";
import "google/protobuf/duration.proto";
import "conf/v1/kratos_conf_middleware.proto";
// 服务器
message Server {
// REST
message REST {
message CORS {
repeated string headers = 1; //
repeated string methods = 2; //
repeated string origins = 3; //
}
string network = 1; // 网络
string addr = 2; // 服务监听地址
google.protobuf.Duration timeout = 3; // 超时时间
CORS cors = 4; // 服务监听地址
Middleware middleware = 5; // 中间件
bool enable_swagger = 6; // 启用SwaggerUI
bool enable_pprof = 7; // 启用pprof
}
// gPRC
message GRPC {
string network = 1; // 网络
string addr = 2; // 服务监听地址
google.protobuf.Duration timeout = 3; // 超时时间
Middleware middleware = 4;
}
// Websocket
message Websocket {
string network = 1; // 网络样式http、https
string addr = 2; // 服务监听地址
string path = 3; // 路径
string codec = 4; // 编解码器: json,xml,yaml...
google.protobuf.Duration timeout = 5; // 超时时间
}
// MQTT
message Mqtt {
string addr = 1; // 对端网络地址
}
// Kafka
message Kafka {
repeated string addrs = 1; // 对端网络地址
}
// RabbitMQ
message RabbitMQ {
repeated string addrs = 1; // 对端网络地址
}
message ActiveMQ {
string endpoint = 1; // 对端网络地址
string codec = 2; // 编解码器: json,xml,yaml...
}
message NATS {
string endpoint = 1; // 对端网络地址
string codec = 2; // 编解码器: json,xml,yaml...
}
message NSQ {
string endpoint = 1; // 对端网络地址
string codec = 2; // 编解码器: json,xml,yaml...
}
message Pulsar {
string endpoint = 1; // 对端网络地址
string codec = 2; // 编解码器: json,xml,yaml...
}
message Redis {
string endpoint = 1; // 对端网络地址
string codec = 2; // 编解码器: json,xml,yaml...
}
message RocketMQ {
string version = 1; // 驱动版本aliyun、v2、v5
string codec = 2; // 编解码器: json,xml,yaml...
bool enable_trace = 3;
repeated string name_servers = 4;
string name_server_domain = 5;
string access_key = 6;
string secret_key = 7;
string security_token = 8;
string namespace = 9;
string instance_name = 10;
string group_name = 11;
}
// Asynq
message Asynq {
string endpoint = 1; // 对端网络地址
string password = 2; // redis登录密码
int32 db = 3; // 数据库索引
}
// Machinery
message Machinery {
repeated string brokers = 1; // broker的地址可以根据实际使用的存储介质分别指定Redis、AMQP或AWS SQS
repeated string backends = 2; // backend配置用来指定存放结果的介质的配置。可以根据需求分别指定为Redis、memcached或mongodb等
}
// SSE
message SSE {
string network = 1; // 网络
string addr = 2; // 服务监听地址
string path = 3; // 路径
string codec = 4; // 编解码器
google.protobuf.Duration timeout = 5; // 超时时间
google.protobuf.Duration event_ttl = 6; // 超时时间
bool auto_stream = 7; //
bool auto_reply = 8; //
bool split_data = 9; //
bool encode_base64 = 10; // 进行BASE64编码
}
// SocketIO
message SocketIO {
string network = 1; // 网络
string addr = 2; // 服务监听地址
string path = 3; // 路径
string codec = 4; // 编解码器
}
// SignalR
message SignalR {
string network = 1; // 网络
string addr = 2; // 服务监听地址
string codec = 3; // 编解码器
google.protobuf.Duration keep_alive_interval = 4; // 超时时间
google.protobuf.Duration chan_receive_timeout = 5; // 超时时间
bool debug = 6; // 调试开关
uint32 stream_buffer_capacity = 7; //
}
// GraphQL
message GraphQL {
string network = 1; // 网络
string addr = 2; // 服务监听地址
string path = 3; // 路径
string codec = 4; // 编解码器
google.protobuf.Duration timeout = 5; // 超时时间
bool strict_slash = 6;
}
// Thrift
message Thrift {
string network = 1; // 网络
string addr = 2; // 服务监听地址
string protocol = 3;
bool buffered = 4;
bool framed = 5;
bool buffer_size = 6;
}
// RPC
REST rest = 1; // REST服务
GRPC grpc = 2; // gRPC服务
GraphQL graphql = 3; // GraphQL服务
Thrift thrift = 4; // Thrift服务
// Message Queue
Mqtt mqtt = 10; // MQTT服务
Kafka kafka = 11; // Kafka服务
RabbitMQ rabbitmq = 12; // RabbitMQ服务
ActiveMQ activemq = 13; // ActiveMQ
NATS nats = 14; // NATS
NSQ nsq = 15; // NATS
Pulsar pulsar = 16; // Pulsar
Redis redis = 17; // Redis
RocketMQ rocketmq = 18; // RocketMQ
// RealTime
Websocket websocket = 20; // Websocket服务
SSE sse = 21; // SSE服务
SocketIO socketio = 22; // SocketIO服务
SignalR signalr = 23; // SignalR服务
// Task Queue
Asynq asynq = 30; // Asynq服务
Machinery machinery = 31; // Machinery服务
}

View File

@@ -0,0 +1,330 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.36.6
// protoc (unknown)
// source: conf/v1/kratos_conf_authn.proto
package v1
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
_ "google.golang.org/protobuf/types/known/durationpb"
reflect "reflect"
sync "sync"
unsafe "unsafe"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// 认证
type Authentication struct {
state protoimpl.MessageState `protogen:"open.v1"`
Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"`
Jwt *Authentication_Jwt `protobuf:"bytes,2,opt,name=jwt,proto3,oneof" json:"jwt,omitempty"` // JWT 认证
Oidc *Authentication_OIDC `protobuf:"bytes,3,opt,name=oidc,proto3,oneof" json:"oidc,omitempty"` // OIDC
PresharedKey *Authentication_PresharedKey `protobuf:"bytes,4,opt,name=preshared_key,json=presharedKey,proto3,oneof" json:"preshared_key,omitempty"` // 预共享密钥
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Authentication) Reset() {
*x = Authentication{}
mi := &file_conf_v1_kratos_conf_authn_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Authentication) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Authentication) ProtoMessage() {}
func (x *Authentication) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_authn_proto_msgTypes[0]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Authentication.ProtoReflect.Descriptor instead.
func (*Authentication) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_authn_proto_rawDescGZIP(), []int{0}
}
func (x *Authentication) GetType() string {
if x != nil {
return x.Type
}
return ""
}
func (x *Authentication) GetJwt() *Authentication_Jwt {
if x != nil {
return x.Jwt
}
return nil
}
func (x *Authentication) GetOidc() *Authentication_OIDC {
if x != nil {
return x.Oidc
}
return nil
}
func (x *Authentication) GetPresharedKey() *Authentication_PresharedKey {
if x != nil {
return x.PresharedKey
}
return nil
}
// JWT
type Authentication_Jwt struct {
state protoimpl.MessageState `protogen:"open.v1"`
Method string `protobuf:"bytes,1,opt,name=method,proto3" json:"method,omitempty"` // JWT签名的算法支持算法HS256
Key string `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"` // JWT 秘钥
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Authentication_Jwt) Reset() {
*x = Authentication_Jwt{}
mi := &file_conf_v1_kratos_conf_authn_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Authentication_Jwt) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Authentication_Jwt) ProtoMessage() {}
func (x *Authentication_Jwt) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_authn_proto_msgTypes[1]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Authentication_Jwt.ProtoReflect.Descriptor instead.
func (*Authentication_Jwt) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_authn_proto_rawDescGZIP(), []int{0, 0}
}
func (x *Authentication_Jwt) GetMethod() string {
if x != nil {
return x.Method
}
return ""
}
func (x *Authentication_Jwt) GetKey() string {
if x != nil {
return x.Key
}
return ""
}
type Authentication_OIDC struct {
state protoimpl.MessageState `protogen:"open.v1"`
IssuerUrl string `protobuf:"bytes,1,opt,name=issuer_url,json=issuerUrl,proto3" json:"issuer_url,omitempty"`
Audience string `protobuf:"bytes,2,opt,name=audience,proto3" json:"audience,omitempty"`
Method string `protobuf:"bytes,3,opt,name=method,proto3" json:"method,omitempty"` // JWT签名的算法支持算法HS256
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Authentication_OIDC) Reset() {
*x = Authentication_OIDC{}
mi := &file_conf_v1_kratos_conf_authn_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Authentication_OIDC) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Authentication_OIDC) ProtoMessage() {}
func (x *Authentication_OIDC) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_authn_proto_msgTypes[2]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Authentication_OIDC.ProtoReflect.Descriptor instead.
func (*Authentication_OIDC) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_authn_proto_rawDescGZIP(), []int{0, 1}
}
func (x *Authentication_OIDC) GetIssuerUrl() string {
if x != nil {
return x.IssuerUrl
}
return ""
}
func (x *Authentication_OIDC) GetAudience() string {
if x != nil {
return x.Audience
}
return ""
}
func (x *Authentication_OIDC) GetMethod() string {
if x != nil {
return x.Method
}
return ""
}
type Authentication_PresharedKey struct {
state protoimpl.MessageState `protogen:"open.v1"`
ValidKeys []string `protobuf:"bytes,1,rep,name=valid_keys,json=validKeys,proto3" json:"valid_keys,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Authentication_PresharedKey) Reset() {
*x = Authentication_PresharedKey{}
mi := &file_conf_v1_kratos_conf_authn_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Authentication_PresharedKey) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Authentication_PresharedKey) ProtoMessage() {}
func (x *Authentication_PresharedKey) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_authn_proto_msgTypes[3]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Authentication_PresharedKey.ProtoReflect.Descriptor instead.
func (*Authentication_PresharedKey) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_authn_proto_rawDescGZIP(), []int{0, 2}
}
func (x *Authentication_PresharedKey) GetValidKeys() []string {
if x != nil {
return x.ValidKeys
}
return nil
}
var File_conf_v1_kratos_conf_authn_proto protoreflect.FileDescriptor
const file_conf_v1_kratos_conf_authn_proto_rawDesc = "" +
"\n" +
"\x1fconf/v1/kratos_conf_authn.proto\x12\x04conf\x1a\x1egoogle/protobuf/duration.proto\"\xb4\x03\n" +
"\x0eAuthentication\x12\x12\n" +
"\x04type\x18\x01 \x01(\tR\x04type\x12/\n" +
"\x03jwt\x18\x02 \x01(\v2\x18.conf.Authentication.JwtH\x00R\x03jwt\x88\x01\x01\x122\n" +
"\x04oidc\x18\x03 \x01(\v2\x19.conf.Authentication.OIDCH\x01R\x04oidc\x88\x01\x01\x12K\n" +
"\rpreshared_key\x18\x04 \x01(\v2!.conf.Authentication.PresharedKeyH\x02R\fpresharedKey\x88\x01\x01\x1a/\n" +
"\x03Jwt\x12\x16\n" +
"\x06method\x18\x01 \x01(\tR\x06method\x12\x10\n" +
"\x03key\x18\x02 \x01(\tR\x03key\x1aY\n" +
"\x04OIDC\x12\x1d\n" +
"\n" +
"issuer_url\x18\x01 \x01(\tR\tissuerUrl\x12\x1a\n" +
"\baudience\x18\x02 \x01(\tR\baudience\x12\x16\n" +
"\x06method\x18\x03 \x01(\tR\x06method\x1a-\n" +
"\fPresharedKey\x12\x1d\n" +
"\n" +
"valid_keys\x18\x01 \x03(\tR\tvalidKeysB\x06\n" +
"\x04_jwtB\a\n" +
"\x05_oidcB\x10\n" +
"\x0e_preshared_keyB\x86\x01\n" +
"\bcom.confB\x14KratosConfAuthnProtoP\x01Z4github.com/tx7do/kratos-bootstrap/api/gen/go/conf/v1\xa2\x02\x03CXX\xaa\x02\x04Conf\xca\x02\x04Conf\xe2\x02\x10Conf\\GPBMetadata\xea\x02\x04Confb\x06proto3"
var (
file_conf_v1_kratos_conf_authn_proto_rawDescOnce sync.Once
file_conf_v1_kratos_conf_authn_proto_rawDescData []byte
)
func file_conf_v1_kratos_conf_authn_proto_rawDescGZIP() []byte {
file_conf_v1_kratos_conf_authn_proto_rawDescOnce.Do(func() {
file_conf_v1_kratos_conf_authn_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_conf_v1_kratos_conf_authn_proto_rawDesc), len(file_conf_v1_kratos_conf_authn_proto_rawDesc)))
})
return file_conf_v1_kratos_conf_authn_proto_rawDescData
}
var file_conf_v1_kratos_conf_authn_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
var file_conf_v1_kratos_conf_authn_proto_goTypes = []any{
(*Authentication)(nil), // 0: conf.Authentication
(*Authentication_Jwt)(nil), // 1: conf.Authentication.Jwt
(*Authentication_OIDC)(nil), // 2: conf.Authentication.OIDC
(*Authentication_PresharedKey)(nil), // 3: conf.Authentication.PresharedKey
}
var file_conf_v1_kratos_conf_authn_proto_depIdxs = []int32{
1, // 0: conf.Authentication.jwt:type_name -> conf.Authentication.Jwt
2, // 1: conf.Authentication.oidc:type_name -> conf.Authentication.OIDC
3, // 2: conf.Authentication.preshared_key:type_name -> conf.Authentication.PresharedKey
3, // [3:3] is the sub-list for method output_type
3, // [3:3] is the sub-list for method input_type
3, // [3:3] is the sub-list for extension type_name
3, // [3:3] is the sub-list for extension extendee
0, // [0:3] is the sub-list for field type_name
}
func init() { file_conf_v1_kratos_conf_authn_proto_init() }
func file_conf_v1_kratos_conf_authn_proto_init() {
if File_conf_v1_kratos_conf_authn_proto != nil {
return
}
file_conf_v1_kratos_conf_authn_proto_msgTypes[0].OneofWrappers = []any{}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_conf_v1_kratos_conf_authn_proto_rawDesc), len(file_conf_v1_kratos_conf_authn_proto_rawDesc)),
NumEnums: 0,
NumMessages: 4,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_conf_v1_kratos_conf_authn_proto_goTypes,
DependencyIndexes: file_conf_v1_kratos_conf_authn_proto_depIdxs,
MessageInfos: file_conf_v1_kratos_conf_authn_proto_msgTypes,
}.Build()
File_conf_v1_kratos_conf_authn_proto = out.File
file_conf_v1_kratos_conf_authn_proto_goTypes = nil
file_conf_v1_kratos_conf_authn_proto_depIdxs = nil
}

View File

@@ -0,0 +1,560 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.36.6
// protoc (unknown)
// source: conf/v1/kratos_conf_authz.proto
package v1
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
_ "google.golang.org/protobuf/types/known/durationpb"
reflect "reflect"
sync "sync"
unsafe "unsafe"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// 授权
type Authorization struct {
state protoimpl.MessageState `protogen:"open.v1"`
Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"`
Casbin *Authorization_Casbin `protobuf:"bytes,2,opt,name=casbin,proto3" json:"casbin,omitempty"` // casbin
Opa *Authorization_OPA `protobuf:"bytes,3,opt,name=opa,proto3" json:"opa,omitempty"` // OPA
Zanzibar *Authorization_Zanzibar `protobuf:"bytes,4,opt,name=zanzibar,proto3" json:"zanzibar,omitempty"` // zanzibar
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Authorization) Reset() {
*x = Authorization{}
mi := &file_conf_v1_kratos_conf_authz_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Authorization) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Authorization) ProtoMessage() {}
func (x *Authorization) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_authz_proto_msgTypes[0]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Authorization.ProtoReflect.Descriptor instead.
func (*Authorization) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_authz_proto_rawDescGZIP(), []int{0}
}
func (x *Authorization) GetType() string {
if x != nil {
return x.Type
}
return ""
}
func (x *Authorization) GetCasbin() *Authorization_Casbin {
if x != nil {
return x.Casbin
}
return nil
}
func (x *Authorization) GetOpa() *Authorization_OPA {
if x != nil {
return x.Opa
}
return nil
}
func (x *Authorization) GetZanzibar() *Authorization_Zanzibar {
if x != nil {
return x.Zanzibar
}
return nil
}
type Authorization_Casbin struct {
state protoimpl.MessageState `protogen:"open.v1"`
ModelPath *string `protobuf:"bytes,1,opt,name=model_path,json=modelPath,proto3,oneof" json:"model_path,omitempty"` // casbin 模型文件路径
PolicyPath *string `protobuf:"bytes,2,opt,name=policy_path,json=policyPath,proto3,oneof" json:"policy_path,omitempty"` // casbin 策略文件路径
Policies []string `protobuf:"bytes,10,rep,name=policies,proto3" json:"policies,omitempty"` // 策略列表
Model *string `protobuf:"bytes,11,opt,name=model,proto3,oneof" json:"model,omitempty"` // 模型内容
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Authorization_Casbin) Reset() {
*x = Authorization_Casbin{}
mi := &file_conf_v1_kratos_conf_authz_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Authorization_Casbin) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Authorization_Casbin) ProtoMessage() {}
func (x *Authorization_Casbin) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_authz_proto_msgTypes[1]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Authorization_Casbin.ProtoReflect.Descriptor instead.
func (*Authorization_Casbin) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_authz_proto_rawDescGZIP(), []int{0, 0}
}
func (x *Authorization_Casbin) GetModelPath() string {
if x != nil && x.ModelPath != nil {
return *x.ModelPath
}
return ""
}
func (x *Authorization_Casbin) GetPolicyPath() string {
if x != nil && x.PolicyPath != nil {
return *x.PolicyPath
}
return ""
}
func (x *Authorization_Casbin) GetPolicies() []string {
if x != nil {
return x.Policies
}
return nil
}
func (x *Authorization_Casbin) GetModel() string {
if x != nil && x.Model != nil {
return *x.Model
}
return ""
}
type Authorization_OPA struct {
state protoimpl.MessageState `protogen:"open.v1"`
Policies map[string]string `protobuf:"bytes,1,rep,name=policies,proto3" json:"policies,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` // OPA 策略列表
Roles map[string]*Authorization_OPA_RoleActions `protobuf:"bytes,2,rep,name=roles,proto3" json:"roles,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` //
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Authorization_OPA) Reset() {
*x = Authorization_OPA{}
mi := &file_conf_v1_kratos_conf_authz_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Authorization_OPA) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Authorization_OPA) ProtoMessage() {}
func (x *Authorization_OPA) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_authz_proto_msgTypes[2]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Authorization_OPA.ProtoReflect.Descriptor instead.
func (*Authorization_OPA) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_authz_proto_rawDescGZIP(), []int{0, 1}
}
func (x *Authorization_OPA) GetPolicies() map[string]string {
if x != nil {
return x.Policies
}
return nil
}
func (x *Authorization_OPA) GetRoles() map[string]*Authorization_OPA_RoleActions {
if x != nil {
return x.Roles
}
return nil
}
type Authorization_Zanzibar struct {
state protoimpl.MessageState `protogen:"open.v1"`
Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` // zanzibar 类型
Keto *Authorization_Zanzibar_Keto `protobuf:"bytes,2,opt,name=keto,proto3,oneof" json:"keto,omitempty"` // Keto 配置
OpenFga *Authorization_Zanzibar_OpenFga `protobuf:"bytes,3,opt,name=open_fga,json=openFga,proto3,oneof" json:"open_fga,omitempty"` // OpenFGA 配置
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Authorization_Zanzibar) Reset() {
*x = Authorization_Zanzibar{}
mi := &file_conf_v1_kratos_conf_authz_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Authorization_Zanzibar) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Authorization_Zanzibar) ProtoMessage() {}
func (x *Authorization_Zanzibar) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_authz_proto_msgTypes[3]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Authorization_Zanzibar.ProtoReflect.Descriptor instead.
func (*Authorization_Zanzibar) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_authz_proto_rawDescGZIP(), []int{0, 2}
}
func (x *Authorization_Zanzibar) GetType() string {
if x != nil {
return x.Type
}
return ""
}
func (x *Authorization_Zanzibar) GetKeto() *Authorization_Zanzibar_Keto {
if x != nil {
return x.Keto
}
return nil
}
func (x *Authorization_Zanzibar) GetOpenFga() *Authorization_Zanzibar_OpenFga {
if x != nil {
return x.OpenFga
}
return nil
}
type Authorization_OPA_RoleActions struct {
state protoimpl.MessageState `protogen:"open.v1"`
Actions []string `protobuf:"bytes,1,rep,name=actions,proto3" json:"actions,omitempty"` // 角色对应的操作列表 {
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Authorization_OPA_RoleActions) Reset() {
*x = Authorization_OPA_RoleActions{}
mi := &file_conf_v1_kratos_conf_authz_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Authorization_OPA_RoleActions) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Authorization_OPA_RoleActions) ProtoMessage() {}
func (x *Authorization_OPA_RoleActions) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_authz_proto_msgTypes[4]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Authorization_OPA_RoleActions.ProtoReflect.Descriptor instead.
func (*Authorization_OPA_RoleActions) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_authz_proto_rawDescGZIP(), []int{0, 1, 0}
}
func (x *Authorization_OPA_RoleActions) GetActions() []string {
if x != nil {
return x.Actions
}
return nil
}
type Authorization_Zanzibar_Keto struct {
state protoimpl.MessageState `protogen:"open.v1"`
WriteUrl string `protobuf:"bytes,1,opt,name=write_url,json=writeUrl,proto3" json:"write_url,omitempty"` // 写入 URL
ReadUrl string `protobuf:"bytes,2,opt,name=read_url,json=readUrl,proto3" json:"read_url,omitempty"` // 读取 URL
UseGrpc bool `protobuf:"varint,3,opt,name=use_grpc,json=useGrpc,proto3" json:"use_grpc,omitempty"` // 是否使用 gRPC
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Authorization_Zanzibar_Keto) Reset() {
*x = Authorization_Zanzibar_Keto{}
mi := &file_conf_v1_kratos_conf_authz_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Authorization_Zanzibar_Keto) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Authorization_Zanzibar_Keto) ProtoMessage() {}
func (x *Authorization_Zanzibar_Keto) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_authz_proto_msgTypes[7]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Authorization_Zanzibar_Keto.ProtoReflect.Descriptor instead.
func (*Authorization_Zanzibar_Keto) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_authz_proto_rawDescGZIP(), []int{0, 2, 0}
}
func (x *Authorization_Zanzibar_Keto) GetWriteUrl() string {
if x != nil {
return x.WriteUrl
}
return ""
}
func (x *Authorization_Zanzibar_Keto) GetReadUrl() string {
if x != nil {
return x.ReadUrl
}
return ""
}
func (x *Authorization_Zanzibar_Keto) GetUseGrpc() bool {
if x != nil {
return x.UseGrpc
}
return false
}
type Authorization_Zanzibar_OpenFga struct {
state protoimpl.MessageState `protogen:"open.v1"`
ApiUrl string `protobuf:"bytes,1,opt,name=api_url,json=apiUrl,proto3" json:"api_url,omitempty"` // OpenFGA API URL
StoreId string `protobuf:"bytes,2,opt,name=store_id,json=storeId,proto3" json:"store_id,omitempty"` // OpenFGA 存储 ID
Token string `protobuf:"bytes,3,opt,name=token,proto3" json:"token,omitempty"` // OpenFGA 访问令牌
ClientId string `protobuf:"bytes,4,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"` // OpenFGA 客户端 ID
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Authorization_Zanzibar_OpenFga) Reset() {
*x = Authorization_Zanzibar_OpenFga{}
mi := &file_conf_v1_kratos_conf_authz_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Authorization_Zanzibar_OpenFga) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Authorization_Zanzibar_OpenFga) ProtoMessage() {}
func (x *Authorization_Zanzibar_OpenFga) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_authz_proto_msgTypes[8]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Authorization_Zanzibar_OpenFga.ProtoReflect.Descriptor instead.
func (*Authorization_Zanzibar_OpenFga) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_authz_proto_rawDescGZIP(), []int{0, 2, 1}
}
func (x *Authorization_Zanzibar_OpenFga) GetApiUrl() string {
if x != nil {
return x.ApiUrl
}
return ""
}
func (x *Authorization_Zanzibar_OpenFga) GetStoreId() string {
if x != nil {
return x.StoreId
}
return ""
}
func (x *Authorization_Zanzibar_OpenFga) GetToken() string {
if x != nil {
return x.Token
}
return ""
}
func (x *Authorization_Zanzibar_OpenFga) GetClientId() string {
if x != nil {
return x.ClientId
}
return ""
}
var File_conf_v1_kratos_conf_authz_proto protoreflect.FileDescriptor
const file_conf_v1_kratos_conf_authz_proto_rawDesc = "" +
"\n" +
"\x1fconf/v1/kratos_conf_authz.proto\x12\x04conf\x1a\x1egoogle/protobuf/duration.proto\"\xc1\b\n" +
"\rAuthorization\x12\x12\n" +
"\x04type\x18\x01 \x01(\tR\x04type\x122\n" +
"\x06casbin\x18\x02 \x01(\v2\x1a.conf.Authorization.CasbinR\x06casbin\x12)\n" +
"\x03opa\x18\x03 \x01(\v2\x17.conf.Authorization.OPAR\x03opa\x128\n" +
"\bzanzibar\x18\x04 \x01(\v2\x1c.conf.Authorization.ZanzibarR\bzanzibar\x1a\xb2\x01\n" +
"\x06Casbin\x12\"\n" +
"\n" +
"model_path\x18\x01 \x01(\tH\x00R\tmodelPath\x88\x01\x01\x12$\n" +
"\vpolicy_path\x18\x02 \x01(\tH\x01R\n" +
"policyPath\x88\x01\x01\x12\x1a\n" +
"\bpolicies\x18\n" +
" \x03(\tR\bpolicies\x12\x19\n" +
"\x05model\x18\v \x01(\tH\x02R\x05model\x88\x01\x01B\r\n" +
"\v_model_pathB\x0e\n" +
"\f_policy_pathB\b\n" +
"\x06_model\x1a\xc7\x02\n" +
"\x03OPA\x12A\n" +
"\bpolicies\x18\x01 \x03(\v2%.conf.Authorization.OPA.PoliciesEntryR\bpolicies\x128\n" +
"\x05roles\x18\x02 \x03(\v2\".conf.Authorization.OPA.RolesEntryR\x05roles\x1a'\n" +
"\vRoleActions\x12\x18\n" +
"\aactions\x18\x01 \x03(\tR\aactions\x1a;\n" +
"\rPoliciesEntry\x12\x10\n" +
"\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" +
"\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\x1a]\n" +
"\n" +
"RolesEntry\x12\x10\n" +
"\x03key\x18\x01 \x01(\tR\x03key\x129\n" +
"\x05value\x18\x02 \x01(\v2#.conf.Authorization.OPA.RoleActionsR\x05value:\x028\x01\x1a\x83\x03\n" +
"\bZanzibar\x12\x12\n" +
"\x04type\x18\x01 \x01(\tR\x04type\x12:\n" +
"\x04keto\x18\x02 \x01(\v2!.conf.Authorization.Zanzibar.KetoH\x00R\x04keto\x88\x01\x01\x12D\n" +
"\bopen_fga\x18\x03 \x01(\v2$.conf.Authorization.Zanzibar.OpenFgaH\x01R\aopenFga\x88\x01\x01\x1aY\n" +
"\x04Keto\x12\x1b\n" +
"\twrite_url\x18\x01 \x01(\tR\bwriteUrl\x12\x19\n" +
"\bread_url\x18\x02 \x01(\tR\areadUrl\x12\x19\n" +
"\buse_grpc\x18\x03 \x01(\bR\auseGrpc\x1ap\n" +
"\aOpenFga\x12\x17\n" +
"\aapi_url\x18\x01 \x01(\tR\x06apiUrl\x12\x19\n" +
"\bstore_id\x18\x02 \x01(\tR\astoreId\x12\x14\n" +
"\x05token\x18\x03 \x01(\tR\x05token\x12\x1b\n" +
"\tclient_id\x18\x04 \x01(\tR\bclientIdB\a\n" +
"\x05_ketoB\v\n" +
"\t_open_fgaB\x86\x01\n" +
"\bcom.confB\x14KratosConfAuthzProtoP\x01Z4github.com/tx7do/kratos-bootstrap/api/gen/go/conf/v1\xa2\x02\x03CXX\xaa\x02\x04Conf\xca\x02\x04Conf\xe2\x02\x10Conf\\GPBMetadata\xea\x02\x04Confb\x06proto3"
var (
file_conf_v1_kratos_conf_authz_proto_rawDescOnce sync.Once
file_conf_v1_kratos_conf_authz_proto_rawDescData []byte
)
func file_conf_v1_kratos_conf_authz_proto_rawDescGZIP() []byte {
file_conf_v1_kratos_conf_authz_proto_rawDescOnce.Do(func() {
file_conf_v1_kratos_conf_authz_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_conf_v1_kratos_conf_authz_proto_rawDesc), len(file_conf_v1_kratos_conf_authz_proto_rawDesc)))
})
return file_conf_v1_kratos_conf_authz_proto_rawDescData
}
var file_conf_v1_kratos_conf_authz_proto_msgTypes = make([]protoimpl.MessageInfo, 9)
var file_conf_v1_kratos_conf_authz_proto_goTypes = []any{
(*Authorization)(nil), // 0: conf.Authorization
(*Authorization_Casbin)(nil), // 1: conf.Authorization.Casbin
(*Authorization_OPA)(nil), // 2: conf.Authorization.OPA
(*Authorization_Zanzibar)(nil), // 3: conf.Authorization.Zanzibar
(*Authorization_OPA_RoleActions)(nil), // 4: conf.Authorization.OPA.RoleActions
nil, // 5: conf.Authorization.OPA.PoliciesEntry
nil, // 6: conf.Authorization.OPA.RolesEntry
(*Authorization_Zanzibar_Keto)(nil), // 7: conf.Authorization.Zanzibar.Keto
(*Authorization_Zanzibar_OpenFga)(nil), // 8: conf.Authorization.Zanzibar.OpenFga
}
var file_conf_v1_kratos_conf_authz_proto_depIdxs = []int32{
1, // 0: conf.Authorization.casbin:type_name -> conf.Authorization.Casbin
2, // 1: conf.Authorization.opa:type_name -> conf.Authorization.OPA
3, // 2: conf.Authorization.zanzibar:type_name -> conf.Authorization.Zanzibar
5, // 3: conf.Authorization.OPA.policies:type_name -> conf.Authorization.OPA.PoliciesEntry
6, // 4: conf.Authorization.OPA.roles:type_name -> conf.Authorization.OPA.RolesEntry
7, // 5: conf.Authorization.Zanzibar.keto:type_name -> conf.Authorization.Zanzibar.Keto
8, // 6: conf.Authorization.Zanzibar.open_fga:type_name -> conf.Authorization.Zanzibar.OpenFga
4, // 7: conf.Authorization.OPA.RolesEntry.value:type_name -> conf.Authorization.OPA.RoleActions
8, // [8:8] is the sub-list for method output_type
8, // [8:8] is the sub-list for method input_type
8, // [8:8] is the sub-list for extension type_name
8, // [8:8] is the sub-list for extension extendee
0, // [0:8] is the sub-list for field type_name
}
func init() { file_conf_v1_kratos_conf_authz_proto_init() }
func file_conf_v1_kratos_conf_authz_proto_init() {
if File_conf_v1_kratos_conf_authz_proto != nil {
return
}
file_conf_v1_kratos_conf_authz_proto_msgTypes[1].OneofWrappers = []any{}
file_conf_v1_kratos_conf_authz_proto_msgTypes[3].OneofWrappers = []any{}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_conf_v1_kratos_conf_authz_proto_rawDesc), len(file_conf_v1_kratos_conf_authz_proto_rawDesc)),
NumEnums: 0,
NumMessages: 9,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_conf_v1_kratos_conf_authz_proto_goTypes,
DependencyIndexes: file_conf_v1_kratos_conf_authz_proto_depIdxs,
MessageInfos: file_conf_v1_kratos_conf_authz_proto_msgTypes,
}.Build()
File_conf_v1_kratos_conf_authz_proto = out.File
file_conf_v1_kratos_conf_authz_proto_goTypes = nil
file_conf_v1_kratos_conf_authz_proto_depIdxs = nil
}

View File

@@ -0,0 +1,262 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.36.6
// protoc (unknown)
// source: conf/v1/kratos_conf_bootstrap.proto
package v1
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
unsafe "unsafe"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// 引导信息
type Bootstrap struct {
state protoimpl.MessageState `protogen:"open.v1"`
Server *Server `protobuf:"bytes,1,opt,name=server,proto3,oneof" json:"server,omitempty"`
Client *Client `protobuf:"bytes,2,opt,name=client,proto3,oneof" json:"client,omitempty"`
Data *Data `protobuf:"bytes,3,opt,name=data,proto3,oneof" json:"data,omitempty"`
Trace *Tracer `protobuf:"bytes,4,opt,name=trace,proto3,oneof" json:"trace,omitempty"`
Logger *Logger `protobuf:"bytes,5,opt,name=logger,proto3,oneof" json:"logger,omitempty"`
Registry *Registry `protobuf:"bytes,6,opt,name=registry,proto3,oneof" json:"registry,omitempty"`
Config *RemoteConfig `protobuf:"bytes,7,opt,name=config,proto3,oneof" json:"config,omitempty"`
Oss *OSS `protobuf:"bytes,8,opt,name=oss,proto3,oneof" json:"oss,omitempty"`
Notify *Notification `protobuf:"bytes,9,opt,name=notify,proto3,oneof" json:"notify,omitempty"`
Authn *Authentication `protobuf:"bytes,10,opt,name=authn,proto3,oneof" json:"authn,omitempty"`
Authz *Authorization `protobuf:"bytes,11,opt,name=authz,proto3,oneof" json:"authz,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Bootstrap) Reset() {
*x = Bootstrap{}
mi := &file_conf_v1_kratos_conf_bootstrap_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Bootstrap) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Bootstrap) ProtoMessage() {}
func (x *Bootstrap) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_bootstrap_proto_msgTypes[0]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Bootstrap.ProtoReflect.Descriptor instead.
func (*Bootstrap) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_bootstrap_proto_rawDescGZIP(), []int{0}
}
func (x *Bootstrap) GetServer() *Server {
if x != nil {
return x.Server
}
return nil
}
func (x *Bootstrap) GetClient() *Client {
if x != nil {
return x.Client
}
return nil
}
func (x *Bootstrap) GetData() *Data {
if x != nil {
return x.Data
}
return nil
}
func (x *Bootstrap) GetTrace() *Tracer {
if x != nil {
return x.Trace
}
return nil
}
func (x *Bootstrap) GetLogger() *Logger {
if x != nil {
return x.Logger
}
return nil
}
func (x *Bootstrap) GetRegistry() *Registry {
if x != nil {
return x.Registry
}
return nil
}
func (x *Bootstrap) GetConfig() *RemoteConfig {
if x != nil {
return x.Config
}
return nil
}
func (x *Bootstrap) GetOss() *OSS {
if x != nil {
return x.Oss
}
return nil
}
func (x *Bootstrap) GetNotify() *Notification {
if x != nil {
return x.Notify
}
return nil
}
func (x *Bootstrap) GetAuthn() *Authentication {
if x != nil {
return x.Authn
}
return nil
}
func (x *Bootstrap) GetAuthz() *Authorization {
if x != nil {
return x.Authz
}
return nil
}
var File_conf_v1_kratos_conf_bootstrap_proto protoreflect.FileDescriptor
const file_conf_v1_kratos_conf_bootstrap_proto_rawDesc = "" +
"\n" +
"#conf/v1/kratos_conf_bootstrap.proto\x12\x04conf\x1a conf/v1/kratos_conf_tracer.proto\x1a\x1econf/v1/kratos_conf_data.proto\x1a conf/v1/kratos_conf_server.proto\x1a conf/v1/kratos_conf_client.proto\x1a conf/v1/kratos_conf_logger.proto\x1a\"conf/v1/kratos_conf_registry.proto\x1a\x1dconf/v1/kratos_conf_oss.proto\x1a conf/v1/kratos_conf_config.proto\x1a conf/v1/kratos_conf_notify.proto\x1a\x1fconf/v1/kratos_conf_authn.proto\x1a\x1fconf/v1/kratos_conf_authz.proto\"\xe3\x04\n" +
"\tBootstrap\x12)\n" +
"\x06server\x18\x01 \x01(\v2\f.conf.ServerH\x00R\x06server\x88\x01\x01\x12)\n" +
"\x06client\x18\x02 \x01(\v2\f.conf.ClientH\x01R\x06client\x88\x01\x01\x12#\n" +
"\x04data\x18\x03 \x01(\v2\n" +
".conf.DataH\x02R\x04data\x88\x01\x01\x12'\n" +
"\x05trace\x18\x04 \x01(\v2\f.conf.TracerH\x03R\x05trace\x88\x01\x01\x12)\n" +
"\x06logger\x18\x05 \x01(\v2\f.conf.LoggerH\x04R\x06logger\x88\x01\x01\x12/\n" +
"\bregistry\x18\x06 \x01(\v2\x0e.conf.RegistryH\x05R\bregistry\x88\x01\x01\x12/\n" +
"\x06config\x18\a \x01(\v2\x12.conf.RemoteConfigH\x06R\x06config\x88\x01\x01\x12 \n" +
"\x03oss\x18\b \x01(\v2\t.conf.OSSH\aR\x03oss\x88\x01\x01\x12/\n" +
"\x06notify\x18\t \x01(\v2\x12.conf.NotificationH\bR\x06notify\x88\x01\x01\x12/\n" +
"\x05authn\x18\n" +
" \x01(\v2\x14.conf.AuthenticationH\tR\x05authn\x88\x01\x01\x12.\n" +
"\x05authz\x18\v \x01(\v2\x13.conf.AuthorizationH\n" +
"R\x05authz\x88\x01\x01B\t\n" +
"\a_serverB\t\n" +
"\a_clientB\a\n" +
"\x05_dataB\b\n" +
"\x06_traceB\t\n" +
"\a_loggerB\v\n" +
"\t_registryB\t\n" +
"\a_configB\x06\n" +
"\x04_ossB\t\n" +
"\a_notifyB\b\n" +
"\x06_authnB\b\n" +
"\x06_authzB\x8a\x01\n" +
"\bcom.confB\x18KratosConfBootstrapProtoP\x01Z4github.com/tx7do/kratos-bootstrap/api/gen/go/conf/v1\xa2\x02\x03CXX\xaa\x02\x04Conf\xca\x02\x04Conf\xe2\x02\x10Conf\\GPBMetadata\xea\x02\x04Confb\x06proto3"
var (
file_conf_v1_kratos_conf_bootstrap_proto_rawDescOnce sync.Once
file_conf_v1_kratos_conf_bootstrap_proto_rawDescData []byte
)
func file_conf_v1_kratos_conf_bootstrap_proto_rawDescGZIP() []byte {
file_conf_v1_kratos_conf_bootstrap_proto_rawDescOnce.Do(func() {
file_conf_v1_kratos_conf_bootstrap_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_conf_v1_kratos_conf_bootstrap_proto_rawDesc), len(file_conf_v1_kratos_conf_bootstrap_proto_rawDesc)))
})
return file_conf_v1_kratos_conf_bootstrap_proto_rawDescData
}
var file_conf_v1_kratos_conf_bootstrap_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_conf_v1_kratos_conf_bootstrap_proto_goTypes = []any{
(*Bootstrap)(nil), // 0: conf.Bootstrap
(*Server)(nil), // 1: conf.Server
(*Client)(nil), // 2: conf.Client
(*Data)(nil), // 3: conf.Data
(*Tracer)(nil), // 4: conf.Tracer
(*Logger)(nil), // 5: conf.Logger
(*Registry)(nil), // 6: conf.Registry
(*RemoteConfig)(nil), // 7: conf.RemoteConfig
(*OSS)(nil), // 8: conf.OSS
(*Notification)(nil), // 9: conf.Notification
(*Authentication)(nil), // 10: conf.Authentication
(*Authorization)(nil), // 11: conf.Authorization
}
var file_conf_v1_kratos_conf_bootstrap_proto_depIdxs = []int32{
1, // 0: conf.Bootstrap.server:type_name -> conf.Server
2, // 1: conf.Bootstrap.client:type_name -> conf.Client
3, // 2: conf.Bootstrap.data:type_name -> conf.Data
4, // 3: conf.Bootstrap.trace:type_name -> conf.Tracer
5, // 4: conf.Bootstrap.logger:type_name -> conf.Logger
6, // 5: conf.Bootstrap.registry:type_name -> conf.Registry
7, // 6: conf.Bootstrap.config:type_name -> conf.RemoteConfig
8, // 7: conf.Bootstrap.oss:type_name -> conf.OSS
9, // 8: conf.Bootstrap.notify:type_name -> conf.Notification
10, // 9: conf.Bootstrap.authn:type_name -> conf.Authentication
11, // 10: conf.Bootstrap.authz:type_name -> conf.Authorization
11, // [11:11] is the sub-list for method output_type
11, // [11:11] is the sub-list for method input_type
11, // [11:11] is the sub-list for extension type_name
11, // [11:11] is the sub-list for extension extendee
0, // [0:11] is the sub-list for field type_name
}
func init() { file_conf_v1_kratos_conf_bootstrap_proto_init() }
func file_conf_v1_kratos_conf_bootstrap_proto_init() {
if File_conf_v1_kratos_conf_bootstrap_proto != nil {
return
}
file_conf_v1_kratos_conf_tracer_proto_init()
file_conf_v1_kratos_conf_data_proto_init()
file_conf_v1_kratos_conf_server_proto_init()
file_conf_v1_kratos_conf_client_proto_init()
file_conf_v1_kratos_conf_logger_proto_init()
file_conf_v1_kratos_conf_registry_proto_init()
file_conf_v1_kratos_conf_oss_proto_init()
file_conf_v1_kratos_conf_config_proto_init()
file_conf_v1_kratos_conf_notify_proto_init()
file_conf_v1_kratos_conf_authn_proto_init()
file_conf_v1_kratos_conf_authz_proto_init()
file_conf_v1_kratos_conf_bootstrap_proto_msgTypes[0].OneofWrappers = []any{}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_conf_v1_kratos_conf_bootstrap_proto_rawDesc), len(file_conf_v1_kratos_conf_bootstrap_proto_rawDesc)),
NumEnums: 0,
NumMessages: 1,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_conf_v1_kratos_conf_bootstrap_proto_goTypes,
DependencyIndexes: file_conf_v1_kratos_conf_bootstrap_proto_depIdxs,
MessageInfos: file_conf_v1_kratos_conf_bootstrap_proto_msgTypes,
}.Build()
File_conf_v1_kratos_conf_bootstrap_proto = out.File
file_conf_v1_kratos_conf_bootstrap_proto_goTypes = nil
file_conf_v1_kratos_conf_bootstrap_proto_depIdxs = nil
}

View File

@@ -0,0 +1,286 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.36.6
// protoc (unknown)
// source: conf/v1/kratos_conf_client.proto
package v1
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
durationpb "google.golang.org/protobuf/types/known/durationpb"
reflect "reflect"
sync "sync"
unsafe "unsafe"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// 客户端
type Client struct {
state protoimpl.MessageState `protogen:"open.v1"`
Rest *Client_REST `protobuf:"bytes,1,opt,name=rest,proto3,oneof" json:"rest,omitempty"` // REST服务
Grpc *Client_GRPC `protobuf:"bytes,2,opt,name=grpc,proto3,oneof" json:"grpc,omitempty"` // gRPC服务
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Client) Reset() {
*x = Client{}
mi := &file_conf_v1_kratos_conf_client_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Client) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Client) ProtoMessage() {}
func (x *Client) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_client_proto_msgTypes[0]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Client.ProtoReflect.Descriptor instead.
func (*Client) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_client_proto_rawDescGZIP(), []int{0}
}
func (x *Client) GetRest() *Client_REST {
if x != nil {
return x.Rest
}
return nil
}
func (x *Client) GetGrpc() *Client_GRPC {
if x != nil {
return x.Grpc
}
return nil
}
// REST
type Client_REST struct {
state protoimpl.MessageState `protogen:"open.v1"`
Timeout *durationpb.Duration `protobuf:"bytes,1,opt,name=timeout,proto3" json:"timeout,omitempty"` // 超时时间
Middleware *Middleware `protobuf:"bytes,2,opt,name=middleware,proto3" json:"middleware,omitempty"` // 中间件
Tls *TLS `protobuf:"bytes,3,opt,name=tls,proto3" json:"tls,omitempty"` // TLS配置
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Client_REST) Reset() {
*x = Client_REST{}
mi := &file_conf_v1_kratos_conf_client_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Client_REST) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Client_REST) ProtoMessage() {}
func (x *Client_REST) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_client_proto_msgTypes[1]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Client_REST.ProtoReflect.Descriptor instead.
func (*Client_REST) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_client_proto_rawDescGZIP(), []int{0, 0}
}
func (x *Client_REST) GetTimeout() *durationpb.Duration {
if x != nil {
return x.Timeout
}
return nil
}
func (x *Client_REST) GetMiddleware() *Middleware {
if x != nil {
return x.Middleware
}
return nil
}
func (x *Client_REST) GetTls() *TLS {
if x != nil {
return x.Tls
}
return nil
}
// gPRC
type Client_GRPC struct {
state protoimpl.MessageState `protogen:"open.v1"`
Timeout *durationpb.Duration `protobuf:"bytes,1,opt,name=timeout,proto3" json:"timeout,omitempty"` // 超时时间
Middleware *Middleware `protobuf:"bytes,2,opt,name=middleware,proto3" json:"middleware,omitempty"` // 中间件
Tls *TLS `protobuf:"bytes,3,opt,name=tls,proto3" json:"tls,omitempty"` // TLS配置
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Client_GRPC) Reset() {
*x = Client_GRPC{}
mi := &file_conf_v1_kratos_conf_client_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Client_GRPC) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Client_GRPC) ProtoMessage() {}
func (x *Client_GRPC) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_client_proto_msgTypes[2]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Client_GRPC.ProtoReflect.Descriptor instead.
func (*Client_GRPC) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_client_proto_rawDescGZIP(), []int{0, 1}
}
func (x *Client_GRPC) GetTimeout() *durationpb.Duration {
if x != nil {
return x.Timeout
}
return nil
}
func (x *Client_GRPC) GetMiddleware() *Middleware {
if x != nil {
return x.Middleware
}
return nil
}
func (x *Client_GRPC) GetTls() *TLS {
if x != nil {
return x.Tls
}
return nil
}
var File_conf_v1_kratos_conf_client_proto protoreflect.FileDescriptor
const file_conf_v1_kratos_conf_client_proto_rawDesc = "" +
"\n" +
" conf/v1/kratos_conf_client.proto\x12\x04conf\x1a\x1egoogle/protobuf/duration.proto\x1a$conf/v1/kratos_conf_middleware.proto\x1a\x1dconf/v1/kratos_conf_tls.proto\"\x8c\x03\n" +
"\x06Client\x12*\n" +
"\x04rest\x18\x01 \x01(\v2\x11.conf.Client.RESTH\x00R\x04rest\x88\x01\x01\x12*\n" +
"\x04grpc\x18\x02 \x01(\v2\x11.conf.Client.GRPCH\x01R\x04grpc\x88\x01\x01\x1a\x8a\x01\n" +
"\x04REST\x123\n" +
"\atimeout\x18\x01 \x01(\v2\x19.google.protobuf.DurationR\atimeout\x120\n" +
"\n" +
"middleware\x18\x02 \x01(\v2\x10.conf.MiddlewareR\n" +
"middleware\x12\x1b\n" +
"\x03tls\x18\x03 \x01(\v2\t.conf.TLSR\x03tls\x1a\x8a\x01\n" +
"\x04GRPC\x123\n" +
"\atimeout\x18\x01 \x01(\v2\x19.google.protobuf.DurationR\atimeout\x120\n" +
"\n" +
"middleware\x18\x02 \x01(\v2\x10.conf.MiddlewareR\n" +
"middleware\x12\x1b\n" +
"\x03tls\x18\x03 \x01(\v2\t.conf.TLSR\x03tlsB\a\n" +
"\x05_restB\a\n" +
"\x05_grpcB\x87\x01\n" +
"\bcom.confB\x15KratosConfClientProtoP\x01Z4github.com/tx7do/kratos-bootstrap/api/gen/go/conf/v1\xa2\x02\x03CXX\xaa\x02\x04Conf\xca\x02\x04Conf\xe2\x02\x10Conf\\GPBMetadata\xea\x02\x04Confb\x06proto3"
var (
file_conf_v1_kratos_conf_client_proto_rawDescOnce sync.Once
file_conf_v1_kratos_conf_client_proto_rawDescData []byte
)
func file_conf_v1_kratos_conf_client_proto_rawDescGZIP() []byte {
file_conf_v1_kratos_conf_client_proto_rawDescOnce.Do(func() {
file_conf_v1_kratos_conf_client_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_conf_v1_kratos_conf_client_proto_rawDesc), len(file_conf_v1_kratos_conf_client_proto_rawDesc)))
})
return file_conf_v1_kratos_conf_client_proto_rawDescData
}
var file_conf_v1_kratos_conf_client_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
var file_conf_v1_kratos_conf_client_proto_goTypes = []any{
(*Client)(nil), // 0: conf.Client
(*Client_REST)(nil), // 1: conf.Client.REST
(*Client_GRPC)(nil), // 2: conf.Client.GRPC
(*durationpb.Duration)(nil), // 3: google.protobuf.Duration
(*Middleware)(nil), // 4: conf.Middleware
(*TLS)(nil), // 5: conf.TLS
}
var file_conf_v1_kratos_conf_client_proto_depIdxs = []int32{
1, // 0: conf.Client.rest:type_name -> conf.Client.REST
2, // 1: conf.Client.grpc:type_name -> conf.Client.GRPC
3, // 2: conf.Client.REST.timeout:type_name -> google.protobuf.Duration
4, // 3: conf.Client.REST.middleware:type_name -> conf.Middleware
5, // 4: conf.Client.REST.tls:type_name -> conf.TLS
3, // 5: conf.Client.GRPC.timeout:type_name -> google.protobuf.Duration
4, // 6: conf.Client.GRPC.middleware:type_name -> conf.Middleware
5, // 7: conf.Client.GRPC.tls:type_name -> conf.TLS
8, // [8:8] is the sub-list for method output_type
8, // [8:8] is the sub-list for method input_type
8, // [8:8] is the sub-list for extension type_name
8, // [8:8] is the sub-list for extension extendee
0, // [0:8] is the sub-list for field type_name
}
func init() { file_conf_v1_kratos_conf_client_proto_init() }
func file_conf_v1_kratos_conf_client_proto_init() {
if File_conf_v1_kratos_conf_client_proto != nil {
return
}
file_conf_v1_kratos_conf_middleware_proto_init()
file_conf_v1_kratos_conf_tls_proto_init()
file_conf_v1_kratos_conf_client_proto_msgTypes[0].OneofWrappers = []any{}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_conf_v1_kratos_conf_client_proto_rawDesc), len(file_conf_v1_kratos_conf_client_proto_rawDesc)),
NumEnums: 0,
NumMessages: 3,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_conf_v1_kratos_conf_client_proto_goTypes,
DependencyIndexes: file_conf_v1_kratos_conf_client_proto_depIdxs,
MessageInfos: file_conf_v1_kratos_conf_client_proto_msgTypes,
}.Build()
File_conf_v1_kratos_conf_client_proto = out.File
file_conf_v1_kratos_conf_client_proto_goTypes = nil
file_conf_v1_kratos_conf_client_proto_depIdxs = nil
}

View File

@@ -0,0 +1,588 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.36.6
// protoc (unknown)
// source: conf/v1/kratos_conf_config.proto
package v1
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
durationpb "google.golang.org/protobuf/types/known/durationpb"
reflect "reflect"
sync "sync"
unsafe "unsafe"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// 配置服务
type RemoteConfig struct {
state protoimpl.MessageState `protogen:"open.v1"`
Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` // 配置类型
Etcd *RemoteConfig_Etcd `protobuf:"bytes,2,opt,name=etcd,proto3,oneof" json:"etcd,omitempty"`
Consul *RemoteConfig_Consul `protobuf:"bytes,3,opt,name=consul,proto3,oneof" json:"consul,omitempty"`
Nacos *RemoteConfig_Nacos `protobuf:"bytes,4,opt,name=nacos,proto3,oneof" json:"nacos,omitempty"`
Apollo *RemoteConfig_Apollo `protobuf:"bytes,6,opt,name=apollo,proto3,oneof" json:"apollo,omitempty"`
Kubernetes *RemoteConfig_Kubernetes `protobuf:"bytes,7,opt,name=kubernetes,proto3,oneof" json:"kubernetes,omitempty"`
Polaris *RemoteConfig_Polaris `protobuf:"bytes,8,opt,name=polaris,proto3,oneof" json:"polaris,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *RemoteConfig) Reset() {
*x = RemoteConfig{}
mi := &file_conf_v1_kratos_conf_config_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *RemoteConfig) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*RemoteConfig) ProtoMessage() {}
func (x *RemoteConfig) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_config_proto_msgTypes[0]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use RemoteConfig.ProtoReflect.Descriptor instead.
func (*RemoteConfig) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_config_proto_rawDescGZIP(), []int{0}
}
func (x *RemoteConfig) GetType() string {
if x != nil {
return x.Type
}
return ""
}
func (x *RemoteConfig) GetEtcd() *RemoteConfig_Etcd {
if x != nil {
return x.Etcd
}
return nil
}
func (x *RemoteConfig) GetConsul() *RemoteConfig_Consul {
if x != nil {
return x.Consul
}
return nil
}
func (x *RemoteConfig) GetNacos() *RemoteConfig_Nacos {
if x != nil {
return x.Nacos
}
return nil
}
func (x *RemoteConfig) GetApollo() *RemoteConfig_Apollo {
if x != nil {
return x.Apollo
}
return nil
}
func (x *RemoteConfig) GetKubernetes() *RemoteConfig_Kubernetes {
if x != nil {
return x.Kubernetes
}
return nil
}
func (x *RemoteConfig) GetPolaris() *RemoteConfig_Polaris {
if x != nil {
return x.Polaris
}
return nil
}
type RemoteConfig_Nacos struct {
state protoimpl.MessageState `protogen:"open.v1"`
Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` // 服务端地址
Port uint64 `protobuf:"varint,2,opt,name=port,proto3" json:"port,omitempty"` // 服务端端口
Key string `protobuf:"bytes,3,opt,name=key,proto3" json:"key,omitempty"` // 配置键
Username string `protobuf:"bytes,4,opt,name=username,proto3" json:"username,omitempty"` // 用户名
Password string `protobuf:"bytes,5,opt,name=password,proto3" json:"password,omitempty"` // 密码
NamespaceId string `protobuf:"bytes,6,opt,name=namespace_id,json=namespaceId,proto3" json:"namespace_id,omitempty"` // 命名空间ID
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *RemoteConfig_Nacos) Reset() {
*x = RemoteConfig_Nacos{}
mi := &file_conf_v1_kratos_conf_config_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *RemoteConfig_Nacos) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*RemoteConfig_Nacos) ProtoMessage() {}
func (x *RemoteConfig_Nacos) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_config_proto_msgTypes[1]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use RemoteConfig_Nacos.ProtoReflect.Descriptor instead.
func (*RemoteConfig_Nacos) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_config_proto_rawDescGZIP(), []int{0, 0}
}
func (x *RemoteConfig_Nacos) GetAddress() string {
if x != nil {
return x.Address
}
return ""
}
func (x *RemoteConfig_Nacos) GetPort() uint64 {
if x != nil {
return x.Port
}
return 0
}
func (x *RemoteConfig_Nacos) GetKey() string {
if x != nil {
return x.Key
}
return ""
}
func (x *RemoteConfig_Nacos) GetUsername() string {
if x != nil {
return x.Username
}
return ""
}
func (x *RemoteConfig_Nacos) GetPassword() string {
if x != nil {
return x.Password
}
return ""
}
func (x *RemoteConfig_Nacos) GetNamespaceId() string {
if x != nil {
return x.NamespaceId
}
return ""
}
type RemoteConfig_Etcd struct {
state protoimpl.MessageState `protogen:"open.v1"`
Endpoints []string `protobuf:"bytes,1,rep,name=endpoints,proto3" json:"endpoints,omitempty"` // 服务端地址
Timeout *durationpb.Duration `protobuf:"bytes,2,opt,name=timeout,proto3" json:"timeout,omitempty"` // 超时时间
Key string `protobuf:"bytes,3,opt,name=key,proto3" json:"key,omitempty"` // 配置键
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *RemoteConfig_Etcd) Reset() {
*x = RemoteConfig_Etcd{}
mi := &file_conf_v1_kratos_conf_config_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *RemoteConfig_Etcd) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*RemoteConfig_Etcd) ProtoMessage() {}
func (x *RemoteConfig_Etcd) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_config_proto_msgTypes[2]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use RemoteConfig_Etcd.ProtoReflect.Descriptor instead.
func (*RemoteConfig_Etcd) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_config_proto_rawDescGZIP(), []int{0, 1}
}
func (x *RemoteConfig_Etcd) GetEndpoints() []string {
if x != nil {
return x.Endpoints
}
return nil
}
func (x *RemoteConfig_Etcd) GetTimeout() *durationpb.Duration {
if x != nil {
return x.Timeout
}
return nil
}
func (x *RemoteConfig_Etcd) GetKey() string {
if x != nil {
return x.Key
}
return ""
}
type RemoteConfig_Consul struct {
state protoimpl.MessageState `protogen:"open.v1"`
Scheme string `protobuf:"bytes,1,opt,name=scheme,proto3" json:"scheme,omitempty"` // 网络样式
Address string `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"` // 服务端地址
Key string `protobuf:"bytes,3,opt,name=key,proto3" json:"key,omitempty"` // 配置键
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *RemoteConfig_Consul) Reset() {
*x = RemoteConfig_Consul{}
mi := &file_conf_v1_kratos_conf_config_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *RemoteConfig_Consul) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*RemoteConfig_Consul) ProtoMessage() {}
func (x *RemoteConfig_Consul) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_config_proto_msgTypes[3]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use RemoteConfig_Consul.ProtoReflect.Descriptor instead.
func (*RemoteConfig_Consul) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_config_proto_rawDescGZIP(), []int{0, 2}
}
func (x *RemoteConfig_Consul) GetScheme() string {
if x != nil {
return x.Scheme
}
return ""
}
func (x *RemoteConfig_Consul) GetAddress() string {
if x != nil {
return x.Address
}
return ""
}
func (x *RemoteConfig_Consul) GetKey() string {
if x != nil {
return x.Key
}
return ""
}
type RemoteConfig_Apollo struct {
state protoimpl.MessageState `protogen:"open.v1"`
Endpoint string `protobuf:"bytes,1,opt,name=endpoint,proto3" json:"endpoint,omitempty"` // 服务端地址
AppId string `protobuf:"bytes,2,opt,name=app_id,json=appId,proto3" json:"app_id,omitempty"` // 应用ID
Cluster string `protobuf:"bytes,3,opt,name=cluster,proto3" json:"cluster,omitempty"` // 集群
Namespace string `protobuf:"bytes,4,opt,name=namespace,proto3" json:"namespace,omitempty"` // 命名空间
Secret string `protobuf:"bytes,5,opt,name=secret,proto3" json:"secret,omitempty"` // 密钥
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *RemoteConfig_Apollo) Reset() {
*x = RemoteConfig_Apollo{}
mi := &file_conf_v1_kratos_conf_config_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *RemoteConfig_Apollo) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*RemoteConfig_Apollo) ProtoMessage() {}
func (x *RemoteConfig_Apollo) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_config_proto_msgTypes[4]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use RemoteConfig_Apollo.ProtoReflect.Descriptor instead.
func (*RemoteConfig_Apollo) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_config_proto_rawDescGZIP(), []int{0, 3}
}
func (x *RemoteConfig_Apollo) GetEndpoint() string {
if x != nil {
return x.Endpoint
}
return ""
}
func (x *RemoteConfig_Apollo) GetAppId() string {
if x != nil {
return x.AppId
}
return ""
}
func (x *RemoteConfig_Apollo) GetCluster() string {
if x != nil {
return x.Cluster
}
return ""
}
func (x *RemoteConfig_Apollo) GetNamespace() string {
if x != nil {
return x.Namespace
}
return ""
}
func (x *RemoteConfig_Apollo) GetSecret() string {
if x != nil {
return x.Secret
}
return ""
}
type RemoteConfig_Kubernetes struct {
state protoimpl.MessageState `protogen:"open.v1"`
Namespace string `protobuf:"bytes,1,opt,name=namespace,proto3" json:"namespace,omitempty"` // 命名空间
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *RemoteConfig_Kubernetes) Reset() {
*x = RemoteConfig_Kubernetes{}
mi := &file_conf_v1_kratos_conf_config_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *RemoteConfig_Kubernetes) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*RemoteConfig_Kubernetes) ProtoMessage() {}
func (x *RemoteConfig_Kubernetes) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_config_proto_msgTypes[5]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use RemoteConfig_Kubernetes.ProtoReflect.Descriptor instead.
func (*RemoteConfig_Kubernetes) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_config_proto_rawDescGZIP(), []int{0, 4}
}
func (x *RemoteConfig_Kubernetes) GetNamespace() string {
if x != nil {
return x.Namespace
}
return ""
}
type RemoteConfig_Polaris struct {
state protoimpl.MessageState `protogen:"open.v1"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *RemoteConfig_Polaris) Reset() {
*x = RemoteConfig_Polaris{}
mi := &file_conf_v1_kratos_conf_config_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *RemoteConfig_Polaris) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*RemoteConfig_Polaris) ProtoMessage() {}
func (x *RemoteConfig_Polaris) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_config_proto_msgTypes[6]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use RemoteConfig_Polaris.ProtoReflect.Descriptor instead.
func (*RemoteConfig_Polaris) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_config_proto_rawDescGZIP(), []int{0, 5}
}
var File_conf_v1_kratos_conf_config_proto protoreflect.FileDescriptor
const file_conf_v1_kratos_conf_config_proto_rawDesc = "" +
"\n" +
" conf/v1/kratos_conf_config.proto\x12\x04conf\x1a\x1egoogle/protobuf/duration.proto\"\xe1\a\n" +
"\fRemoteConfig\x12\x12\n" +
"\x04type\x18\x01 \x01(\tR\x04type\x120\n" +
"\x04etcd\x18\x02 \x01(\v2\x17.conf.RemoteConfig.EtcdH\x00R\x04etcd\x88\x01\x01\x126\n" +
"\x06consul\x18\x03 \x01(\v2\x19.conf.RemoteConfig.ConsulH\x01R\x06consul\x88\x01\x01\x123\n" +
"\x05nacos\x18\x04 \x01(\v2\x18.conf.RemoteConfig.NacosH\x02R\x05nacos\x88\x01\x01\x126\n" +
"\x06apollo\x18\x06 \x01(\v2\x19.conf.RemoteConfig.ApolloH\x03R\x06apollo\x88\x01\x01\x12B\n" +
"\n" +
"kubernetes\x18\a \x01(\v2\x1d.conf.RemoteConfig.KubernetesH\x04R\n" +
"kubernetes\x88\x01\x01\x129\n" +
"\apolaris\x18\b \x01(\v2\x1a.conf.RemoteConfig.PolarisH\x05R\apolaris\x88\x01\x01\x1a\xa2\x01\n" +
"\x05Nacos\x12\x18\n" +
"\aaddress\x18\x01 \x01(\tR\aaddress\x12\x12\n" +
"\x04port\x18\x02 \x01(\x04R\x04port\x12\x10\n" +
"\x03key\x18\x03 \x01(\tR\x03key\x12\x1a\n" +
"\busername\x18\x04 \x01(\tR\busername\x12\x1a\n" +
"\bpassword\x18\x05 \x01(\tR\bpassword\x12!\n" +
"\fnamespace_id\x18\x06 \x01(\tR\vnamespaceId\x1ak\n" +
"\x04Etcd\x12\x1c\n" +
"\tendpoints\x18\x01 \x03(\tR\tendpoints\x123\n" +
"\atimeout\x18\x02 \x01(\v2\x19.google.protobuf.DurationR\atimeout\x12\x10\n" +
"\x03key\x18\x03 \x01(\tR\x03key\x1aL\n" +
"\x06Consul\x12\x16\n" +
"\x06scheme\x18\x01 \x01(\tR\x06scheme\x12\x18\n" +
"\aaddress\x18\x02 \x01(\tR\aaddress\x12\x10\n" +
"\x03key\x18\x03 \x01(\tR\x03key\x1a\x8b\x01\n" +
"\x06Apollo\x12\x1a\n" +
"\bendpoint\x18\x01 \x01(\tR\bendpoint\x12\x15\n" +
"\x06app_id\x18\x02 \x01(\tR\x05appId\x12\x18\n" +
"\acluster\x18\x03 \x01(\tR\acluster\x12\x1c\n" +
"\tnamespace\x18\x04 \x01(\tR\tnamespace\x12\x16\n" +
"\x06secret\x18\x05 \x01(\tR\x06secret\x1a*\n" +
"\n" +
"Kubernetes\x12\x1c\n" +
"\tnamespace\x18\x01 \x01(\tR\tnamespace\x1a\t\n" +
"\aPolarisB\a\n" +
"\x05_etcdB\t\n" +
"\a_consulB\b\n" +
"\x06_nacosB\t\n" +
"\a_apolloB\r\n" +
"\v_kubernetesB\n" +
"\n" +
"\b_polarisB\x87\x01\n" +
"\bcom.confB\x15KratosConfConfigProtoP\x01Z4github.com/tx7do/kratos-bootstrap/api/gen/go/conf/v1\xa2\x02\x03CXX\xaa\x02\x04Conf\xca\x02\x04Conf\xe2\x02\x10Conf\\GPBMetadata\xea\x02\x04Confb\x06proto3"
var (
file_conf_v1_kratos_conf_config_proto_rawDescOnce sync.Once
file_conf_v1_kratos_conf_config_proto_rawDescData []byte
)
func file_conf_v1_kratos_conf_config_proto_rawDescGZIP() []byte {
file_conf_v1_kratos_conf_config_proto_rawDescOnce.Do(func() {
file_conf_v1_kratos_conf_config_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_conf_v1_kratos_conf_config_proto_rawDesc), len(file_conf_v1_kratos_conf_config_proto_rawDesc)))
})
return file_conf_v1_kratos_conf_config_proto_rawDescData
}
var file_conf_v1_kratos_conf_config_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
var file_conf_v1_kratos_conf_config_proto_goTypes = []any{
(*RemoteConfig)(nil), // 0: conf.RemoteConfig
(*RemoteConfig_Nacos)(nil), // 1: conf.RemoteConfig.Nacos
(*RemoteConfig_Etcd)(nil), // 2: conf.RemoteConfig.Etcd
(*RemoteConfig_Consul)(nil), // 3: conf.RemoteConfig.Consul
(*RemoteConfig_Apollo)(nil), // 4: conf.RemoteConfig.Apollo
(*RemoteConfig_Kubernetes)(nil), // 5: conf.RemoteConfig.Kubernetes
(*RemoteConfig_Polaris)(nil), // 6: conf.RemoteConfig.Polaris
(*durationpb.Duration)(nil), // 7: google.protobuf.Duration
}
var file_conf_v1_kratos_conf_config_proto_depIdxs = []int32{
2, // 0: conf.RemoteConfig.etcd:type_name -> conf.RemoteConfig.Etcd
3, // 1: conf.RemoteConfig.consul:type_name -> conf.RemoteConfig.Consul
1, // 2: conf.RemoteConfig.nacos:type_name -> conf.RemoteConfig.Nacos
4, // 3: conf.RemoteConfig.apollo:type_name -> conf.RemoteConfig.Apollo
5, // 4: conf.RemoteConfig.kubernetes:type_name -> conf.RemoteConfig.Kubernetes
6, // 5: conf.RemoteConfig.polaris:type_name -> conf.RemoteConfig.Polaris
7, // 6: conf.RemoteConfig.Etcd.timeout:type_name -> google.protobuf.Duration
7, // [7:7] is the sub-list for method output_type
7, // [7:7] is the sub-list for method input_type
7, // [7:7] is the sub-list for extension type_name
7, // [7:7] is the sub-list for extension extendee
0, // [0:7] is the sub-list for field type_name
}
func init() { file_conf_v1_kratos_conf_config_proto_init() }
func file_conf_v1_kratos_conf_config_proto_init() {
if File_conf_v1_kratos_conf_config_proto != nil {
return
}
file_conf_v1_kratos_conf_config_proto_msgTypes[0].OneofWrappers = []any{}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_conf_v1_kratos_conf_config_proto_rawDesc), len(file_conf_v1_kratos_conf_config_proto_rawDesc)),
NumEnums: 0,
NumMessages: 7,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_conf_v1_kratos_conf_config_proto_goTypes,
DependencyIndexes: file_conf_v1_kratos_conf_config_proto_depIdxs,
MessageInfos: file_conf_v1_kratos_conf_config_proto_msgTypes,
}.Build()
File_conf_v1_kratos_conf_config_proto = out.File
file_conf_v1_kratos_conf_config_proto_goTypes = nil
file_conf_v1_kratos_conf_config_proto_depIdxs = nil
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,559 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.36.6
// protoc (unknown)
// source: conf/v1/kratos_conf_logger.proto
package v1
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
unsafe "unsafe"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// 日志
type Logger struct {
state protoimpl.MessageState `protogen:"open.v1"`
Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"`
Zap *Logger_Zap `protobuf:"bytes,2,opt,name=zap,proto3,oneof" json:"zap,omitempty"`
Logrus *Logger_Logrus `protobuf:"bytes,3,opt,name=logrus,proto3,oneof" json:"logrus,omitempty"`
Fluent *Logger_Fluent `protobuf:"bytes,4,opt,name=fluent,proto3,oneof" json:"fluent,omitempty"`
Aliyun *Logger_Aliyun `protobuf:"bytes,5,opt,name=aliyun,proto3,oneof" json:"aliyun,omitempty"`
Tencent *Logger_Tencent `protobuf:"bytes,6,opt,name=tencent,proto3,oneof" json:"tencent,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Logger) Reset() {
*x = Logger{}
mi := &file_conf_v1_kratos_conf_logger_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Logger) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Logger) ProtoMessage() {}
func (x *Logger) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_logger_proto_msgTypes[0]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Logger.ProtoReflect.Descriptor instead.
func (*Logger) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_logger_proto_rawDescGZIP(), []int{0}
}
func (x *Logger) GetType() string {
if x != nil {
return x.Type
}
return ""
}
func (x *Logger) GetZap() *Logger_Zap {
if x != nil {
return x.Zap
}
return nil
}
func (x *Logger) GetLogrus() *Logger_Logrus {
if x != nil {
return x.Logrus
}
return nil
}
func (x *Logger) GetFluent() *Logger_Fluent {
if x != nil {
return x.Fluent
}
return nil
}
func (x *Logger) GetAliyun() *Logger_Aliyun {
if x != nil {
return x.Aliyun
}
return nil
}
func (x *Logger) GetTencent() *Logger_Tencent {
if x != nil {
return x.Tencent
}
return nil
}
// Zap
type Logger_Zap struct {
state protoimpl.MessageState `protogen:"open.v1"`
Filename string `protobuf:"bytes,1,opt,name=filename,proto3" json:"filename,omitempty"` //
Level string `protobuf:"bytes,2,opt,name=level,proto3" json:"level,omitempty"` //
MaxSize int32 `protobuf:"varint,3,opt,name=max_size,json=maxSize,proto3" json:"max_size,omitempty"` //
MaxAge int32 `protobuf:"varint,4,opt,name=max_age,json=maxAge,proto3" json:"max_age,omitempty"` //
MaxBackups int32 `protobuf:"varint,5,opt,name=max_backups,json=maxBackups,proto3" json:"max_backups,omitempty"` //
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Logger_Zap) Reset() {
*x = Logger_Zap{}
mi := &file_conf_v1_kratos_conf_logger_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Logger_Zap) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Logger_Zap) ProtoMessage() {}
func (x *Logger_Zap) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_logger_proto_msgTypes[1]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Logger_Zap.ProtoReflect.Descriptor instead.
func (*Logger_Zap) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_logger_proto_rawDescGZIP(), []int{0, 0}
}
func (x *Logger_Zap) GetFilename() string {
if x != nil {
return x.Filename
}
return ""
}
func (x *Logger_Zap) GetLevel() string {
if x != nil {
return x.Level
}
return ""
}
func (x *Logger_Zap) GetMaxSize() int32 {
if x != nil {
return x.MaxSize
}
return 0
}
func (x *Logger_Zap) GetMaxAge() int32 {
if x != nil {
return x.MaxAge
}
return 0
}
func (x *Logger_Zap) GetMaxBackups() int32 {
if x != nil {
return x.MaxBackups
}
return 0
}
// logrus
type Logger_Logrus struct {
state protoimpl.MessageState `protogen:"open.v1"`
Level string `protobuf:"bytes,1,opt,name=level,proto3" json:"level,omitempty"` // 日志等级
Formatter string `protobuf:"bytes,2,opt,name=formatter,proto3" json:"formatter,omitempty"` // 输出格式text, json.
TimestampFormat string `protobuf:"bytes,3,opt,name=timestamp_format,json=timestampFormat,proto3" json:"timestamp_format,omitempty"` // 定义时间戳格式,例如:"2006-01-02 15:04:05"
DisableColors bool `protobuf:"varint,4,opt,name=disable_colors,json=disableColors,proto3" json:"disable_colors,omitempty"` // 不需要彩色日志
DisableTimestamp bool `protobuf:"varint,5,opt,name=disable_timestamp,json=disableTimestamp,proto3" json:"disable_timestamp,omitempty"` // 不需要时间戳
ForceColors bool `protobuf:"varint,6,opt,name=force_colors,json=forceColors,proto3" json:"force_colors,omitempty"` // 是否开启彩色日志
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Logger_Logrus) Reset() {
*x = Logger_Logrus{}
mi := &file_conf_v1_kratos_conf_logger_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Logger_Logrus) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Logger_Logrus) ProtoMessage() {}
func (x *Logger_Logrus) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_logger_proto_msgTypes[2]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Logger_Logrus.ProtoReflect.Descriptor instead.
func (*Logger_Logrus) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_logger_proto_rawDescGZIP(), []int{0, 1}
}
func (x *Logger_Logrus) GetLevel() string {
if x != nil {
return x.Level
}
return ""
}
func (x *Logger_Logrus) GetFormatter() string {
if x != nil {
return x.Formatter
}
return ""
}
func (x *Logger_Logrus) GetTimestampFormat() string {
if x != nil {
return x.TimestampFormat
}
return ""
}
func (x *Logger_Logrus) GetDisableColors() bool {
if x != nil {
return x.DisableColors
}
return false
}
func (x *Logger_Logrus) GetDisableTimestamp() bool {
if x != nil {
return x.DisableTimestamp
}
return false
}
func (x *Logger_Logrus) GetForceColors() bool {
if x != nil {
return x.ForceColors
}
return false
}
// Fluent
type Logger_Fluent struct {
state protoimpl.MessageState `protogen:"open.v1"`
Endpoint string `protobuf:"bytes,1,opt,name=endpoint,proto3" json:"endpoint,omitempty"` // 公网接入地址
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Logger_Fluent) Reset() {
*x = Logger_Fluent{}
mi := &file_conf_v1_kratos_conf_logger_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Logger_Fluent) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Logger_Fluent) ProtoMessage() {}
func (x *Logger_Fluent) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_logger_proto_msgTypes[3]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Logger_Fluent.ProtoReflect.Descriptor instead.
func (*Logger_Fluent) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_logger_proto_rawDescGZIP(), []int{0, 2}
}
func (x *Logger_Fluent) GetEndpoint() string {
if x != nil {
return x.Endpoint
}
return ""
}
// 阿里云
type Logger_Aliyun struct {
state protoimpl.MessageState `protogen:"open.v1"`
Endpoint string `protobuf:"bytes,1,opt,name=endpoint,proto3" json:"endpoint,omitempty"` // 公网接入地址
Project string `protobuf:"bytes,2,opt,name=project,proto3" json:"project,omitempty"` //
AccessKey string `protobuf:"bytes,3,opt,name=access_key,json=accessKey,proto3" json:"access_key,omitempty"` // 访问密钥ID
AccessSecret string `protobuf:"bytes,4,opt,name=access_secret,json=accessSecret,proto3" json:"access_secret,omitempty"` // 访问密钥
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Logger_Aliyun) Reset() {
*x = Logger_Aliyun{}
mi := &file_conf_v1_kratos_conf_logger_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Logger_Aliyun) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Logger_Aliyun) ProtoMessage() {}
func (x *Logger_Aliyun) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_logger_proto_msgTypes[4]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Logger_Aliyun.ProtoReflect.Descriptor instead.
func (*Logger_Aliyun) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_logger_proto_rawDescGZIP(), []int{0, 3}
}
func (x *Logger_Aliyun) GetEndpoint() string {
if x != nil {
return x.Endpoint
}
return ""
}
func (x *Logger_Aliyun) GetProject() string {
if x != nil {
return x.Project
}
return ""
}
func (x *Logger_Aliyun) GetAccessKey() string {
if x != nil {
return x.AccessKey
}
return ""
}
func (x *Logger_Aliyun) GetAccessSecret() string {
if x != nil {
return x.AccessSecret
}
return ""
}
// 腾讯
type Logger_Tencent struct {
state protoimpl.MessageState `protogen:"open.v1"`
Endpoint string `protobuf:"bytes,1,opt,name=endpoint,proto3" json:"endpoint,omitempty"` // 公网接入地址
TopicId string `protobuf:"bytes,2,opt,name=topic_id,json=topicId,proto3" json:"topic_id,omitempty"` //
AccessKey string `protobuf:"bytes,3,opt,name=access_key,json=accessKey,proto3" json:"access_key,omitempty"` // 访问密钥ID
AccessSecret string `protobuf:"bytes,4,opt,name=access_secret,json=accessSecret,proto3" json:"access_secret,omitempty"` // 访问密钥
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Logger_Tencent) Reset() {
*x = Logger_Tencent{}
mi := &file_conf_v1_kratos_conf_logger_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Logger_Tencent) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Logger_Tencent) ProtoMessage() {}
func (x *Logger_Tencent) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_logger_proto_msgTypes[5]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Logger_Tencent.ProtoReflect.Descriptor instead.
func (*Logger_Tencent) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_logger_proto_rawDescGZIP(), []int{0, 4}
}
func (x *Logger_Tencent) GetEndpoint() string {
if x != nil {
return x.Endpoint
}
return ""
}
func (x *Logger_Tencent) GetTopicId() string {
if x != nil {
return x.TopicId
}
return ""
}
func (x *Logger_Tencent) GetAccessKey() string {
if x != nil {
return x.AccessKey
}
return ""
}
func (x *Logger_Tencent) GetAccessSecret() string {
if x != nil {
return x.AccessSecret
}
return ""
}
var File_conf_v1_kratos_conf_logger_proto protoreflect.FileDescriptor
const file_conf_v1_kratos_conf_logger_proto_rawDesc = "" +
"\n" +
" conf/v1/kratos_conf_logger.proto\x12\x04conf\"\xe7\a\n" +
"\x06Logger\x12\x12\n" +
"\x04type\x18\x01 \x01(\tR\x04type\x12'\n" +
"\x03zap\x18\x02 \x01(\v2\x10.conf.Logger.ZapH\x00R\x03zap\x88\x01\x01\x120\n" +
"\x06logrus\x18\x03 \x01(\v2\x13.conf.Logger.LogrusH\x01R\x06logrus\x88\x01\x01\x120\n" +
"\x06fluent\x18\x04 \x01(\v2\x13.conf.Logger.FluentH\x02R\x06fluent\x88\x01\x01\x120\n" +
"\x06aliyun\x18\x05 \x01(\v2\x13.conf.Logger.AliyunH\x03R\x06aliyun\x88\x01\x01\x123\n" +
"\atencent\x18\x06 \x01(\v2\x14.conf.Logger.TencentH\x04R\atencent\x88\x01\x01\x1a\x8c\x01\n" +
"\x03Zap\x12\x1a\n" +
"\bfilename\x18\x01 \x01(\tR\bfilename\x12\x14\n" +
"\x05level\x18\x02 \x01(\tR\x05level\x12\x19\n" +
"\bmax_size\x18\x03 \x01(\x05R\amaxSize\x12\x17\n" +
"\amax_age\x18\x04 \x01(\x05R\x06maxAge\x12\x1f\n" +
"\vmax_backups\x18\x05 \x01(\x05R\n" +
"maxBackups\x1a\xde\x01\n" +
"\x06Logrus\x12\x14\n" +
"\x05level\x18\x01 \x01(\tR\x05level\x12\x1c\n" +
"\tformatter\x18\x02 \x01(\tR\tformatter\x12)\n" +
"\x10timestamp_format\x18\x03 \x01(\tR\x0ftimestampFormat\x12%\n" +
"\x0edisable_colors\x18\x04 \x01(\bR\rdisableColors\x12+\n" +
"\x11disable_timestamp\x18\x05 \x01(\bR\x10disableTimestamp\x12!\n" +
"\fforce_colors\x18\x06 \x01(\bR\vforceColors\x1a$\n" +
"\x06Fluent\x12\x1a\n" +
"\bendpoint\x18\x01 \x01(\tR\bendpoint\x1a\x82\x01\n" +
"\x06Aliyun\x12\x1a\n" +
"\bendpoint\x18\x01 \x01(\tR\bendpoint\x12\x18\n" +
"\aproject\x18\x02 \x01(\tR\aproject\x12\x1d\n" +
"\n" +
"access_key\x18\x03 \x01(\tR\taccessKey\x12#\n" +
"\raccess_secret\x18\x04 \x01(\tR\faccessSecret\x1a\x84\x01\n" +
"\aTencent\x12\x1a\n" +
"\bendpoint\x18\x01 \x01(\tR\bendpoint\x12\x19\n" +
"\btopic_id\x18\x02 \x01(\tR\atopicId\x12\x1d\n" +
"\n" +
"access_key\x18\x03 \x01(\tR\taccessKey\x12#\n" +
"\raccess_secret\x18\x04 \x01(\tR\faccessSecretB\x06\n" +
"\x04_zapB\t\n" +
"\a_logrusB\t\n" +
"\a_fluentB\t\n" +
"\a_aliyunB\n" +
"\n" +
"\b_tencentB\x87\x01\n" +
"\bcom.confB\x15KratosConfLoggerProtoP\x01Z4github.com/tx7do/kratos-bootstrap/api/gen/go/conf/v1\xa2\x02\x03CXX\xaa\x02\x04Conf\xca\x02\x04Conf\xe2\x02\x10Conf\\GPBMetadata\xea\x02\x04Confb\x06proto3"
var (
file_conf_v1_kratos_conf_logger_proto_rawDescOnce sync.Once
file_conf_v1_kratos_conf_logger_proto_rawDescData []byte
)
func file_conf_v1_kratos_conf_logger_proto_rawDescGZIP() []byte {
file_conf_v1_kratos_conf_logger_proto_rawDescOnce.Do(func() {
file_conf_v1_kratos_conf_logger_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_conf_v1_kratos_conf_logger_proto_rawDesc), len(file_conf_v1_kratos_conf_logger_proto_rawDesc)))
})
return file_conf_v1_kratos_conf_logger_proto_rawDescData
}
var file_conf_v1_kratos_conf_logger_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
var file_conf_v1_kratos_conf_logger_proto_goTypes = []any{
(*Logger)(nil), // 0: conf.Logger
(*Logger_Zap)(nil), // 1: conf.Logger.Zap
(*Logger_Logrus)(nil), // 2: conf.Logger.Logrus
(*Logger_Fluent)(nil), // 3: conf.Logger.Fluent
(*Logger_Aliyun)(nil), // 4: conf.Logger.Aliyun
(*Logger_Tencent)(nil), // 5: conf.Logger.Tencent
}
var file_conf_v1_kratos_conf_logger_proto_depIdxs = []int32{
1, // 0: conf.Logger.zap:type_name -> conf.Logger.Zap
2, // 1: conf.Logger.logrus:type_name -> conf.Logger.Logrus
3, // 2: conf.Logger.fluent:type_name -> conf.Logger.Fluent
4, // 3: conf.Logger.aliyun:type_name -> conf.Logger.Aliyun
5, // 4: conf.Logger.tencent:type_name -> conf.Logger.Tencent
5, // [5:5] is the sub-list for method output_type
5, // [5:5] is the sub-list for method input_type
5, // [5:5] is the sub-list for extension type_name
5, // [5:5] is the sub-list for extension extendee
0, // [0:5] is the sub-list for field type_name
}
func init() { file_conf_v1_kratos_conf_logger_proto_init() }
func file_conf_v1_kratos_conf_logger_proto_init() {
if File_conf_v1_kratos_conf_logger_proto != nil {
return
}
file_conf_v1_kratos_conf_logger_proto_msgTypes[0].OneofWrappers = []any{}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_conf_v1_kratos_conf_logger_proto_rawDesc), len(file_conf_v1_kratos_conf_logger_proto_rawDesc)),
NumEnums: 0,
NumMessages: 6,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_conf_v1_kratos_conf_logger_proto_goTypes,
DependencyIndexes: file_conf_v1_kratos_conf_logger_proto_depIdxs,
MessageInfos: file_conf_v1_kratos_conf_logger_proto_msgTypes,
}.Build()
File_conf_v1_kratos_conf_logger_proto = out.File
file_conf_v1_kratos_conf_logger_proto_goTypes = nil
file_conf_v1_kratos_conf_logger_proto_depIdxs = nil
}

View File

@@ -0,0 +1,426 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.36.6
// protoc (unknown)
// source: conf/v1/kratos_conf_middleware.proto
package v1
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
durationpb "google.golang.org/protobuf/types/known/durationpb"
reflect "reflect"
sync "sync"
unsafe "unsafe"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// 中间件
type Middleware struct {
state protoimpl.MessageState `protogen:"open.v1"`
Limiter *Middleware_RateLimiter `protobuf:"bytes,1,opt,name=limiter,proto3" json:"limiter,omitempty"`
Metrics *Middleware_Metrics `protobuf:"bytes,2,opt,name=metrics,proto3" json:"metrics,omitempty"`
Auth *Middleware_Auth `protobuf:"bytes,3,opt,name=auth,proto3" json:"auth,omitempty"`
EnableLogging bool `protobuf:"varint,10,opt,name=enable_logging,json=enableLogging,proto3" json:"enable_logging,omitempty"` // 日志开关
EnableRecovery bool `protobuf:"varint,11,opt,name=enable_recovery,json=enableRecovery,proto3" json:"enable_recovery,omitempty"` // 异常恢复
EnableTracing bool `protobuf:"varint,12,opt,name=enable_tracing,json=enableTracing,proto3" json:"enable_tracing,omitempty"` // 链路追踪开关
EnableValidate bool `protobuf:"varint,13,opt,name=enable_validate,json=enableValidate,proto3" json:"enable_validate,omitempty"` // 参数校验开关
EnableCircuitBreaker bool `protobuf:"varint,14,opt,name=enable_circuit_breaker,json=enableCircuitBreaker,proto3" json:"enable_circuit_breaker,omitempty"` // 熔断器
EnableMetadata bool `protobuf:"varint,15,opt,name=enable_metadata,json=enableMetadata,proto3" json:"enable_metadata,omitempty"` // 元数据
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Middleware) Reset() {
*x = Middleware{}
mi := &file_conf_v1_kratos_conf_middleware_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Middleware) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Middleware) ProtoMessage() {}
func (x *Middleware) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_middleware_proto_msgTypes[0]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Middleware.ProtoReflect.Descriptor instead.
func (*Middleware) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_middleware_proto_rawDescGZIP(), []int{0}
}
func (x *Middleware) GetLimiter() *Middleware_RateLimiter {
if x != nil {
return x.Limiter
}
return nil
}
func (x *Middleware) GetMetrics() *Middleware_Metrics {
if x != nil {
return x.Metrics
}
return nil
}
func (x *Middleware) GetAuth() *Middleware_Auth {
if x != nil {
return x.Auth
}
return nil
}
func (x *Middleware) GetEnableLogging() bool {
if x != nil {
return x.EnableLogging
}
return false
}
func (x *Middleware) GetEnableRecovery() bool {
if x != nil {
return x.EnableRecovery
}
return false
}
func (x *Middleware) GetEnableTracing() bool {
if x != nil {
return x.EnableTracing
}
return false
}
func (x *Middleware) GetEnableValidate() bool {
if x != nil {
return x.EnableValidate
}
return false
}
func (x *Middleware) GetEnableCircuitBreaker() bool {
if x != nil {
return x.EnableCircuitBreaker
}
return false
}
func (x *Middleware) GetEnableMetadata() bool {
if x != nil {
return x.EnableMetadata
}
return false
}
// JWT校验
type Middleware_Auth struct {
state protoimpl.MessageState `protogen:"open.v1"`
Method string `protobuf:"bytes,1,opt,name=method,proto3" json:"method,omitempty"` // JWT签名的算法支持算法HS256
Key string `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"` // JWT 秘钥
AccessTokenExpires *durationpb.Duration `protobuf:"bytes,3,opt,name=access_token_expires,json=accessTokenExpires,proto3,oneof" json:"access_token_expires,omitempty"` // 访问令牌过期时间
RefreshTokenExpires *durationpb.Duration `protobuf:"bytes,4,opt,name=refresh_token_expires,json=refreshTokenExpires,proto3,oneof" json:"refresh_token_expires,omitempty"` // 刷新令牌过期时间
AccessTokenKeyPrefix *string `protobuf:"bytes,5,opt,name=access_token_key_prefix,json=accessTokenKeyPrefix,proto3,oneof" json:"access_token_key_prefix,omitempty"` // 访问令牌键前缀
RefreshTokenKeyPrefix *string `protobuf:"bytes,6,opt,name=refresh_token_key_prefix,json=refreshTokenKeyPrefix,proto3,oneof" json:"refresh_token_key_prefix,omitempty"` // 刷新令牌键前缀
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Middleware_Auth) Reset() {
*x = Middleware_Auth{}
mi := &file_conf_v1_kratos_conf_middleware_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Middleware_Auth) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Middleware_Auth) ProtoMessage() {}
func (x *Middleware_Auth) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_middleware_proto_msgTypes[1]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Middleware_Auth.ProtoReflect.Descriptor instead.
func (*Middleware_Auth) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_middleware_proto_rawDescGZIP(), []int{0, 0}
}
func (x *Middleware_Auth) GetMethod() string {
if x != nil {
return x.Method
}
return ""
}
func (x *Middleware_Auth) GetKey() string {
if x != nil {
return x.Key
}
return ""
}
func (x *Middleware_Auth) GetAccessTokenExpires() *durationpb.Duration {
if x != nil {
return x.AccessTokenExpires
}
return nil
}
func (x *Middleware_Auth) GetRefreshTokenExpires() *durationpb.Duration {
if x != nil {
return x.RefreshTokenExpires
}
return nil
}
func (x *Middleware_Auth) GetAccessTokenKeyPrefix() string {
if x != nil && x.AccessTokenKeyPrefix != nil {
return *x.AccessTokenKeyPrefix
}
return ""
}
func (x *Middleware_Auth) GetRefreshTokenKeyPrefix() string {
if x != nil && x.RefreshTokenKeyPrefix != nil {
return *x.RefreshTokenKeyPrefix
}
return ""
}
// 限流器
type Middleware_RateLimiter struct {
state protoimpl.MessageState `protogen:"open.v1"`
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` // 限流器名字支持bbr。
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Middleware_RateLimiter) Reset() {
*x = Middleware_RateLimiter{}
mi := &file_conf_v1_kratos_conf_middleware_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Middleware_RateLimiter) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Middleware_RateLimiter) ProtoMessage() {}
func (x *Middleware_RateLimiter) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_middleware_proto_msgTypes[2]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Middleware_RateLimiter.ProtoReflect.Descriptor instead.
func (*Middleware_RateLimiter) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_middleware_proto_rawDescGZIP(), []int{0, 1}
}
func (x *Middleware_RateLimiter) GetName() string {
if x != nil {
return x.Name
}
return ""
}
// 性能指标
type Middleware_Metrics struct {
state protoimpl.MessageState `protogen:"open.v1"`
Histogram bool `protobuf:"varint,1,opt,name=histogram,proto3" json:"histogram,omitempty"` // 直方图
Counter bool `protobuf:"varint,2,opt,name=counter,proto3" json:"counter,omitempty"` // 计数器
Gauge bool `protobuf:"varint,3,opt,name=gauge,proto3" json:"gauge,omitempty"` // 仪表盘
Summary bool `protobuf:"varint,4,opt,name=summary,proto3" json:"summary,omitempty"` // 摘要
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Middleware_Metrics) Reset() {
*x = Middleware_Metrics{}
mi := &file_conf_v1_kratos_conf_middleware_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Middleware_Metrics) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Middleware_Metrics) ProtoMessage() {}
func (x *Middleware_Metrics) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_middleware_proto_msgTypes[3]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Middleware_Metrics.ProtoReflect.Descriptor instead.
func (*Middleware_Metrics) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_middleware_proto_rawDescGZIP(), []int{0, 2}
}
func (x *Middleware_Metrics) GetHistogram() bool {
if x != nil {
return x.Histogram
}
return false
}
func (x *Middleware_Metrics) GetCounter() bool {
if x != nil {
return x.Counter
}
return false
}
func (x *Middleware_Metrics) GetGauge() bool {
if x != nil {
return x.Gauge
}
return false
}
func (x *Middleware_Metrics) GetSummary() bool {
if x != nil {
return x.Summary
}
return false
}
var File_conf_v1_kratos_conf_middleware_proto protoreflect.FileDescriptor
const file_conf_v1_kratos_conf_middleware_proto_rawDesc = "" +
"\n" +
"$conf/v1/kratos_conf_middleware.proto\x12\x04conf\x1a\x1egoogle/protobuf/duration.proto\"\xf7\a\n" +
"\n" +
"Middleware\x126\n" +
"\alimiter\x18\x01 \x01(\v2\x1c.conf.Middleware.RateLimiterR\alimiter\x122\n" +
"\ametrics\x18\x02 \x01(\v2\x18.conf.Middleware.MetricsR\ametrics\x12)\n" +
"\x04auth\x18\x03 \x01(\v2\x15.conf.Middleware.AuthR\x04auth\x12%\n" +
"\x0eenable_logging\x18\n" +
" \x01(\bR\renableLogging\x12'\n" +
"\x0fenable_recovery\x18\v \x01(\bR\x0eenableRecovery\x12%\n" +
"\x0eenable_tracing\x18\f \x01(\bR\renableTracing\x12'\n" +
"\x0fenable_validate\x18\r \x01(\bR\x0eenableValidate\x124\n" +
"\x16enable_circuit_breaker\x18\x0e \x01(\bR\x14enableCircuitBreaker\x12'\n" +
"\x0fenable_metadata\x18\x0f \x01(\bR\x0eenableMetadata\x1a\xbc\x03\n" +
"\x04Auth\x12\x16\n" +
"\x06method\x18\x01 \x01(\tR\x06method\x12\x10\n" +
"\x03key\x18\x02 \x01(\tR\x03key\x12P\n" +
"\x14access_token_expires\x18\x03 \x01(\v2\x19.google.protobuf.DurationH\x00R\x12accessTokenExpires\x88\x01\x01\x12R\n" +
"\x15refresh_token_expires\x18\x04 \x01(\v2\x19.google.protobuf.DurationH\x01R\x13refreshTokenExpires\x88\x01\x01\x12:\n" +
"\x17access_token_key_prefix\x18\x05 \x01(\tH\x02R\x14accessTokenKeyPrefix\x88\x01\x01\x12<\n" +
"\x18refresh_token_key_prefix\x18\x06 \x01(\tH\x03R\x15refreshTokenKeyPrefix\x88\x01\x01B\x17\n" +
"\x15_access_token_expiresB\x18\n" +
"\x16_refresh_token_expiresB\x1a\n" +
"\x18_access_token_key_prefixB\x1b\n" +
"\x19_refresh_token_key_prefix\x1a!\n" +
"\vRateLimiter\x12\x12\n" +
"\x04name\x18\x01 \x01(\tR\x04name\x1aq\n" +
"\aMetrics\x12\x1c\n" +
"\thistogram\x18\x01 \x01(\bR\thistogram\x12\x18\n" +
"\acounter\x18\x02 \x01(\bR\acounter\x12\x14\n" +
"\x05gauge\x18\x03 \x01(\bR\x05gauge\x12\x18\n" +
"\asummary\x18\x04 \x01(\bR\asummaryB\x8b\x01\n" +
"\bcom.confB\x19KratosConfMiddlewareProtoP\x01Z4github.com/tx7do/kratos-bootstrap/api/gen/go/conf/v1\xa2\x02\x03CXX\xaa\x02\x04Conf\xca\x02\x04Conf\xe2\x02\x10Conf\\GPBMetadata\xea\x02\x04Confb\x06proto3"
var (
file_conf_v1_kratos_conf_middleware_proto_rawDescOnce sync.Once
file_conf_v1_kratos_conf_middleware_proto_rawDescData []byte
)
func file_conf_v1_kratos_conf_middleware_proto_rawDescGZIP() []byte {
file_conf_v1_kratos_conf_middleware_proto_rawDescOnce.Do(func() {
file_conf_v1_kratos_conf_middleware_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_conf_v1_kratos_conf_middleware_proto_rawDesc), len(file_conf_v1_kratos_conf_middleware_proto_rawDesc)))
})
return file_conf_v1_kratos_conf_middleware_proto_rawDescData
}
var file_conf_v1_kratos_conf_middleware_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
var file_conf_v1_kratos_conf_middleware_proto_goTypes = []any{
(*Middleware)(nil), // 0: conf.Middleware
(*Middleware_Auth)(nil), // 1: conf.Middleware.Auth
(*Middleware_RateLimiter)(nil), // 2: conf.Middleware.RateLimiter
(*Middleware_Metrics)(nil), // 3: conf.Middleware.Metrics
(*durationpb.Duration)(nil), // 4: google.protobuf.Duration
}
var file_conf_v1_kratos_conf_middleware_proto_depIdxs = []int32{
2, // 0: conf.Middleware.limiter:type_name -> conf.Middleware.RateLimiter
3, // 1: conf.Middleware.metrics:type_name -> conf.Middleware.Metrics
1, // 2: conf.Middleware.auth:type_name -> conf.Middleware.Auth
4, // 3: conf.Middleware.Auth.access_token_expires:type_name -> google.protobuf.Duration
4, // 4: conf.Middleware.Auth.refresh_token_expires:type_name -> google.protobuf.Duration
5, // [5:5] is the sub-list for method output_type
5, // [5:5] is the sub-list for method input_type
5, // [5:5] is the sub-list for extension type_name
5, // [5:5] is the sub-list for extension extendee
0, // [0:5] is the sub-list for field type_name
}
func init() { file_conf_v1_kratos_conf_middleware_proto_init() }
func file_conf_v1_kratos_conf_middleware_proto_init() {
if File_conf_v1_kratos_conf_middleware_proto != nil {
return
}
file_conf_v1_kratos_conf_middleware_proto_msgTypes[1].OneofWrappers = []any{}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_conf_v1_kratos_conf_middleware_proto_rawDesc), len(file_conf_v1_kratos_conf_middleware_proto_rawDesc)),
NumEnums: 0,
NumMessages: 4,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_conf_v1_kratos_conf_middleware_proto_goTypes,
DependencyIndexes: file_conf_v1_kratos_conf_middleware_proto_depIdxs,
MessageInfos: file_conf_v1_kratos_conf_middleware_proto_msgTypes,
}.Build()
File_conf_v1_kratos_conf_middleware_proto = out.File
file_conf_v1_kratos_conf_middleware_proto_goTypes = nil
file_conf_v1_kratos_conf_middleware_proto_depIdxs = nil
}

View File

@@ -0,0 +1,202 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.36.6
// protoc (unknown)
// source: conf/v1/kratos_conf_notify.proto
package v1
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
unsafe "unsafe"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// 通知消息
type Notification struct {
state protoimpl.MessageState `protogen:"open.v1"`
Sms *Notification_SMS `protobuf:"bytes,1,opt,name=sms,proto3,oneof" json:"sms,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Notification) Reset() {
*x = Notification{}
mi := &file_conf_v1_kratos_conf_notify_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Notification) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Notification) ProtoMessage() {}
func (x *Notification) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_notify_proto_msgTypes[0]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Notification.ProtoReflect.Descriptor instead.
func (*Notification) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_notify_proto_rawDescGZIP(), []int{0}
}
func (x *Notification) GetSms() *Notification_SMS {
if x != nil {
return x.Sms
}
return nil
}
// 短信
type Notification_SMS struct {
state protoimpl.MessageState `protogen:"open.v1"`
Endpoint string `protobuf:"bytes,1,opt,name=endpoint,proto3" json:"endpoint,omitempty"` // 公网接入地址
RegionId string `protobuf:"bytes,2,opt,name=region_id,json=regionId,proto3" json:"region_id,omitempty"` // 地域ID
AccessKeyId string `protobuf:"bytes,3,opt,name=access_key_id,json=accessKeyId,proto3" json:"access_key_id,omitempty"` // 访问密钥ID
AccessKeySecret string `protobuf:"bytes,4,opt,name=access_key_secret,json=accessKeySecret,proto3" json:"access_key_secret,omitempty"` // 访问密钥
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Notification_SMS) Reset() {
*x = Notification_SMS{}
mi := &file_conf_v1_kratos_conf_notify_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Notification_SMS) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Notification_SMS) ProtoMessage() {}
func (x *Notification_SMS) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_notify_proto_msgTypes[1]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Notification_SMS.ProtoReflect.Descriptor instead.
func (*Notification_SMS) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_notify_proto_rawDescGZIP(), []int{0, 0}
}
func (x *Notification_SMS) GetEndpoint() string {
if x != nil {
return x.Endpoint
}
return ""
}
func (x *Notification_SMS) GetRegionId() string {
if x != nil {
return x.RegionId
}
return ""
}
func (x *Notification_SMS) GetAccessKeyId() string {
if x != nil {
return x.AccessKeyId
}
return ""
}
func (x *Notification_SMS) GetAccessKeySecret() string {
if x != nil {
return x.AccessKeySecret
}
return ""
}
var File_conf_v1_kratos_conf_notify_proto protoreflect.FileDescriptor
const file_conf_v1_kratos_conf_notify_proto_rawDesc = "" +
"\n" +
" conf/v1/kratos_conf_notify.proto\x12\x04conf\"\xd6\x01\n" +
"\fNotification\x12-\n" +
"\x03sms\x18\x01 \x01(\v2\x16.conf.Notification.SMSH\x00R\x03sms\x88\x01\x01\x1a\x8e\x01\n" +
"\x03SMS\x12\x1a\n" +
"\bendpoint\x18\x01 \x01(\tR\bendpoint\x12\x1b\n" +
"\tregion_id\x18\x02 \x01(\tR\bregionId\x12\"\n" +
"\raccess_key_id\x18\x03 \x01(\tR\vaccessKeyId\x12*\n" +
"\x11access_key_secret\x18\x04 \x01(\tR\x0faccessKeySecretB\x06\n" +
"\x04_smsB\x87\x01\n" +
"\bcom.confB\x15KratosConfNotifyProtoP\x01Z4github.com/tx7do/kratos-bootstrap/api/gen/go/conf/v1\xa2\x02\x03CXX\xaa\x02\x04Conf\xca\x02\x04Conf\xe2\x02\x10Conf\\GPBMetadata\xea\x02\x04Confb\x06proto3"
var (
file_conf_v1_kratos_conf_notify_proto_rawDescOnce sync.Once
file_conf_v1_kratos_conf_notify_proto_rawDescData []byte
)
func file_conf_v1_kratos_conf_notify_proto_rawDescGZIP() []byte {
file_conf_v1_kratos_conf_notify_proto_rawDescOnce.Do(func() {
file_conf_v1_kratos_conf_notify_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_conf_v1_kratos_conf_notify_proto_rawDesc), len(file_conf_v1_kratos_conf_notify_proto_rawDesc)))
})
return file_conf_v1_kratos_conf_notify_proto_rawDescData
}
var file_conf_v1_kratos_conf_notify_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_conf_v1_kratos_conf_notify_proto_goTypes = []any{
(*Notification)(nil), // 0: conf.Notification
(*Notification_SMS)(nil), // 1: conf.Notification.SMS
}
var file_conf_v1_kratos_conf_notify_proto_depIdxs = []int32{
1, // 0: conf.Notification.sms:type_name -> conf.Notification.SMS
1, // [1:1] is the sub-list for method output_type
1, // [1:1] is the sub-list for method input_type
1, // [1:1] is the sub-list for extension type_name
1, // [1:1] is the sub-list for extension extendee
0, // [0:1] is the sub-list for field type_name
}
func init() { file_conf_v1_kratos_conf_notify_proto_init() }
func file_conf_v1_kratos_conf_notify_proto_init() {
if File_conf_v1_kratos_conf_notify_proto != nil {
return
}
file_conf_v1_kratos_conf_notify_proto_msgTypes[0].OneofWrappers = []any{}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_conf_v1_kratos_conf_notify_proto_rawDesc), len(file_conf_v1_kratos_conf_notify_proto_rawDesc)),
NumEnums: 0,
NumMessages: 2,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_conf_v1_kratos_conf_notify_proto_goTypes,
DependencyIndexes: file_conf_v1_kratos_conf_notify_proto_depIdxs,
MessageInfos: file_conf_v1_kratos_conf_notify_proto_msgTypes,
}.Build()
File_conf_v1_kratos_conf_notify_proto = out.File
file_conf_v1_kratos_conf_notify_proto_goTypes = nil
file_conf_v1_kratos_conf_notify_proto_depIdxs = nil
}

View File

@@ -0,0 +1,245 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.36.6
// protoc (unknown)
// source: conf/v1/kratos_conf_oss.proto
package v1
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
unsafe "unsafe"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// 对象存储
type OSS struct {
state protoimpl.MessageState `protogen:"open.v1"`
Minio *OSS_MinIO `protobuf:"bytes,1,opt,name=minio,proto3,oneof" json:"minio,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *OSS) Reset() {
*x = OSS{}
mi := &file_conf_v1_kratos_conf_oss_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *OSS) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*OSS) ProtoMessage() {}
func (x *OSS) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_oss_proto_msgTypes[0]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use OSS.ProtoReflect.Descriptor instead.
func (*OSS) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_oss_proto_rawDescGZIP(), []int{0}
}
func (x *OSS) GetMinio() *OSS_MinIO {
if x != nil {
return x.Minio
}
return nil
}
// MinIO
type OSS_MinIO struct {
state protoimpl.MessageState `protogen:"open.v1"`
Endpoint string `protobuf:"bytes,1,opt,name=endpoint,proto3" json:"endpoint,omitempty"` // 对端端口
AccessKey string `protobuf:"bytes,2,opt,name=access_key,json=accessKey,proto3" json:"access_key,omitempty"` // 访问密钥
SecretKey string `protobuf:"bytes,3,opt,name=secret_key,json=secretKey,proto3" json:"secret_key,omitempty"` // 密钥
Token string `protobuf:"bytes,4,opt,name=token,proto3" json:"token,omitempty"` // 令牌
UseSsl bool `protobuf:"varint,10,opt,name=use_ssl,json=useSsl,proto3" json:"use_ssl,omitempty"` // 使用SSL
Tls *TLS `protobuf:"bytes,11,opt,name=tls,proto3" json:"tls,omitempty"` // TLS配置
UploadHost string `protobuf:"bytes,20,opt,name=upload_host,json=uploadHost,proto3" json:"upload_host,omitempty"` // 上传链接的主机名
DownloadHost string `protobuf:"bytes,21,opt,name=download_host,json=downloadHost,proto3" json:"download_host,omitempty"` // 下载链接的主机名
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *OSS_MinIO) Reset() {
*x = OSS_MinIO{}
mi := &file_conf_v1_kratos_conf_oss_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *OSS_MinIO) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*OSS_MinIO) ProtoMessage() {}
func (x *OSS_MinIO) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_oss_proto_msgTypes[1]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use OSS_MinIO.ProtoReflect.Descriptor instead.
func (*OSS_MinIO) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_oss_proto_rawDescGZIP(), []int{0, 0}
}
func (x *OSS_MinIO) GetEndpoint() string {
if x != nil {
return x.Endpoint
}
return ""
}
func (x *OSS_MinIO) GetAccessKey() string {
if x != nil {
return x.AccessKey
}
return ""
}
func (x *OSS_MinIO) GetSecretKey() string {
if x != nil {
return x.SecretKey
}
return ""
}
func (x *OSS_MinIO) GetToken() string {
if x != nil {
return x.Token
}
return ""
}
func (x *OSS_MinIO) GetUseSsl() bool {
if x != nil {
return x.UseSsl
}
return false
}
func (x *OSS_MinIO) GetTls() *TLS {
if x != nil {
return x.Tls
}
return nil
}
func (x *OSS_MinIO) GetUploadHost() string {
if x != nil {
return x.UploadHost
}
return ""
}
func (x *OSS_MinIO) GetDownloadHost() string {
if x != nil {
return x.DownloadHost
}
return ""
}
var File_conf_v1_kratos_conf_oss_proto protoreflect.FileDescriptor
const file_conf_v1_kratos_conf_oss_proto_rawDesc = "" +
"\n" +
"\x1dconf/v1/kratos_conf_oss.proto\x12\x04conf\x1a\x1dconf/v1/kratos_conf_tls.proto\"\xb1\x02\n" +
"\x03OSS\x12*\n" +
"\x05minio\x18\x01 \x01(\v2\x0f.conf.OSS.MinIOH\x00R\x05minio\x88\x01\x01\x1a\xf3\x01\n" +
"\x05MinIO\x12\x1a\n" +
"\bendpoint\x18\x01 \x01(\tR\bendpoint\x12\x1d\n" +
"\n" +
"access_key\x18\x02 \x01(\tR\taccessKey\x12\x1d\n" +
"\n" +
"secret_key\x18\x03 \x01(\tR\tsecretKey\x12\x14\n" +
"\x05token\x18\x04 \x01(\tR\x05token\x12\x17\n" +
"\ause_ssl\x18\n" +
" \x01(\bR\x06useSsl\x12\x1b\n" +
"\x03tls\x18\v \x01(\v2\t.conf.TLSR\x03tls\x12\x1f\n" +
"\vupload_host\x18\x14 \x01(\tR\n" +
"uploadHost\x12#\n" +
"\rdownload_host\x18\x15 \x01(\tR\fdownloadHostB\b\n" +
"\x06_minioB\x84\x01\n" +
"\bcom.confB\x12KratosConfOssProtoP\x01Z4github.com/tx7do/kratos-bootstrap/api/gen/go/conf/v1\xa2\x02\x03CXX\xaa\x02\x04Conf\xca\x02\x04Conf\xe2\x02\x10Conf\\GPBMetadata\xea\x02\x04Confb\x06proto3"
var (
file_conf_v1_kratos_conf_oss_proto_rawDescOnce sync.Once
file_conf_v1_kratos_conf_oss_proto_rawDescData []byte
)
func file_conf_v1_kratos_conf_oss_proto_rawDescGZIP() []byte {
file_conf_v1_kratos_conf_oss_proto_rawDescOnce.Do(func() {
file_conf_v1_kratos_conf_oss_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_conf_v1_kratos_conf_oss_proto_rawDesc), len(file_conf_v1_kratos_conf_oss_proto_rawDesc)))
})
return file_conf_v1_kratos_conf_oss_proto_rawDescData
}
var file_conf_v1_kratos_conf_oss_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_conf_v1_kratos_conf_oss_proto_goTypes = []any{
(*OSS)(nil), // 0: conf.OSS
(*OSS_MinIO)(nil), // 1: conf.OSS.MinIO
(*TLS)(nil), // 2: conf.TLS
}
var file_conf_v1_kratos_conf_oss_proto_depIdxs = []int32{
1, // 0: conf.OSS.minio:type_name -> conf.OSS.MinIO
2, // 1: conf.OSS.MinIO.tls:type_name -> conf.TLS
2, // [2:2] is the sub-list for method output_type
2, // [2:2] is the sub-list for method input_type
2, // [2:2] is the sub-list for extension type_name
2, // [2:2] is the sub-list for extension extendee
0, // [0:2] is the sub-list for field type_name
}
func init() { file_conf_v1_kratos_conf_oss_proto_init() }
func file_conf_v1_kratos_conf_oss_proto_init() {
if File_conf_v1_kratos_conf_oss_proto != nil {
return
}
file_conf_v1_kratos_conf_tls_proto_init()
file_conf_v1_kratos_conf_oss_proto_msgTypes[0].OneofWrappers = []any{}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_conf_v1_kratos_conf_oss_proto_rawDesc), len(file_conf_v1_kratos_conf_oss_proto_rawDesc)),
NumEnums: 0,
NumMessages: 2,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_conf_v1_kratos_conf_oss_proto_goTypes,
DependencyIndexes: file_conf_v1_kratos_conf_oss_proto_depIdxs,
MessageInfos: file_conf_v1_kratos_conf_oss_proto_msgTypes,
}.Build()
File_conf_v1_kratos_conf_oss_proto = out.File
file_conf_v1_kratos_conf_oss_proto_goTypes = nil
file_conf_v1_kratos_conf_oss_proto_depIdxs = nil
}

View File

@@ -0,0 +1,883 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.36.6
// protoc (unknown)
// source: conf/v1/kratos_conf_registry.proto
package v1
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
durationpb "google.golang.org/protobuf/types/known/durationpb"
reflect "reflect"
sync "sync"
unsafe "unsafe"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// 注册发现中心
type Registry struct {
state protoimpl.MessageState `protogen:"open.v1"`
Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"`
Consul *Registry_Consul `protobuf:"bytes,2,opt,name=consul,proto3,oneof" json:"consul,omitempty"` // Consul
Etcd *Registry_Etcd `protobuf:"bytes,3,opt,name=etcd,proto3,oneof" json:"etcd,omitempty"` // Etcd
Zookeeper *Registry_ZooKeeper `protobuf:"bytes,4,opt,name=zookeeper,proto3,oneof" json:"zookeeper,omitempty"` // ZooKeeper
Nacos *Registry_Nacos `protobuf:"bytes,5,opt,name=nacos,proto3,oneof" json:"nacos,omitempty"` // Nacos
Kubernetes *Registry_Kubernetes `protobuf:"bytes,6,opt,name=kubernetes,proto3,oneof" json:"kubernetes,omitempty"` // Kubernetes
Eureka *Registry_Eureka `protobuf:"bytes,7,opt,name=eureka,proto3,oneof" json:"eureka,omitempty"` // Eureka
Polaris *Registry_Polaris `protobuf:"bytes,8,opt,name=polaris,proto3,oneof" json:"polaris,omitempty"` // Polaris
Servicecomb *Registry_Servicecomb `protobuf:"bytes,9,opt,name=servicecomb,proto3,oneof" json:"servicecomb,omitempty"` // Servicecomb
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Registry) Reset() {
*x = Registry{}
mi := &file_conf_v1_kratos_conf_registry_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Registry) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Registry) ProtoMessage() {}
func (x *Registry) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_registry_proto_msgTypes[0]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Registry.ProtoReflect.Descriptor instead.
func (*Registry) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_registry_proto_rawDescGZIP(), []int{0}
}
func (x *Registry) GetType() string {
if x != nil {
return x.Type
}
return ""
}
func (x *Registry) GetConsul() *Registry_Consul {
if x != nil {
return x.Consul
}
return nil
}
func (x *Registry) GetEtcd() *Registry_Etcd {
if x != nil {
return x.Etcd
}
return nil
}
func (x *Registry) GetZookeeper() *Registry_ZooKeeper {
if x != nil {
return x.Zookeeper
}
return nil
}
func (x *Registry) GetNacos() *Registry_Nacos {
if x != nil {
return x.Nacos
}
return nil
}
func (x *Registry) GetKubernetes() *Registry_Kubernetes {
if x != nil {
return x.Kubernetes
}
return nil
}
func (x *Registry) GetEureka() *Registry_Eureka {
if x != nil {
return x.Eureka
}
return nil
}
func (x *Registry) GetPolaris() *Registry_Polaris {
if x != nil {
return x.Polaris
}
return nil
}
func (x *Registry) GetServicecomb() *Registry_Servicecomb {
if x != nil {
return x.Servicecomb
}
return nil
}
// Consul
type Registry_Consul struct {
state protoimpl.MessageState `protogen:"open.v1"`
Scheme string `protobuf:"bytes,1,opt,name=scheme,proto3" json:"scheme,omitempty"` // 网络样式
Address string `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"` // 服务端地址
HealthCheck bool `protobuf:"varint,3,opt,name=health_check,json=healthCheck,proto3" json:"health_check,omitempty"` // 健康检查
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Registry_Consul) Reset() {
*x = Registry_Consul{}
mi := &file_conf_v1_kratos_conf_registry_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Registry_Consul) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Registry_Consul) ProtoMessage() {}
func (x *Registry_Consul) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_registry_proto_msgTypes[1]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Registry_Consul.ProtoReflect.Descriptor instead.
func (*Registry_Consul) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_registry_proto_rawDescGZIP(), []int{0, 0}
}
func (x *Registry_Consul) GetScheme() string {
if x != nil {
return x.Scheme
}
return ""
}
func (x *Registry_Consul) GetAddress() string {
if x != nil {
return x.Address
}
return ""
}
func (x *Registry_Consul) GetHealthCheck() bool {
if x != nil {
return x.HealthCheck
}
return false
}
// Etcd
type Registry_Etcd struct {
state protoimpl.MessageState `protogen:"open.v1"`
Endpoints []string `protobuf:"bytes,1,rep,name=endpoints,proto3" json:"endpoints,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Registry_Etcd) Reset() {
*x = Registry_Etcd{}
mi := &file_conf_v1_kratos_conf_registry_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Registry_Etcd) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Registry_Etcd) ProtoMessage() {}
func (x *Registry_Etcd) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_registry_proto_msgTypes[2]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Registry_Etcd.ProtoReflect.Descriptor instead.
func (*Registry_Etcd) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_registry_proto_rawDescGZIP(), []int{0, 1}
}
func (x *Registry_Etcd) GetEndpoints() []string {
if x != nil {
return x.Endpoints
}
return nil
}
// ZooKeeper
type Registry_ZooKeeper struct {
state protoimpl.MessageState `protogen:"open.v1"`
Endpoints []string `protobuf:"bytes,1,rep,name=endpoints,proto3" json:"endpoints,omitempty"`
Timeout *durationpb.Duration `protobuf:"bytes,2,opt,name=timeout,proto3" json:"timeout,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Registry_ZooKeeper) Reset() {
*x = Registry_ZooKeeper{}
mi := &file_conf_v1_kratos_conf_registry_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Registry_ZooKeeper) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Registry_ZooKeeper) ProtoMessage() {}
func (x *Registry_ZooKeeper) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_registry_proto_msgTypes[3]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Registry_ZooKeeper.ProtoReflect.Descriptor instead.
func (*Registry_ZooKeeper) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_registry_proto_rawDescGZIP(), []int{0, 2}
}
func (x *Registry_ZooKeeper) GetEndpoints() []string {
if x != nil {
return x.Endpoints
}
return nil
}
func (x *Registry_ZooKeeper) GetTimeout() *durationpb.Duration {
if x != nil {
return x.Timeout
}
return nil
}
// Nacos
type Registry_Nacos struct {
state protoimpl.MessageState `protogen:"open.v1"`
Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` // 服务端地址
Port uint64 `protobuf:"varint,2,opt,name=port,proto3" json:"port,omitempty"` // 服务端端口
NamespaceId string `protobuf:"bytes,3,opt,name=namespace_id,json=namespaceId,proto3" json:"namespace_id,omitempty"` // 命名空间ID
RegionId string `protobuf:"bytes,4,opt,name=region_id,json=regionId,proto3" json:"region_id,omitempty"` // 区域ID
AppName string `protobuf:"bytes,5,opt,name=app_name,json=appName,proto3" json:"app_name,omitempty"` // 应用名称
AppKey string `protobuf:"bytes,6,opt,name=app_key,json=appKey,proto3" json:"app_key,omitempty"` // 应用密钥
AccessKey string `protobuf:"bytes,7,opt,name=access_key,json=accessKey,proto3" json:"access_key,omitempty"` // 访问密钥
SecretKey string `protobuf:"bytes,8,opt,name=secret_key,json=secretKey,proto3" json:"secret_key,omitempty"` // 密钥
Username string `protobuf:"bytes,9,opt,name=username,proto3" json:"username,omitempty"` // 用户名
Password string `protobuf:"bytes,10,opt,name=password,proto3" json:"password,omitempty"` // 密码
Timeout *durationpb.Duration `protobuf:"bytes,20,opt,name=timeout,proto3" json:"timeout,omitempty"` // http请求超时时间单位: 毫秒
BeatInterval *durationpb.Duration `protobuf:"bytes,21,opt,name=beat_interval,json=beatInterval,proto3" json:"beat_interval,omitempty"` // 心跳间隔时间,单位: 毫秒
ListenInterval *durationpb.Duration `protobuf:"bytes,22,opt,name=listen_interval,json=listenInterval,proto3" json:"listen_interval,omitempty"` // 心跳间隔时间,单位: 毫秒
UpdateThreadNum int32 `protobuf:"varint,30,opt,name=update_thread_num,json=updateThreadNum,proto3" json:"update_thread_num,omitempty"` // 更新服务的线程数
NotLoadCacheAtStart bool `protobuf:"varint,40,opt,name=not_load_cache_at_start,json=notLoadCacheAtStart,proto3" json:"not_load_cache_at_start,omitempty"` // 在启动时不读取本地缓存数据true: 不读取false: 读取
UpdateCacheWhenEmpty bool `protobuf:"varint,41,opt,name=update_cache_when_empty,json=updateCacheWhenEmpty,proto3" json:"update_cache_when_empty,omitempty"` // 当服务列表为空时是否更新本地缓存true: 更新,false: 不更新
OpenKms bool `protobuf:"varint,42,opt,name=open_kms,json=openKms,proto3" json:"open_kms,omitempty"` // 是否开启kms加密true: 开启false: 关闭
LogLevel string `protobuf:"bytes,50,opt,name=log_level,json=logLevel,proto3" json:"log_level,omitempty"` // 日志等级
LogDir string `protobuf:"bytes,51,opt,name=log_dir,json=logDir,proto3" json:"log_dir,omitempty"` // 日志目录
CacheDir string `protobuf:"bytes,52,opt,name=cache_dir,json=cacheDir,proto3" json:"cache_dir,omitempty"` // 缓存目录
ContextPath string `protobuf:"bytes,53,opt,name=context_path,json=contextPath,proto3" json:"context_path,omitempty"` // 上下文路径
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Registry_Nacos) Reset() {
*x = Registry_Nacos{}
mi := &file_conf_v1_kratos_conf_registry_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Registry_Nacos) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Registry_Nacos) ProtoMessage() {}
func (x *Registry_Nacos) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_registry_proto_msgTypes[4]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Registry_Nacos.ProtoReflect.Descriptor instead.
func (*Registry_Nacos) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_registry_proto_rawDescGZIP(), []int{0, 3}
}
func (x *Registry_Nacos) GetAddress() string {
if x != nil {
return x.Address
}
return ""
}
func (x *Registry_Nacos) GetPort() uint64 {
if x != nil {
return x.Port
}
return 0
}
func (x *Registry_Nacos) GetNamespaceId() string {
if x != nil {
return x.NamespaceId
}
return ""
}
func (x *Registry_Nacos) GetRegionId() string {
if x != nil {
return x.RegionId
}
return ""
}
func (x *Registry_Nacos) GetAppName() string {
if x != nil {
return x.AppName
}
return ""
}
func (x *Registry_Nacos) GetAppKey() string {
if x != nil {
return x.AppKey
}
return ""
}
func (x *Registry_Nacos) GetAccessKey() string {
if x != nil {
return x.AccessKey
}
return ""
}
func (x *Registry_Nacos) GetSecretKey() string {
if x != nil {
return x.SecretKey
}
return ""
}
func (x *Registry_Nacos) GetUsername() string {
if x != nil {
return x.Username
}
return ""
}
func (x *Registry_Nacos) GetPassword() string {
if x != nil {
return x.Password
}
return ""
}
func (x *Registry_Nacos) GetTimeout() *durationpb.Duration {
if x != nil {
return x.Timeout
}
return nil
}
func (x *Registry_Nacos) GetBeatInterval() *durationpb.Duration {
if x != nil {
return x.BeatInterval
}
return nil
}
func (x *Registry_Nacos) GetListenInterval() *durationpb.Duration {
if x != nil {
return x.ListenInterval
}
return nil
}
func (x *Registry_Nacos) GetUpdateThreadNum() int32 {
if x != nil {
return x.UpdateThreadNum
}
return 0
}
func (x *Registry_Nacos) GetNotLoadCacheAtStart() bool {
if x != nil {
return x.NotLoadCacheAtStart
}
return false
}
func (x *Registry_Nacos) GetUpdateCacheWhenEmpty() bool {
if x != nil {
return x.UpdateCacheWhenEmpty
}
return false
}
func (x *Registry_Nacos) GetOpenKms() bool {
if x != nil {
return x.OpenKms
}
return false
}
func (x *Registry_Nacos) GetLogLevel() string {
if x != nil {
return x.LogLevel
}
return ""
}
func (x *Registry_Nacos) GetLogDir() string {
if x != nil {
return x.LogDir
}
return ""
}
func (x *Registry_Nacos) GetCacheDir() string {
if x != nil {
return x.CacheDir
}
return ""
}
func (x *Registry_Nacos) GetContextPath() string {
if x != nil {
return x.ContextPath
}
return ""
}
// Kubernetes
type Registry_Kubernetes struct {
state protoimpl.MessageState `protogen:"open.v1"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Registry_Kubernetes) Reset() {
*x = Registry_Kubernetes{}
mi := &file_conf_v1_kratos_conf_registry_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Registry_Kubernetes) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Registry_Kubernetes) ProtoMessage() {}
func (x *Registry_Kubernetes) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_registry_proto_msgTypes[5]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Registry_Kubernetes.ProtoReflect.Descriptor instead.
func (*Registry_Kubernetes) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_registry_proto_rawDescGZIP(), []int{0, 4}
}
// Eureka
type Registry_Eureka struct {
state protoimpl.MessageState `protogen:"open.v1"`
Endpoints []string `protobuf:"bytes,1,rep,name=endpoints,proto3" json:"endpoints,omitempty"`
HeartbeatInterval *durationpb.Duration `protobuf:"bytes,2,opt,name=heartbeat_interval,json=heartbeatInterval,proto3" json:"heartbeat_interval,omitempty"`
RefreshInterval *durationpb.Duration `protobuf:"bytes,3,opt,name=refresh_interval,json=refreshInterval,proto3" json:"refresh_interval,omitempty"`
Path string `protobuf:"bytes,4,opt,name=path,proto3" json:"path,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Registry_Eureka) Reset() {
*x = Registry_Eureka{}
mi := &file_conf_v1_kratos_conf_registry_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Registry_Eureka) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Registry_Eureka) ProtoMessage() {}
func (x *Registry_Eureka) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_registry_proto_msgTypes[6]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Registry_Eureka.ProtoReflect.Descriptor instead.
func (*Registry_Eureka) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_registry_proto_rawDescGZIP(), []int{0, 5}
}
func (x *Registry_Eureka) GetEndpoints() []string {
if x != nil {
return x.Endpoints
}
return nil
}
func (x *Registry_Eureka) GetHeartbeatInterval() *durationpb.Duration {
if x != nil {
return x.HeartbeatInterval
}
return nil
}
func (x *Registry_Eureka) GetRefreshInterval() *durationpb.Duration {
if x != nil {
return x.RefreshInterval
}
return nil
}
func (x *Registry_Eureka) GetPath() string {
if x != nil {
return x.Path
}
return ""
}
// Polaris
type Registry_Polaris struct {
state protoimpl.MessageState `protogen:"open.v1"`
Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` // 服务端地址
Port int32 `protobuf:"varint,2,opt,name=port,proto3" json:"port,omitempty"` // 服务端端口
InstanceCount int32 `protobuf:"varint,3,opt,name=instance_count,json=instanceCount,proto3" json:"instance_count,omitempty"`
Namespace string `protobuf:"bytes,4,opt,name=namespace,proto3" json:"namespace,omitempty"`
Service string `protobuf:"bytes,5,opt,name=service,proto3" json:"service,omitempty"`
Token string `protobuf:"bytes,6,opt,name=token,proto3" json:"token,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Registry_Polaris) Reset() {
*x = Registry_Polaris{}
mi := &file_conf_v1_kratos_conf_registry_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Registry_Polaris) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Registry_Polaris) ProtoMessage() {}
func (x *Registry_Polaris) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_registry_proto_msgTypes[7]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Registry_Polaris.ProtoReflect.Descriptor instead.
func (*Registry_Polaris) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_registry_proto_rawDescGZIP(), []int{0, 6}
}
func (x *Registry_Polaris) GetAddress() string {
if x != nil {
return x.Address
}
return ""
}
func (x *Registry_Polaris) GetPort() int32 {
if x != nil {
return x.Port
}
return 0
}
func (x *Registry_Polaris) GetInstanceCount() int32 {
if x != nil {
return x.InstanceCount
}
return 0
}
func (x *Registry_Polaris) GetNamespace() string {
if x != nil {
return x.Namespace
}
return ""
}
func (x *Registry_Polaris) GetService() string {
if x != nil {
return x.Service
}
return ""
}
func (x *Registry_Polaris) GetToken() string {
if x != nil {
return x.Token
}
return ""
}
// Servicecomb
type Registry_Servicecomb struct {
state protoimpl.MessageState `protogen:"open.v1"`
Endpoints []string `protobuf:"bytes,1,rep,name=endpoints,proto3" json:"endpoints,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Registry_Servicecomb) Reset() {
*x = Registry_Servicecomb{}
mi := &file_conf_v1_kratos_conf_registry_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Registry_Servicecomb) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Registry_Servicecomb) ProtoMessage() {}
func (x *Registry_Servicecomb) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_registry_proto_msgTypes[8]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Registry_Servicecomb.ProtoReflect.Descriptor instead.
func (*Registry_Servicecomb) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_registry_proto_rawDescGZIP(), []int{0, 7}
}
func (x *Registry_Servicecomb) GetEndpoints() []string {
if x != nil {
return x.Endpoints
}
return nil
}
var File_conf_v1_kratos_conf_registry_proto protoreflect.FileDescriptor
const file_conf_v1_kratos_conf_registry_proto_rawDesc = "" +
"\n" +
"\"conf/v1/kratos_conf_registry.proto\x12\x04conf\x1a\x1egoogle/protobuf/duration.proto\"\xdf\x0f\n" +
"\bRegistry\x12\x12\n" +
"\x04type\x18\x01 \x01(\tR\x04type\x122\n" +
"\x06consul\x18\x02 \x01(\v2\x15.conf.Registry.ConsulH\x00R\x06consul\x88\x01\x01\x12,\n" +
"\x04etcd\x18\x03 \x01(\v2\x13.conf.Registry.EtcdH\x01R\x04etcd\x88\x01\x01\x12;\n" +
"\tzookeeper\x18\x04 \x01(\v2\x18.conf.Registry.ZooKeeperH\x02R\tzookeeper\x88\x01\x01\x12/\n" +
"\x05nacos\x18\x05 \x01(\v2\x14.conf.Registry.NacosH\x03R\x05nacos\x88\x01\x01\x12>\n" +
"\n" +
"kubernetes\x18\x06 \x01(\v2\x19.conf.Registry.KubernetesH\x04R\n" +
"kubernetes\x88\x01\x01\x122\n" +
"\x06eureka\x18\a \x01(\v2\x15.conf.Registry.EurekaH\x05R\x06eureka\x88\x01\x01\x125\n" +
"\apolaris\x18\b \x01(\v2\x16.conf.Registry.PolarisH\x06R\apolaris\x88\x01\x01\x12A\n" +
"\vservicecomb\x18\t \x01(\v2\x1a.conf.Registry.ServicecombH\aR\vservicecomb\x88\x01\x01\x1a]\n" +
"\x06Consul\x12\x16\n" +
"\x06scheme\x18\x01 \x01(\tR\x06scheme\x12\x18\n" +
"\aaddress\x18\x02 \x01(\tR\aaddress\x12!\n" +
"\fhealth_check\x18\x03 \x01(\bR\vhealthCheck\x1a$\n" +
"\x04Etcd\x12\x1c\n" +
"\tendpoints\x18\x01 \x03(\tR\tendpoints\x1a^\n" +
"\tZooKeeper\x12\x1c\n" +
"\tendpoints\x18\x01 \x03(\tR\tendpoints\x123\n" +
"\atimeout\x18\x02 \x01(\v2\x19.google.protobuf.DurationR\atimeout\x1a\x82\x06\n" +
"\x05Nacos\x12\x18\n" +
"\aaddress\x18\x01 \x01(\tR\aaddress\x12\x12\n" +
"\x04port\x18\x02 \x01(\x04R\x04port\x12!\n" +
"\fnamespace_id\x18\x03 \x01(\tR\vnamespaceId\x12\x1b\n" +
"\tregion_id\x18\x04 \x01(\tR\bregionId\x12\x19\n" +
"\bapp_name\x18\x05 \x01(\tR\aappName\x12\x17\n" +
"\aapp_key\x18\x06 \x01(\tR\x06appKey\x12\x1d\n" +
"\n" +
"access_key\x18\a \x01(\tR\taccessKey\x12\x1d\n" +
"\n" +
"secret_key\x18\b \x01(\tR\tsecretKey\x12\x1a\n" +
"\busername\x18\t \x01(\tR\busername\x12\x1a\n" +
"\bpassword\x18\n" +
" \x01(\tR\bpassword\x123\n" +
"\atimeout\x18\x14 \x01(\v2\x19.google.protobuf.DurationR\atimeout\x12>\n" +
"\rbeat_interval\x18\x15 \x01(\v2\x19.google.protobuf.DurationR\fbeatInterval\x12B\n" +
"\x0flisten_interval\x18\x16 \x01(\v2\x19.google.protobuf.DurationR\x0elistenInterval\x12*\n" +
"\x11update_thread_num\x18\x1e \x01(\x05R\x0fupdateThreadNum\x124\n" +
"\x17not_load_cache_at_start\x18( \x01(\bR\x13notLoadCacheAtStart\x125\n" +
"\x17update_cache_when_empty\x18) \x01(\bR\x14updateCacheWhenEmpty\x12\x19\n" +
"\bopen_kms\x18* \x01(\bR\aopenKms\x12\x1b\n" +
"\tlog_level\x182 \x01(\tR\blogLevel\x12\x17\n" +
"\alog_dir\x183 \x01(\tR\x06logDir\x12\x1b\n" +
"\tcache_dir\x184 \x01(\tR\bcacheDir\x12!\n" +
"\fcontext_path\x185 \x01(\tR\vcontextPath\x1a\f\n" +
"\n" +
"Kubernetes\x1a\xca\x01\n" +
"\x06Eureka\x12\x1c\n" +
"\tendpoints\x18\x01 \x03(\tR\tendpoints\x12H\n" +
"\x12heartbeat_interval\x18\x02 \x01(\v2\x19.google.protobuf.DurationR\x11heartbeatInterval\x12D\n" +
"\x10refresh_interval\x18\x03 \x01(\v2\x19.google.protobuf.DurationR\x0frefreshInterval\x12\x12\n" +
"\x04path\x18\x04 \x01(\tR\x04path\x1a\xac\x01\n" +
"\aPolaris\x12\x18\n" +
"\aaddress\x18\x01 \x01(\tR\aaddress\x12\x12\n" +
"\x04port\x18\x02 \x01(\x05R\x04port\x12%\n" +
"\x0einstance_count\x18\x03 \x01(\x05R\rinstanceCount\x12\x1c\n" +
"\tnamespace\x18\x04 \x01(\tR\tnamespace\x12\x18\n" +
"\aservice\x18\x05 \x01(\tR\aservice\x12\x14\n" +
"\x05token\x18\x06 \x01(\tR\x05token\x1a+\n" +
"\vServicecomb\x12\x1c\n" +
"\tendpoints\x18\x01 \x03(\tR\tendpointsB\t\n" +
"\a_consulB\a\n" +
"\x05_etcdB\f\n" +
"\n" +
"_zookeeperB\b\n" +
"\x06_nacosB\r\n" +
"\v_kubernetesB\t\n" +
"\a_eurekaB\n" +
"\n" +
"\b_polarisB\x0e\n" +
"\f_servicecombB\x89\x01\n" +
"\bcom.confB\x17KratosConfRegistryProtoP\x01Z4github.com/tx7do/kratos-bootstrap/api/gen/go/conf/v1\xa2\x02\x03CXX\xaa\x02\x04Conf\xca\x02\x04Conf\xe2\x02\x10Conf\\GPBMetadata\xea\x02\x04Confb\x06proto3"
var (
file_conf_v1_kratos_conf_registry_proto_rawDescOnce sync.Once
file_conf_v1_kratos_conf_registry_proto_rawDescData []byte
)
func file_conf_v1_kratos_conf_registry_proto_rawDescGZIP() []byte {
file_conf_v1_kratos_conf_registry_proto_rawDescOnce.Do(func() {
file_conf_v1_kratos_conf_registry_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_conf_v1_kratos_conf_registry_proto_rawDesc), len(file_conf_v1_kratos_conf_registry_proto_rawDesc)))
})
return file_conf_v1_kratos_conf_registry_proto_rawDescData
}
var file_conf_v1_kratos_conf_registry_proto_msgTypes = make([]protoimpl.MessageInfo, 9)
var file_conf_v1_kratos_conf_registry_proto_goTypes = []any{
(*Registry)(nil), // 0: conf.Registry
(*Registry_Consul)(nil), // 1: conf.Registry.Consul
(*Registry_Etcd)(nil), // 2: conf.Registry.Etcd
(*Registry_ZooKeeper)(nil), // 3: conf.Registry.ZooKeeper
(*Registry_Nacos)(nil), // 4: conf.Registry.Nacos
(*Registry_Kubernetes)(nil), // 5: conf.Registry.Kubernetes
(*Registry_Eureka)(nil), // 6: conf.Registry.Eureka
(*Registry_Polaris)(nil), // 7: conf.Registry.Polaris
(*Registry_Servicecomb)(nil), // 8: conf.Registry.Servicecomb
(*durationpb.Duration)(nil), // 9: google.protobuf.Duration
}
var file_conf_v1_kratos_conf_registry_proto_depIdxs = []int32{
1, // 0: conf.Registry.consul:type_name -> conf.Registry.Consul
2, // 1: conf.Registry.etcd:type_name -> conf.Registry.Etcd
3, // 2: conf.Registry.zookeeper:type_name -> conf.Registry.ZooKeeper
4, // 3: conf.Registry.nacos:type_name -> conf.Registry.Nacos
5, // 4: conf.Registry.kubernetes:type_name -> conf.Registry.Kubernetes
6, // 5: conf.Registry.eureka:type_name -> conf.Registry.Eureka
7, // 6: conf.Registry.polaris:type_name -> conf.Registry.Polaris
8, // 7: conf.Registry.servicecomb:type_name -> conf.Registry.Servicecomb
9, // 8: conf.Registry.ZooKeeper.timeout:type_name -> google.protobuf.Duration
9, // 9: conf.Registry.Nacos.timeout:type_name -> google.protobuf.Duration
9, // 10: conf.Registry.Nacos.beat_interval:type_name -> google.protobuf.Duration
9, // 11: conf.Registry.Nacos.listen_interval:type_name -> google.protobuf.Duration
9, // 12: conf.Registry.Eureka.heartbeat_interval:type_name -> google.protobuf.Duration
9, // 13: conf.Registry.Eureka.refresh_interval:type_name -> google.protobuf.Duration
14, // [14:14] is the sub-list for method output_type
14, // [14:14] is the sub-list for method input_type
14, // [14:14] is the sub-list for extension type_name
14, // [14:14] is the sub-list for extension extendee
0, // [0:14] is the sub-list for field type_name
}
func init() { file_conf_v1_kratos_conf_registry_proto_init() }
func file_conf_v1_kratos_conf_registry_proto_init() {
if File_conf_v1_kratos_conf_registry_proto != nil {
return
}
file_conf_v1_kratos_conf_registry_proto_msgTypes[0].OneofWrappers = []any{}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_conf_v1_kratos_conf_registry_proto_rawDesc), len(file_conf_v1_kratos_conf_registry_proto_rawDesc)),
NumEnums: 0,
NumMessages: 9,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_conf_v1_kratos_conf_registry_proto_goTypes,
DependencyIndexes: file_conf_v1_kratos_conf_registry_proto_depIdxs,
MessageInfos: file_conf_v1_kratos_conf_registry_proto_msgTypes,
}.Build()
File_conf_v1_kratos_conf_registry_proto = out.File
file_conf_v1_kratos_conf_registry_proto_goTypes = nil
file_conf_v1_kratos_conf_registry_proto_depIdxs = nil
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,288 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.36.6
// protoc (unknown)
// source: conf/v1/kratos_conf_tls.proto
package v1
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
unsafe "unsafe"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// TLS配置
type TLS struct {
state protoimpl.MessageState `protogen:"open.v1"`
File *TLS_File `protobuf:"bytes,1,opt,name=file,proto3,oneof" json:"file,omitempty"`
Config *TLS_Config `protobuf:"bytes,2,opt,name=config,proto3,oneof" json:"config,omitempty"`
InsecureSkipVerify bool `protobuf:"varint,3,opt,name=insecure_skip_verify,json=insecureSkipVerify,proto3" json:"insecure_skip_verify,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *TLS) Reset() {
*x = TLS{}
mi := &file_conf_v1_kratos_conf_tls_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *TLS) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*TLS) ProtoMessage() {}
func (x *TLS) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_tls_proto_msgTypes[0]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use TLS.ProtoReflect.Descriptor instead.
func (*TLS) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_tls_proto_rawDescGZIP(), []int{0}
}
func (x *TLS) GetFile() *TLS_File {
if x != nil {
return x.File
}
return nil
}
func (x *TLS) GetConfig() *TLS_Config {
if x != nil {
return x.Config
}
return nil
}
func (x *TLS) GetInsecureSkipVerify() bool {
if x != nil {
return x.InsecureSkipVerify
}
return false
}
type TLS_File struct {
state protoimpl.MessageState `protogen:"open.v1"`
CertPath *string `protobuf:"bytes,1,opt,name=cert_path,json=certPath,proto3,oneof" json:"cert_path,omitempty"`
KeyPath *string `protobuf:"bytes,2,opt,name=key_path,json=keyPath,proto3,oneof" json:"key_path,omitempty"`
CaPath *string `protobuf:"bytes,3,opt,name=ca_path,json=caPath,proto3,oneof" json:"ca_path,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *TLS_File) Reset() {
*x = TLS_File{}
mi := &file_conf_v1_kratos_conf_tls_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *TLS_File) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*TLS_File) ProtoMessage() {}
func (x *TLS_File) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_tls_proto_msgTypes[1]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use TLS_File.ProtoReflect.Descriptor instead.
func (*TLS_File) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_tls_proto_rawDescGZIP(), []int{0, 0}
}
func (x *TLS_File) GetCertPath() string {
if x != nil && x.CertPath != nil {
return *x.CertPath
}
return ""
}
func (x *TLS_File) GetKeyPath() string {
if x != nil && x.KeyPath != nil {
return *x.KeyPath
}
return ""
}
func (x *TLS_File) GetCaPath() string {
if x != nil && x.CaPath != nil {
return *x.CaPath
}
return ""
}
type TLS_Config struct {
state protoimpl.MessageState `protogen:"open.v1"`
CertPem []byte `protobuf:"bytes,1,opt,name=cert_pem,json=certPem,proto3,oneof" json:"cert_pem,omitempty"`
KeyPem []byte `protobuf:"bytes,2,opt,name=key_pem,json=keyPem,proto3,oneof" json:"key_pem,omitempty"`
CaPem []byte `protobuf:"bytes,3,opt,name=ca_pem,json=caPem,proto3,oneof" json:"ca_pem,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *TLS_Config) Reset() {
*x = TLS_Config{}
mi := &file_conf_v1_kratos_conf_tls_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *TLS_Config) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*TLS_Config) ProtoMessage() {}
func (x *TLS_Config) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_tls_proto_msgTypes[2]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use TLS_Config.ProtoReflect.Descriptor instead.
func (*TLS_Config) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_tls_proto_rawDescGZIP(), []int{0, 1}
}
func (x *TLS_Config) GetCertPem() []byte {
if x != nil {
return x.CertPem
}
return nil
}
func (x *TLS_Config) GetKeyPem() []byte {
if x != nil {
return x.KeyPem
}
return nil
}
func (x *TLS_Config) GetCaPem() []byte {
if x != nil {
return x.CaPem
}
return nil
}
var File_conf_v1_kratos_conf_tls_proto protoreflect.FileDescriptor
const file_conf_v1_kratos_conf_tls_proto_rawDesc = "" +
"\n" +
"\x1dconf/v1/kratos_conf_tls.proto\x12\x04conf\"\xbc\x03\n" +
"\x03TLS\x12'\n" +
"\x04file\x18\x01 \x01(\v2\x0e.conf.TLS.FileH\x00R\x04file\x88\x01\x01\x12-\n" +
"\x06config\x18\x02 \x01(\v2\x10.conf.TLS.ConfigH\x01R\x06config\x88\x01\x01\x120\n" +
"\x14insecure_skip_verify\x18\x03 \x01(\bR\x12insecureSkipVerify\x1a\x8d\x01\n" +
"\x04File\x12 \n" +
"\tcert_path\x18\x01 \x01(\tH\x00R\bcertPath\x88\x01\x01\x12\x1e\n" +
"\bkey_path\x18\x02 \x01(\tH\x01R\akeyPath\x88\x01\x01\x12\x1c\n" +
"\aca_path\x18\x03 \x01(\tH\x02R\x06caPath\x88\x01\x01B\f\n" +
"\n" +
"_cert_pathB\v\n" +
"\t_key_pathB\n" +
"\n" +
"\b_ca_path\x1a\x86\x01\n" +
"\x06Config\x12\x1e\n" +
"\bcert_pem\x18\x01 \x01(\fH\x00R\acertPem\x88\x01\x01\x12\x1c\n" +
"\akey_pem\x18\x02 \x01(\fH\x01R\x06keyPem\x88\x01\x01\x12\x1a\n" +
"\x06ca_pem\x18\x03 \x01(\fH\x02R\x05caPem\x88\x01\x01B\v\n" +
"\t_cert_pemB\n" +
"\n" +
"\b_key_pemB\t\n" +
"\a_ca_pemB\a\n" +
"\x05_fileB\t\n" +
"\a_configB\x84\x01\n" +
"\bcom.confB\x12KratosConfTlsProtoP\x01Z4github.com/tx7do/kratos-bootstrap/api/gen/go/conf/v1\xa2\x02\x03CXX\xaa\x02\x04Conf\xca\x02\x04Conf\xe2\x02\x10Conf\\GPBMetadata\xea\x02\x04Confb\x06proto3"
var (
file_conf_v1_kratos_conf_tls_proto_rawDescOnce sync.Once
file_conf_v1_kratos_conf_tls_proto_rawDescData []byte
)
func file_conf_v1_kratos_conf_tls_proto_rawDescGZIP() []byte {
file_conf_v1_kratos_conf_tls_proto_rawDescOnce.Do(func() {
file_conf_v1_kratos_conf_tls_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_conf_v1_kratos_conf_tls_proto_rawDesc), len(file_conf_v1_kratos_conf_tls_proto_rawDesc)))
})
return file_conf_v1_kratos_conf_tls_proto_rawDescData
}
var file_conf_v1_kratos_conf_tls_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
var file_conf_v1_kratos_conf_tls_proto_goTypes = []any{
(*TLS)(nil), // 0: conf.TLS
(*TLS_File)(nil), // 1: conf.TLS.File
(*TLS_Config)(nil), // 2: conf.TLS.Config
}
var file_conf_v1_kratos_conf_tls_proto_depIdxs = []int32{
1, // 0: conf.TLS.file:type_name -> conf.TLS.File
2, // 1: conf.TLS.config:type_name -> conf.TLS.Config
2, // [2:2] is the sub-list for method output_type
2, // [2:2] is the sub-list for method input_type
2, // [2:2] is the sub-list for extension type_name
2, // [2:2] is the sub-list for extension extendee
0, // [0:2] is the sub-list for field type_name
}
func init() { file_conf_v1_kratos_conf_tls_proto_init() }
func file_conf_v1_kratos_conf_tls_proto_init() {
if File_conf_v1_kratos_conf_tls_proto != nil {
return
}
file_conf_v1_kratos_conf_tls_proto_msgTypes[0].OneofWrappers = []any{}
file_conf_v1_kratos_conf_tls_proto_msgTypes[1].OneofWrappers = []any{}
file_conf_v1_kratos_conf_tls_proto_msgTypes[2].OneofWrappers = []any{}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_conf_v1_kratos_conf_tls_proto_rawDesc), len(file_conf_v1_kratos_conf_tls_proto_rawDesc)),
NumEnums: 0,
NumMessages: 3,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_conf_v1_kratos_conf_tls_proto_goTypes,
DependencyIndexes: file_conf_v1_kratos_conf_tls_proto_depIdxs,
MessageInfos: file_conf_v1_kratos_conf_tls_proto_msgTypes,
}.Build()
File_conf_v1_kratos_conf_tls_proto = out.File
file_conf_v1_kratos_conf_tls_proto_goTypes = nil
file_conf_v1_kratos_conf_tls_proto_depIdxs = nil
}

View File

@@ -0,0 +1,160 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.36.6
// protoc (unknown)
// source: conf/v1/kratos_conf_tracer.proto
package v1
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
unsafe "unsafe"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// 链路追踪
type Tracer struct {
state protoimpl.MessageState `protogen:"open.v1"`
Batcher string `protobuf:"bytes,1,opt,name=batcher,proto3" json:"batcher,omitempty"` // jaeger或者zipkin
Endpoint string `protobuf:"bytes,2,opt,name=endpoint,proto3" json:"endpoint,omitempty"` // 端口
Sampler float64 `protobuf:"fixed64,3,opt,name=sampler,proto3" json:"sampler,omitempty"` // 采样率默认1.0
Env string `protobuf:"bytes,4,opt,name=env,proto3" json:"env,omitempty"` // 运行环境dev、debug、product
Insecure bool `protobuf:"varint,5,opt,name=insecure,proto3" json:"insecure,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Tracer) Reset() {
*x = Tracer{}
mi := &file_conf_v1_kratos_conf_tracer_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Tracer) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Tracer) ProtoMessage() {}
func (x *Tracer) ProtoReflect() protoreflect.Message {
mi := &file_conf_v1_kratos_conf_tracer_proto_msgTypes[0]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Tracer.ProtoReflect.Descriptor instead.
func (*Tracer) Descriptor() ([]byte, []int) {
return file_conf_v1_kratos_conf_tracer_proto_rawDescGZIP(), []int{0}
}
func (x *Tracer) GetBatcher() string {
if x != nil {
return x.Batcher
}
return ""
}
func (x *Tracer) GetEndpoint() string {
if x != nil {
return x.Endpoint
}
return ""
}
func (x *Tracer) GetSampler() float64 {
if x != nil {
return x.Sampler
}
return 0
}
func (x *Tracer) GetEnv() string {
if x != nil {
return x.Env
}
return ""
}
func (x *Tracer) GetInsecure() bool {
if x != nil {
return x.Insecure
}
return false
}
var File_conf_v1_kratos_conf_tracer_proto protoreflect.FileDescriptor
const file_conf_v1_kratos_conf_tracer_proto_rawDesc = "" +
"\n" +
" conf/v1/kratos_conf_tracer.proto\x12\x04conf\"\x86\x01\n" +
"\x06Tracer\x12\x18\n" +
"\abatcher\x18\x01 \x01(\tR\abatcher\x12\x1a\n" +
"\bendpoint\x18\x02 \x01(\tR\bendpoint\x12\x18\n" +
"\asampler\x18\x03 \x01(\x01R\asampler\x12\x10\n" +
"\x03env\x18\x04 \x01(\tR\x03env\x12\x1a\n" +
"\binsecure\x18\x05 \x01(\bR\binsecureB\x87\x01\n" +
"\bcom.confB\x15KratosConfTracerProtoP\x01Z4github.com/tx7do/kratos-bootstrap/api/gen/go/conf/v1\xa2\x02\x03CXX\xaa\x02\x04Conf\xca\x02\x04Conf\xe2\x02\x10Conf\\GPBMetadata\xea\x02\x04Confb\x06proto3"
var (
file_conf_v1_kratos_conf_tracer_proto_rawDescOnce sync.Once
file_conf_v1_kratos_conf_tracer_proto_rawDescData []byte
)
func file_conf_v1_kratos_conf_tracer_proto_rawDescGZIP() []byte {
file_conf_v1_kratos_conf_tracer_proto_rawDescOnce.Do(func() {
file_conf_v1_kratos_conf_tracer_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_conf_v1_kratos_conf_tracer_proto_rawDesc), len(file_conf_v1_kratos_conf_tracer_proto_rawDesc)))
})
return file_conf_v1_kratos_conf_tracer_proto_rawDescData
}
var file_conf_v1_kratos_conf_tracer_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_conf_v1_kratos_conf_tracer_proto_goTypes = []any{
(*Tracer)(nil), // 0: conf.Tracer
}
var file_conf_v1_kratos_conf_tracer_proto_depIdxs = []int32{
0, // [0:0] is the sub-list for method output_type
0, // [0:0] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
}
func init() { file_conf_v1_kratos_conf_tracer_proto_init() }
func file_conf_v1_kratos_conf_tracer_proto_init() {
if File_conf_v1_kratos_conf_tracer_proto != nil {
return
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_conf_v1_kratos_conf_tracer_proto_rawDesc), len(file_conf_v1_kratos_conf_tracer_proto_rawDesc)),
NumEnums: 0,
NumMessages: 1,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_conf_v1_kratos_conf_tracer_proto_goTypes,
DependencyIndexes: file_conf_v1_kratos_conf_tracer_proto_depIdxs,
MessageInfos: file_conf_v1_kratos_conf_tracer_proto_msgTypes,
}.Build()
File_conf_v1_kratos_conf_tracer_proto = out.File
file_conf_v1_kratos_conf_tracer_proto_goTypes = nil
file_conf_v1_kratos_conf_tracer_proto_depIdxs = nil
}

View File

@@ -0,0 +1,273 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.36.6
// protoc (unknown)
// source: pagination/v1/pagination.proto
package v1
import (
_ "github.com/google/gnostic/openapiv3"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
fieldmaskpb "google.golang.org/protobuf/types/known/fieldmaskpb"
reflect "reflect"
sync "sync"
unsafe "unsafe"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// 分页通用请求
type PagingRequest struct {
state protoimpl.MessageState `protogen:"open.v1"`
// 当前页码
Page *int32 `protobuf:"varint,1,opt,name=page,proto3,oneof" json:"page,omitempty"`
// 每一页的行数
PageSize *int32 `protobuf:"varint,2,opt,name=page_size,json=pageSize,proto3,oneof" json:"page_size,omitempty"`
// AND过滤参数其语法为json格式的字符串{"key1":"val1","key2":"val2"}具体请参见https://github.com/tx7do/go-utils/tree/main/entgo/query/README.md
Query *string `protobuf:"bytes,3,opt,name=query,proto3,oneof" json:"query,omitempty"`
// OR过滤参数语法同AND过滤参数。
OrQuery *string `protobuf:"bytes,4,opt,name=or_query,json=or,proto3,oneof" json:"or_query,omitempty"`
// 排序条件其语法为JSON字符串例如{"val1", "-val2"}。字段名前加'-'为降序,否则为升序。
OrderBy []string `protobuf:"bytes,5,rep,name=order_by,json=orderBy,proto3" json:"order_by,omitempty"`
// 是否不分页如果为true则page和pageSize参数无效。
NoPaging *bool `protobuf:"varint,6,opt,name=no_paging,json=noPaging,proto3,oneof" json:"no_paging,omitempty"`
// 字段掩码其作用为SELECT中的字段其语法为使用逗号分隔字段名例如id,realName,userName。如果为空则选中所有字段即SELECT *。
FieldMask *fieldmaskpb.FieldMask `protobuf:"bytes,7,opt,name=field_mask,json=fieldMask,proto3,oneof" json:"field_mask,omitempty"`
TenantId *uint32 `protobuf:"varint,8,opt,name=tenant_id,json=tenantId,proto3,oneof" json:"tenant_id,omitempty"` // 租户ID
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *PagingRequest) Reset() {
*x = PagingRequest{}
mi := &file_pagination_v1_pagination_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *PagingRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*PagingRequest) ProtoMessage() {}
func (x *PagingRequest) ProtoReflect() protoreflect.Message {
mi := &file_pagination_v1_pagination_proto_msgTypes[0]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use PagingRequest.ProtoReflect.Descriptor instead.
func (*PagingRequest) Descriptor() ([]byte, []int) {
return file_pagination_v1_pagination_proto_rawDescGZIP(), []int{0}
}
func (x *PagingRequest) GetPage() int32 {
if x != nil && x.Page != nil {
return *x.Page
}
return 0
}
func (x *PagingRequest) GetPageSize() int32 {
if x != nil && x.PageSize != nil {
return *x.PageSize
}
return 0
}
func (x *PagingRequest) GetQuery() string {
if x != nil && x.Query != nil {
return *x.Query
}
return ""
}
func (x *PagingRequest) GetOrQuery() string {
if x != nil && x.OrQuery != nil {
return *x.OrQuery
}
return ""
}
func (x *PagingRequest) GetOrderBy() []string {
if x != nil {
return x.OrderBy
}
return nil
}
func (x *PagingRequest) GetNoPaging() bool {
if x != nil && x.NoPaging != nil {
return *x.NoPaging
}
return false
}
func (x *PagingRequest) GetFieldMask() *fieldmaskpb.FieldMask {
if x != nil {
return x.FieldMask
}
return nil
}
func (x *PagingRequest) GetTenantId() uint32 {
if x != nil && x.TenantId != nil {
return *x.TenantId
}
return 0
}
// 分页通用结果
type PagingResponse struct {
state protoimpl.MessageState `protogen:"open.v1"`
// 总数
Total int32 `protobuf:"varint,1,opt,name=total,proto3" json:"total,omitempty"`
// 分页数据
Items [][]byte `protobuf:"bytes,2,rep,name=items,proto3" json:"items,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *PagingResponse) Reset() {
*x = PagingResponse{}
mi := &file_pagination_v1_pagination_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *PagingResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*PagingResponse) ProtoMessage() {}
func (x *PagingResponse) ProtoReflect() protoreflect.Message {
mi := &file_pagination_v1_pagination_proto_msgTypes[1]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use PagingResponse.ProtoReflect.Descriptor instead.
func (*PagingResponse) Descriptor() ([]byte, []int) {
return file_pagination_v1_pagination_proto_rawDescGZIP(), []int{1}
}
func (x *PagingResponse) GetTotal() int32 {
if x != nil {
return x.Total
}
return 0
}
func (x *PagingResponse) GetItems() [][]byte {
if x != nil {
return x.Items
}
return nil
}
var File_pagination_v1_pagination_proto protoreflect.FileDescriptor
const file_pagination_v1_pagination_proto_rawDesc = "" +
"\n" +
"\x1epagination/v1/pagination.proto\x12\n" +
"pagination\x1a google/protobuf/field_mask.proto\x1a$gnostic/openapi/v3/annotations.proto\"\x95\t\n" +
"\rPagingRequest\x127\n" +
"\x04page\x18\x01 \x01(\x05B\x1e\xbaG\x1b\x8a\x02\t\t\x00\x00\x00\x00\x00\x00\xf0?\x92\x02\f当前页码H\x00R\x04page\x88\x01\x01\x12F\n" +
"\tpage_size\x18\x02 \x01(\x05B$\xbaG!\x8a\x02\t\t\x00\x00\x00\x00\x00\x00$@\x92\x02\x12每一页的行数H\x01R\bpageSize\x88\x01\x01\x12\xf5\x01\n" +
"\x05query\x18\x03 \x01(\tB\xd9\x01\xbaG\xd5\x01:\x1f\x12\x1d{\"key1\":\"val1\",\"key2\":\"val2\"}\x92\x02\xb0\x01AND过滤参数其语法为json格式的字符串{\"key1\":\"val1\",\"key2\":\"val2\"}具体请参见https://github.com/tx7do/go-utils/tree/main/entgo/query/README.mdH\x02R\x05query\x88\x01\x01\x12P\n" +
"\bor_query\x18\x04 \x01(\tB5\xbaG2:\x1f\x12\x1d{\"key1\":\"val1\",\"key2\":\"val2\"}\x92\x02\x0eOR过滤参数H\x03R\x02or\x88\x01\x01\x12\xb0\x01\n" +
"\border_by\x18\x05 \x03(\tB\x94\x01\xbaG\x90\x01:\x13\x12\x11{\"val1\", \"-val2\"}\x92\x02x排序条件其语法为JSON字符串例如{\"val1\", \"-val2\"}。字段名前加'-'为降序否则为升序。R\aorderBy\x12k\n" +
"\tno_paging\x18\x06 \x01(\bBI\xbaGF\x92\x02C是否不分页如果为true则page和pageSize参数无效。H\x04R\bnoPaging\x88\x01\x01\x12\x8d\x02\n" +
"\n" +
"field_mask\x18\a \x01(\v2\x1a.google.protobuf.FieldMaskB\xcc\x01\xbaG\xc8\x01:\x16\x12\x14id,realName,userName\x92\x02\xac\x01字段掩码其作用为SELECT中的字段其语法为使用逗号分隔字段名例如id,realName,userName。如果为空则选中所有字段即SELECT *。H\x05R\tfieldMask\x88\x01\x01\x120\n" +
"\ttenant_id\x18\b \x01(\rB\x0e\xbaG\v\x92\x02\b租户IDH\x06R\btenantId\x88\x01\x01B\a\n" +
"\x05_pageB\f\n" +
"\n" +
"_page_sizeB\b\n" +
"\x06_queryB\v\n" +
"\t_or_queryB\f\n" +
"\n" +
"_no_pagingB\r\n" +
"\v_field_maskB\f\n" +
"\n" +
"_tenant_id\"<\n" +
"\x0ePagingResponse\x12\x14\n" +
"\x05total\x18\x01 \x01(\x05R\x05total\x12\x14\n" +
"\x05items\x18\x02 \x03(\fR\x05itemsB\xa5\x01\n" +
"\x0ecom.paginationB\x0fPaginationProtoP\x01Z:github.com/tx7do/kratos-bootstrap/api/gen/go/pagination/v1\xa2\x02\x03PXX\xaa\x02\n" +
"Pagination\xca\x02\n" +
"Pagination\xe2\x02\x16Pagination\\GPBMetadata\xea\x02\n" +
"Paginationb\x06proto3"
var (
file_pagination_v1_pagination_proto_rawDescOnce sync.Once
file_pagination_v1_pagination_proto_rawDescData []byte
)
func file_pagination_v1_pagination_proto_rawDescGZIP() []byte {
file_pagination_v1_pagination_proto_rawDescOnce.Do(func() {
file_pagination_v1_pagination_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_pagination_v1_pagination_proto_rawDesc), len(file_pagination_v1_pagination_proto_rawDesc)))
})
return file_pagination_v1_pagination_proto_rawDescData
}
var file_pagination_v1_pagination_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_pagination_v1_pagination_proto_goTypes = []any{
(*PagingRequest)(nil), // 0: pagination.PagingRequest
(*PagingResponse)(nil), // 1: pagination.PagingResponse
(*fieldmaskpb.FieldMask)(nil), // 2: google.protobuf.FieldMask
}
var file_pagination_v1_pagination_proto_depIdxs = []int32{
2, // 0: pagination.PagingRequest.field_mask:type_name -> google.protobuf.FieldMask
1, // [1:1] is the sub-list for method output_type
1, // [1:1] is the sub-list for method input_type
1, // [1:1] is the sub-list for extension type_name
1, // [1:1] is the sub-list for extension extendee
0, // [0:1] is the sub-list for field type_name
}
func init() { file_pagination_v1_pagination_proto_init() }
func file_pagination_v1_pagination_proto_init() {
if File_pagination_v1_pagination_proto != nil {
return
}
file_pagination_v1_pagination_proto_msgTypes[0].OneofWrappers = []any{}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_pagination_v1_pagination_proto_rawDesc), len(file_pagination_v1_pagination_proto_rawDesc)),
NumEnums: 0,
NumMessages: 2,
NumExtensions: 0,
NumServices: 0,
},
GoTypes: file_pagination_v1_pagination_proto_goTypes,
DependencyIndexes: file_pagination_v1_pagination_proto_depIdxs,
MessageInfos: file_pagination_v1_pagination_proto_msgTypes,
}.Build()
File_pagination_v1_pagination_proto = out.File
file_pagination_v1_pagination_proto_goTypes = nil
file_pagination_v1_pagination_proto_depIdxs = nil
}

18
api/go.mod Normal file
View File

@@ -0,0 +1,18 @@
module github.com/tx7do/kratos-bootstrap/api
go 1.22.0
toolchain go1.22.1
require (
github.com/google/gnostic v0.7.0
google.golang.org/protobuf v1.36.6
)
require (
github.com/google/gnostic-models v0.6.9 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/rogpeppe/go-internal v1.10.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

1524
api/go.sum Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,81 +0,0 @@
syntax = "proto3";
package pagination;
option go_package = "github.com/tx7do/kratos-bootstrap/gen/api/go/pagination/v1;pagination";
import "google/protobuf/any.proto";
import "google/protobuf/field_mask.proto";
import "gnostic/openapi/v3/annotations.proto";
// 分页通用请求
message PagingRequest {
// 当前页码
optional int32 page = 1 [
json_name = "page",
(gnostic.openapi.v3.property) = {
description: "当前页码",
default: {number: 1}
}
];
// 每页的行数
optional int32 page_size = 2 [
json_name = "pageSize",
(gnostic.openapi.v3.property) = {
description: "每一页的行数",
default: {number: 10}
}
];
// 与过滤参数
optional string query = 3 [
json_name = "query",
(gnostic.openapi.v3.property) = {
description: "与过滤参数",
example: {yaml: "{\"key1\":\"val1\",\"key2\":\"val2\"}"}
}
];
// 或过滤参数
optional string or_query = 4 [
json_name = "or",
(gnostic.openapi.v3.property) = {
description: "或过滤参数",
example: {yaml: "{\"key1\":\"val1\",\"key2\":\"val2\"}"}
}
];
// 排序条件
repeated string order_by = 5 [
json_name = "orderBy",
(gnostic.openapi.v3.property) = {
description: "排序条件,字段名前加'-'为降序,否则为升序。"
example: {yaml: "{\"val1\", \"-val2\"}"}
}
];
// 是否不分页
optional bool no_paging = 6 [
json_name = "nopaging",
(gnostic.openapi.v3.property) = {description: "是否不分页"}
];
// 字段掩码
google.protobuf.FieldMask field_mask = 7 [
json_name = "fieldMask",
(gnostic.openapi.v3.property) = {
description: "字段掩码,如果为空则选中所有字段。",
example: {yaml : "id,realName,userName"}
}
];
}
// 分页通用结果
message PagingResponse {
// 总数
int32 total = 1;
// 分页数据
repeated google.protobuf.Any items = 2;
}

28
api/protos/buf.lock Normal file
View File

@@ -0,0 +1,28 @@
# Generated by buf. DO NOT EDIT.
version: v1
deps:
- remote: buf.build
owner: envoyproxy
repository: protoc-gen-validate
commit: eac44469a7af47e7839a7f1f3d7ac004
digest: shake256:0feabcde01b6b11e3c75a5e3f807968d5995626546f39c37e5d4205892b3a59cced0ed83b35a2eb9e6dddd3309660ad46b737c9dcd224b425de0a6654ce04417
- remote: buf.build
owner: gnostic
repository: gnostic
commit: 087bc8072ce44e339f213209e4d57bf0
digest: shake256:4689c26f0460fea84c4c277c1b9c7e7d657388c5b4116d1065f907a92100ffbea87de05bbd138a0166411361e1f6ce063b4c0c6002358d39710f3c4a8de788d5
- remote: buf.build
owner: gogo
repository: protobuf
commit: 5461a3dfa9d941da82028ab185dc2a0e
digest: shake256:37c7c75224982038cb1abf45b481ef06716c1f806ffaa162018d0df092bd11a2a9b62c2d0dc0a2ae43beff86b6014fc0eb8c594ffd84d52ade4b08fca901eadc
- remote: buf.build
owner: googleapis
repository: googleapis
commit: 28151c0d0a1641bf938a7672c500e01d
digest: shake256:49215edf8ef57f7863004539deff8834cfb2195113f0b890dd1f67815d9353e28e668019165b9d872395871eeafcbab3ccfdb2b5f11734d3cca95be9e8d139de
- remote: buf.build
owner: kratos
repository: apis
commit: c2de25f14fa445a79a054214f31d17a8
digest: shake256:91c024935d46f7966667c29e4fc933435959f93c3f0e675e1227c99db09905d44f8ec275b770da7659df5a6b18f4710da157b6d8ad760a4a95f60365b231e637

View File

@@ -0,0 +1,32 @@
syntax = "proto3";
package conf;
option go_package = "github.com/tx7do/kratos-bootstrap/api/gen/go/conf/v1;conf";
import "google/protobuf/duration.proto";
// 认证
message Authentication {
// JWT
message Jwt {
string method = 1; // JWT签名的算法支持算法HS256
string key = 2; // JWT 秘钥
}
message OIDC {
string issuer_url = 1;
string audience = 2;
string method = 3; // JWT签名的算法支持算法HS256
}
message PresharedKey {
repeated string valid_keys = 1;
}
string type = 1;
optional Jwt jwt = 2; // JWT 认证
optional OIDC oidc = 3; // OIDC
optional PresharedKey preshared_key = 4; // 预共享密钥
}

View File

@@ -0,0 +1,53 @@
syntax = "proto3";
package conf;
option go_package = "github.com/tx7do/kratos-bootstrap/api/gen/go/conf/v1;conf";
import "google/protobuf/duration.proto";
// 授权
message Authorization {
message Casbin {
optional string model_path = 1; // casbin 模型文件路径
optional string policy_path = 2; // casbin 策略文件路径
repeated string policies = 10; // 策略列表
optional string model = 11; // 模型内容
}
message OPA {
message RoleActions {
repeated string actions = 1; // 角色对应的操作列表 {
}
map<string, string> policies = 1; // OPA 策略列表
map<string, RoleActions> roles = 2; //
}
message Zanzibar {
message Keto {
string write_url = 1; // 写入 URL
string read_url = 2; // 读取 URL
bool use_grpc = 3; // 是否使用 gRPC
}
message OpenFga {
string api_url = 1; // OpenFGA API URL
string store_id = 2; // OpenFGA 存储 ID
string token = 3; // OpenFGA 访问令牌
string client_id = 4; // OpenFGA 客户端 ID
}
string type = 1; // zanzibar 类型
optional Keto keto = 2; // Keto 配置
optional OpenFga open_fga = 3; // OpenFGA 配置
}
string type = 1;
Casbin casbin = 2; // casbin
OPA opa = 3; // OPA
Zanzibar zanzibar = 4; // zanzibar
}

View File

@@ -0,0 +1,32 @@
syntax = "proto3";
package conf;
option go_package = "github.com/tx7do/kratos-bootstrap/api/gen/go/conf/v1;conf";
import "conf/v1/kratos_conf_tracer.proto";
import "conf/v1/kratos_conf_data.proto";
import "conf/v1/kratos_conf_server.proto";
import "conf/v1/kratos_conf_client.proto";
import "conf/v1/kratos_conf_logger.proto";
import "conf/v1/kratos_conf_registry.proto";
import "conf/v1/kratos_conf_oss.proto";
import "conf/v1/kratos_conf_config.proto";
import "conf/v1/kratos_conf_notify.proto";
import "conf/v1/kratos_conf_authn.proto";
import "conf/v1/kratos_conf_authz.proto";
// 引导信息
message Bootstrap {
optional Server server = 1;
optional Client client = 2;
optional Data data = 3;
optional Tracer trace = 4;
optional Logger logger = 5;
optional Registry registry = 6;
optional RemoteConfig config = 7;
optional OSS oss = 8;
optional Notification notify = 9;
optional Authentication authn = 10;
optional Authorization authz = 11;
}

View File

@@ -0,0 +1,30 @@
syntax = "proto3";
package conf;
option go_package = "github.com/tx7do/kratos-bootstrap/api/gen/go/conf/v1;conf";
import "google/protobuf/duration.proto";
import "conf/v1/kratos_conf_middleware.proto";
import "conf/v1/kratos_conf_tls.proto";
// 客户端
message Client {
// REST
message REST {
google.protobuf.Duration timeout = 1; // 超时时间
Middleware middleware = 2; // 中间件
TLS tls = 3; // TLS配置
}
// gPRC
message GRPC {
google.protobuf.Duration timeout = 1; // 超时时间
Middleware middleware = 2; // 中间件
TLS tls = 3; // TLS配置
}
optional REST rest = 1; // REST服务
optional GRPC grpc = 2; // gRPC服务
}

View File

@@ -0,0 +1,56 @@
syntax = "proto3";
package conf;
option go_package = "github.com/tx7do/kratos-bootstrap/api/gen/go/conf/v1;conf";
import "google/protobuf/duration.proto";
// 配置服务
message RemoteConfig {
message Nacos {
string address = 1; // 服务端地址
uint64 port = 2; // 服务端端口
string key = 3; // 配置键
string username = 4; // 用户名
string password = 5; // 密码
string namespace_id = 6; // 命名空间ID
}
message Etcd {
repeated string endpoints = 1; // 服务端地址
google.protobuf.Duration timeout = 2; // 超时时间
string key = 3; // 配置键
}
message Consul {
string scheme = 1; // 网络样式
string address = 2; // 服务端地址
string key = 3; // 配置键
}
message Apollo {
string endpoint = 1; // 服务端地址
string app_id = 2; // 应用ID
string cluster = 3; // 集群
string namespace = 4; // 命名空间
string secret = 5; // 密钥
}
message Kubernetes {
string namespace = 1; // 命名空间
}
message Polaris {
}
string type = 1; // 配置类型
optional Etcd etcd = 2;
optional Consul consul = 3;
optional Nacos nacos = 4;
optional Apollo apollo = 6;
optional Kubernetes kubernetes = 7;
optional Polaris polaris = 8;
}

View File

@@ -0,0 +1,263 @@
syntax = "proto3";
package conf;
option go_package = "github.com/tx7do/kratos-bootstrap/api/gen/go/conf/v1;conf";
import "google/protobuf/duration.proto";
import "conf/v1/kratos_conf_tls.proto";
// 数据
message Data {
// 数据库
message Database {
string driver = 1; // 驱动名mysql、postgresql、mongodb、sqlite……
string source = 2; // 数据源DSN字符串
bool migrate = 10; // 数据迁移开关
bool debug = 11; // 调试开关
bool enable_trace = 12; // 链路追踪开关
bool enable_metrics = 13; // 性能分析开关
optional int32 max_idle_connections = 20; // 连接池最大空闲连接数
optional int32 max_open_connections = 21; // 连接池最大打开连接数
optional google.protobuf.Duration connection_max_lifetime = 22; // 连接可重用的最大时间长度
optional string prometheus_push_addr = 30;
optional string prometheus_db_name = 31;
optional uint32 prometheus_http_port = 32;
}
// redis
message Redis {
string network = 1; // 网络
string addr = 2; // 服务端地址
string password = 3; // 密码
int32 db = 4; // 数据库索引
google.protobuf.Duration dial_timeout = 50; // 连接超时时间
google.protobuf.Duration read_timeout = 51; // 读取超时时间
google.protobuf.Duration write_timeout = 52; // 写入超时时间
bool enable_tracing = 100; // 打开链路追踪
bool enable_metrics = 1001; // 打开性能度量
}
// MongoDB
message MongoDB {
string uri = 1;
optional string database = 2;
optional string username = 10;
optional string password = 11;
optional string auth_mechanism = 20; // 认证机制SCRAM-SHA-1、SCRAM-SHA-256、MONGODB-X509、GSSAPI、PLAIN
map<string, string> auth_mechanism_properties = 21; // 认证机制属性
optional string auth_source = 22; // 认证源admin、$external等
google.protobuf.Duration connect_timeout = 50; // 连接超时时间
google.protobuf.Duration heartbeat_interval = 51; // 心跳间隔
google.protobuf.Duration local_threshold = 52; // 本地延迟阈值
google.protobuf.Duration max_conn_idle_time = 53; // 最大连接空闲时间
google.protobuf.Duration max_staleness = 54; // 最大陈旧时间
google.protobuf.Duration server_selection_timeout = 55; // 服务器选择超时时间
google.protobuf.Duration socket_timeout = 56; // 套接字超时时间
google.protobuf.Duration timeout = 57; // 总超时时间
bool enable_tracing = 100; // 打开链路追踪
bool enable_metrics = 101; // 打开性能度量
}
// ClickHouse
message ClickHouse {
repeated string addresses = 1; // 对端网络地址
optional string database = 2; // 数据库名
optional string username = 3; // 用户名
optional string password = 4; // 密码
optional bool debug = 5; // 调试开关
optional string scheme = 6; // 协议http、https、native
optional TLS tls = 7; // TLS配置
optional int32 block_buffer_size = 8; // 数据块缓冲区大小
optional string compression_method = 10; // 压缩方法zstd、lz4、lz4hc、gzip、deflate、br、none
optional int32 compression_level = 11; // 压缩级别0-9
optional int32 max_compression_buffer = 12; // 最大压缩缓冲区大小
optional string connection_open_strategy = 20; // 连接打开策略in_order、round_robin、random
optional google.protobuf.Duration dial_timeout = 30; // 连接超时时间
optional google.protobuf.Duration read_timeout = 31; // 读取超时时间
optional google.protobuf.Duration conn_max_lifetime = 32; // 连接可重用的最大时间长度
optional int32 max_idle_conns = 40; // 连接池最大空闲连接数
optional int32 max_open_conns = 41; // 连接池最大打开连接数
optional string dsn = 50; // 数据源名称DSN字符串
optional string http_proxy = 60; // HTTP代理地址
optional bool enable_tracing = 100; // 打开链路追踪
optional bool enable_metrics = 101; // 打开性能度量
}
// InfluxDB
message InfluxDB {
string host = 1; // 主机地址
string token = 2; // 认证令牌
string auth_scheme = 3; // 认证方案default、basic
string proxy = 4; // 代理地址
string organization = 10; // 组织名
string database = 11; // 数据库名
google.protobuf.Duration timeout = 20; // 连接超时时间
google.protobuf.Duration idle_connection_timeout = 21; // 空闲连接超时时间
int32 max_idle_connections = 22; // 连接池最大空闲连接数
}
message Doris {
string address = 1;
}
message ElasticSearch {
repeated string addresses = 1;
string username = 10;
string password = 11;
string cloud_id = 20;
string api_key = 21;
string service_token = 22;
string certificate_fingerprint = 23;
bool disable_retry = 30;
int32 max_retries = 31;
bool compress_request_body = 40;
int32 compress_request_body_level = 41;
bool pool_compressor = 42;
bool discover_nodes_on_start = 50;
google.protobuf.Duration discover_nodes_interval = 51;
bool enable_metrics = 60;
bool enable_debug_logger = 61;
bool enable_compatibility_mode = 62;
bool disable_meta_header = 63;
TLS tls = 70; // TLS配置
}
message Cassandra {
string address = 1;
string username = 2;
string password = 3;
string keyspace = 5;
google.protobuf.Duration connect_timeout = 6;
google.protobuf.Duration timeout = 7;
uint32 consistency = 8;
bool disable_initial_host_lookup = 9;
bool ignore_peer_addr = 10;
TLS tls = 11; // TLS配置
}
message Snowflake {
}
// Kafka
message Kafka {
repeated string endpoints = 1; // 对端网络地址
string codec = 2; // 编解码器
bool async = 3; // 异步发送
bool allow_auto_topic_creation = 4; // 允许发送的时候自动创建主题
int32 batch_size = 5; // 批量发送量
int64 batch_bytes = 6;// 批量发送字节数
google.protobuf.Duration batch_timeout = 7; // 批量发送超时时间
google.protobuf.Duration read_timeout = 8; // 读取超时时间
google.protobuf.Duration write_timeout = 9; // 发送超时时间
}
// RabbitMQ
message RabbitMQ {
repeated string endpoints = 1; // 对端网络地址
}
// MQTT
message Mqtt {
string endpoint = 1; // 对端网络地址
string codec = 2; // 编解码器: json,xml,yaml...
}
message ActiveMQ {
string endpoint = 1; // 对端网络地址
string codec = 2; // 编解码器: json,xml,yaml...
}
message NATS {
string endpoint = 1; // 对端网络地址
string codec = 2; // 编解码器: json,xml,yaml...
}
message NSQ {
string endpoint = 1; // 对端网络地址
string codec = 2; // 编解码器: json,xml,yaml...
}
message Pulsar {
string endpoint = 1; // 对端网络地址
string codec = 2; // 编解码器: json,xml,yaml...
}
message RocketMQ {
string version = 1; // 驱动版本aliyun、v2、v5
string codec = 2; // 编解码器: json,xml,yaml...
bool enable_trace = 3;
repeated string name_servers = 4;
string name_server_domain = 5;
string access_key = 6;
string secret_key = 7;
string security_token = 8;
string namespace = 9;
string instance_name = 10;
string group_name = 11;
}
optional Database database = 1; // 数据库DSN
optional Redis redis = 10; // Redis
optional MongoDB mongodb = 11; // MongoDB数据库
optional ElasticSearch elastic_search = 12; // ElasticSearch数据库
optional Cassandra cassandra = 13; // Cassandra数据库
optional ClickHouse clickhouse = 20; // ClickHouse数据库
optional InfluxDB influxdb = 21; // InfluxDB数据库
optional Doris doris = 22; // Doris数据库
// Message Queue
optional Kafka kafka = 30; // Kafka服务
optional RabbitMQ rabbitmq = 31; // RabbitMQ服务
optional Mqtt mqtt = 32; // MQTT服务
optional ActiveMQ activemq = 33; // ActiveMQ
optional NATS nats = 34; // NATS
optional NSQ nsq = 35; // NATS
optional Pulsar pulsar = 36; // Pulsar
optional RocketMQ rocketmq = 38; // RocketMQ
}

View File

@@ -2,7 +2,7 @@ syntax = "proto3";
package conf;
option go_package = "github.com/tx7do/kratos-bootstrap/gen/api/go/conf/v1;conf";
option go_package = "github.com/tx7do/kratos-bootstrap/api/gen/go/conf/v1;conf";
//
message Logger {
@@ -22,6 +22,7 @@ message Logger {
string timestamp_format = 3; // "2006-01-02 15:04:05"
bool disable_colors = 4; //
bool disable_timestamp = 5; //
bool force_colors = 6; //
}
// Fluent
@@ -47,9 +48,9 @@ message Logger {
string type = 1;
Zap zap = 2;
Logrus logrus = 3;
Fluent fluent = 4;
Aliyun aliyun = 5;
Tencent tencent = 6;
optional Zap zap = 2;
optional Logrus logrus = 3;
optional Fluent fluent = 4;
optional Aliyun aliyun = 5;
optional Tencent tencent = 6;
}

View File

@@ -0,0 +1,46 @@
syntax = "proto3";
package conf;
option go_package = "github.com/tx7do/kratos-bootstrap/api/gen/go/conf/v1;conf";
import "google/protobuf/duration.proto";
// 中间件
message Middleware {
// JWT校验
message Auth {
string method = 1; // JWT签名的算法支持算法HS256
string key = 2; // JWT 秘钥
optional google.protobuf.Duration access_token_expires = 3; // 访问令牌过期时间
optional google.protobuf.Duration refresh_token_expires = 4; // 刷新令牌过期时间
optional string access_token_key_prefix = 5; // 访问令牌键前缀
optional string refresh_token_key_prefix = 6; // 刷新令牌键前缀
}
// 限流器
message RateLimiter {
string name = 1; // 限流器名字支持bbr。
}
// 性能指标
message Metrics {
bool histogram = 1; // 直方图
bool counter = 2; // 计数器
bool gauge = 3; // 仪表盘
bool summary = 4; // 摘要
}
RateLimiter limiter = 1;
Metrics metrics = 2;
Auth auth = 3;
bool enable_logging = 10; // 日志开关
bool enable_recovery = 11; // 异常恢复
bool enable_tracing = 12; // 链路追踪开关
bool enable_validate = 13; // 参数校验开关
bool enable_circuit_breaker = 14; // 熔断器
bool enable_metadata = 15; // 元数据
}

View File

@@ -2,7 +2,7 @@ syntax = "proto3";
package conf;
option go_package = "github.com/tx7do/kratos-bootstrap/gen/api/go/conf/v1;conf";
option go_package = "github.com/tx7do/kratos-bootstrap/api/gen/go/conf/v1;conf";
//
message Notification {
@@ -14,5 +14,5 @@ message Notification {
string access_key_secret = 4; // 访
}
SMS sms = 1;
optional SMS sms = 1;
}

View File

@@ -0,0 +1,26 @@
syntax = "proto3";
package conf;
option go_package = "github.com/tx7do/kratos-bootstrap/api/gen/go/conf/v1;conf";
import "conf/v1/kratos_conf_tls.proto";
// 对象存储
message OSS {
// MinIO
message MinIO {
string endpoint = 1; // 对端端口
string access_key = 2; // 访问密钥
string secret_key = 3; // 密钥
string token = 4; // 令牌
bool use_ssl = 10; // 使用SSL
TLS tls = 11; // TLS配置
string upload_host = 20; // 上传链接的主机名
string download_host = 21; // 下载链接的主机名
}
optional MinIO minio = 1;
}

View File

@@ -0,0 +1,101 @@
syntax = "proto3";
package conf;
option go_package = "github.com/tx7do/kratos-bootstrap/api/gen/go/conf/v1;conf";
import "google/protobuf/duration.proto";
// 注册发现中心
message Registry {
// Consul
message Consul {
string scheme = 1; // 网络样式
string address = 2; // 服务端地址
bool health_check = 3; // 健康检查
}
// Etcd
message Etcd {
repeated string endpoints = 1;
}
// ZooKeeper
message ZooKeeper {
repeated string endpoints = 1;
google.protobuf.Duration timeout = 2;
}
// Nacos
message Nacos {
string address = 1; // 服务端地址
uint64 port = 2; // 服务端端口
string namespace_id = 3; // 命名空间ID
string region_id = 4; // 区域ID
string app_name = 5; // 应用名称
string app_key = 6; // 应用密钥
string access_key = 7; // 访问密钥
string secret_key = 8; // 密钥
string username = 9; // 用户名
string password = 10; // 密码
google.protobuf.Duration timeout = 20; // http请求超时时间单位: 毫秒
google.protobuf.Duration beat_interval = 21; // 心跳间隔时间,单位: 毫秒
google.protobuf.Duration listen_interval = 22; // 心跳间隔时间,单位: 毫秒
int32 update_thread_num = 30; // 更新服务的线程数
bool not_load_cache_at_start = 40; // 在启动时不读取本地缓存数据true: 不读取false: 读取
bool update_cache_when_empty = 41; // 当服务列表为空时是否更新本地缓存true: 更新,false: 不更新
bool open_kms = 42; // 是否开启kms加密true: 开启false: 关闭
string log_level = 50; // 日志等级
string log_dir = 51; // 日志目录
string cache_dir = 52; // 缓存目录
string context_path = 53; // 上下文路径
}
// Kubernetes
message Kubernetes {
}
// Eureka
message Eureka {
repeated string endpoints = 1;
google.protobuf.Duration heartbeat_interval = 2;
google.protobuf.Duration refresh_interval = 3;
string path = 4;
}
// Polaris
message Polaris {
string address = 1; // 服务端地址
int32 port = 2; // 服务端端口
int32 instance_count = 3;
string namespace = 4;
string service = 5;
string token = 6;
}
// Servicecomb
message Servicecomb {
repeated string endpoints = 1;
}
string type = 1;
optional Consul consul = 2; // Consul
optional Etcd etcd = 3; // Etcd
optional ZooKeeper zookeeper = 4; // ZooKeeper
optional Nacos nacos = 5; // Nacos
optional Kubernetes kubernetes = 6; // Kubernetes
optional Eureka eureka = 7; // Eureka
optional Polaris polaris = 8; // Polaris
optional Servicecomb servicecomb = 9; // Servicecomb
}

View File

@@ -0,0 +1,334 @@
syntax = "proto3";
package conf;
option go_package = "github.com/tx7do/kratos-bootstrap/api/gen/go/conf/v1;conf";
import "google/protobuf/duration.proto";
import "conf/v1/kratos_conf_middleware.proto";
import "conf/v1/kratos_conf_tls.proto";
// 服务器
message Server {
// REST
message REST {
message CORS {
repeated string headers = 1; //
repeated string methods = 2; //
repeated string origins = 3; //
}
string network = 1; // 网络
string addr = 2; // 服务监听地址
google.protobuf.Duration timeout = 3; // 超时时间
CORS cors = 10; // 服务监听地址
Middleware middleware = 11; // 中间件
TLS tls = 12; // TLS配置
bool enable_swagger = 20; // 启用SwaggerUI
bool enable_pprof = 21; // 启用pprof
}
// gPRC
message GRPC {
string network = 1; // 网络
string addr = 2; // 服务监听地址
google.protobuf.Duration timeout = 3; // 超时时间
Middleware middleware = 4;
TLS tls = 5; // TLS配置
}
// Websocket
message Websocket {
string network = 1; // 网络样式http、https
string addr = 2; // 服务监听地址
string path = 3; // 路径
string codec = 4; // 编解码器: json,xml,yaml...
google.protobuf.Duration timeout = 5; // 超时时间
TLS tls = 6; // TLS配置
}
// MQTT
message Mqtt {
string endpoint = 1; // 对端网络地址
string codec = 2; // 编解码器: json,xml,yaml...
TLS tls = 3; // TLS配置
string username = 4; // 用户名
string password = 5; // 密码
string client_id = 6; // 客户端ID
bool clean_session = 7; // 清除会话
}
// Kafka
message Kafka {
repeated string endpoints = 1; // 对端网络地址
string codec = 2; // 编解码器: json,xml,yaml...
TLS tls = 3; // TLS配置
}
// RabbitMQ
message RabbitMQ {
repeated string endpoints = 1; // 对端网络地址
string codec = 2; // 编解码器: json,xml,yaml...
TLS tls = 3; // TLS配置
}
message ActiveMQ {
string endpoint = 1; // 对端网络地址
string codec = 2; // 编解码器: json,xml,yaml...
TLS tls = 3; // TLS配置
}
message NATS {
string endpoint = 1; // 对端网络地址
string codec = 2; // 编解码器: json,xml,yaml...
TLS tls = 3; // TLS配置
}
message NSQ {
string endpoint = 1; // 对端网络地址
string codec = 2; // 编解码器: json,xml,yaml...
TLS tls = 3; // TLS配置
}
message Pulsar {
string endpoint = 1; // 对端网络地址
string codec = 2; // 编解码器: json,xml,yaml...
TLS tls = 3; // TLS配置
}
message Redis {
string endpoint = 1; // 对端网络地址
string codec = 2; // 编解码器: json,xml,yaml...
TLS tls = 3; // TLS配置
}
message RocketMQ {
string version = 1; // 驱动版本aliyun、v2、v5
string codec = 2; // 编解码器: json,xml,yaml...
repeated string name_servers = 3;
string name_server_domain = 4;
string access_key = 5;
string secret_key = 6;
string security_token = 7;
string namespace = 8;
string instance_name = 9;
string group_name = 10;
TLS tls = 11; // TLS配置
bool enable_trace = 100;
}
// Asynq
message Asynq {
string network = 1; // Redis对端网络地址
string endpoint = 2; // Redis对端网络地址
string password = 3; // Redis登录密码
int32 db = 4; // Redis数据库索引
string uri = 5; // Redis URI
int32 pool_size = 6; // Redis连接池大小
TLS tls = 7; // TLS配置
string codec = 8; // 编解码器: json,xml,yaml...
string location = 10; // 时区
int32 concurrency = 11; // 并发数
int32 group_max_size = 12; // 组最大大小
map<string, int32> queues = 13; // 队列
bool enable_gracefully_shutdown = 20; // 优雅关闭
bool enable_strict_priority = 21; // 严格优先级
google.protobuf.Duration shutdown_timeout = 30; // 关闭超时时间
google.protobuf.Duration dial_timeout = 31; // 拨号超时时间
google.protobuf.Duration read_timeout = 32; // 读取超时时间
google.protobuf.Duration write_timeout = 33; // 写入超时时间
google.protobuf.Duration health_check_interval = 34; // 健康检查时间间隔
google.protobuf.Duration delayed_task_check_interval = 35; // 延迟任务检查时间间隔
google.protobuf.Duration group_grace_period = 36; // 组宽限期
google.protobuf.Duration group_max_delay = 37; // 组最大延迟
}
// Machinery
message Machinery {
string broker_type = 1; // broker类型可以根据实际使用的存储介质分别指定Redis、AMQP或AWS SQS
string broker_addr = 2; // broker的地址
int32 broker_db = 3; // broker的数据库索引
string backend_type = 10; // backend类型可以分别指定为redis、memcached或mongodb等
string backend_addr = 11; // backend的地址
int32 backend_db = 12; // backend的数据库索引
string lock_type = 20; // lock类型可以分别指定为redis、memcached或mongodb等
string lock_addr = 21; // lock的地址
int32 lock_db = 22; // lock的数据库索引
string consumer_tag = 30; // 消费者标签
int32 consumer_concurrency = 31; // 消费者并发数
string consumer_queue = 32; // 消费者队列
TLS tls = 50; // TLS配置
string default_queue = 51; // 默认队列
int32 results_expire_in = 52; // 结果过期时间
bool no_unix_signals = 53; // 禁用Unix信号
message Redis {
int32 max_idle = 1;
int32 max_active = 2;
int32 max_idle_timeout = 3;
bool wait = 4;
int32 read_timeout = 5;
int32 write_timeout = 6;
int32 connect_timeout = 7;
int32 normal_tasks_poll_period = 8;
int32 delayed_tasks_poll_period = 9;
string delayed_tasks_key = 10;
string master_name = 11;
}
Redis redis = 100; // Redis配置
message AMQP {
string exchange = 1;
string exchange_type = 2;
map<string, string> queue_declare_args = 3;
map<string, string> queue_binding_args = 4;
string binding_key = 5;
int32 prefetch_count = 6;
bool auto_delete = 7;
string delayed_queue = 8;
}
AMQP amqp = 101; // AMQP配置
message SQS {
int32 receive_wait_time_seconds = 1;
optional int32 receive_visibility_timeout = 2;
}
SQS sqs = 102; // SQS配置
message GCP {
google.protobuf.Duration max_extension = 1;
}
GCP gcp = 103; // GCP配置
message MongoDB {
string database = 1;
}
MongoDB mongodb = 104; // MongoDB配置
message DynamoDB {
string task_states_table = 1;
string group_metas_table = 2;
}
DynamoDB dynamodb = 105; // DynamoDB配置
}
// SSE
message SSE {
string network = 1; // 网络
string addr = 2; // 服务监听地址
string path = 3; // 路径
string codec = 4; // 编解码器
TLS tls = 5; // TLS配置
google.protobuf.Duration timeout = 10; // 超时时间
google.protobuf.Duration event_ttl = 11; //
bool auto_stream = 20; //
bool auto_reply = 21; //
bool split_data = 22; //
bool encode_base64 = 23; // 进行BASE64编码
}
// SocketIO
message SocketIO {
string network = 1; // 网络
string addr = 2; // 服务监听地址
string path = 3; // 路径
string codec = 4; // 编解码器
TLS tls = 5; // TLS配置
}
// SignalR
message SignalR {
string network = 1; // 网络
string addr = 2; // 服务监听地址
string codec = 3; // 编解码器
TLS tls = 4; // TLS配置
google.protobuf.Duration keep_alive_interval = 10; // 超时时间
google.protobuf.Duration chan_receive_timeout = 11; // 超时时间
bool debug = 6; // 调试开关
uint32 stream_buffer_capacity = 7; //
}
// GraphQL
message GraphQL {
string network = 1; // 网络
string addr = 2; // 服务监听地址
string path = 3; // 路径
string codec = 4; // 编解码器
google.protobuf.Duration timeout = 5; // 超时时间
bool strict_slash = 6;
TLS tls = 7; // TLS配置
}
// Thrift
message Thrift {
string network = 1; // 网络
string addr = 2; // 服务监听地址
string protocol = 3;
bool buffered = 4;
bool framed = 5;
bool buffer_size = 6;
TLS tls = 7; // TLS配置
}
message KeepAlive {
string network = 1; // 网络
string addr = 2; // 服务监听地址
TLS tls = 3; // TLS配置
}
// RPC
optional REST rest = 1; // REST服务
optional GRPC grpc = 2; // gRPC服务
optional GraphQL graphql = 3; // GraphQL服务
optional Thrift thrift = 4; // Thrift服务
optional KeepAlive keepalive = 5; // 保活服务
// Message Queue
optional Mqtt mqtt = 10; // MQTT服务
optional Kafka kafka = 11; // Kafka服务
optional RabbitMQ rabbitmq = 12; // RabbitMQ服务
optional ActiveMQ activemq = 13; // ActiveMQ
optional NATS nats = 14; // NATS
optional NSQ nsq = 15; // NATS
optional Pulsar pulsar = 16; // Pulsar
optional Redis redis = 17; // Redis
optional RocketMQ rocketmq = 18; // RocketMQ
// RealTime
optional Websocket websocket = 20; // Websocket服务
optional SSE sse = 21; // SSE服务
optional SocketIO socketio = 22; // SocketIO服务
optional SignalR signalr = 23; // SignalR服务
// Task Queue
optional Asynq asynq = 30; // Asynq服务
optional Machinery machinery = 31; // Machinery服务
}

View File

@@ -0,0 +1,24 @@
syntax = "proto3";
package conf;
option go_package = "github.com/tx7do/kratos-bootstrap/api/gen/go/conf/v1;conf";
// TLS配置
message TLS {
message File {
optional string cert_path = 1;
optional string key_path = 2;
optional string ca_path = 3;
}
message Config {
optional bytes cert_pem = 1;
optional bytes key_pem = 2;
optional bytes ca_pem = 3;
}
optional File file = 1;
optional Config config = 2;
bool insecure_skip_verify = 3;
}

View File

@@ -2,7 +2,7 @@ syntax = "proto3";
package conf;
option go_package = "github.com/tx7do/kratos-bootstrap/gen/api/go/conf/v1;conf";
option go_package = "github.com/tx7do/kratos-bootstrap/api/gen/go/conf/v1;conf";
//
message Tracer {

View File

@@ -0,0 +1,87 @@
syntax = "proto3";
package pagination;
option go_package = "github.com/tx7do/kratos-bootstrap/api/gen/go/pagination/v1;pagination";
import "google/protobuf/field_mask.proto";
import "gnostic/openapi/v3/annotations.proto";
// 分页通用请求
message PagingRequest {
// 当前页码
optional int32 page = 1 [
json_name = "page",
(gnostic.openapi.v3.property) = {
description: "当前页码",
default: {number: 1}
}
];
// 每一页的行数
optional int32 page_size = 2 [
json_name = "pageSize",
(gnostic.openapi.v3.property) = {
description: "每一页的行数",
default: {number: 10}
}
];
// AND过滤参数其语法为json格式的字符串{"key1":"val1","key2":"val2"}具体请参见https://github.com/tx7do/go-utils/tree/main/entgo/query/README.md
optional string query = 3 [
json_name = "query",
(gnostic.openapi.v3.property) = {
description: "AND过滤参数其语法为json格式的字符串{\"key1\":\"val1\",\"key2\":\"val2\"}具体请参见https://github.com/tx7do/go-utils/tree/main/entgo/query/README.md",
example: {yaml: "{\"key1\":\"val1\",\"key2\":\"val2\"}"}
}
];
// OR过滤参数语法同AND过滤参数。
optional string or_query = 4 [
json_name = "or",
(gnostic.openapi.v3.property) = {
description: "OR过滤参数",
example: {yaml: "{\"key1\":\"val1\",\"key2\":\"val2\"}"}
}
];
// 排序条件其语法为JSON字符串例如{"val1", "-val2"}。字段名前加'-'为降序,否则为升序。
repeated string order_by = 5 [
json_name = "orderBy",
(gnostic.openapi.v3.property) = {
description: "排序条件其语法为JSON字符串例如{\"val1\", \"-val2\"}。字段名前加'-'为降序,否则为升序。"
example: {yaml: "{\"val1\", \"-val2\"}"}
}
];
// 是否不分页如果为true则page和pageSize参数无效。
optional bool no_paging = 6 [
json_name = "noPaging",
(gnostic.openapi.v3.property) = {
description: "是否不分页如果为true则page和pageSize参数无效。"
}
];
// 字段掩码其作用为SELECT中的字段其语法为使用逗号分隔字段名例如id,realName,userName。如果为空则选中所有字段即SELECT *。
optional google.protobuf.FieldMask field_mask = 7 [
json_name = "fieldMask",
(gnostic.openapi.v3.property) = {
description: "字段掩码其作用为SELECT中的字段其语法为使用逗号分隔字段名例如id,realName,userName。如果为空则选中所有字段即SELECT *。",
example: {yaml : "id,realName,userName"}
}
];
optional uint32 tenant_id = 8 [
(gnostic.openapi.v3.property) = {description: "租户ID"},
json_name = "tenantId"
]; // 租户ID
}
// 分页通用结果
message PagingResponse {
// 总数
int32 total = 1;
// 分页数据
repeated bytes items = 2;
}

View File

@@ -1,36 +0,0 @@
package bootstrap
import (
"fmt"
"github.com/go-kratos/kratos/v2/log"
"github.com/go-kratos/kratos/v2/registry"
conf "github.com/tx7do/kratos-bootstrap/gen/api/go/conf/v1"
)
// Bootstrap 应用引导启动
func Bootstrap(serviceInfo *ServiceInfo) (*conf.Bootstrap, log.Logger, registry.Registrar) {
// inject command flags
Flags := NewCommandFlags()
Flags.Init()
var err error
// load configs
if err = LoadBootstrapConfig(Flags.Conf); err != nil {
panic(fmt.Sprintf("load config failed: %v", err))
}
// init logger
ll := NewLoggerProvider(commonConfig.Logger, serviceInfo)
// init registrar
reg := NewRegistry(commonConfig.Registry)
// init tracer
if err = NewTracerProvider(commonConfig.Trace, serviceInfo); err != nil {
panic(fmt.Sprintf("init tracer failed: %v", err))
}
return commonConfig, ll, reg
}

96
bootstrap/bootstrap.go Normal file
View File

@@ -0,0 +1,96 @@
package bootstrap
import (
"fmt"
"runtime"
"github.com/go-kratos/kratos/v2"
"github.com/go-kratos/kratos/v2/log"
kratosRegistry "github.com/go-kratos/kratos/v2/registry"
"github.com/go-kratos/kratos/v2/transport"
"github.com/tx7do/kratos-bootstrap/logger"
"github.com/tx7do/kratos-bootstrap/tracer"
conf "github.com/tx7do/kratos-bootstrap/api/gen/go/conf/v1"
"github.com/tx7do/kratos-bootstrap/utils"
)
var (
Service = utils.NewServiceInfo(
"",
"1.0.0",
"",
)
)
// NewApp 创建应用程序
func NewApp(ll log.Logger, rr kratosRegistry.Registrar, srv ...transport.Server) *kratos.App {
return kratos.New(
kratos.ID(Service.GetInstanceId()),
kratos.Name(Service.Name),
kratos.Version(Service.Version),
kratos.Metadata(Service.Metadata),
kratos.Logger(ll),
kratos.Server(
srv...,
),
kratos.Registrar(rr),
)
}
// DoBootstrap 执行引导
func DoBootstrap(serviceInfo *utils.ServiceInfo) (*conf.Bootstrap, log.Logger, kratosRegistry.Registrar) {
// inject command flags
Flags := NewCommandFlags()
Flags.Init()
var err error
// load configs
if err = LoadBootstrapConfig(Flags.Conf); err != nil {
panic(fmt.Sprintf("load config failed: %v", err))
}
// init logger
ll := logger.NewLoggerProvider(GetBootstrapConfig().Logger, serviceInfo)
// init registrar
reg := NewRegistry(GetBootstrapConfig().Registry)
// init tracer
if err = tracer.NewTracerProvider(GetBootstrapConfig().Trace, serviceInfo); err != nil {
panic(fmt.Sprintf("init tracer failed: %v", err))
}
return GetBootstrapConfig(), ll, reg
}
type InitApp func(logger log.Logger, registrar kratosRegistry.Registrar, bootstrap *conf.Bootstrap) (*kratos.App, func(), error)
// Bootstrap 应用引导启动
func Bootstrap(initApp InitApp, serviceName, version *string) {
if serviceName != nil && len(*serviceName) != 0 {
Service.Name = *serviceName
}
if version != nil && len(*version) != 0 {
Service.Version = *version
}
// bootstrap
cfg, ll, reg := DoBootstrap(Service)
// init app
app, cleanup, err := initApp(ll, reg, cfg)
if err != nil {
panic(err)
}
defer cleanup()
// run the app.
if err = app.Run(); err != nil {
buf := make([]byte, 1024)
n := runtime.Stack(buf, false)
panic(fmt.Sprintf("Panic: %v\nStack trace:\n%s", err, string(buf[:n])))
}
}

View File

@@ -0,0 +1,65 @@
package bootstrap
import conf "github.com/tx7do/kratos-bootstrap/api/gen/go/conf/v1"
var configList []interface{}
var commonConfig = &conf.Bootstrap{}
func GetBootstrapConfig() *conf.Bootstrap {
return commonConfig
}
// RegisterConfig 注册配置
func RegisterConfig(c interface{}) {
initBootstrapConfig()
configList = append(configList, c)
}
func initBootstrapConfig() {
if len(configList) > 0 {
return
}
configList = append(configList, commonConfig)
if commonConfig.Server == nil {
commonConfig.Server = &conf.Server{}
configList = append(configList, commonConfig.Server)
}
if commonConfig.Client == nil {
commonConfig.Client = &conf.Client{}
configList = append(configList, commonConfig.Client)
}
if commonConfig.Data == nil {
commonConfig.Data = &conf.Data{}
configList = append(configList, commonConfig.Data)
}
if commonConfig.Trace == nil {
commonConfig.Trace = &conf.Tracer{}
configList = append(configList, commonConfig.Trace)
}
if commonConfig.Logger == nil {
commonConfig.Logger = &conf.Logger{}
configList = append(configList, commonConfig.Logger)
}
if commonConfig.Registry == nil {
commonConfig.Registry = &conf.Registry{}
configList = append(configList, commonConfig.Registry)
}
if commonConfig.Oss == nil {
commonConfig.Oss = &conf.OSS{}
configList = append(configList, commonConfig.Oss)
}
if commonConfig.Notify == nil {
commonConfig.Notify = &conf.Notification{}
configList = append(configList, commonConfig.Notify)
}
}

View File

@@ -0,0 +1,56 @@
package bootstrap
import (
"testing"
"github.com/go-kratos/kratos/v2"
"github.com/go-kratos/kratos/v2/log"
"github.com/go-kratos/kratos/v2/registry"
v1 "github.com/tx7do/kratos-bootstrap/api/gen/go/conf/v1"
)
func initApp(logger log.Logger, registrar registry.Registrar, _ *v1.Bootstrap) (*kratos.App, func(), error) {
app := NewApp(logger, registrar)
return app, func() {
}, nil
}
func TestBootstrap(t *testing.T) {
serviceName := "test"
version := "v0.0.1"
Bootstrap(initApp, &serviceName, &version)
}
type CustomConfig struct {
Cfg string `protobuf:"bytes,1,opt,name=cfg,proto3" json:"cfg,omitempty"`
}
func initAppEx(logger log.Logger, registrar registry.Registrar, _ *v1.Bootstrap, _ *CustomConfig) (*kratos.App, func(), error) {
app := NewApp(logger, registrar)
return app, func() {
}, nil
}
func TestCustomBootstrap(t *testing.T) {
customCfg := &CustomConfig{}
RegisterConfig(customCfg)
Service.SetName("test")
Service.SetVersion("v0.0.1")
// bootstrap
cfg, ll, reg := DoBootstrap(Service)
// init app
app, cleanup, err := initAppEx(ll, reg, cfg, customCfg)
if err != nil {
panic(err)
}
defer cleanup()
// run the app.
if err = app.Run(); err != nil {
panic(err)
}
}

98
bootstrap/config.go Normal file
View File

@@ -0,0 +1,98 @@
package bootstrap
import (
"github.com/go-kratos/kratos/v2/config"
fileKratos "github.com/go-kratos/kratos/v2/config/file"
"github.com/go-kratos/kratos/v2/log"
conf "github.com/tx7do/kratos-bootstrap/api/gen/go/conf/v1"
"github.com/tx7do/kratos-bootstrap/utils"
)
// NewFileConfigSource 创建一个本地文件配置源
func NewFileConfigSource(filePath string) config.Source {
return fileKratos.NewSource(filePath)
}
// NewConfigProvider 创建一个配置
func NewConfigProvider(configPath string) config.Config {
err, rc := LoadRemoteConfigSourceConfigs(configPath)
if err != nil {
log.Error("LoadRemoteConfigSourceConfigs: ", err.Error())
}
if rc != nil {
return config.New(
config.WithSource(
NewFileConfigSource(configPath),
NewRemoteConfigSource(rc),
),
)
} else {
return config.New(
config.WithSource(
NewFileConfigSource(configPath),
),
)
}
}
// LoadBootstrapConfig 加载程序引导配置
func LoadBootstrapConfig(configPath string) error {
cfg := NewConfigProvider(configPath)
var err error
if err = cfg.Load(); err != nil {
return err
}
initBootstrapConfig()
if err = scanConfigs(cfg); err != nil {
return err
}
return nil
}
func scanConfigs(cfg config.Config) error {
initBootstrapConfig()
for _, c := range configList {
if err := cfg.Scan(c); err != nil {
return err
}
}
return nil
}
// LoadRemoteConfigSourceConfigs 加载远程配置源的本地配置
func LoadRemoteConfigSourceConfigs(configPath string) (error, *conf.RemoteConfig) {
configPath = configPath + "/" + remoteConfigSourceConfigFile
if !utils.PathExists(configPath) {
return nil, nil
}
cfg := config.New(
config.WithSource(
NewFileConfigSource(configPath),
),
)
defer func(cfg config.Config) {
if err := cfg.Close(); err != nil {
panic(err)
}
}(cfg)
var err error
if err = cfg.Load(); err != nil {
return err, nil
}
if err = scanConfigs(cfg); err != nil {
return err, nil
}
return nil, GetBootstrapConfig().Config
}

12
bootstrap/config_test.go Normal file
View File

@@ -0,0 +1,12 @@
package bootstrap
import (
"testing"
)
func TestRegisterConfig(t *testing.T) {
var cfg struct {
Test string
}
RegisterConfig(&cfg)
}

View File

@@ -1,7 +1,12 @@
package bootstrap
import "flag"
import (
"flag"
"github.com/tx7do/kratos-bootstrap/utils"
)
// CommandFlags 命令传参
type CommandFlags struct {
Conf string // 引导配置文件路径,默认为:../../configs
Env string // 开发环境dev、debug……
@@ -11,25 +16,31 @@ type CommandFlags struct {
}
func NewCommandFlags() *CommandFlags {
return &CommandFlags{
f := &CommandFlags{
Conf: "",
Env: "",
ConfigHost: "",
ConfigType: "",
Daemon: false,
}
f.defineFlag()
return f
}
func (f *CommandFlags) Init() {
func (f *CommandFlags) defineFlag() {
flag.StringVar(&f.Conf, "conf", "../../configs", "config path, eg: -conf ../../configs")
flag.StringVar(&f.Env, "env", "dev", "runtime environment, eg: -env dev")
flag.StringVar(&f.ConfigHost, "chost", "127.0.0.1:8500", "config server host, eg: -chost 127.0.0.1:8500")
flag.StringVar(&f.ConfigType, "ctype", "consul", "config server host, eg: -ctype consul")
flag.BoolVar(&f.Daemon, "d", false, "run app as a daemon with -d=true.")
}
func (f *CommandFlags) Init() {
flag.Parse()
if f.Daemon {
BeDaemon("-d")
utils.BeDaemon("-d")
}
flag.Parse()
}

223
bootstrap/go.mod Normal file
View File

@@ -0,0 +1,223 @@
module github.com/tx7do/kratos-bootstrap/bootstrap
go 1.24.0
toolchain go1.24.3
replace (
github.com/armon/go-metrics => github.com/hashicorp/go-metrics v0.4.1
github.com/tx7do/kratos-bootstrap/api => ../api
github.com/tx7do/kratos-bootstrap/logger => ../logger
github.com/tx7do/kratos-bootstrap/registry => ../registry
github.com/tx7do/kratos-bootstrap/registry/consul => ../registry/consul
github.com/tx7do/kratos-bootstrap/registry/etcd => ../registry/etcd
github.com/tx7do/kratos-bootstrap/registry/eureka => ../registry/eureka
github.com/tx7do/kratos-bootstrap/registry/kubernetes => ../registry/kubernetes
github.com/tx7do/kratos-bootstrap/registry/nacos => ../registry/nacos
github.com/tx7do/kratos-bootstrap/registry/polaris => ../registry/polaris
github.com/tx7do/kratos-bootstrap/registry/servicecomb => ../registry/servicecomb
github.com/tx7do/kratos-bootstrap/registry/zookeeper => ../registry/zookeeper
github.com/tx7do/kratos-bootstrap/remoteconfig/apollo => ../remoteconfig/apollo
github.com/tx7do/kratos-bootstrap/remoteconfig/consul => ../remoteconfig/consul
github.com/tx7do/kratos-bootstrap/remoteconfig/etcd => ../remoteconfig/etcd
github.com/tx7do/kratos-bootstrap/remoteconfig/kubernetes => ../remoteconfig/kubernetes
github.com/tx7do/kratos-bootstrap/remoteconfig/nacos => ../remoteconfig/nacos
github.com/tx7do/kratos-bootstrap/remoteconfig/polaris => ../remoteconfig/polaris
github.com/tx7do/kratos-bootstrap/tracer => ../tracer
github.com/tx7do/kratos-bootstrap/utils => ../utils
)
require (
github.com/go-kratos/kratos/v2 v2.8.4
github.com/google/subcommands v1.2.0
github.com/olekukonko/tablewriter v1.0.7
github.com/spf13/cobra v1.9.1
github.com/tx7do/kratos-bootstrap/api v0.0.21
github.com/tx7do/kratos-bootstrap/logger v0.0.10
github.com/tx7do/kratos-bootstrap/registry v0.1.0
github.com/tx7do/kratos-bootstrap/registry/consul v0.1.0
github.com/tx7do/kratos-bootstrap/registry/etcd v0.1.0
github.com/tx7do/kratos-bootstrap/registry/eureka v0.1.0
github.com/tx7do/kratos-bootstrap/registry/kubernetes v0.1.0
github.com/tx7do/kratos-bootstrap/registry/nacos v0.1.0
github.com/tx7do/kratos-bootstrap/registry/servicecomb v0.1.0
github.com/tx7do/kratos-bootstrap/registry/zookeeper v0.1.0
github.com/tx7do/kratos-bootstrap/remoteconfig/apollo v0.1.0
github.com/tx7do/kratos-bootstrap/remoteconfig/consul v0.1.0
github.com/tx7do/kratos-bootstrap/remoteconfig/etcd v0.1.0
github.com/tx7do/kratos-bootstrap/remoteconfig/kubernetes v0.1.0
github.com/tx7do/kratos-bootstrap/remoteconfig/nacos v0.1.1
github.com/tx7do/kratos-bootstrap/remoteconfig/polaris v0.1.0
github.com/tx7do/kratos-bootstrap/tracer v0.0.10
github.com/tx7do/kratos-bootstrap/utils v0.1.3
golang.org/x/tools v0.33.0
)
require (
dario.cat/mergo v1.0.2 // indirect
github.com/alibabacloud-go/alibabacloud-gateway-pop v0.0.8 // indirect
github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.5 // indirect
github.com/alibabacloud-go/darabonba-array v0.1.0 // indirect
github.com/alibabacloud-go/darabonba-encode-util v0.0.2 // indirect
github.com/alibabacloud-go/darabonba-map v0.0.2 // indirect
github.com/alibabacloud-go/darabonba-openapi/v2 v2.1.7 // indirect
github.com/alibabacloud-go/darabonba-signature-util v0.0.7 // indirect
github.com/alibabacloud-go/darabonba-string v1.0.2 // indirect
github.com/alibabacloud-go/debug v1.0.1 // indirect
github.com/alibabacloud-go/endpoint-util v1.1.1 // indirect
github.com/alibabacloud-go/kms-20160120/v3 v3.2.3 // indirect
github.com/alibabacloud-go/openapi-util v0.1.1 // indirect
github.com/alibabacloud-go/tea v1.3.9 // indirect
github.com/alibabacloud-go/tea-utils/v2 v2.0.7 // indirect
github.com/aliyun/alibaba-cloud-sdk-go v1.63.107 // indirect
github.com/aliyun/alibabacloud-dkms-gcs-go-sdk v0.5.1 // indirect
github.com/aliyun/alibabacloud-dkms-transfer-go-sdk v0.1.9 // indirect
github.com/aliyun/aliyun-secretsmanager-client-go v1.1.5 // indirect
github.com/aliyun/credentials-go v1.4.6 // indirect
github.com/apolloconfig/agollo/v4 v4.4.0 // indirect
github.com/armon/go-metrics v0.5.4 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/buger/jsonparser v1.1.1 // indirect
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
github.com/cenkalti/backoff/v5 v5.0.2 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/clbanning/mxj/v2 v2.7.0 // indirect
github.com/coreos/go-semver v0.3.1 // indirect
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/deckarep/golang-set v1.8.0 // indirect
github.com/emicklei/go-restful/v3 v3.12.2 // indirect
github.com/fatih/color v1.18.0 // indirect
github.com/fluent/fluent-logger-golang v1.10.0 // indirect
github.com/fsnotify/fsnotify v1.9.0 // indirect
github.com/fxamacker/cbor/v2 v2.8.0 // indirect
github.com/go-chassis/cari v0.9.0 // indirect
github.com/go-chassis/foundation v0.4.0 // indirect
github.com/go-chassis/openlog v1.1.3 // indirect
github.com/go-chassis/sc-client v0.7.0 // indirect
github.com/go-kratos/aegis v0.2.0 // indirect
github.com/go-kratos/kratos/contrib/log/fluent/v2 v2.0.0-20250527152916-d6f5f00cf562 // indirect
github.com/go-kratos/kratos/contrib/log/logrus/v2 v2.0.0-20250527152916-d6f5f00cf562 // indirect
github.com/go-kratos/kratos/contrib/log/tencent/v2 v2.0.0-20250527152916-d6f5f00cf562 // indirect
github.com/go-kratos/kratos/contrib/log/zap/v2 v2.0.0-20250527152916-d6f5f00cf562 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/jsonpointer v0.21.1 // indirect
github.com/go-openapi/jsonreference v0.21.0 // indirect
github.com/go-openapi/swag v0.23.1 // indirect
github.com/go-playground/form/v4 v4.2.1 // indirect
github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
github.com/go-zookeeper/zk v1.0.4 // indirect
github.com/gofrs/uuid v4.4.0+incompatible // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/mock v1.6.0 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/gnostic-models v0.6.9 // indirect
github.com/google/go-cmp v0.7.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/mux v1.8.1 // indirect
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect
github.com/hashicorp/consul/api v1.32.1 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-hclog v1.6.3 // indirect
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
github.com/hashicorp/go-metrics v0.5.4 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
github.com/hashicorp/golang-lru v1.0.2 // indirect
github.com/hashicorp/serf v0.10.2 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/karlseguin/ccache/v2 v2.0.8 // indirect
github.com/klauspost/compress v1.18.0 // indirect
github.com/mailru/easyjson v0.9.0 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.16 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/nacos-group/nacos-sdk-go/v2 v2.3.2 // indirect
github.com/olekukonko/errors v1.1.0 // indirect
github.com/olekukonko/ll v0.0.8 // indirect
github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect
github.com/openzipkin/zipkin-go v0.4.3 // indirect
github.com/orcaman/concurrent-map v1.0.0 // indirect
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c // indirect
github.com/pierrec/lz4 v2.6.1+incompatible // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/prometheus/client_golang v1.22.0 // indirect
github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.64.0 // indirect
github.com/prometheus/procfs v0.16.1 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/sagikazarmark/locafero v0.9.0 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spf13/afero v1.14.0 // indirect
github.com/spf13/cast v1.9.1 // indirect
github.com/spf13/pflag v1.0.6 // indirect
github.com/spf13/viper v1.20.1 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/tencentcloud/tencentcloud-cls-sdk-go v1.0.11 // indirect
github.com/tinylib/msgp v1.3.0 // indirect
github.com/tjfoc/gmsm v1.4.1 // indirect
github.com/x448/float16 v0.8.4 // indirect
go.etcd.io/etcd/api/v3 v3.6.0 // indirect
go.etcd.io/etcd/client/pkg/v3 v3.6.0 // indirect
go.etcd.io/etcd/client/v3 v3.6.0 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/otel v1.36.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.36.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.36.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.36.0 // indirect
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.36.0 // indirect
go.opentelemetry.io/otel/exporters/zipkin v1.36.0 // indirect
go.opentelemetry.io/otel/metric v1.36.0 // indirect
go.opentelemetry.io/otel/sdk v1.36.0 // indirect
go.opentelemetry.io/otel/trace v1.36.0 // indirect
go.opentelemetry.io/proto/otlp v1.7.0 // indirect
go.uber.org/atomic v1.11.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
golang.org/x/crypto v0.38.0 // indirect
golang.org/x/exp v0.0.0-20250531010427-b6e5de432a8b // indirect
golang.org/x/mod v0.24.0 // indirect
golang.org/x/net v0.40.0 // indirect
golang.org/x/oauth2 v0.30.0 // indirect
golang.org/x/sync v0.14.0 // indirect
golang.org/x/sys v0.33.0 // indirect
golang.org/x/term v0.32.0 // indirect
golang.org/x/text v0.25.0 // indirect
golang.org/x/time v0.11.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250528174236-200df99c418a // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a // indirect
google.golang.org/grpc v1.72.2 // indirect
google.golang.org/protobuf v1.36.6 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/api v0.33.1 // indirect
k8s.io/apimachinery v0.33.1 // indirect
k8s.io/client-go v0.33.1 // indirect
k8s.io/klog/v2 v2.130.1 // indirect
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect
k8s.io/utils v0.0.0-20250502105355-0f33e8f1c979 // indirect
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
sigs.k8s.io/randfill v1.0.0 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.7.0 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
)

1207
bootstrap/go.sum Normal file

File diff suppressed because it is too large Load Diff

46
bootstrap/registry.go Normal file
View File

@@ -0,0 +1,46 @@
package bootstrap
import (
kRegistry "github.com/go-kratos/kratos/v2/registry"
"github.com/tx7do/kratos-bootstrap/registry"
conf "github.com/tx7do/kratos-bootstrap/api/gen/go/conf/v1"
_ "github.com/tx7do/kratos-bootstrap/registry/consul"
_ "github.com/tx7do/kratos-bootstrap/registry/etcd"
_ "github.com/tx7do/kratos-bootstrap/registry/eureka"
_ "github.com/tx7do/kratos-bootstrap/registry/kubernetes"
_ "github.com/tx7do/kratos-bootstrap/registry/nacos"
_ "github.com/tx7do/kratos-bootstrap/registry/servicecomb"
_ "github.com/tx7do/kratos-bootstrap/registry/zookeeper"
)
// NewRegistry 创建一个注册客户端
func NewRegistry(cfg *conf.Registry) kRegistry.Registrar {
if cfg == nil {
return nil
}
creator := registry.GetRegistrarCreator(cfg.GetType())
if creator == nil {
panic("registrar creator not found:" + cfg.GetType())
return nil
}
return creator(cfg)
}
// NewDiscovery 创建一个发现客户端
func NewDiscovery(cfg *conf.Registry) kRegistry.Discovery {
if cfg == nil {
return nil
}
creator := registry.GetDiscoveryCreator(cfg.GetType())
if creator == nil {
panic("discovery creator not found:" + cfg.GetType())
return nil
}
return creator(cfg)
}

View File

@@ -0,0 +1,49 @@
package bootstrap
import (
"github.com/go-kratos/kratos/v2/config"
conf "github.com/tx7do/kratos-bootstrap/api/gen/go/conf/v1"
"github.com/tx7do/kratos-bootstrap/remoteconfig/apollo"
"github.com/tx7do/kratos-bootstrap/remoteconfig/consul"
"github.com/tx7do/kratos-bootstrap/remoteconfig/etcd"
"github.com/tx7do/kratos-bootstrap/remoteconfig/kubernetes"
"github.com/tx7do/kratos-bootstrap/remoteconfig/nacos"
"github.com/tx7do/kratos-bootstrap/remoteconfig/polaris"
)
const remoteConfigSourceConfigFile = "remote.yaml"
type Type string
const (
LocalFile Type = "file"
Nacos Type = "nacos"
Consul Type = "consul"
Etcd Type = "etcd"
Apollo Type = "apollo"
Kubernetes Type = "kubernetes"
Polaris Type = "polaris"
)
// NewRemoteConfigSource 创建一个远程配置源
func NewRemoteConfigSource(c *conf.RemoteConfig) config.Source {
switch Type(c.Type) {
default:
fallthrough
case LocalFile:
return nil
case Nacos:
return nacos.NewConfigSource(c)
case Consul:
return consul.NewConfigSource(c)
case Etcd:
return etcd.NewConfigSource(c)
case Apollo:
return apollo.NewConfigSource(c)
case Kubernetes:
return kubernetes.NewConfigSource(c)
case Polaris:
return polaris.NewConfigSource(c)
}
}

View File

@@ -1,2 +0,0 @@
# Generated by buf. DO NOT EDIT.
version: v1

View File

@@ -1,9 +0,0 @@
version: v1
breaking:
use:
- FILE
lint:
use:
- DEFAULT

27
cache/redis/go.mod vendored Normal file
View File

@@ -0,0 +1,27 @@
module github.com/tx7do/kratos-bootstrap/cache/redis
go 1.23.0
toolchain go1.24.3
replace github.com/tx7do/kratos-bootstrap/api => ../../api
require (
github.com/go-kratos/kratos/v2 v2.8.4
github.com/redis/go-redis/extra/redisotel/v9 v9.10.0
github.com/redis/go-redis/v9 v9.10.0
github.com/tx7do/kratos-bootstrap/api v0.0.23
)
require (
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/redis/go-redis/extra/rediscmd/v9 v9.10.0 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/otel v1.36.0 // indirect
go.opentelemetry.io/otel/metric v1.36.0 // indirect
go.opentelemetry.io/otel/trace v1.36.0 // indirect
google.golang.org/protobuf v1.36.6 // indirect
)

47
cache/redis/go.sum vendored Normal file
View File

@@ -0,0 +1,47 @@
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/go-kratos/kratos/v2 v2.8.4 h1:eIJLE9Qq9WSoKx+Buy2uPyrahtF/lPh+Xf4MTpxhmjs=
github.com/go-kratos/kratos/v2 v2.8.4/go.mod h1:mq62W2101a5uYyRxe+7IdWubu7gZCGYqSNKwGFiiRcw=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/redis/go-redis/extra/rediscmd/v9 v9.10.0 h1:uTiEyEyfLhkw678n6EulHVto8AkcXVr8zUcBJNZ0ark=
github.com/redis/go-redis/extra/rediscmd/v9 v9.10.0/go.mod h1:eFYL/99JvdLP4T9/3FZ5t2pClnv7mMskc+WstTcyVr4=
github.com/redis/go-redis/extra/redisotel/v9 v9.10.0 h1:4z7/hCJ9Jft8EBb2tDmK38p2WjyIEJ1ShhhwAhjOCps=
github.com/redis/go-redis/extra/redisotel/v9 v9.10.0/go.mod h1:B0thqLh4hB8MvvcUKSwyP5YiIcCCp8UrQ0cA9gEqyjk=
github.com/redis/go-redis/v9 v9.10.0 h1:FxwK3eV8p/CQa0Ch276C7u2d0eNC9kCmAYQ7mCXCzVs=
github.com/redis/go-redis/v9 v9.10.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg=
go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E=
go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE=
go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs=
go.opentelemetry.io/otel/sdk v1.24.0 h1:YMPPDNymmQN3ZgczicBY3B6sf9n62Dlj9pWD3ucgoDw=
go.opentelemetry.io/otel/sdk v1.24.0/go.mod h1:KVrIYw6tEubO9E96HQpcmpTKDVn9gdv35HoYiQWGDFg=
go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w=
go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA=
golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

43
cache/redis/redis.go vendored Normal file
View File

@@ -0,0 +1,43 @@
package redis
import (
"github.com/go-kratos/kratos/v2/log"
"github.com/redis/go-redis/extra/redisotel/v9"
"github.com/redis/go-redis/v9"
conf "github.com/tx7do/kratos-bootstrap/api/gen/go/conf/v1"
)
// NewClient create go-redis client
func NewClient(conf *conf.Data, logger *log.Helper) (rdb *redis.Client) {
if rdb = redis.NewClient(&redis.Options{
Addr: conf.GetRedis().GetAddr(),
Password: conf.GetRedis().GetPassword(),
DB: int(conf.GetRedis().GetDb()),
DialTimeout: conf.GetRedis().GetDialTimeout().AsDuration(),
WriteTimeout: conf.GetRedis().GetWriteTimeout().AsDuration(),
ReadTimeout: conf.GetRedis().GetReadTimeout().AsDuration(),
}); rdb == nil {
logger.Fatalf("failed opening connection to redis")
return nil
}
// open tracing instrumentation.
if conf.GetRedis().GetEnableTracing() {
if err := redisotel.InstrumentTracing(rdb); err != nil {
logger.Fatalf("failed open tracing: %s", err.Error())
return nil
}
}
// open metrics instrumentation.
if conf.GetRedis().GetEnableMetrics() {
if err := redisotel.InstrumentMetrics(rdb); err != nil {
logger.Fatalf("failed open metrics: %s", err.Error())
return nil
}
}
return rdb
}

358
config.go
View File

@@ -1,358 +0,0 @@
package bootstrap
import (
"os"
"path/filepath"
"strings"
"google.golang.org/grpc"
"github.com/go-kratos/kratos/v2/config"
"github.com/go-kratos/kratos/v2/log"
// file
fileKratos "github.com/go-kratos/kratos/v2/config/file"
// etcd
etcdKratos "github.com/go-kratos/kratos/contrib/config/etcd/v2"
etcdClient "go.etcd.io/etcd/client/v3"
// consul
consulKratos "github.com/go-kratos/kratos/contrib/config/consul/v2"
consulApi "github.com/hashicorp/consul/api"
// nacos
nacosKratos "github.com/go-kratos/kratos/contrib/config/nacos/v2"
nacosClients "github.com/nacos-group/nacos-sdk-go/clients"
nacosConstant "github.com/nacos-group/nacos-sdk-go/common/constant"
nacosVo "github.com/nacos-group/nacos-sdk-go/vo"
// apollo
apolloKratos "github.com/go-kratos/kratos/contrib/config/apollo/v2"
// kubernetes
k8sKratos "github.com/go-kratos/kratos/contrib/config/kubernetes/v2"
k8sUtil "k8s.io/client-go/util/homedir"
conf "github.com/tx7do/kratos-bootstrap/gen/api/go/conf/v1"
)
var commonConfig = &conf.Bootstrap{}
var configList []interface{}
const remoteConfigSourceConfigFile = "remote.yaml"
// RegisterConfig 注册配置
func RegisterConfig(c interface{}) {
initBootstrapConfig()
configList = append(configList, c)
}
func initBootstrapConfig() {
if len(configList) > 0 {
return
}
configList = append(configList, commonConfig)
if commonConfig.Server == nil {
commonConfig.Server = &conf.Server{}
configList = append(configList, commonConfig.Server)
}
if commonConfig.Client == nil {
commonConfig.Client = &conf.Client{}
configList = append(configList, commonConfig.Client)
}
if commonConfig.Data == nil {
commonConfig.Data = &conf.Data{}
configList = append(configList, commonConfig.Data)
}
if commonConfig.Trace == nil {
commonConfig.Trace = &conf.Tracer{}
configList = append(configList, commonConfig.Trace)
}
if commonConfig.Logger == nil {
commonConfig.Logger = &conf.Logger{}
configList = append(configList, commonConfig.Logger)
}
if commonConfig.Registry == nil {
commonConfig.Registry = &conf.Registry{}
configList = append(configList, commonConfig.Registry)
}
if commonConfig.Oss == nil {
commonConfig.Oss = &conf.OSS{}
configList = append(configList, commonConfig.Oss)
}
if commonConfig.Notify == nil {
commonConfig.Notify = &conf.Notification{}
configList = append(configList, commonConfig.Notify)
}
}
// NewConfigProvider 创建一个配置
func NewConfigProvider(configPath string) config.Config {
err, rc := LoadRemoteConfigSourceConfigs(configPath)
if err != nil {
log.Error("LoadRemoteConfigSourceConfigs: ", err.Error())
}
if rc != nil {
return config.New(
config.WithSource(
NewFileConfigSource(configPath),
NewRemoteConfigSource(rc),
),
)
} else {
return config.New(
config.WithSource(
NewFileConfigSource(configPath),
),
)
}
}
// LoadBootstrapConfig 加载程序引导配置
func LoadBootstrapConfig(configPath string) error {
cfg := NewConfigProvider(configPath)
var err error
if err = cfg.Load(); err != nil {
return err
}
initBootstrapConfig()
if err = scanConfigs(cfg); err != nil {
return err
}
return nil
}
func scanConfigs(cfg config.Config) error {
initBootstrapConfig()
for _, c := range configList {
if err := cfg.Scan(c); err != nil {
return err
}
}
return nil
}
func pathExists(path string) bool {
_, err := os.Stat(path)
if err == nil {
return true
}
if os.IsNotExist(err) {
return false
}
return false
}
// LoadRemoteConfigSourceConfigs 加载远程配置源的本地配置
func LoadRemoteConfigSourceConfigs(configPath string) (error, *conf.RemoteConfig) {
configPath = configPath + "/" + remoteConfigSourceConfigFile
if !pathExists(configPath) {
return nil, nil
}
cfg := config.New(
config.WithSource(
NewFileConfigSource(configPath),
),
)
defer func(cfg config.Config) {
if err := cfg.Close(); err != nil {
panic(err)
}
}(cfg)
var err error
if err = cfg.Load(); err != nil {
return err, nil
}
if err = scanConfigs(cfg); err != nil {
return err, nil
}
return nil, commonConfig.Config
}
type ConfigType string
const (
ConfigTypeLocalFile ConfigType = "file"
ConfigTypeNacos ConfigType = "nacos"
ConfigTypeConsul ConfigType = "consul"
ConfigTypeEtcd ConfigType = "etcd"
ConfigTypeApollo ConfigType = "apollo"
ConfigTypeKubernetes ConfigType = "kubernetes"
ConfigTypePolaris ConfigType = "polaris"
)
// NewRemoteConfigSource 创建一个远程配置源
func NewRemoteConfigSource(c *conf.RemoteConfig) config.Source {
switch ConfigType(c.Type) {
default:
fallthrough
case ConfigTypeLocalFile:
return nil
case ConfigTypeNacos:
return NewNacosConfigSource(c)
case ConfigTypeConsul:
return NewConsulConfigSource(c)
case ConfigTypeEtcd:
return NewEtcdConfigSource(c)
case ConfigTypeApollo:
return NewApolloConfigSource(c)
case ConfigTypeKubernetes:
return NewKubernetesConfigSource(c)
case ConfigTypePolaris:
return NewPolarisConfigSource(c)
}
}
// getConfigKey 获取合法的配置名
func getConfigKey(configKey string, useBackslash bool) string {
if useBackslash {
return strings.Replace(configKey, `.`, `/`, -1)
} else {
return configKey
}
}
// NewFileConfigSource 创建一个本地文件配置源
func NewFileConfigSource(filePath string) config.Source {
return fileKratos.NewSource(filePath)
}
// NewNacosConfigSource 创建一个远程配置源 - Nacos
func NewNacosConfigSource(c *conf.RemoteConfig) config.Source {
srvConf := []nacosConstant.ServerConfig{
*nacosConstant.NewServerConfig(c.Nacos.Address, c.Nacos.Port),
}
cliConf := nacosConstant.ClientConfig{
TimeoutMs: 10 * 1000, // http请求超时时间单位毫秒
BeatInterval: 5 * 1000, // 心跳间隔时间,单位毫秒
UpdateThreadNum: 20, // 更新服务的线程数
LogLevel: "debug",
CacheDir: "../../configs/cache", // 缓存目录
LogDir: "../../configs/log", // 日志目录
NotLoadCacheAtStart: true, // 在启动时不读取本地缓存数据true--不读取false--读取
UpdateCacheWhenEmpty: true, // 当服务列表为空时是否更新本地缓存true--更新,false--不更新
}
nacosClient, err := nacosClients.NewConfigClient(
nacosVo.NacosClientParam{
ClientConfig: &cliConf,
ServerConfigs: srvConf,
},
)
if err != nil {
log.Fatal(err)
}
return nacosKratos.NewConfigSource(nacosClient,
nacosKratos.WithGroup(getConfigKey(c.Nacos.Key, false)),
nacosKratos.WithDataID("bootstrap.yaml"),
)
}
// NewEtcdConfigSource 创建一个远程配置源 - Etcd
func NewEtcdConfigSource(c *conf.RemoteConfig) config.Source {
cfg := etcdClient.Config{
Endpoints: c.Etcd.Endpoints,
DialTimeout: c.Etcd.Timeout.AsDuration(),
DialOptions: []grpc.DialOption{grpc.WithBlock()},
}
cli, err := etcdClient.New(cfg)
if err != nil {
panic(err)
}
source, err := etcdKratos.New(cli, etcdKratos.WithPath(getConfigKey(c.Etcd.Key, true)))
if err != nil {
log.Fatal(err)
}
return source
}
// NewConsulConfigSource 创建一个远程配置源 - Consul
func NewConsulConfigSource(c *conf.RemoteConfig) config.Source {
cfg := consulApi.DefaultConfig()
cfg.Address = c.Consul.Address
cfg.Scheme = c.Consul.Scheme
cli, err := consulApi.NewClient(cfg)
if err != nil {
log.Fatal(err)
}
source, err := consulKratos.New(cli,
consulKratos.WithPath(getConfigKey(c.Consul.Key, true)),
)
if err != nil {
log.Fatal(err)
}
return source
}
// NewApolloConfigSource 创建一个远程配置源 - Apollo
func NewApolloConfigSource(c *conf.RemoteConfig) config.Source {
source := apolloKratos.NewSource(
apolloKratos.WithAppID(c.Apollo.AppId),
apolloKratos.WithCluster(c.Apollo.Cluster),
apolloKratos.WithEndpoint(c.Apollo.Endpoint),
apolloKratos.WithNamespace(c.Apollo.Namespace),
apolloKratos.WithSecret(c.Apollo.Secret),
apolloKratos.WithEnableBackup(),
)
return source
}
// NewKubernetesConfigSource 创建一个远程配置源 - Kubernetes
func NewKubernetesConfigSource(c *conf.RemoteConfig) config.Source {
source := k8sKratos.NewSource(
k8sKratos.Namespace(c.Kubernetes.Namespace),
k8sKratos.LabelSelector(""),
k8sKratos.KubeConfig(filepath.Join(k8sUtil.HomeDir(), ".kube", "config")),
)
return source
}
// NewPolarisConfigSource 创建一个远程配置源 - Polaris
func NewPolarisConfigSource(_ *conf.RemoteConfig) config.Source {
//configApi, err := polarisApi.NewConfigAPI()
//if err != nil {
// log.Fatal(err)
//}
//
//var opts []polarisKratos.Option
//opts = append(opts, polarisKratos.WithNamespace("default"))
//opts = append(opts, polarisKratos.WithFileGroup("default"))
//opts = append(opts, polarisKratos.WithFileName("default.yaml"))
//
//source, err := polarisKratos.New(configApi, opts...)
//if err != nil {
// log.Fatal(err)
//}
//
//return source
return nil
}

View File

@@ -0,0 +1,60 @@
package cassandra
import (
"crypto/tls"
"github.com/gocql/gocql"
"github.com/go-kratos/kratos/v2/log"
conf "github.com/tx7do/kratos-bootstrap/api/gen/go/conf/v1"
"github.com/tx7do/kratos-bootstrap/utils"
)
func NewCassandraClient(cfg *conf.Bootstrap, l *log.Helper) *gocql.Session {
if cfg.Data == nil || cfg.Data.Cassandra == nil {
l.Warn("cassandra config is nil")
return nil
}
clusterConfig := gocql.NewCluster(cfg.Data.Cassandra.Address)
// 设置用户名密码
clusterConfig.Authenticator = gocql.PasswordAuthenticator{
Username: cfg.Data.Cassandra.Username,
Password: cfg.Data.Cassandra.Password,
}
clusterConfig.Keyspace = cfg.Data.Cassandra.Keyspace
// 设置ssl
if cfg.Data.Cassandra.Tls != nil {
var tlsCfg *tls.Config
var err error
if tlsCfg, err = utils.LoadServerTlsConfig(cfg.Data.Cassandra.Tls); err != nil {
panic(err)
}
if tlsCfg != nil {
clusterConfig.SslOpts = &gocql.SslOptions{Config: tlsCfg}
}
}
// 设置超时时间
clusterConfig.ConnectTimeout = cfg.Data.Cassandra.ConnectTimeout.AsDuration()
clusterConfig.Timeout = cfg.Data.Cassandra.Timeout.AsDuration()
clusterConfig.Consistency = gocql.Consistency(cfg.Data.Cassandra.Consistency)
// 禁止主机查找
clusterConfig.DisableInitialHostLookup = cfg.Data.Cassandra.DisableInitialHostLookup
session, err := clusterConfig.CreateSession()
if err != nil {
l.Fatalf("failed opening connection to cassandra: %v", err)
return nil
}
return session
}

23
database/cassandra/go.mod Normal file
View File

@@ -0,0 +1,23 @@
module github.com/tx7do/kratos-bootstrap/database/cassandra
go 1.23.0
toolchain go1.23.3
replace github.com/tx7do/kratos-bootstrap/api => ../../api
require (
github.com/go-kratos/kratos/v2 v2.8.4
github.com/gocql/gocql v1.7.0
github.com/tx7do/kratos-bootstrap/api v0.0.21
github.com/tx7do/kratos-bootstrap/utils v0.1.3
)
require (
github.com/golang/snappy v1.0.0 // indirect
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect
github.com/kr/text v0.2.0 // indirect
golang.org/x/sync v0.9.0 // indirect
google.golang.org/protobuf v1.36.6 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
)

37
database/cassandra/go.sum Normal file
View File

@@ -0,0 +1,37 @@
github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932 h1:mXoPYz/Ul5HYEDvkta6I8/rnYM5gSdSV2tJ6XbZuEtY=
github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k=
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY=
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-kratos/kratos/v2 v2.8.4 h1:eIJLE9Qq9WSoKx+Buy2uPyrahtF/lPh+Xf4MTpxhmjs=
github.com/go-kratos/kratos/v2 v2.8.4/go.mod h1:mq62W2101a5uYyRxe+7IdWubu7gZCGYqSNKwGFiiRcw=
github.com/gocql/gocql v1.7.0 h1:O+7U7/1gSN7QTEAaMEsJc1Oq2QHXvCWoF3DFK9HDHus=
github.com/gocql/gocql v1.7.0/go.mod h1:vnlvXyFZeLBF0Wy+RS8hrOdbn0UWsWtdg07XJnFxZ+4=
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs=
github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8=
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/tx7do/kratos-bootstrap/utils v0.1.3 h1:1Ja6UTzWsfQWNLbaSCo9Of7yiJ+zQK+lMNceFCTD+wU=
github.com/tx7do/kratos-bootstrap/utils v0.1.3/go.mod h1:CXisY/y1eZIxesxuzLQs4z5AgXrYIijAmlAXf8dKZCo=
golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ=
golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=

View File

@@ -0,0 +1,18 @@
# ClickHouse
## Docker部署
```bash
docker pull bitnami/clickhouse:latest
docker run -itd \
--name clickhouse-server \
--network=app-tier \
-p 8123:8123 \
-p 9000:9000 \
-p 9004:9004 \
-e ALLOW_EMPTY_PASSWORD=no \
-e CLICKHOUSE_ADMIN_USER=default \
-e CLICKHOUSE_ADMIN_PASSWORD=123456 \
bitnami/clickhouse:latest
```

View File

@@ -0,0 +1,199 @@
package clickhouse
import (
"context"
"errors"
"fmt"
"reflect"
"strings"
"sync"
clickhouseV2 "github.com/ClickHouse/clickhouse-go/v2"
driverV2 "github.com/ClickHouse/clickhouse-go/v2/lib/driver"
)
// BatchInserter 批量插入器
type BatchInserter struct {
conn clickhouseV2.Conn
tableName string
columns []string
batchSize int
rows []interface{}
insertStmt string
mu sync.Mutex
ctx context.Context
cancel context.CancelFunc
}
// NewBatchInserter 创建新的批量插入器
func NewBatchInserter(
ctx context.Context,
conn clickhouseV2.Conn,
tableName string,
batchSize int,
columns []string,
) (*BatchInserter, error) {
if batchSize <= 0 {
batchSize = 1000 // 默认批量大小
}
if len(columns) == 0 {
return nil, errors.New("必须指定列名")
}
// 构建INSERT语句
placeholders := make([]string, len(columns))
for i := range placeholders {
placeholders[i] = "?"
}
insertStmt := fmt.Sprintf(
"INSERT INTO %s (%s) VALUES (%s)",
tableName,
strings.Join(columns, ", "),
strings.Join(placeholders, ", "),
)
ctx, cancel := context.WithCancel(ctx)
return &BatchInserter{
conn: conn,
tableName: tableName,
columns: columns,
batchSize: batchSize,
rows: make([]interface{}, 0, batchSize),
insertStmt: insertStmt,
ctx: ctx,
cancel: cancel,
}, nil
}
// Add 添加数据行
func (bi *BatchInserter) Add(row interface{}) error {
bi.mu.Lock()
defer bi.mu.Unlock()
// 检查上下文是否已取消
if bi.ctx.Err() != nil {
return bi.ctx.Err()
}
bi.rows = append(bi.rows, row)
// 达到批量大小时自动提交
if len(bi.rows) >= bi.batchSize {
return bi.flush()
}
return nil
}
// Flush 强制提交当前批次
func (bi *BatchInserter) Flush() error {
bi.mu.Lock()
defer bi.mu.Unlock()
return bi.flush()
}
// Close 关闭插入器并提交剩余数据
func (bi *BatchInserter) Close() error {
defer bi.cancel()
bi.mu.Lock()
defer bi.mu.Unlock()
return bi.flush()
}
// flush 内部提交方法
func (bi *BatchInserter) flush() error {
if len(bi.rows) == 0 {
return nil
}
// 创建批量
batch, err := bi.conn.PrepareBatch(bi.ctx, bi.insertStmt)
if err != nil {
return ErrBatchPrepareFailed
}
// 添加所有行
for _, row := range bi.rows {
// 使用反射获取字段值
if err = appendStructToBatch(batch, row, bi.columns); err != nil {
return ErrBatchAppendFailed
}
}
// 提交批量
if err = batch.Send(); err != nil {
return ErrBatchSendFailed
}
// 清空批次
bi.rows = bi.rows[:0]
return nil
}
// appendStructToBatch 使用反射将结构体字段添加到批次
func appendStructToBatch(batch driverV2.Batch, obj interface{}, columns []string) error {
v := reflect.ValueOf(obj)
// 如果是指针,获取指针指向的值
if v.Kind() == reflect.Ptr {
if v.IsNil() {
return errors.New("nil指针")
}
v = v.Elem()
}
// 必须是结构体
if v.Kind() != reflect.Struct {
return fmt.Errorf("期望结构体类型,得到 %v", v.Kind())
}
// 获取结构体类型
t := v.Type()
// 准备参数值
values := make([]interface{}, len(columns))
// 映射列名到结构体字段
for i, col := range columns {
// 查找匹配的字段
found := false
for j := 0; j < v.NumField(); j++ {
field := t.Field(j)
// 检查ch标签
if tag := field.Tag.Get("ch"); strings.TrimSpace(tag) == col {
values[i] = v.Field(j).Interface()
found = true
break
}
// 检查json标签
jsonTags := strings.Split(field.Tag.Get("json"), ",")
if len(jsonTags) > 0 && strings.TrimSpace(jsonTags[0]) == col {
values[i] = v.Field(j).Interface()
found = true
break
}
// 检查字段名
if field.Name == col {
values[i] = v.Field(j).Interface()
found = true
break
}
}
if !found {
return fmt.Errorf("未找到列 %s 对应的结构体字段", col)
}
}
// 添加到批次
return batch.Append(values...)
}

View File

@@ -0,0 +1,632 @@
package clickhouse
import (
"context"
"crypto/tls"
"database/sql"
"fmt"
"net/url"
"reflect"
"strings"
clickhouseV2 "github.com/ClickHouse/clickhouse-go/v2"
driverV2 "github.com/ClickHouse/clickhouse-go/v2/lib/driver"
"github.com/go-kratos/kratos/v2/log"
conf "github.com/tx7do/kratos-bootstrap/api/gen/go/conf/v1"
"github.com/tx7do/kratos-bootstrap/utils"
)
type Creator func() any
var compressionMap = map[string]clickhouseV2.CompressionMethod{
"none": clickhouseV2.CompressionNone,
"zstd": clickhouseV2.CompressionZSTD,
"lz4": clickhouseV2.CompressionLZ4,
"lz4hc": clickhouseV2.CompressionLZ4HC,
"gzip": clickhouseV2.CompressionGZIP,
"deflate": clickhouseV2.CompressionDeflate,
"br": clickhouseV2.CompressionBrotli,
}
type Client struct {
log *log.Helper
conn clickhouseV2.Conn
db *sql.DB
}
func NewClient(logger log.Logger, cfg *conf.Bootstrap) (*Client, error) {
c := &Client{
log: log.NewHelper(log.With(logger, "module", "clickhouse-client")),
}
if err := c.createClickHouseClient(cfg); err != nil {
return nil, err
}
return c, nil
}
// createClickHouseClient 创建ClickHouse客户端
func (c *Client) createClickHouseClient(cfg *conf.Bootstrap) error {
if cfg.Data == nil || cfg.Data.Clickhouse == nil {
return nil
}
opts := &clickhouseV2.Options{}
if cfg.Data.Clickhouse.Dsn != nil {
tmp, err := clickhouseV2.ParseDSN(cfg.Data.Clickhouse.GetDsn())
if err != nil {
c.log.Errorf("failed to parse clickhouse DSN: %v", err)
return ErrInvalidDSN
}
opts = tmp
}
if cfg.Data.Clickhouse.Addresses != nil {
opts.Addr = cfg.Data.Clickhouse.GetAddresses()
}
if cfg.Data.Clickhouse.Database != nil ||
cfg.Data.Clickhouse.Username != nil ||
cfg.Data.Clickhouse.Password != nil {
opts.Auth = clickhouseV2.Auth{}
if cfg.Data.Clickhouse.Database != nil {
opts.Auth.Database = cfg.Data.Clickhouse.GetDatabase()
}
if cfg.Data.Clickhouse.Username != nil {
opts.Auth.Username = cfg.Data.Clickhouse.GetUsername()
}
if cfg.Data.Clickhouse.Password != nil {
opts.Auth.Password = cfg.Data.Clickhouse.GetPassword()
}
}
if cfg.Data.Clickhouse.Debug != nil {
opts.Debug = cfg.Data.Clickhouse.GetDebug()
}
if cfg.Data.Clickhouse.MaxOpenConns != nil {
opts.MaxOpenConns = int(cfg.Data.Clickhouse.GetMaxOpenConns())
}
if cfg.Data.Clickhouse.MaxIdleConns != nil {
opts.MaxIdleConns = int(cfg.Data.Clickhouse.GetMaxIdleConns())
}
if cfg.Data.Clickhouse.Tls != nil {
var tlsCfg *tls.Config
var err error
if tlsCfg, err = utils.LoadServerTlsConfig(cfg.Server.Grpc.Tls); err != nil {
panic(err)
}
if tlsCfg != nil {
opts.TLS = tlsCfg
}
}
if cfg.Data.Clickhouse.CompressionMethod != nil || cfg.Data.Clickhouse.CompressionLevel != nil {
opts.Compression = &clickhouseV2.Compression{}
if cfg.Data.Clickhouse.GetCompressionMethod() != "" {
opts.Compression.Method = compressionMap[cfg.Data.Clickhouse.GetCompressionMethod()]
}
if cfg.Data.Clickhouse.CompressionLevel != nil {
opts.Compression.Level = int(cfg.Data.Clickhouse.GetCompressionLevel())
}
}
if cfg.Data.Clickhouse.MaxCompressionBuffer != nil {
opts.MaxCompressionBuffer = int(cfg.Data.Clickhouse.GetMaxCompressionBuffer())
}
if cfg.Data.Clickhouse.DialTimeout != nil {
opts.DialTimeout = cfg.Data.Clickhouse.GetDialTimeout().AsDuration()
}
if cfg.Data.Clickhouse.ReadTimeout != nil {
opts.ReadTimeout = cfg.Data.Clickhouse.GetReadTimeout().AsDuration()
}
if cfg.Data.Clickhouse.ConnMaxLifetime != nil {
opts.ConnMaxLifetime = cfg.Data.Clickhouse.GetConnMaxLifetime().AsDuration()
}
if cfg.Data.Clickhouse.HttpProxy != nil {
proxyURL, err := url.Parse(cfg.Data.Clickhouse.GetHttpProxy())
if err != nil {
c.log.Errorf("failed to parse HTTP proxy URL: %v", err)
return ErrInvalidProxyURL
}
opts.HTTPProxyURL = proxyURL
}
if cfg.Data.Clickhouse.ConnectionOpenStrategy != nil {
strategy := clickhouseV2.ConnOpenInOrder
switch cfg.Data.Clickhouse.GetConnectionOpenStrategy() {
case "in_order":
strategy = clickhouseV2.ConnOpenInOrder
case "round_robin":
strategy = clickhouseV2.ConnOpenRoundRobin
case "random":
strategy = clickhouseV2.ConnOpenRandom
}
opts.ConnOpenStrategy = strategy
}
if cfg.Data.Clickhouse.Scheme != nil {
switch cfg.Data.Clickhouse.GetScheme() {
case "http":
opts.Protocol = clickhouseV2.HTTP
case "https":
opts.Protocol = clickhouseV2.HTTP
default:
opts.Protocol = clickhouseV2.Native
}
}
if cfg.Data.Clickhouse.BlockBufferSize != nil {
opts.BlockBufferSize = uint8(cfg.Data.Clickhouse.GetBlockBufferSize())
}
// 创建ClickHouse连接
conn, err := clickhouseV2.Open(opts)
if err != nil {
c.log.Errorf("failed to create clickhouse client: %v", err)
return ErrConnectionFailed
}
c.conn = conn
return nil
}
// Close 关闭ClickHouse客户端连接
func (c *Client) Close() {
if c.conn == nil {
c.log.Warn("clickhouse client is already closed or not initialized")
return
}
if err := c.conn.Close(); err != nil {
c.log.Errorf("failed to close clickhouse client: %v", err)
} else {
c.log.Info("clickhouse client closed successfully")
}
}
// GetServerVersion 获取ClickHouse服务器版本
func (c *Client) GetServerVersion() string {
if c.conn == nil {
c.log.Error("clickhouse client is not initialized")
return ""
}
version, err := c.conn.ServerVersion()
if err != nil {
c.log.Errorf("failed to get server version: %v", err)
return ""
} else {
c.log.Infof("ClickHouse server version: %s", version)
return version.String()
}
}
// CheckConnection 检查ClickHouse客户端连接是否正常
func (c *Client) CheckConnection(ctx context.Context) error {
if c.conn == nil {
c.log.Error("clickhouse client is not initialized")
return ErrClientNotInitialized
}
if err := c.conn.Ping(ctx); err != nil {
c.log.Errorf("ping failed: %v", err)
return ErrPingFailed
}
c.log.Info("clickhouse client connection is healthy")
return nil
}
// Query 执行查询并返回结果
func (c *Client) Query(ctx context.Context, creator Creator, results *[]any, query string, args ...any) error {
if c.conn == nil {
c.log.Error("clickhouse client is not initialized")
return ErrClientNotInitialized
}
if creator == nil {
c.log.Error("creator function cannot be nil")
return ErrCreatorFunctionNil
}
rows, err := c.conn.Query(ctx, query, args...)
if err != nil {
c.log.Errorf("query failed: %v", err)
return ErrQueryExecutionFailed
}
defer func(rows driverV2.Rows) {
if err = rows.Close(); err != nil {
c.log.Errorf("failed to close rows: %v", err)
}
}(rows)
for rows.Next() {
row := creator()
if err = rows.ScanStruct(row); err != nil {
c.log.Errorf("failed to scan row: %v", err)
return ErrRowScanFailed
}
*results = append(*results, row)
}
// 检查是否有未处理的错误
if rows.Err() != nil {
c.log.Errorf("Rows iteration error: %v", rows.Err())
return ErrRowsIterationError
}
return nil
}
// QueryRow 执行查询并返回单行结果
func (c *Client) QueryRow(ctx context.Context, dest any, query string, args ...any) error {
row := c.conn.QueryRow(ctx, query, args...)
if row == nil {
c.log.Error("query row returned nil")
return ErrRowNotFound
}
if err := row.ScanStruct(dest); err != nil {
c.log.Errorf("")
return ErrRowScanFailed
}
return nil
}
// Select 封装 SELECT 子句
func (c *Client) Select(ctx context.Context, dest any, query string, args ...any) error {
if c.conn == nil {
c.log.Error("clickhouse client is not initialized")
return ErrClientNotInitialized
}
err := c.conn.Select(ctx, dest, query, args...)
if err != nil {
c.log.Errorf("select failed: %v", err)
return ErrQueryExecutionFailed
}
return nil
}
// Exec 执行非查询语句
func (c *Client) Exec(ctx context.Context, query string, args ...any) error {
if c.conn == nil {
c.log.Error("clickhouse client is not initialized")
return ErrClientNotInitialized
}
if err := c.conn.Exec(ctx, query, args...); err != nil {
c.log.Errorf("exec failed: %v", err)
return ErrExecutionFailed
}
return nil
}
func (c *Client) prepareInsertData(data any) (string, string, []any, error) {
val := reflect.ValueOf(data)
if val.Kind() != reflect.Ptr || val.IsNil() {
return "", "", nil, fmt.Errorf("data must be a non-nil pointer")
}
val = val.Elem()
typ := val.Type()
columns := make([]string, 0, typ.NumField())
placeholders := make([]string, 0, typ.NumField())
values := make([]any, 0, typ.NumField())
values = structToValueArray(data)
for i := 0; i < typ.NumField(); i++ {
field := typ.Field(i)
// 优先获取 `ch` 标签,其次获取 `json` 标签,最后使用字段名
columnName := field.Tag.Get("ch")
if columnName == "" {
jsonTag := field.Tag.Get("json")
if jsonTag != "" {
tags := strings.Split(jsonTag, ",") // 只取逗号前的部分
if len(tags) > 0 {
columnName = tags[0]
}
}
}
if columnName == "" {
columnName = field.Name
}
//columnName = strings.TrimSpace(columnName)
columns = append(columns, columnName)
placeholders = append(placeholders, "?")
}
return strings.Join(columns, ", "), strings.Join(placeholders, ", "), values, nil
}
// Insert 插入数据到指定表
func (c *Client) Insert(ctx context.Context, tableName string, in any) error {
if c.conn == nil {
c.log.Error("clickhouse client is not initialized")
return ErrClientNotInitialized
}
columns, placeholders, values, err := c.prepareInsertData(in)
if err != nil {
c.log.Errorf("prepare insert in failed: %v", err)
return ErrPrepareInsertDataFailed
}
// 构造 SQL 语句
query := fmt.Sprintf("INSERT INTO %s (%s) VALUES (%s)",
tableName,
columns,
placeholders,
)
// 执行插入操作
if err = c.conn.Exec(ctx, query, values...); err != nil {
c.log.Errorf("insert failed: %v", err)
return ErrInsertFailed
}
return nil
}
func (c *Client) InsertMany(ctx context.Context, tableName string, data []any) error {
if c.conn == nil {
c.log.Error("clickhouse client is not initialized")
return ErrClientNotInitialized
}
if len(data) == 0 {
c.log.Error("data slice is empty")
return ErrInvalidColumnData
}
var columns string
var placeholders []string
var values []any
for _, item := range data {
itemColumns, itemPlaceholders, itemValues, err := c.prepareInsertData(item)
if err != nil {
c.log.Errorf("prepare insert data failed: %v", err)
return ErrPrepareInsertDataFailed
}
if columns == "" {
columns = itemColumns
} else if columns != itemColumns {
c.log.Error("data items have inconsistent columns")
return ErrInvalidColumnData
}
placeholders = append(placeholders, fmt.Sprintf("(%s)", itemPlaceholders))
values = append(values, itemValues...)
}
// 构造 SQL 语句
query := fmt.Sprintf("INSERT INTO %s (%s) VALUES (%s)",
tableName,
columns,
strings.Join(placeholders, ", "),
)
// 执行插入操作
if err := c.conn.Exec(ctx, query, values...); err != nil {
c.log.Errorf("insert many failed: %v", err)
return ErrInsertFailed
}
return nil
}
// AsyncInsert 异步插入数据
func (c *Client) AsyncInsert(ctx context.Context, tableName string, data any, wait bool) error {
if c.conn == nil {
c.log.Error("clickhouse client is not initialized")
return ErrClientNotInitialized
}
// 准备插入数据
columns, placeholders, values, err := c.prepareInsertData(data)
if err != nil {
c.log.Errorf("prepare insert data failed: %v", err)
return ErrPrepareInsertDataFailed
}
// 构造 SQL 语句
query := fmt.Sprintf("INSERT INTO %s (%s) VALUES (%s)",
tableName,
columns,
placeholders,
)
// 执行异步插入
if err = c.asyncInsert(ctx, query, wait, values...); err != nil {
c.log.Errorf("async insert failed: %v", err)
return ErrAsyncInsertFailed
}
return nil
}
// asyncInsert 异步插入数据
func (c *Client) asyncInsert(ctx context.Context, query string, wait bool, args ...any) error {
if c.conn == nil {
c.log.Error("clickhouse client is not initialized")
return ErrClientNotInitialized
}
if err := c.conn.AsyncInsert(ctx, query, wait, args...); err != nil {
c.log.Errorf("async insert failed: %v", err)
return ErrAsyncInsertFailed
}
return nil
}
// AsyncInsertMany 批量异步插入数据
func (c *Client) AsyncInsertMany(ctx context.Context, tableName string, data []any, wait bool) error {
if c.conn == nil {
c.log.Error("clickhouse client is not initialized")
return ErrClientNotInitialized
}
if len(data) == 0 {
c.log.Error("data slice is empty")
return ErrInvalidColumnData
}
// 准备插入数据的列名和占位符
var columns string
var placeholders []string
var values []any
for _, item := range data {
itemColumns, itemPlaceholders, itemValues, err := c.prepareInsertData(item)
if err != nil {
c.log.Errorf("prepare insert data failed: %v", err)
return ErrPrepareInsertDataFailed
}
if columns == "" {
columns = itemColumns
} else if columns != itemColumns {
c.log.Error("data items have inconsistent columns")
return ErrInvalidColumnData
}
placeholders = append(placeholders, fmt.Sprintf("(%s)", itemPlaceholders))
values = append(values, itemValues...)
}
// 构造 SQL 语句
query := fmt.Sprintf("INSERT INTO %s (%s) VALUES %s",
tableName,
columns,
strings.Join(placeholders, ", "),
)
// 执行异步插入操作
if err := c.asyncInsert(ctx, query, wait, values...); err != nil {
c.log.Errorf("batch insert failed: %v", err)
return err
}
return nil
}
// BatchInsert 批量插入数据
func (c *Client) BatchInsert(ctx context.Context, tableName string, data []any) error {
if c.conn == nil {
c.log.Error("clickhouse client is not initialized")
return ErrClientNotInitialized
}
if len(data) == 0 {
c.log.Error("data slice is empty")
return ErrInvalidColumnData
}
// 准备插入数据的列名和占位符
var columns string
var values [][]any
for _, item := range data {
itemColumns, _, itemValues, err := c.prepareInsertData(item)
if err != nil {
c.log.Errorf("prepare insert data failed: %v", err)
return ErrPrepareInsertDataFailed
}
if columns == "" {
columns = itemColumns
} else if columns != itemColumns {
c.log.Error("data items have inconsistent columns")
return ErrInvalidColumnData
}
values = append(values, itemValues)
}
// 构造 SQL 语句
query := fmt.Sprintf("INSERT INTO %s (%s) VALUES", tableName, columns)
// 调用 batchExec 方法执行批量插入
if err := c.batchExec(ctx, query, values); err != nil {
c.log.Errorf("batch insert failed: %v", err)
return ErrBatchInsertFailed
}
return nil
}
// batchExec 执行批量操作
func (c *Client) batchExec(ctx context.Context, query string, data [][]any) error {
batch, err := c.conn.PrepareBatch(ctx, query)
if err != nil {
c.log.Errorf("failed to prepare batch: %v", err)
return ErrBatchPrepareFailed
}
for _, row := range data {
if err = batch.Append(row...); err != nil {
c.log.Errorf("failed to append batch data: %v", err)
return ErrBatchAppendFailed
}
}
if err = batch.Send(); err != nil {
c.log.Errorf("failed to send batch: %v", err)
return ErrBatchSendFailed
}
return nil
}
// BatchStructs 批量插入结构体数据
func (c *Client) BatchStructs(ctx context.Context, query string, data []any) error {
if c.conn == nil {
c.log.Error("clickhouse client is not initialized")
return ErrClientNotInitialized
}
// 准备批量插入
batch, err := c.conn.PrepareBatch(ctx, query)
if err != nil {
c.log.Errorf("failed to prepare batch: %v", err)
return ErrBatchPrepareFailed
}
// 遍历数据并添加到批量插入
for _, row := range data {
if err := batch.AppendStruct(row); err != nil {
c.log.Errorf("failed to append batch struct data: %v", err)
return ErrBatchAppendFailed
}
}
// 发送批量插入
if err = batch.Send(); err != nil {
c.log.Errorf("failed to send batch: %v", err)
return ErrBatchSendFailed
}
return nil
}

View File

@@ -0,0 +1,500 @@
package clickhouse
import (
"context"
"testing"
"time"
"github.com/go-kratos/kratos/v2/log"
"github.com/stretchr/testify/assert"
conf "github.com/tx7do/kratos-bootstrap/api/gen/go/conf/v1"
)
type Candle struct {
Timestamp *time.Time `json:"timestamp" ch:"timestamp"`
Symbol *string `json:"symbol" ch:"symbol"`
Open *float64 `json:"open" ch:"open"`
High *float64 `json:"high" ch:"high"`
Low *float64 `json:"low" ch:"low"`
Close *float64 `json:"close" ch:"close"`
Volume *float64 `json:"volume" ch:"volume"`
}
func createTestClient() *Client {
cli, _ := NewClient(
log.DefaultLogger,
&conf.Bootstrap{
Data: &conf.Data{
Clickhouse: &conf.Data_ClickHouse{
Addresses: []string{"localhost:9000"},
Database: Ptr("finances"),
Username: Ptr("default"),
Password: Ptr("*Abcd123456"),
},
},
},
)
return cli
}
func createCandlesTable(client *Client) {
// 创建表的 SQL 语句
createTableQuery := `
CREATE TABLE IF NOT EXISTS candles (
timestamp DateTime64(3),
symbol String,
open Float64,
high Float64,
low Float64,
close Float64,
volume Float64
) ENGINE = MergeTree()
ORDER BY timestamp
`
err := client.Exec(context.Background(), createTableQuery)
if err != nil {
log.Errorf("Failed to create candles table: %v", err)
return
}
}
func TestNewClient(t *testing.T) {
client := createTestClient()
assert.NotNil(t, client)
// 测试 CheckConnection
err := client.CheckConnection(context.Background())
assert.NoError(t, err, "CheckConnection 应该成功执行")
// 测试 GetServerVersion
version := client.GetServerVersion()
assert.NotEmpty(t, version, "GetServerVersion 应该返回非空值")
createCandlesTable(client)
}
func TestInsertCandlesTable(t *testing.T) {
client := createTestClient()
assert.NotNil(t, client)
createCandlesTable(client)
// 测试数据
candle := &Candle{
Timestamp: Ptr(time.Now()),
Symbol: Ptr("AAPL"),
Open: Ptr(100.5),
High: Ptr(105.0),
Low: Ptr(99.5),
Close: Ptr(102.0),
Volume: Ptr(1500.0),
}
// 插入数据
err := client.Insert(context.Background(), "candles", candle)
assert.NoError(t, err, "InsertCandlesTable 应该成功执行")
}
func TestInsertManyCandlesTable(t *testing.T) {
client := createTestClient()
assert.NotNil(t, client)
createCandlesTable(client)
// 测试数据
data := []any{
&Candle{
Timestamp: Ptr(time.Now()),
Symbol: Ptr("AAPL"),
Open: Ptr(100.5),
High: Ptr(105.0),
Low: Ptr(99.5),
Close: Ptr(102.0),
Volume: Ptr(1500.0),
},
&Candle{
Timestamp: Ptr(time.Now()),
Symbol: Ptr("GOOG"),
Open: Ptr(200.5),
High: Ptr(205.0),
Low: Ptr(199.5),
Close: Ptr(202.0),
Volume: Ptr(2500.0),
},
}
// 插入数据
err := client.InsertMany(context.Background(), "candles", data)
assert.NoError(t, err, "InsertManyCandlesTable 应该成功执行")
}
func TestAsyncInsertCandlesTable(t *testing.T) {
client := createTestClient()
assert.NotNil(t, client)
createCandlesTable(client)
// 测试数据
candle := &Candle{
Timestamp: Ptr(time.Now()),
Symbol: Ptr("BTC/USD"),
Open: Ptr(30000.0),
High: Ptr(31000.0),
Low: Ptr(29000.0),
Close: Ptr(30500.0),
Volume: Ptr(500.0),
}
// 异步插入数据
err := client.AsyncInsert(context.Background(), "candles", candle, true)
assert.NoError(t, err, "AsyncInsert 方法应该成功执行")
// 验证插入结果
query := `
SELECT timestamp, symbol, open, high, low, close, volume
FROM candles
WHERE symbol = ?
`
var result Candle
err = client.QueryRow(context.Background(), &result, query, "BTC/USD")
assert.NoError(t, err, "QueryRow 应该成功执行")
assert.Equal(t, "BTC/USD", *result.Symbol, "symbol 列值应该为 BTC/USD")
assert.Equal(t, 30500.0, *result.Close, "close 列值应该为 30500.0")
assert.Equal(t, 500.0, *result.Volume, "volume 列值应该为 500.0")
}
func TestAsyncInsertManyCandlesTable(t *testing.T) {
client := createTestClient()
assert.NotNil(t, client)
createCandlesTable(client)
// 测试数据
data := []any{
&Candle{
Timestamp: Ptr(time.Now()),
Symbol: Ptr("AAPL"),
Open: Ptr(100.5),
High: Ptr(105.0),
Low: Ptr(99.5),
Close: Ptr(102.0),
Volume: Ptr(1500.0),
},
&Candle{
Timestamp: Ptr(time.Now()),
Symbol: Ptr("GOOG"),
Open: Ptr(200.5),
High: Ptr(205.0),
Low: Ptr(199.5),
Close: Ptr(202.0),
Volume: Ptr(2500.0),
},
&Candle{
Timestamp: Ptr(time.Now()),
Symbol: Ptr("MSFT"),
Open: Ptr(300.5),
High: Ptr(305.0),
Low: Ptr(299.5),
Close: Ptr(302.0),
Volume: Ptr(3500.0),
},
}
// 批量插入数据
err := client.AsyncInsertMany(context.Background(), "candles", data, true)
assert.NoError(t, err, "AsyncInsertMany 方法应该成功执行")
// 验证插入结果
query := `
SELECT timestamp, symbol, open, high, low, close, volume
FROM candles
`
var results []Candle
err = client.Select(context.Background(), &results, query)
assert.NoError(t, err, "查询数据应该成功执行")
}
func TestInternalBatchExecCandlesTable(t *testing.T) {
client := createTestClient()
assert.NotNil(t, client)
createCandlesTable(client)
// 插入数据的 SQL 语句
insertQuery := `
INSERT INTO candles (timestamp, symbol, open, high, low, close, volume)
VALUES (?, ?, ?, ?, ?, ?, ?)
`
// 测试数据
data := [][]interface{}{
{"2023-10-01 12:00:00", "AAPL", 100.5, 105.0, 99.5, 102.0, 1500.0},
{"2023-10-01 12:01:00", "GOOG", 200.5, 205.0, 199.5, 202.0, 2500.0},
{"2023-10-01 12:02:00", "MSFT", 300.5, 305.0, 299.5, 302.0, 3500.0},
}
// 批量插入数据
err := client.batchExec(context.Background(), insertQuery, data)
assert.NoError(t, err, "batchExec 应该成功执行")
}
func TestBatchInsertCandlesTable(t *testing.T) {
client := createTestClient()
assert.NotNil(t, client)
createCandlesTable(client)
// 测试数据
data := []any{
&Candle{
Timestamp: Ptr(time.Now()),
Symbol: Ptr("AAPL"),
Open: Ptr(100.5),
High: Ptr(105.0),
Low: Ptr(99.5),
Close: Ptr(102.0),
Volume: Ptr(1500.0),
},
&Candle{
Timestamp: Ptr(time.Now()),
Symbol: Ptr("GOOG"),
Open: Ptr(200.5),
High: Ptr(205.0),
Low: Ptr(199.5),
Close: Ptr(202.0),
Volume: Ptr(2500.0),
},
&Candle{
Timestamp: Ptr(time.Now()),
Symbol: Ptr("MSFT"),
Open: Ptr(300.5),
High: Ptr(305.0),
Low: Ptr(299.5),
Close: Ptr(302.0),
Volume: Ptr(3500.0),
},
}
// 批量插入数据
err := client.BatchInsert(context.Background(), "candles", data)
assert.NoError(t, err, "BatchInsert 方法应该成功执行")
// 验证插入结果
query := `
SELECT timestamp, symbol, open, high, low, close, volume
FROM candles
`
var results []Candle
err = client.Select(context.Background(), &results, query)
assert.NoError(t, err, "查询数据应该成功执行")
}
func TestBatchStructsCandlesTable(t *testing.T) {
client := createTestClient()
assert.NotNil(t, client)
createCandlesTable(client)
// 插入数据的 SQL 语句
insertQuery := `
INSERT INTO candles (timestamp, symbol, open, high, low, close, volume)
VALUES (?, ?, ?, ?, ?, ?, ?)
`
// 测试数据
data := []any{
&Candle{
Timestamp: Ptr(time.Now()),
Symbol: Ptr("AAPL"),
Open: Ptr(100.5),
High: Ptr(105.0),
Low: Ptr(99.5),
Close: Ptr(102.0),
Volume: Ptr(1500.0),
},
&Candle{
Timestamp: Ptr(time.Now()),
Symbol: Ptr("GOOG"),
Open: Ptr(200.5),
High: Ptr(205.0),
Low: Ptr(199.5),
Close: Ptr(202.0),
Volume: Ptr(2500.0),
},
}
// 批量插入数据
err := client.BatchStructs(context.Background(), insertQuery, data)
assert.NoError(t, err, "BatchStructsCandlesTable 应该成功执行")
}
func TestInternalAsyncInsertIntoCandlesTable(t *testing.T) {
client := createTestClient()
assert.NotNil(t, client)
createCandlesTable(client)
// 插入数据的 SQL 语句
insertQuery := `
INSERT INTO candles (timestamp, symbol, open, high, low, close, volume)
VALUES (?, ?, ?, ?, ?, ?, ?)
`
// 测试数据
err := client.asyncInsert(context.Background(), insertQuery, true,
"2023-10-01 12:00:00", "AAPL", 100.5, 105.0, 99.5, 102.0, 1500.0)
assert.NoError(t, err, "InsertIntoCandlesTable 应该成功执行")
}
func TestQueryCandlesTable(t *testing.T) {
client := createTestClient()
assert.NotNil(t, client)
createCandlesTable(client)
// 查询数据的 SQL 语句
query := `
SELECT timestamp, symbol, open, high, low, close, volume
FROM candles
`
// 定义结果集
var results []any
// 执行查询
err := client.Query(context.Background(), func() interface{} { return &Candle{} }, &results, query)
assert.NoError(t, err, "QueryCandlesTable 应该成功执行")
assert.NotEmpty(t, results, "QueryCandlesTable 应该返回结果")
for _, result := range results {
candle, ok := result.(*Candle)
assert.True(t, ok, "结果应该是 Candle 类型")
assert.NotNil(t, candle.Timestamp, "Timestamp 列不应该为 nil")
assert.NotNil(t, candle.Symbol, "Symbol 列不应该为 nil")
assert.NotNil(t, candle.Open, "Open 列不应该为 nil")
assert.NotNil(t, candle.High, "High 列不应该为 nil")
assert.NotNil(t, candle.Low, "Low 列不应该为 nil")
assert.NotNil(t, candle.Close, "Close 列不应该为 nil")
assert.NotNil(t, candle.Volume, "Volume 列不应该为 nil")
t.Logf("[%v] Candle: %s, Open: %f, High: %f, Low: %f, Close: %f, Volume: %f\n",
candle.Timestamp.String(),
*candle.Symbol,
*candle.Open, *candle.High, *candle.Low, *candle.Close, *candle.Volume,
)
}
}
func TestSelectCandlesTable(t *testing.T) {
client := createTestClient()
assert.NotNil(t, client)
createCandlesTable(client)
// 查询数据的 SQL 语句
query := `
SELECT timestamp, symbol, open, high, low, close, volume
FROM candles
`
// 定义结果集
var results []Candle
// 执行查询
err := client.Select(context.Background(), &results, query)
assert.NoError(t, err, "QueryCandlesTable 应该成功执行")
assert.NotEmpty(t, results, "QueryCandlesTable 应该返回结果")
for _, result := range results {
assert.NotNil(t, result.Timestamp, "Timestamp 列不应该为 nil")
assert.NotNil(t, result.Symbol, "Symbol 列不应该为 nil")
assert.NotNil(t, result.Open, "Open 列不应该为 nil")
assert.NotNil(t, result.High, "High 列不应该为 nil")
assert.NotNil(t, result.Low, "Low 列不应该为 nil")
assert.NotNil(t, result.Close, "Close 列不应该为 nil")
assert.NotNil(t, result.Volume, "Volume 列不应该为 nil")
t.Logf("[%v] Candle: %s, Open: %f, High: %f, Low: %f, Close: %f, Volume: %f\n",
result.Timestamp.String(),
*result.Symbol,
*result.Open, *result.High, *result.Low, *result.Close, *result.Volume,
)
}
}
func TestQueryRow(t *testing.T) {
client := createTestClient()
assert.NotNil(t, client)
createCandlesTable(client)
// 插入测试数据
insertQuery := `
INSERT INTO candles (timestamp, symbol, open, high, low, close, volume)
VALUES (?, ?, ?, ?, ?, ?, ?)
`
err := client.asyncInsert(context.Background(), insertQuery, true,
"2023-10-01 12:00:00", "AAPL", 100.5, 105.0, 99.5, 102.0, 1500.0)
assert.NoError(t, err, "数据插入失败")
// 查询单行数据
query := `
SELECT timestamp, symbol, open, high, low, close, volume
FROM candles
WHERE symbol = ?
`
var result Candle
err = client.QueryRow(context.Background(), &result, query, "AAPL")
assert.NoError(t, err, "QueryRow 应该成功执行")
assert.Equal(t, "AAPL", *result.Symbol, "symbol 列值应该为 AAPL")
assert.Equal(t, 100.5, *result.Open, "open 列值应该为 100.5")
assert.Equal(t, 1500.0, *result.Volume, "volume 列值应该为 1500.0")
t.Logf("QueryRow Result: [%v] Candle: %s, Open: %f, High: %f, Low: %f, Close: %f, Volume: %f\n",
result.Timestamp.String(),
*result.Symbol,
*result.Open, *result.High, *result.Low, *result.Close, *result.Volume,
)
}
func TestDropCandlesTable(t *testing.T) {
client := createTestClient()
assert.NotNil(t, client)
// 删除表的 SQL 语句
dropTableQuery := `DROP TABLE IF EXISTS candles`
// 执行删除表操作
err := client.Exec(context.Background(), dropTableQuery)
assert.NoError(t, err, "DropCandlesTable 应该成功执行")
}
func TestAggregateCandlesTable(t *testing.T) {
client := createTestClient()
assert.NotNil(t, client)
createCandlesTable(client)
// 聚合查询的 SQL 语句
query := `
SELECT symbol,
MAX(high) AS max_high,
MIN(low) AS min_low,
AVG(close) AS avg_close,
SUM(volume) AS total_volume
FROM candles
GROUP BY symbol
`
// 定义结果集
var results []struct {
Symbol string `ch:"symbol"`
MaxHigh float64 `ch:"max_high"`
MinLow float64 `ch:"min_low"`
AvgClose float64 `ch:"avg_close"`
TotalVolume float64 `ch:"total_volume"`
}
// 执行查询
err := client.Select(context.Background(), &results, query)
assert.NoError(t, err, "AggregateCandlesTable 应该成功执行")
assert.NotEmpty(t, results, "AggregateCandlesTable 应该返回结果")
}

View File

@@ -0,0 +1,89 @@
package clickhouse
import "github.com/go-kratos/kratos/v2/errors"
var (
// ErrInvalidColumnName is returned when an invalid column name is used.
ErrInvalidColumnName = errors.InternalServer("INVALID_COLUMN_NAME", "invalid column name")
// ErrInvalidTableName is returned when an invalid table name is used.
ErrInvalidTableName = errors.InternalServer("INVALID_TABLE_NAME", "invalid table name")
// ErrInvalidCondition is returned when an invalid condition is used in a query.
ErrInvalidCondition = errors.InternalServer("INVALID_CONDITION", "invalid condition in query")
// ErrQueryExecutionFailed is returned when a query execution fails.
ErrQueryExecutionFailed = errors.InternalServer("QUERY_EXECUTION_FAILED", "query execution failed")
// ErrExecutionFailed is returned when a general execution fails.
ErrExecutionFailed = errors.InternalServer("EXECUTION_FAILED", "execution failed")
// ErrAsyncInsertFailed is returned when an asynchronous insert operation fails.
ErrAsyncInsertFailed = errors.InternalServer("ASYNC_INSERT_FAILED", "async insert operation failed")
// ErrRowScanFailed is returned when scanning rows from a query result fails.
ErrRowScanFailed = errors.InternalServer("ROW_SCAN_FAILED", "row scan failed")
// ErrRowsIterationError is returned when there is an error iterating over rows.
ErrRowsIterationError = errors.InternalServer("ROWS_ITERATION_ERROR", "rows iteration error")
// ErrRowNotFound is returned when a specific row is not found in the result set.
ErrRowNotFound = errors.InternalServer("ROW_NOT_FOUND", "row not found")
// ErrConnectionFailed is returned when the connection to ClickHouse fails.
ErrConnectionFailed = errors.InternalServer("CONNECTION_FAILED", "failed to connect to ClickHouse")
// ErrDatabaseNotFound is returned when the specified database is not found.
ErrDatabaseNotFound = errors.InternalServer("DATABASE_NOT_FOUND", "specified database not found")
// ErrTableNotFound is returned when the specified table is not found.
ErrTableNotFound = errors.InternalServer("TABLE_NOT_FOUND", "specified table not found")
// ErrInsertFailed is returned when an insert operation fails.
ErrInsertFailed = errors.InternalServer("INSERT_FAILED", "insert operation failed")
// ErrUpdateFailed is returned when an update operation fails.
ErrUpdateFailed = errors.InternalServer("UPDATE_FAILED", "update operation failed")
// ErrDeleteFailed is returned when a delete operation fails.
ErrDeleteFailed = errors.InternalServer("DELETE_FAILED", "delete operation failed")
// ErrTransactionFailed is returned when a transaction fails.
ErrTransactionFailed = errors.InternalServer("TRANSACTION_FAILED", "transaction failed")
// ErrClientNotInitialized is returned when the ClickHouse client is not initialized.
ErrClientNotInitialized = errors.InternalServer("CLIENT_NOT_INITIALIZED", "clickhouse client not initialized")
// ErrGetServerVersionFailed is returned when getting the server version fails.
ErrGetServerVersionFailed = errors.InternalServer("GET_SERVER_VERSION_FAILED", "failed to get server version")
// ErrPingFailed is returned when a ping to the ClickHouse server fails.
ErrPingFailed = errors.InternalServer("PING_FAILED", "ping to ClickHouse server failed")
// ErrCreatorFunctionNil is returned when the creator function is nil.
ErrCreatorFunctionNil = errors.InternalServer("CREATOR_FUNCTION_NIL", "creator function cannot be nil")
// ErrBatchPrepareFailed is returned when a batch prepare operation fails.
ErrBatchPrepareFailed = errors.InternalServer("BATCH_PREPARE_FAILED", "batch prepare operation failed")
// ErrBatchSendFailed is returned when a batch send operation fails.
ErrBatchSendFailed = errors.InternalServer("BATCH_SEND_FAILED", "batch send operation failed")
// ErrBatchAppendFailed is returned when appending to a batch fails.
ErrBatchAppendFailed = errors.InternalServer("BATCH_APPEND_FAILED", "batch append operation failed")
// ErrBatchInsertFailed is returned when a batch insert operation fails.
ErrBatchInsertFailed = errors.InternalServer("BATCH_INSERT_FAILED", "batch insert operation failed")
// ErrInvalidDSN is returned when the data source name (DSN) is invalid.
ErrInvalidDSN = errors.InternalServer("INVALID_DSN", "invalid data source name")
// ErrInvalidProxyURL is returned when the proxy URL is invalid.
ErrInvalidProxyURL = errors.InternalServer("INVALID_PROXY_URL", "invalid proxy URL")
// ErrPrepareInsertDataFailed is returned when preparing insert data fails.
ErrPrepareInsertDataFailed = errors.InternalServer("PREPARE_INSERT_DATA_FAILED", "failed to prepare insert data")
// ErrInvalidColumnData is returned when the column data type is invalid.
ErrInvalidColumnData = errors.InternalServer("INVALID_COLUMN_DATA", "invalid column data type")
)

View File

@@ -0,0 +1,38 @@
module github.com/tx7do/kratos-bootstrap/database/clickhouse
go 1.23.0
toolchain go1.23.3
replace github.com/tx7do/kratos-bootstrap/api => ../../api
require (
github.com/ClickHouse/clickhouse-go/v2 v2.37.2
github.com/go-kratos/kratos/v2 v2.8.4
github.com/stretchr/testify v1.10.0
github.com/tx7do/kratos-bootstrap/api v0.0.27
github.com/tx7do/kratos-bootstrap/utils v0.1.3
)
require (
github.com/ClickHouse/ch-go v0.66.1 // indirect
github.com/andybalholm/brotli v1.2.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-faster/city v1.0.1 // indirect
github.com/go-faster/errors v0.7.1 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/klauspost/compress v1.18.0 // indirect
github.com/paulmach/orb v0.11.1 // indirect
github.com/pierrec/lz4/v4 v4.1.22 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rogpeppe/go-internal v1.13.1 // indirect
github.com/segmentio/asm v1.2.0 // indirect
github.com/shopspring/decimal v1.4.0 // indirect
go.opentelemetry.io/otel v1.37.0 // indirect
go.opentelemetry.io/otel/trace v1.37.0 // indirect
golang.org/x/sys v0.33.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect
google.golang.org/grpc v1.73.0 // indirect
google.golang.org/protobuf v1.36.6 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

130
database/clickhouse/go.sum Normal file
View File

@@ -0,0 +1,130 @@
github.com/ClickHouse/ch-go v0.66.1 h1:LQHFslfVYZsISOY0dnOYOXGkOUvpv376CCm8g7W74A4=
github.com/ClickHouse/ch-go v0.66.1/go.mod h1:NEYcg3aOFv2EmTJfo4m2WF7sHB/YFbLUuIWv9iq76xY=
github.com/ClickHouse/clickhouse-go/v2 v2.37.2 h1:wRLNKoynvHQEN4znnVHNLaYnrqVc9sGJmGYg+GGCfto=
github.com/ClickHouse/clickhouse-go/v2 v2.37.2/go.mod h1:pH2zrBGp5Y438DMwAxXMm1neSXPPjSI7tD4MURVULw8=
github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwToPjQ=
github.com/andybalholm/brotli v1.2.0/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-faster/city v1.0.1 h1:4WAxSZ3V2Ws4QRDrscLEDcibJY8uf41H6AhXDrNDcGw=
github.com/go-faster/city v1.0.1/go.mod h1:jKcUJId49qdW3L1qKHH/3wPeUstCVpVSXTM6vO3VcTw=
github.com/go-faster/errors v0.7.1 h1:MkJTnDoEdi9pDabt1dpWf7AA8/BaSYZqibYyhZ20AYg=
github.com/go-faster/errors v0.7.1/go.mod h1:5ySTjWFiphBs07IKuiL69nxdfd5+fzh1u7FPGZP2quo=
github.com/go-kratos/kratos/v2 v2.8.4 h1:eIJLE9Qq9WSoKx+Buy2uPyrahtF/lPh+Xf4MTpxhmjs=
github.com/go-kratos/kratos/v2 v2.8.4/go.mod h1:mq62W2101a5uYyRxe+7IdWubu7gZCGYqSNKwGFiiRcw=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
github.com/paulmach/orb v0.11.1 h1:3koVegMC4X/WeiXYz9iswopaTwMem53NzTJuTF20JzU=
github.com/paulmach/orb v0.11.1/go.mod h1:5mULz1xQfs3bmQm63QEJA6lNGujuRafwA5S/EnuLaLU=
github.com/paulmach/protoscan v0.2.1/go.mod h1:SpcSwydNLrxUGSDvXvO0P7g7AuhJ7lcKfDlhJCDw2gY=
github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU=
github.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys=
github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs=
github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/tx7do/kratos-bootstrap/utils v0.1.3 h1:1Ja6UTzWsfQWNLbaSCo9Of7yiJ+zQK+lMNceFCTD+wU=
github.com/tx7do/kratos-bootstrap/utils v0.1.3/go.mod h1:CXisY/y1eZIxesxuzLQs4z5AgXrYIijAmlAXf8dKZCo=
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g=
github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8=
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.mongodb.org/mongo-driver v1.11.4/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g=
go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ=
go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I=
go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw=
golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8=
golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok=
google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@@ -0,0 +1,246 @@
package clickhouse
import (
"fmt"
"regexp"
"strings"
"github.com/go-kratos/kratos/v2/log"
)
type QueryBuilder struct {
table string
columns []string
distinct bool
conditions []string
orderBy []string
groupBy []string
having []string
joins []string
with []string
union []string
limit int
offset int
params []interface{} // 用于存储参数
useIndex string // 索引提示
cacheResult bool // 是否缓存查询结果
debug bool // 是否启用调试
log *log.Helper
}
// NewQueryBuilder 创建一个新的 QueryBuilder 实例
func NewQueryBuilder(table string, log *log.Helper) *QueryBuilder {
return &QueryBuilder{
log: log,
table: table,
params: []interface{}{},
}
}
// EnableDebug 启用调试模式
func (qb *QueryBuilder) EnableDebug() *QueryBuilder {
qb.debug = true
return qb
}
// logDebug 打印调试信息
func (qb *QueryBuilder) logDebug(message string) {
if qb.debug {
qb.log.Debug("[QueryBuilder Debug]:", message)
}
}
// Select 设置查询的列
func (qb *QueryBuilder) Select(columns ...string) *QueryBuilder {
for _, column := range columns {
if !isValidIdentifier(column) {
panic("Invalid column name")
}
}
qb.columns = columns
return qb
}
// Distinct 设置 DISTINCT 查询
func (qb *QueryBuilder) Distinct() *QueryBuilder {
qb.distinct = true
return qb
}
// Where 添加查询条件并支持参数化
func (qb *QueryBuilder) Where(condition string, args ...interface{}) *QueryBuilder {
if !isValidCondition(condition) {
panic("Invalid condition")
}
qb.conditions = append(qb.conditions, condition)
qb.params = append(qb.params, args...)
return qb
}
// OrderBy 设置排序条件
func (qb *QueryBuilder) OrderBy(order string) *QueryBuilder {
qb.orderBy = append(qb.orderBy, order)
return qb
}
// GroupBy 设置分组条件
func (qb *QueryBuilder) GroupBy(columns ...string) *QueryBuilder {
qb.groupBy = append(qb.groupBy, columns...)
return qb
}
// Having 添加分组后的过滤条件并支持参数化
func (qb *QueryBuilder) Having(condition string, args ...interface{}) *QueryBuilder {
qb.having = append(qb.having, condition)
qb.params = append(qb.params, args...)
return qb
}
// Join 添加 JOIN 操作
func (qb *QueryBuilder) Join(joinType, table, onCondition string) *QueryBuilder {
join := fmt.Sprintf("%s JOIN %s ON %s", joinType, table, onCondition)
qb.joins = append(qb.joins, join)
return qb
}
// With 添加 WITH 子句
func (qb *QueryBuilder) With(expression string) *QueryBuilder {
qb.with = append(qb.with, expression)
return qb
}
// Union 添加 UNION 操作
func (qb *QueryBuilder) Union(query string) *QueryBuilder {
qb.union = append(qb.union, query)
return qb
}
// Limit 设置查询结果的限制数量
func (qb *QueryBuilder) Limit(limit int) *QueryBuilder {
qb.limit = limit
return qb
}
// Offset 设置查询结果的偏移量
func (qb *QueryBuilder) Offset(offset int) *QueryBuilder {
qb.offset = offset
return qb
}
// UseIndex 设置索引提示
func (qb *QueryBuilder) UseIndex(index string) *QueryBuilder {
qb.useIndex = index
return qb
}
// CacheResult 启用查询结果缓存
func (qb *QueryBuilder) CacheResult() *QueryBuilder {
qb.cacheResult = true
return qb
}
// ArrayJoin 添加 ARRAY JOIN 子句
func (qb *QueryBuilder) ArrayJoin(expression string) *QueryBuilder {
qb.joins = append(qb.joins, fmt.Sprintf("ARRAY JOIN %s", expression))
return qb
}
// Final 添加 FINAL 修饰符
func (qb *QueryBuilder) Final() *QueryBuilder {
qb.table = fmt.Sprintf("%s FINAL", qb.table)
return qb
}
// Sample 添加 SAMPLE 子句
func (qb *QueryBuilder) Sample(sampleRate float64) *QueryBuilder {
qb.table = fmt.Sprintf("%s SAMPLE %f", qb.table, sampleRate)
return qb
}
// LimitBy 添加 LIMIT BY 子句
func (qb *QueryBuilder) LimitBy(limit int, columns ...string) *QueryBuilder {
qb.limit = limit
qb.orderBy = append(qb.orderBy, fmt.Sprintf("LIMIT BY %d (%s)", limit, strings.Join(columns, ", ")))
return qb
}
// PreWhere 添加 PREWHERE 子句
func (qb *QueryBuilder) PreWhere(condition string, args ...interface{}) *QueryBuilder {
qb.conditions = append([]string{condition}, qb.conditions...)
qb.params = append(args, qb.params...)
return qb
}
// Format 添加 FORMAT 子句
func (qb *QueryBuilder) Format(format string) *QueryBuilder {
qb.union = append(qb.union, fmt.Sprintf("FORMAT %s", format))
return qb
}
// Build 构建最终的 SQL 查询
func (qb *QueryBuilder) Build() (string, []interface{}) {
query := ""
if qb.cacheResult {
query += "/* CACHE */ "
}
query += "SELECT "
if qb.distinct {
query += "DISTINCT "
}
query += qb.buildColumns()
query += fmt.Sprintf(" FROM %s", qb.table)
if qb.useIndex != "" {
query += fmt.Sprintf(" USE INDEX (%s)", qb.useIndex)
}
if len(qb.conditions) > 0 {
query += fmt.Sprintf(" WHERE %s", strings.Join(qb.conditions, " AND "))
}
if len(qb.groupBy) > 0 {
query += fmt.Sprintf(" GROUP BY %s", strings.Join(qb.groupBy, ", "))
}
if len(qb.having) > 0 {
query += fmt.Sprintf(" HAVING %s", strings.Join(qb.having, " AND "))
}
if len(qb.orderBy) > 0 {
query += fmt.Sprintf(" ORDER BY %s", strings.Join(qb.orderBy, ", "))
}
if qb.limit > 0 {
query += fmt.Sprintf(" LIMIT %d", qb.limit)
}
if qb.offset > 0 {
query += fmt.Sprintf(" OFFSET %d", qb.offset)
}
return query, qb.params
}
func (qb *QueryBuilder) buildColumns() string {
if len(qb.columns) == 0 {
return "*"
}
return strings.Join(qb.columns, ", ")
}
// isValidIdentifier 验证表名或列名是否合法
func isValidIdentifier(identifier string) bool {
// 仅允许字母、数字、下划线,且不能以数字开头
matched, _ := regexp.MatchString(`^[a-zA-Z_][a-zA-Z0-9_]*$`, identifier)
return matched
}
// isValidCondition 验证条件语句是否合法
func isValidCondition(condition string) bool {
// 简单验证条件中是否包含危险字符
return !strings.Contains(condition, ";") && !strings.Contains(condition, "--")
}

View File

@@ -0,0 +1,120 @@
package clickhouse
import (
"testing"
"github.com/go-kratos/kratos/v2/log"
"github.com/stretchr/testify/assert"
)
func TestQueryBuilder(t *testing.T) {
logger := log.NewHelper(log.DefaultLogger)
qb := NewQueryBuilder("test_table", logger)
// 测试 Select 方法
qb.Select("id", "name")
query, params := qb.Build()
assert.Contains(t, query, "SELECT id, name FROM test_table")
// 测试 Distinct 方法
qb.Distinct()
query, _ = qb.Build()
assert.Contains(t, query, "SELECT DISTINCT id, name FROM test_table")
// 测试 Where 方法
qb.Where("id > ?", 10).Where("name = ?", "example")
query, params = qb.Build()
assert.Contains(t, query, "WHERE id > ? AND name = ?")
assert.Equal(t, []interface{}{10, "example"}, params)
// 测试 OrderBy 方法
qb.OrderBy("name ASC")
query, _ = qb.Build()
assert.Contains(t, query, "ORDER BY name ASC")
// 测试 GroupBy 方法
qb.GroupBy("category")
query, _ = qb.Build()
assert.Contains(t, query, "GROUP BY category")
// 测试 Having 方法
qb.Having("COUNT(id) > ?", 5)
query, params = qb.Build()
assert.Contains(t, query, "HAVING COUNT(id) > ?")
assert.Equal(t, []interface{}{10, "example", 5}, params)
// 测试 Join 方法
qb.Join("INNER", "other_table", "test_table.id = other_table.id")
query, _ = qb.Build()
assert.Contains(t, query, "INNER JOIN other_table ON test_table.id = other_table.id")
// 测试 With 方法
qb.With("temp AS (SELECT id FROM another_table WHERE status = 'active')")
query, _ = qb.Build()
assert.Contains(t, query, "WITH temp AS (SELECT id FROM another_table WHERE status = 'active')")
// 测试 Union 方法
qb.Union("SELECT id FROM another_table")
query, _ = qb.Build()
assert.Contains(t, query, "UNION SELECT id FROM another_table")
// 测试 Limit 和 Offset 方法
qb.Limit(10).Offset(20)
query, _ = qb.Build()
assert.Contains(t, query, "LIMIT 10 OFFSET 20")
// 测试 UseIndex 方法
qb.UseIndex("idx_name")
query, _ = qb.Build()
assert.Contains(t, query, "USE INDEX (idx_name)")
// 测试 CacheResult 方法
qb.CacheResult()
query, _ = qb.Build()
assert.Contains(t, query, "/* CACHE */")
// 测试 EnableDebug 方法
qb.EnableDebug()
assert.True(t, qb.debug)
// 测试 ArrayJoin 方法
qb.ArrayJoin("array_column")
query, _ = qb.Build()
assert.Contains(t, query, "ARRAY JOIN array_column")
// 测试 Final 方法
qb.Final()
query, _ = qb.Build()
assert.Contains(t, query, "test_table FINAL")
// 测试 Sample 方法
qb.Sample(0.1)
query, _ = qb.Build()
assert.Contains(t, query, "test_table SAMPLE 0.100000")
// 测试 LimitBy 方法
qb.LimitBy(5, "name")
query, _ = qb.Build()
assert.Contains(t, query, "LIMIT BY 5 (name)")
// 测试 PreWhere 方法
qb.PreWhere("status = ?", "active")
query, params = qb.Build()
assert.Contains(t, query, "PREWHERE status = ?")
assert.Equal(t, []interface{}{"active"}, params)
// 测试 Format 方法
qb.Format("JSON")
query, _ = qb.Build()
assert.Contains(t, query, "FORMAT JSON")
// 测试边界情况:空列名
assert.Panics(t, func() {
qb.Select("")
}, "应该抛出异常:无效的列名")
// 测试边界情况:无效条件
assert.Panics(t, func() {
qb.Where("id = 1; DROP TABLE test_table")
}, "应该抛出异常:无效的条件")
}

View File

@@ -0,0 +1,146 @@
package clickhouse
import (
"database/sql"
"reflect"
"time"
"google.golang.org/protobuf/types/known/durationpb"
"google.golang.org/protobuf/types/known/timestamppb"
)
const (
timeFormat = "2006-01-02 15:04:05.000000000"
)
func structToValueArray(input any) []any {
// 检查是否是指针类型,如果是则解引用
val := reflect.ValueOf(input)
if val.Kind() == reflect.Ptr {
val = val.Elem()
}
// 确保输入是结构体
if val.Kind() != reflect.Struct {
return nil
}
var values []any
for i := 0; i < val.NumField(); i++ {
value := val.Field(i).Interface()
switch v := value.(type) {
case *sql.NullString:
if v.Valid {
values = append(values, v.String)
} else {
values = append(values, nil)
}
case *sql.NullInt64:
if v.Valid {
values = append(values, v.Int64)
} else {
values = append(values, nil)
}
case *sql.NullFloat64:
if v.Valid {
values = append(values, v.Float64)
} else {
values = append(values, nil)
}
case *sql.NullBool:
if v.Valid {
values = append(values, v.Bool)
} else {
values = append(values, nil)
}
case *sql.NullTime:
if v != nil && v.Valid {
values = append(values, v.Time.Format(timeFormat))
} else {
values = append(values, nil)
}
case *time.Time:
if v != nil {
values = append(values, v.Format(timeFormat))
} else {
values = append(values, nil)
}
case time.Time:
// 处理 time.Time 类型
if !v.IsZero() {
values = append(values, v.Format(timeFormat))
} else {
values = append(values, nil) // 如果时间为零值,插入 NULL
}
case timestamppb.Timestamp:
// 处理 timestamppb.Timestamp 类型
if !v.IsValid() {
values = append(values, v.AsTime().Format(timeFormat))
} else {
values = append(values, nil) // 如果时间为零值,插入 NULL
}
case *timestamppb.Timestamp:
// 处理 *timestamppb.Timestamp 类型
if v != nil && v.IsValid() {
values = append(values, v.AsTime().Format(timeFormat))
} else {
values = append(values, nil) // 如果时间为零值,插入 NULL
}
case durationpb.Duration:
// 处理 timestamppb.Duration 类型
if v.AsDuration() != 0 {
values = append(values, v.AsDuration().String())
} else {
values = append(values, nil) // 如果时间为零值,插入 NULL
}
case *durationpb.Duration:
// 处理 *timestamppb.Duration 类型
if v != nil && v.AsDuration() != 0 {
values = append(values, v.AsDuration().String())
} else {
values = append(values, nil) // 如果时间为零值,插入 NULL
}
case []any:
// 处理切片类型
if len(v) > 0 {
for _, item := range v {
if item == nil {
values = append(values, nil)
} else {
values = append(values, item)
}
}
} else {
values = append(values, nil) // 如果切片为空,插入 NULL
}
case [][]any:
// 处理二维切片类型
if len(v) > 0 {
for _, item := range v {
if len(item) > 0 {
values = append(values, item)
} else {
values = append(values, nil) // 如果子切片为空,插入 NULL
}
}
} else {
values = append(values, nil) // 如果二维切片为空,插入 NULL
}
default:
values = append(values, v)
}
}
return values
}

View File

@@ -0,0 +1,83 @@
package clickhouse
import (
"testing"
"time"
"github.com/stretchr/testify/assert"
)
// Ptr returns a pointer to the provided value.
func Ptr[T any](v T) *T {
return &v
}
func TestStructToValueArrayWithCandle(t *testing.T) {
now := time.Now()
candle := Candle{
Timestamp: Ptr(now),
Symbol: Ptr("AAPL"),
Open: Ptr(100.5),
High: Ptr(105.0),
Low: Ptr(99.5),
Close: Ptr(102.0),
Volume: Ptr(1500.0),
}
values := structToValueArray(candle)
assert.NotNil(t, values, "Values should not be nil")
assert.Len(t, values, 7, "Expected 7 fields in the Candle struct")
assert.Equal(t, now.Format(timeFormat), values[0].(string), "Timestamp should match")
assert.Equal(t, *candle.Symbol, *(values[1].(*string)), "Symbol should match")
assert.Equal(t, *candle.Open, *values[2].(*float64), "Open price should match")
assert.Equal(t, *candle.High, *values[3].(*float64), "High price should match")
assert.Equal(t, *candle.Low, *values[4].(*float64), "Low price should match")
assert.Equal(t, *candle.Close, *values[5].(*float64), "Close price should match")
assert.Equal(t, *candle.Volume, *values[6].(*float64), "Volume should match")
t.Logf("QueryRow Result: [%v] Candle: %s, Open: %f, High: %f, Low: %f, Close: %f, Volume: %f\n",
values[0],
*(values[1].(*string)),
*values[2].(*float64),
*values[3].(*float64),
*values[4].(*float64),
*values[5].(*float64),
*values[6].(*float64),
)
}
func TestStructToValueArrayWithCandlePtr(t *testing.T) {
now := time.Now()
candle := &Candle{
Timestamp: Ptr(now),
Symbol: Ptr("AAPL"),
Open: Ptr(100.5),
High: Ptr(105.0),
Low: Ptr(99.5),
Close: Ptr(102.0),
Volume: Ptr(1500.0),
}
values := structToValueArray(candle)
assert.NotNil(t, values, "Values should not be nil")
assert.Len(t, values, 7, "Expected 7 fields in the Candle struct")
assert.Equal(t, now.Format(timeFormat), values[0].(string), "Timestamp should match")
assert.Equal(t, *candle.Symbol, *(values[1].(*string)), "Symbol should match")
assert.Equal(t, *candle.Open, *values[2].(*float64), "Open price should match")
assert.Equal(t, *candle.High, *values[3].(*float64), "High price should match")
assert.Equal(t, *candle.Low, *values[4].(*float64), "Low price should match")
assert.Equal(t, *candle.Close, *values[5].(*float64), "Close price should match")
assert.Equal(t, *candle.Volume, *values[6].(*float64), "Volume should match")
t.Logf("QueryRow Result: [%v] Candle: %s, Open: %f, High: %f, Low: %f, Close: %f, Volume: %f\n",
values[0],
*(values[1].(*string)),
*values[2].(*float64),
*values[3].(*float64),
*values[4].(*float64),
*values[5].(*float64),
*values[6].(*float64),
)
}

View File

@@ -0,0 +1,32 @@
# ElasticSearch
## 概念对比
| ES存储结构 | RDBMS存储结构 |
|----------|-----------|
| Index | 表 |
| Document | 行 |
| Field | 表字段 |
| Mapping | 表结构定义 |
## mapping
- 动态映射dynamic mapping
- 显式映射explicit mapping
- 严格映射strict mappings
## Docker部署
```bash
docker pull bitnami/elasticsearch:latest
docker run -itd \
--name elasticsearch \
-p 9200:9200 \
-p 9300:9300 \
-e ELASTICSEARCH_USERNAME=elastic \
-e ELASTICSEARCH_PASSWORD=elastic \
-e ELASTICSEARCH_NODE_NAME=elasticsearch-node-1 \
-e ELASTICSEARCH_CLUSTER_NAME=elasticsearch-cluster \
bitnami/elasticsearch:latest
```

View File

@@ -0,0 +1,442 @@
package elasticsearch
import (
"bytes"
"context"
"encoding/json"
"io"
"github.com/go-kratos/kratos/v2/log"
elasticsearchV9 "github.com/elastic/go-elasticsearch/v9"
esapiV9 "github.com/elastic/go-elasticsearch/v9/esapi"
conf "github.com/tx7do/kratos-bootstrap/api/gen/go/conf/v1"
pagination "github.com/tx7do/kratos-bootstrap/api/gen/go/pagination/v1"
)
type Client struct {
cli *elasticsearchV9.Client
log *log.Helper
}
func NewClient(logger log.Logger, cfg *conf.Bootstrap) (*Client, error) {
c := &Client{
log: log.NewHelper(log.With(logger, "module", "elasticsearch-client")),
}
if err := c.createESClient(cfg); err != nil {
return nil, err
}
return c, nil
}
// createESClient 创建Elasticsearch客户端
func (c *Client) createESClient(cfg *conf.Bootstrap) error {
if cfg.Data == nil || cfg.Data.ElasticSearch == nil {
return nil // No Elasticsearch configuration provided
}
cli, err := elasticsearchV9.NewClient(
elasticsearchV9.Config{
Addresses: cfg.Data.ElasticSearch.GetAddresses(),
Username: cfg.Data.ElasticSearch.GetUsername(),
Password: cfg.Data.ElasticSearch.GetPassword(),
},
)
if err != nil {
c.log.Errorf("failed to create elasticsearch client: %v", err)
return err
}
c.cli = cli
return nil
}
func (c *Client) Close() {
}
// CheckConnectStatus 检查Elasticsearch连接
func (c *Client) CheckConnectStatus() bool {
if c.cli == nil {
return false
}
resp, err := c.cli.Info()
if err != nil {
c.log.Errorf("failed to connect to elasticsearch: %v", err)
return false
}
defer func(Body io.ReadCloser) {
if err = Body.Close(); err != nil {
c.log.Errorf("failed to close response body: %v", err)
}
}(resp.Body)
if resp.IsError() {
c.log.Errorf("Error: %s", resp.String())
return false
}
var r map[string]interface{}
if err = json.NewDecoder(resp.Body).Decode(&r); err != nil {
log.Fatalf("Error parsing the response body: %s", err)
return false
}
c.log.Infof("Client Version: %s", elasticsearchV9.Version)
c.log.Infof("Server Version: %s", r["version"].(map[string]interface{})["number"])
return true
}
// IndexExists 检查索引是否存在
func (c *Client) IndexExists(ctx context.Context, indexName string) (bool, error) {
resp, err := c.cli.Indices.Exists(
[]string{indexName},
c.cli.Indices.Exists.WithContext(ctx),
)
if err != nil {
c.log.Errorf("failed to check if index exists: %v", err)
return false, err
}
return !resp.IsError(), nil
}
// CreateIndex 创建一条索引
//
// 如果mapping为空("")则表示不创建模型
func (c *Client) CreateIndex(ctx context.Context, indexName string, mapping, settings string) error {
exist, err := c.IndexExists(ctx, indexName)
if err != nil {
return err
}
if exist {
return ErrIndexAlreadyExists
}
body, err := MergeOptions(mapping, settings)
if err != nil {
c.log.Errorf("failed to merge options: %v", err)
return err
}
resp, err := c.cli.Indices.Create(
indexName,
c.cli.Indices.Create.WithContext(ctx),
c.cli.Indices.Create.WithBody(bytes.NewReader([]byte(body))),
)
if err != nil {
c.log.Errorf("failed to create index: %v", err)
return err
}
if resp.IsError() {
var errResp *ErrorResponse
if errResp, err = ParseErrorMessage(resp.Body); err != nil {
c.log.Errorf("failed to parse error message: %v", err)
return err
}
c.log.Errorf("create index failed: %s", errResp.Error)
return ErrCreateIndex
}
return nil
}
// DeleteIndex 删除一条索引
func (c *Client) DeleteIndex(ctx context.Context, indexName string) error {
exist, err := c.IndexExists(ctx, indexName)
if err != nil {
c.log.Errorf("failed to check if index exists: %v", err)
return err
}
if !exist {
return ErrIndexNotFound
}
resp, err := c.cli.Indices.Delete(
[]string{indexName},
c.cli.Indices.Delete.WithContext(ctx),
)
if err != nil {
c.log.Errorf("failed to delete index: %v", err)
return err
}
if resp.IsError() {
var errResp *ErrorResponse
if errResp, err = ParseErrorMessage(resp.Body); err != nil {
c.log.Errorf("failed to parse error message: %v", err)
return err
}
c.log.Errorf("delete index failed: %s", errResp.Error.Reason)
return ErrDeleteIndex
}
return nil
}
// DeleteDocument 删除一条数据
func (c *Client) DeleteDocument(ctx context.Context, indexName, id string) error {
_, err := c.cli.Delete(
indexName, id,
c.cli.Delete.WithContext(ctx),
)
if err != nil {
c.log.Errorf("failed to delete document: %v", err)
return err
}
return nil
}
// InsertDocument 插入一条数据
func (c *Client) InsertDocument(ctx context.Context, indexName, id string, data interface{}) error {
var err error
var dataBytes []byte
dataBytes, err = json.Marshal(data)
if err != nil {
c.log.Errorf("failed to marshal data: %v", err)
return err
}
var resp *esapiV9.Response
if id == "" {
resp, err = c.cli.Index(
indexName,
bytes.NewReader(dataBytes),
c.cli.Index.WithContext(ctx),
)
} else {
resp, err = c.cli.Create(
indexName, id,
bytes.NewReader(dataBytes),
c.cli.Create.WithContext(ctx),
)
}
if err != nil {
c.log.Errorf("failed to insert document: %v", err)
return err
}
defer func(Body io.ReadCloser) {
if err = Body.Close(); err != nil {
c.log.Errorf("failed to close response body: %v", err)
}
}(resp.Body)
if resp.IsError() {
var errResp *ErrorResponse
if errResp, err = ParseErrorMessage(resp.Body); err != nil {
c.log.Errorf("failed to parse error message: %v", err)
return err
}
c.log.Errorf("insert data failed: %s", errResp.Error.Reason)
return ErrInsertDocument
}
return nil
}
// BatchInsertDocument 批量插入数据
func (c *Client) BatchInsertDocument(ctx context.Context, indexName string, dataSet []interface{}) error {
var buf bytes.Buffer
for _, data := range dataSet {
meta := []byte(`{"index":{}}` + "\n")
dataBytes, err := json.Marshal(data)
if err != nil {
c.log.Errorf("failed to marshal data: %v", err)
continue
}
dataBytes = append(dataBytes, "\n"...)
buf.Grow(len(meta) + len(dataBytes))
buf.Write(meta)
buf.Write(dataBytes)
}
resp, err := c.cli.Bulk(
bytes.NewReader(buf.Bytes()),
c.cli.Bulk.WithContext(ctx),
c.cli.Bulk.WithIndex(indexName),
)
if err != nil {
c.log.Errorf("failed to perform bulk insert: %v", err)
return err
}
defer func(Body io.ReadCloser) {
if err = Body.Close(); err != nil {
c.log.Errorf("failed to close response body: %v", err)
}
}(resp.Body)
if resp.IsError() {
var errResp *ErrorResponse
if errResp, err = ParseErrorMessage(resp.Body); err != nil {
c.log.Errorf("failed to parse error message: %v", err)
return err
}
c.log.Errorf("batch insert data failed: %s", errResp.Error.Reason)
return ErrBatchInsertDocument
}
return nil
}
func (c *Client) UpdateDocument(ctx context.Context, indexName string, pk string, doc interface{}) error {
data, err := json.Marshal(doc)
if err != nil {
c.log.Errorf("failed to marshal data: %v", err)
return err
}
_, err = c.cli.Update(
indexName, pk,
bytes.NewReader(data),
c.cli.Update.WithContext(ctx),
)
if err != nil {
c.log.Errorf("failed to update document: %v", err)
return err
}
return nil
}
// GetDocument 查询数据
func (c *Client) GetDocument(
ctx context.Context,
indexName string,
id string,
sourceFields []string,
out interface{},
) error {
resp, err := c.cli.Get(
indexName, id,
c.cli.Get.WithContext(ctx),
c.cli.Get.WithSource(sourceFields...), // 指定返回的字段
)
if err != nil {
c.log.Errorf("failed to get document: %v", err)
return err
}
if resp.IsError() {
var errResp *ErrorResponse
if errResp, err = ParseErrorMessage(resp.Body); err != nil {
c.log.Errorf("failed to parse error message: %v", err)
return err
}
if resp.StatusCode == 404 {
c.log.Warnf("document not found: %s", errResp.Error.Reason)
return ErrDocumentNotFound
}
c.log.Errorf("get document failed: %s", errResp.Error.Reason)
return ErrGetDocument
}
if err = json.NewDecoder(resp.Body).Decode(&out); err != nil {
c.log.Errorf("failed to decode document: %v", err)
return err
}
return nil
}
func (c *Client) Search(
ctx context.Context,
indexName string,
req *pagination.PagingRequest,
) (*SearchResult, error) {
var query string
ParseQueryString(req.GetQuery())
sortBy := make(map[string]bool)
pageSize := req.GetPageSize()
if pageSize <= 0 {
pageSize = 20 // Default page size
}
return c.search(ctx, indexName, query, nil, sortBy, int(req.GetPage()), int(pageSize))
}
// search 查询数据
//
// @param ctx 上下文
// @param indexName 索引名
// @param query 查询条件例如field1:value1 AND field2:value2
// @param sourceFields 指定返回的字段传入nil表示返回所有字段
// @param sortBy 排序
// @param from 分页的页码
// @param pageSize 分页每页的行数
func (c *Client) search(
ctx context.Context,
indexName string,
query string,
sourceFields []string,
sortBy map[string]bool,
from, pageSize int,
) (*SearchResult, error) {
var sorts []string
for k, v := range sortBy {
if v {
sorts = append(sorts, k+":asc")
} else {
sorts = append(sorts, k+":desc")
}
}
resp, err := c.cli.Search(
c.cli.Search.WithContext(ctx),
c.cli.Search.WithIndex(indexName),
c.cli.Search.WithFrom(from),
c.cli.Search.WithSize(pageSize),
c.cli.Search.WithSort(sorts...),
c.cli.Search.WithQuery(query),
c.cli.Search.WithSource(sourceFields...), // 指定返回的字段
)
if err != nil {
c.log.Errorf("failed to search documents: %v", err)
return nil, err
}
defer func(Body io.ReadCloser) {
if err := Body.Close(); err != nil {
c.log.Errorf("failed to close response body: %v", err)
}
}(resp.Body)
if resp.IsError() {
var errResp *ErrorResponse
if errResp, err = ParseErrorMessage(resp.Body); err != nil {
return nil, err
}
c.log.Errorf("search document failed: %s", errResp.Error.Reason)
return nil, ErrSearchDocument
}
var searchResult SearchResult
if err = json.NewDecoder(resp.Body).Decode(&searchResult); err != nil {
c.log.Errorf("failed to decode search result: %v", err)
return nil, err
}
return &searchResult, nil
}

View File

@@ -0,0 +1,359 @@
package elasticsearch
import (
"context"
"encoding/json"
"fmt"
"math/rand"
"strconv"
"strings"
"testing"
"time"
"github.com/go-kratos/kratos/v2/log"
"github.com/stretchr/testify/assert"
conf "github.com/tx7do/kratos-bootstrap/api/gen/go/conf/v1"
)
const (
userIndex = "user"
tweetIndex = "tweet"
sensorIndex = "sensor"
)
type User struct {
Name string `json:"name"`
Age int `json:"age"`
Phone string `json:"phone"`
Birth time.Time `json:"birth"`
Height float32 `json:"height"`
Smoke bool `json:"smoke"`
Home string `json:"home"`
}
// UserMapping 定义用户mapping
const UserMapping = `
{
"mappings": {
"properties": {
"name": {"type": "text"},
"age": {"type": "byte"},
"phone": {"type": "text"},
"birth": {"type": "date"},
"height": {"type": "float"},
"smoke": {"type": "boolean"},
"home": {"type": "geo_point"}
}
}
}`
type Tweet struct {
User string `json:"user"` // 用户
Message string `json:"message"` // 微博内容
Retweets int `json:"retweets"` // 转发数
Image string `json:"image,omitempty"` // 图片
Created time.Time `json:"created,omitempty"` // 创建时间
Tags []string `json:"tags,omitempty"` // 标签
Location string `json:"location,omitempty"` //位置
//Suggest *elasticsearchV9.SuggestField `json:"suggest_field,omitempty"`
}
const TweetMapping = `
{
"mappings": {
"properties": {
"user": {"type": "keyword"},
"message": {"type": "text"},
"image": {"type": "keyword"},
"created": {"type": "date"},
"tags": {"type": "keyword"},
"location": {"type": "geo_point"},
"suggest_field": {"type": "completion"}
}
}
}`
type Sensor struct {
Id int `json:"id" bson:"_id,omitempty"`
Type string `json:"type" bson:"type,omitempty"`
Location string `json:"location,omitempty" bson:"location,omitempty"`
}
type SensorData struct {
Id string `json:"id" bson:"_id,omitempty"`
Time time.Time `json:"time" bson:"created,omitempty"`
SensorId int `json:"sensor_id" bson:"sensor_id,omitempty"`
Temperature float64 `json:"temperature" bson:"temperature,omitempty"`
CPU float64 `json:"cpu" bson:"cpu,omitempty"`
}
const SensorMapping = `
{
"mappings": {
"properties": {
"sensor_id": {"type": "integer"},
"temperature": {"type": "double"},
"cpu": {"type": "double"},
"location": {"type": "geo_point"}
}
}
}`
func createTestClient() *Client {
cli, _ := NewClient(
log.DefaultLogger,
&conf.Bootstrap{
Data: &conf.Data{
ElasticSearch: &conf.Data_ElasticSearch{
Addresses: []string{"http://localhost:9200"},
Username: "elastic",
Password: "elastic",
},
},
},
)
return cli
}
func TestNewClient(t *testing.T) {
client := createTestClient()
assert.NotNil(t, client)
client.CheckConnectStatus()
}
func TestCreateIndex(t *testing.T) {
client := createTestClient()
assert.NotNil(t, client)
var esCtx = context.Background()
{
_ = client.DeleteIndex(esCtx, userIndex)
err := client.CreateIndex(esCtx, userIndex, UserMapping, "")
assert.Nil(t, err)
}
{
_ = client.DeleteIndex(esCtx, tweetIndex)
err := client.CreateIndex(esCtx, tweetIndex, TweetMapping, "")
assert.Nil(t, err)
}
{
_ = client.DeleteIndex(esCtx, sensorIndex)
err := client.CreateIndex(esCtx, sensorIndex, SensorMapping, "")
assert.Nil(t, err)
}
}
func TestDeleteIndex(t *testing.T) {
client := createTestClient()
assert.NotNil(t, client)
var esCtx = context.Background()
err := client.DeleteIndex(esCtx, userIndex)
assert.Nil(t, err)
err = client.DeleteIndex(esCtx, tweetIndex)
assert.Nil(t, err)
err = client.DeleteIndex(esCtx, sensorIndex)
assert.Nil(t, err)
}
func TestInsertDocument(t *testing.T) {
client := createTestClient()
assert.NotNil(t, client)
var esCtx = context.Background()
{
// http://localhost:9200/user/_search?q=*&pretty
loc, _ := time.LoadLocation("Local")
birth, _ := time.ParseInLocation("2006-01-02", "1991-04-25", loc)
userOne := User{
Name: "张三",
Age: 23,
Phone: "17600000000",
Birth: birth,
Height: 170.5,
Home: "41.40338,2.17403",
}
err := client.InsertDocument(esCtx, userIndex, "", userOne)
assert.Nil(t, err)
}
{
tweetOne := Tweet{User: "olive", Message: "打酱油的一天", Retweets: 0}
err := client.InsertDocument(esCtx, tweetIndex, "", tweetOne)
assert.Nil(t, err)
}
}
func TestBatchInsertDocument(t *testing.T) {
client := createTestClient()
assert.NotNil(t, client)
var esCtx = context.Background()
{
loc, _ := time.LoadLocation("Local")
// 生日
birthSlice := []string{"1991-04-25", "1990-01-15", "1989-11-05", "1988-01-25", "1994-10-12"}
// 姓名
nameSlice := []string{"李四", "张飞", "赵云", "关羽", "刘备"}
var users []interface{}
for i := 1; i < 20; i++ {
birth, _ := time.ParseInLocation("2006-01-02", birthSlice[rand.Intn(len(birthSlice))], loc)
height, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", rand.Float32()+175.0), 32)
user := User{
Name: nameSlice[rand.Intn(len(nameSlice))],
Age: rand.Intn(10) + 18,
Phone: "1760000000" + strconv.Itoa(i),
Birth: birth,
Height: float32(height),
Home: "41.40338,2.17403",
}
users = append(users, user)
}
err := client.BatchInsertDocument(esCtx, userIndex, users)
assert.Nil(t, err)
}
}
func TestGetDocument(t *testing.T) {
client := createTestClient()
assert.NotNil(t, client)
var esCtx = context.Background()
var user User
const id = "N_1fm5cBE8GqVkmNBLNY"
err := client.GetDocument(esCtx, userIndex, id, nil, &user)
assert.Equal(t, err, ErrDocumentNotFound)
assert.NotNil(t, user)
}
func TestSearch(t *testing.T) {
client := createTestClient()
assert.NotNil(t, client)
var esCtx = context.Background()
//// 创建索引并插入测试数据
//_ = client.DeleteIndex(esCtx, userIndex)
//err := client.CreateIndex(esCtx, userIndex, UserMapping, "")
//assert.Nil(t, err)
//
//userOne := User{
// Name: "张三",
// Age: 23,
// Phone: "17600000000",
// Height: 170.5,
// Home: "41.40338,2.17403",
//}
//err = client.InsertDocument(esCtx, userIndex, "", userOne)
//assert.Nil(t, err)
// 测试Search方法
query := "name:张三"
sortBy := map[string]bool{"age": true}
from := 0
pageSize := 10
searchResult, err := client.search(
esCtx, userIndex, query, nil, sortBy, from, pageSize,
)
assert.Nil(t, err)
assert.NotNil(t, searchResult)
var users []User
for _, hit := range searchResult.Hits.Hits {
var user User
if err = json.Unmarshal(hit.Source, &user); err != nil {
t.Errorf("Failed to unmarshal hit: %v", err)
continue
}
users = append(users, user)
}
t.Logf("Search result: %v", users)
}
func TestMergeOptions(t *testing.T) {
mapping := `{
"properties": {
"name": {
"type": "text"
},
"age": {
"type": "integer"
}
}
}`
settings := `{
"index": {
"number_of_shards": 1,
"number_of_replicas": 0
}
}`
//expected := `{"mappings":{"properties":{"name":{"type":"text"},"age":{"type":"integer"}}},"settings":{"index":{"number_of_shards":1,"number_of_replicas":0}}}`
result, err := MergeOptions(mapping, settings)
assert.Nil(t, err)
//assert.Equal(t, expected, result)
t.Log(result)
}
func TestParseQueryString(t *testing.T) {
// 测试单个键值对的查询字符串
query := `{"name":"张三"}`
result := ParseQueryString(query)
assert.NotNil(t, result)
assert.Equal(t, []string{"name:张三"}, result)
// 测试多个键值对的查询字符串
query = `[{"name":"张三"},{"age":"23"}]`
result = ParseQueryString(query)
assert.NotNil(t, result)
assert.Equal(t, []string{"name:张三", "age:23"}, result)
t.Log(strings.Join(result, " AND "))
// 测试无效的查询字符串
query = `invalid`
result = ParseQueryString(query)
assert.Nil(t, result)
}
func TestMakeQueryString(t *testing.T) {
// 测试 AND 查询
andQuery := `{"name":"张三","age":"23"}`
orQuery := ``
result := MakeQueryString(andQuery, orQuery)
assert.Equal(t, "name:张三 AND age:23", result)
// 测试 OR 查询
andQuery = ``
orQuery = `[{"city":"北京"},{"country":"中国"}]`
result = MakeQueryString(andQuery, orQuery)
assert.Equal(t, "city:北京 OR country:中国", result)
// 测试 AND 和 OR 查询同时存在
andQuery = `{"name":"张三"}`
orQuery = `[{"city":"北京"},{"country":"中国"}]`
result = MakeQueryString(andQuery, orQuery)
assert.Equal(t, "name:张三 AND (city:北京 OR country:中国)", result)
// 测试空查询
andQuery = ``
orQuery = ``
result = MakeQueryString(andQuery, orQuery)
assert.Equal(t, "", result)
}

View File

@@ -0,0 +1,38 @@
package elasticsearch
import "github.com/go-kratos/kratos/v2/errors"
var (
// ErrRequestFailed is returned when a request to Elasticsearch fails.
ErrRequestFailed = errors.InternalServer("REQUEST_FAILED", "request failed")
// ErrIndexNotFound is returned when the specified index does not exist.
ErrIndexNotFound = errors.InternalServer("INDEX_NOT_FOUND", "index not found")
// ErrIndexAlreadyExists is returned when trying to create an index that already exists.
ErrIndexAlreadyExists = errors.InternalServer("INDEX_ALREADY_EXISTS", "index already exists")
ErrCreateIndex = errors.InternalServer("CREATE_INDEX_FAILED", "failed to create index")
ErrDeleteIndex = errors.InternalServer("DELETE_INDEX_FAILED", "failed to delete index")
// ErrDocumentNotFound is returned when a document is not found in the index.
ErrDocumentNotFound = errors.InternalServer("DOCUMENT_NOT_FOUND", "document not found")
// ErrDocumentAlreadyExists is returned when trying to create a document that already exists.
ErrDocumentAlreadyExists = errors.InternalServer("DOCUMENT_ALREADY_EXISTS", "document already exists")
// ErrInvalidQuery is returned when the query provided to Elasticsearch is invalid.
ErrInvalidQuery = errors.InternalServer("INVALID_QUERY", "invalid query")
// ErrUnmarshalResponse is returned when the response from Elasticsearch cannot be unmarshalled.
ErrUnmarshalResponse = errors.InternalServer("UNMARSHAL_RESPONSE_FAILED", "failed to unmarshal response")
ErrInsertDocument = errors.InternalServer("INSERT_DOCUMENT_FAILED", "failed to insert document")
ErrBatchInsertDocument = errors.InternalServer("BATCH_INSERT_DOCUMENT_FAILED", "failed to batch insert documents")
ErrGetDocument = errors.InternalServer("GET_DOCUMENT_FAILED", "failed to get document")
ErrSearchDocument = errors.InternalServer("SEARCH_DOCUMENT_FAILED", "failed to search document")
)

View File

@@ -0,0 +1,36 @@
module github.com/tx7do/kratos-bootstrap/database/elasticsearch
go 1.23.0
toolchain go1.23.3
replace github.com/tx7do/kratos-bootstrap/api => ../../api
require (
github.com/elastic/go-elasticsearch/v9 v9.0.0
github.com/go-kratos/kratos/v2 v2.8.4
github.com/stretchr/testify v1.10.0
github.com/tx7do/kratos-bootstrap/api v0.0.27
)
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/elastic/elastic-transport-go/v8 v8.7.0 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/google/gnostic v0.7.0 // indirect
github.com/google/gnostic-models v0.7.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/otel v1.37.0 // indirect
go.opentelemetry.io/otel/metric v1.37.0 // indirect
go.opentelemetry.io/otel/trace v1.37.0 // indirect
go.yaml.in/yaml/v3 v3.0.3 // indirect
golang.org/x/net v0.40.0 // indirect
golang.org/x/sync v0.14.0 // indirect
golang.org/x/sys v0.33.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect
google.golang.org/grpc v1.73.0 // indirect
google.golang.org/protobuf v1.36.6 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,38 @@
package elasticsearch
import "encoding/json"
// ErrorResponse 表示 Elasticsearch 错误响应的结构
type ErrorResponse struct {
Error struct {
RootCause []struct {
Type string `json:"type"`
Reason string `json:"reason"`
} `json:"root_cause"`
Type string `json:"type"`
Reason string `json:"reason"`
CausedBy struct {
Type string `json:"type"`
Reason string `json:"reason"`
} `json:"caused_by,omitempty"`
} `json:"error"`
Status int `json:"status"`
}
type SearchResult struct {
Took int `json:"took"`
TimedOut bool `json:"timed_out"`
Hits struct {
Total struct {
Value int `json:"value"`
Relation string `json:"relation"`
} `json:"total"`
Hits []struct {
Index string `json:"_index"`
Type string `json:"_type"`
ID string `json:"_id"`
Score float64 `json:"_score"`
Source json.RawMessage `json:"_source"`
} `json:"hits"`
} `json:"hits"`
}

View File

@@ -0,0 +1,111 @@
package elasticsearch
import (
"encoding/json"
"io"
"strings"
"github.com/go-kratos/kratos/v2/encoding"
_ "github.com/go-kratos/kratos/v2/encoding/json"
"github.com/go-kratos/kratos/v2/log"
)
// ParseErrorMessage 解析 Elasticsearch 错误消息
func ParseErrorMessage(body io.ReadCloser) (*ErrorResponse, error) {
defer body.Close()
var errorResponse ErrorResponse
if err := json.NewDecoder(body).Decode(&errorResponse); err != nil {
return nil, ErrUnmarshalResponse
}
return &errorResponse, nil
}
// MergeOptions 合并 Elasticsearch 索引的映射和设置
func MergeOptions(mapping, settings string) (string, error) {
codec := encoding.GetCodec("json")
body := make(map[string]interface{})
if mapping != "" {
var mappingObj map[string]interface{}
if err := codec.Unmarshal([]byte(mapping), &mappingObj); err != nil {
log.Errorf("failed to unmarshal mapping: %v", err)
return "", err
}
if existingMappings, ok := mappingObj["mappings"]; ok {
body["mappings"] = existingMappings
} else {
body["mappings"] = mappingObj
}
}
if settings != "" {
var settingsObj map[string]interface{}
if err := codec.Unmarshal([]byte(settings), &settingsObj); err != nil {
log.Errorf("failed to unmarshal settings: %v", err)
return "", err
}
// 检查 settings 是否包含 settings 字段
if existingSettings, ok := settingsObj["settings"]; ok {
body["settings"] = existingSettings
} else {
body["settings"] = settingsObj
}
}
bodyBytes, err := codec.Marshal(body)
if err != nil {
log.Errorf("failed to marshal request body: %v", err)
return "", err
}
return string(bodyBytes), nil
}
func ParseQueryString(query string) []string {
codec := encoding.GetCodec("json")
var err error
queryMap := make(map[string]string)
if err = codec.Unmarshal([]byte(query), &queryMap); err == nil {
var queries []string
for k, v := range queryMap {
queries = append(queries, k+":"+v)
}
return queries
}
var queryMapArray []map[string]string
if err = codec.Unmarshal([]byte(query), &queryMapArray); err == nil {
var queries []string
for _, item := range queryMapArray {
for k, v := range item {
queries = append(queries, k+":"+v)
}
}
return queries
}
return nil
}
func MakeQueryString(andQuery, orQuery string) string {
a := ParseQueryString(andQuery)
o := ParseQueryString(orQuery)
if len(a) == 0 && len(o) == 0 {
return ""
}
if len(a) > 0 && len(o) == 0 {
return strings.Join(a, " AND ")
} else if len(a) == 0 && len(o) > 0 {
return strings.Join(o, " OR ")
} else if len(a) > 0 && len(o) > 0 {
return strings.Join(a, " AND ") + " AND (" + strings.Join(o, " OR ") + ")"
} else {
return strings.Join(a, " AND ") + " AND " + strings.Join(o, " OR ")
}
}

45
database/ent/client.go Normal file
View File

@@ -0,0 +1,45 @@
package ent
import (
_ "github.com/go-sql-driver/mysql"
_ "github.com/jackc/pgx/v4/stdlib"
_ "github.com/lib/pq"
"github.com/go-kratos/kratos/v2/log"
conf "github.com/tx7do/kratos-bootstrap/api/gen/go/conf/v1"
)
// NewEntClient 创建Ent ORM数据库客户端
func NewEntClient[T ClientInterface](cfg *conf.Bootstrap, l *log.Helper, db T) *ClientWrapper[T] {
if cfg.Data == nil || cfg.Data.Database == nil {
l.Warn("database config is nil")
return nil
}
drv, err := CreateDriver(
cfg.Data.Database.GetDriver(),
cfg.Data.Database.GetSource(),
cfg.Data.Database.GetEnableTrace(),
cfg.Data.Database.GetEnableMetrics(),
)
if err != nil {
l.Fatalf("failed opening connection to db: %v", err)
return nil
}
wrapperClient := NewEntClientWrapper(db, drv)
if cfg.Data.Database.MaxIdleConnections != nil &&
cfg.Data.Database.MaxOpenConnections != nil &&
cfg.Data.Database.ConnectionMaxLifetime != nil {
wrapperClient.SetConnectionOption(
int(cfg.Data.Database.GetMaxIdleConnections()),
int(cfg.Data.Database.GetMaxOpenConnections()),
cfg.Data.Database.GetConnectionMaxLifetime().AsDuration(),
)
}
return wrapperClient
}

View File

@@ -0,0 +1,119 @@
package ent
import (
"context"
"database/sql"
"errors"
"fmt"
"time"
"go.opentelemetry.io/otel/attribute"
semconv "go.opentelemetry.io/otel/semconv/v1.10.0"
"github.com/XSAM/otelsql"
entSql "entgo.io/ent/dialect/sql"
)
type ClientInterface interface {
Close() error
}
type ClientWrapper[T ClientInterface] struct {
db T
drv *entSql.Driver
}
func NewEntClientWrapper[T ClientInterface](db T, drv *entSql.Driver) *ClientWrapper[T] {
return &ClientWrapper[T]{
db: db,
drv: drv,
}
}
func (c *ClientWrapper[T]) Client() T {
return c.db
}
func (c *ClientWrapper[T]) Driver() *entSql.Driver {
return c.drv
}
func (c *ClientWrapper[T]) DB() *sql.DB {
return c.drv.DB()
}
// Close 关闭数据库连接
func (c *ClientWrapper[T]) Close() error {
return c.db.Close()
}
// Query 查询数据
func (c *ClientWrapper[T]) Query(ctx context.Context, query string, args, v any) error {
return c.Driver().Query(ctx, query, args, v)
}
func (c *ClientWrapper[T]) Exec(ctx context.Context, query string, args, v any) error {
return c.Driver().Exec(ctx, query, args, v)
}
// SetConnectionOption 设置连接配置
func (c *ClientWrapper[T]) SetConnectionOption(maxIdleConnections, maxOpenConnections int, connMaxLifetime time.Duration) {
// 连接池中最多保留的空闲连接数量
c.DB().SetMaxIdleConns(maxIdleConnections)
// 连接池在同一时间打开连接的最大数量
c.DB().SetMaxOpenConns(maxOpenConnections)
// 连接可重用的最大时间长度
c.DB().SetConnMaxLifetime(connMaxLifetime)
}
func driverNameToSemConvKeyValue(driverName string) attribute.KeyValue {
switch driverName {
case "mariadb":
return semconv.DBSystemMariaDB
case "mysql":
return semconv.DBSystemMySQL
case "postgresql":
return semconv.DBSystemPostgreSQL
case "sqlite":
return semconv.DBSystemSqlite
default:
return semconv.DBSystemKey.String(driverName)
}
}
// CreateDriver 创建数据库驱动
func CreateDriver(driverName, dsn string, enableTrace, enableMetrics bool) (*entSql.Driver, error) {
var db *sql.DB
var drv *entSql.Driver
var err error
if enableTrace {
// Connect to database
if db, err = otelsql.Open(driverName, dsn, otelsql.WithAttributes(
driverNameToSemConvKeyValue(driverName),
)); err != nil {
return nil, errors.New(fmt.Sprintf("failed opening connection to db: %v", err))
}
drv = entSql.OpenDB(driverName, db)
} else {
if drv, err = entSql.Open(driverName, dsn); err != nil {
return nil, errors.New(fmt.Sprintf("failed opening connection to db: %v", err))
}
db = drv.DB()
}
// Register DB stats to meter
if enableMetrics {
err = otelsql.RegisterDBStatsMetrics(db, otelsql.WithAttributes(
driverNameToSemConvKeyValue(driverName),
))
if err != nil {
return nil, errors.New(fmt.Sprintf("failed register otel meter: %v", err))
}
}
return drv, nil
}

40
database/ent/go.mod Normal file
View File

@@ -0,0 +1,40 @@
module github.com/tx7do/kratos-bootstrap/database/ent
go 1.23.0
toolchain go1.23.3
replace github.com/tx7do/kratos-bootstrap/api => ../../api
require (
entgo.io/ent v0.14.4
github.com/XSAM/otelsql v0.38.0
github.com/go-kratos/kratos/v2 v2.8.4
github.com/go-sql-driver/mysql v1.9.2
github.com/jackc/pgx/v4 v4.18.3
github.com/lib/pq v1.10.9
github.com/tx7do/kratos-bootstrap/api v0.0.21
go.opentelemetry.io/otel v1.36.0
)
require (
filippo.io/edwards25519 v1.1.0 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
github.com/jackc/pgconn v1.14.3 // indirect
github.com/jackc/pgio v1.0.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgproto3/v2 v2.3.3 // indirect
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
github.com/jackc/pgtype v1.14.4 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/shopspring/decimal v1.4.0 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/otel/metric v1.36.0 // indirect
go.opentelemetry.io/otel/trace v1.36.0 // indirect
golang.org/x/crypto v0.38.0 // indirect
golang.org/x/text v0.25.0 // indirect
google.golang.org/protobuf v1.36.6 // indirect
)

259
database/ent/go.sum Normal file
View File

@@ -0,0 +1,259 @@
entgo.io/ent v0.14.4 h1:/DhDraSLXIkBhyiVoJeSshr4ZYi7femzhj6/TckzZuI=
entgo.io/ent v0.14.4/go.mod h1:aDPE/OziPEu8+OWbzy4UlvWmD2/kbRuWfK2A40hcxJM=
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
github.com/XSAM/otelsql v0.38.0 h1:zWU0/YM9cJhPE71zJcQ2EBHwQDp+G4AX2tPpljslaB8=
github.com/XSAM/otelsql v0.38.0/go.mod h1:5ePOgcLEkWvZtN9H3GV4BUlPeM3p3pzLDCnRG73X8h8=
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
github.com/go-kratos/kratos/v2 v2.8.4 h1:eIJLE9Qq9WSoKx+Buy2uPyrahtF/lPh+Xf4MTpxhmjs=
github.com/go-kratos/kratos/v2 v2.8.4/go.mod h1:mq62W2101a5uYyRxe+7IdWubu7gZCGYqSNKwGFiiRcw=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-sql-driver/mysql v1.9.2 h1:4cNKDYQ1I84SXslGddlsrMhc8k4LeDVj6Ad6WRjiHuU=
github.com/go-sql-driver/mysql v1.9.2/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw=
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8=
github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA=
github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE=
github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s=
github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o=
github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY=
github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI=
github.com/jackc/pgconn v1.14.3 h1:bVoTr12EGANZz66nZPkMInAV/KHD2TxH9npjXXgiB3w=
github.com/jackc/pgconn v1.14.3/go.mod h1:RZbme4uasqzybK2RK5c65VsHxoyaml09lx3tXOcO/VM=
github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=
github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8=
github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE=
github.com/jackc/pgmock v0.0.0-20201204152224-4fe30f7445fd/go.mod h1:hrBW0Enj2AZTNpt/7Y5rr2xe/9Mn757Wtb2xeBzPv2c=
github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65 h1:DadwsjnMwFjfWc9y5Wi/+Zz7xoE5ALHsRQlOctkOiHc=
github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65/go.mod h1:5R2h2EEX+qri8jOWMbJCtaPWkrrNc7OHwsp2TCqp7ak=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78=
github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA=
github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg=
github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
github.com/jackc/pgproto3/v2 v2.3.3 h1:1HLSx5H+tXR9pW3in3zaztoEwQYRC9SQaYUHjTSUOag=
github.com/jackc/pgproto3/v2 v2.3.3/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg=
github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc=
github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw=
github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM=
github.com/jackc/pgtype v1.14.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4=
github.com/jackc/pgtype v1.14.4 h1:fKuNiCumbKTAIxQwXfB/nsrnkEI6bPJrrSiMKgbJ2j8=
github.com/jackc/pgtype v1.14.4/go.mod h1:aKeozOde08iifGosdJpz9MBZonJOUJxqNpPBcMJTlVA=
github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y=
github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM=
github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc=
github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs=
github.com/jackc/pgx/v4 v4.18.2/go.mod h1:Ey4Oru5tH5sB6tV7hDmfWFahwF15Eb7DNXlRKx2CkVw=
github.com/jackc/pgx/v4 v4.18.3 h1:dE2/TrEsGX3RBprb3qryqSV9Y60iZN1C6i8IrmW9/BA=
github.com/jackc/pgx/v4 v4.18.3/go.mod h1:Ey4Oru5tH5sB6tV7hDmfWFahwF15Eb7DNXlRKx2CkVw=
github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg=
go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E=
go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE=
go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs=
go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY=
go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg=
go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o=
go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w=
go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w=
go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ=
golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8=
golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ=
golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=
golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=

102
database/gorm/client.go Normal file
View File

@@ -0,0 +1,102 @@
package gorm
import (
"gorm.io/driver/bigquery"
"gorm.io/driver/clickhouse"
"gorm.io/driver/mysql"
"gorm.io/driver/postgres"
"gorm.io/driver/sqlite"
"gorm.io/driver/sqlserver"
"gorm.io/plugin/opentelemetry/tracing"
"gorm.io/plugin/prometheus"
"gorm.io/gorm"
"github.com/go-kratos/kratos/v2/log"
conf "github.com/tx7do/kratos-bootstrap/api/gen/go/conf/v1"
)
// NewGormClient 创建GORM数据库客户端
func NewGormClient(cfg *conf.Bootstrap, l *log.Helper, migrates []interface{}) *gorm.DB {
if cfg.Data == nil || cfg.Data.Database == nil {
l.Warn("database config is nil")
return nil
}
var driver gorm.Dialector
switch cfg.Data.Database.Driver {
default:
fallthrough
case "mysql":
driver = mysql.Open(cfg.Data.Database.Source)
break
case "postgres":
driver = postgres.Open(cfg.Data.Database.Source)
break
case "clickhouse":
driver = clickhouse.Open(cfg.Data.Database.Source)
break
case "sqlite":
driver = sqlite.Open(cfg.Data.Database.Source)
break
case "sqlserver":
driver = sqlserver.Open(cfg.Data.Database.Source)
break
case "bigquery":
driver = bigquery.Open(cfg.Data.Database.Source)
break
}
db, err := gorm.Open(driver, &gorm.Config{})
if err != nil {
l.Fatalf("failed opening connection to db: %v", err)
return nil
}
// 运行数据库迁移工具
if cfg.Data.Database.Migrate {
if err = db.AutoMigrate(
migrates...,
); err != nil {
l.Fatalf("failed creating schema resources: %v", err)
return nil
}
}
if cfg.Data.Database.GetEnableTrace() {
if err = db.Use(tracing.NewPlugin()); err != nil {
l.Fatalf("failed enable trace: %v", err)
return nil
}
}
if cfg.Data.Database.GetEnableMetrics() {
if err = db.Use(prometheus.New(prometheus.Config{
RefreshInterval: 15, // refresh metrics interval (default 15 seconds)
StartServer: true, // start http server to expose metrics
DBName: cfg.Data.Database.GetPrometheusDbName(), // `DBName` as metrics label
PushAddr: cfg.Data.Database.GetPrometheusPushAddr(), // push metrics if `PushAddr` configured
HTTPServerPort: cfg.Data.Database.GetPrometheusHttpPort(), // configure http server port, default port 8080 (if you have configured multiple instances, only the first `HTTPServerPort` will be used to start server)
})); err != nil {
l.Fatalf("failed enable metrics: %v", err)
return nil
}
}
sqlDB, err := db.DB()
if sqlDB != nil {
if cfg.Data.Database.MaxIdleConnections != nil {
sqlDB.SetMaxIdleConns(int(cfg.Data.Database.GetMaxIdleConnections()))
}
if cfg.Data.Database.MaxOpenConnections != nil {
sqlDB.SetMaxOpenConns(int(cfg.Data.Database.GetMaxOpenConnections()))
}
if cfg.Data.Database.ConnectionMaxLifetime != nil {
sqlDB.SetConnMaxLifetime(cfg.Data.Database.GetConnectionMaxLifetime().AsDuration())
}
}
return db
}

97
database/gorm/go.mod Normal file
View File

@@ -0,0 +1,97 @@
module github.com/tx7do/kratos-bootstrap/database/gorm
go 1.23.0
toolchain go1.23.3
replace github.com/tx7do/kratos-bootstrap/api => ../../api
require (
github.com/go-kratos/kratos/v2 v2.8.4
github.com/tx7do/kratos-bootstrap/api v0.0.21
gorm.io/driver/bigquery v1.2.0
gorm.io/driver/clickhouse v0.7.0
gorm.io/driver/mysql v1.5.7
gorm.io/driver/postgres v1.6.0
gorm.io/driver/sqlite v1.5.7
gorm.io/driver/sqlserver v1.6.0
gorm.io/gorm v1.30.0
gorm.io/plugin/opentelemetry v0.1.14
gorm.io/plugin/prometheus v0.1.0
)
require (
cloud.google.com/go v0.121.2 // indirect
cloud.google.com/go/auth v0.16.1 // indirect
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
cloud.google.com/go/bigquery v1.69.0 // indirect
cloud.google.com/go/compute/metadata v0.7.0 // indirect
cloud.google.com/go/iam v1.5.2 // indirect
filippo.io/edwards25519 v1.1.0 // indirect
github.com/ClickHouse/ch-go v0.66.0 // indirect
github.com/ClickHouse/clickhouse-go/v2 v2.35.0 // indirect
github.com/andybalholm/brotli v1.1.1 // indirect
github.com/apache/arrow/go/v15 v15.0.2 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/go-faster/city v1.0.1 // indirect
github.com/go-faster/errors v0.7.1 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-sql-driver/mysql v1.9.2 // indirect
github.com/goccy/go-json v0.10.5 // indirect
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect
github.com/golang-sql/sqlexp v0.1.0 // indirect
github.com/google/flatbuffers v25.2.10+incompatible // indirect
github.com/google/s2a-go v0.1.9 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
github.com/googleapis/gax-go/v2 v2.14.2 // indirect
github.com/hashicorp/go-version v1.7.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
github.com/jackc/pgx/v5 v5.7.5 // indirect
github.com/jackc/puddle/v2 v2.2.2 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/klauspost/compress v1.18.0 // indirect
github.com/klauspost/cpuid/v2 v2.2.10 // indirect
github.com/mattn/go-sqlite3 v1.14.28 // indirect
github.com/microsoft/go-mssqldb v1.8.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/paulmach/orb v0.11.1 // indirect
github.com/pierrec/lz4/v4 v4.1.22 // indirect
github.com/prometheus/client_golang v1.22.0 // indirect
github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.64.0 // indirect
github.com/prometheus/procfs v0.16.1 // indirect
github.com/segmentio/asm v1.2.0 // indirect
github.com/shopspring/decimal v1.4.0 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/zeebo/xxh3 v1.0.2 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect
go.opentelemetry.io/otel v1.36.0 // indirect
go.opentelemetry.io/otel/metric v1.36.0 // indirect
go.opentelemetry.io/otel/trace v1.36.0 // indirect
golang.org/x/crypto v0.38.0 // indirect
golang.org/x/exp v0.0.0-20250531010427-b6e5de432a8b // indirect
golang.org/x/mod v0.24.0 // indirect
golang.org/x/net v0.40.0 // indirect
golang.org/x/oauth2 v0.30.0 // indirect
golang.org/x/sync v0.14.0 // indirect
golang.org/x/sys v0.33.0 // indirect
golang.org/x/text v0.25.0 // indirect
golang.org/x/time v0.11.0 // indirect
golang.org/x/tools v0.33.0 // indirect
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect
google.golang.org/api v0.235.0 // indirect
google.golang.org/genproto v0.0.0-20250528174236-200df99c418a // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250528174236-200df99c418a // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a // indirect
google.golang.org/grpc v1.72.2 // indirect
google.golang.org/protobuf v1.36.6 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

1281
database/gorm/go.sum Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,56 @@
# InfluxDB
### Docker部署
pull image
```bash
docker pull bitnami/influxdb:latest
```
#### 2.x
```bash
docker run -itd \
--name influxdb2-server \
-p 8086:8086 \
-e INFLUXDB_HTTP_AUTH_ENABLED=true \
-e INFLUXDB_ADMIN_USER=admin \
-e INFLUXDB_ADMIN_USER_PASSWORD=123456789 \
-e INFLUXDB_ADMIN_USER_TOKEN=admintoken123 \
-e INFLUXDB_DB=my_database \
bitnami/influxdb:2.7.11
```
create admin user sql script:
```sql
create user "admin" with password '123456789' with all privileges
```
管理后台: <http://localhost:8086/>
#### 3.x
```bash
docker run -itd \
--name influxdb3-server \
-p 8181:8181 \
-e INFLUXDB_NODE_ID=0 \
-e INFLUXDB_HTTP_PORT_NUMBER=8181 \
-e INFLUXDB_HTTP_AUTH_ENABLED=true \
-e INFLUXDB_CREATE_ADMIN_TOKEN=yes \
-e INFLUXDB_DB=my_database \
bitnami/influxdb:latest
docker run -itd \
--name influxdb3-explorer \
-p 8888:80 \
-p 8889:8888 \
quay.io/influxdb/influxdb3-explorer:latest \
--mode=admin
```
这个版本分离出来一个管理后台 InfluxDB Explorer<http://localhost:8888/>
在管理后台填写:`http://host.docker.internal:8181`

144
database/influxdb/client.go Normal file
View File

@@ -0,0 +1,144 @@
package influxdb
import (
"context"
"github.com/InfluxCommunity/influxdb3-go/v2/influxdb3"
"github.com/go-kratos/kratos/v2/log"
conf "github.com/tx7do/kratos-bootstrap/api/gen/go/conf/v1"
)
type Client struct {
cli *influxdb3.Client
log *log.Helper
}
func NewClient(logger log.Logger, cfg *conf.Bootstrap) (*Client, error) {
c := &Client{
log: log.NewHelper(log.With(logger, "module", "influxdb-client")),
}
if err := c.createInfluxdbClient(cfg); err != nil {
return nil, err
}
return c, nil
}
// createInfluxdbClient 创建InfluxDB客户端
func (c *Client) createInfluxdbClient(cfg *conf.Bootstrap) error {
if cfg.Data == nil || cfg.Data.Influxdb == nil {
return nil
}
client, err := influxdb3.New(influxdb3.ClientConfig{
Host: cfg.Data.Influxdb.GetHost(),
Token: cfg.Data.Influxdb.GetToken(),
Database: cfg.Data.Influxdb.GetDatabase(),
Organization: cfg.Data.Influxdb.GetOrganization(),
})
if err != nil {
c.log.Errorf("failed to create influxdb client: %v", err)
return err
}
c.cli = client
return nil
}
// Close 关闭InfluxDB客户端
func (c *Client) Close() {
if c.cli == nil {
c.log.Warn("influxdb client is nil, nothing to close")
return
}
if err := c.cli.Close(); err != nil {
c.log.Errorf("failed to close influxdb client: %v", err)
} else {
c.log.Info("influxdb client closed successfully")
}
}
// Query 查询数据
func (c *Client) Query(ctx context.Context, query string) (*influxdb3.QueryIterator, error) {
if c.cli == nil {
return nil, ErrInfluxDBClientNotInitialized
}
result, err := c.cli.Query(
ctx,
query,
influxdb3.WithQueryType(influxdb3.InfluxQL),
)
if err != nil {
c.log.Errorf("failed to query data: %v", err)
return nil, ErrInfluxDBQueryFailed
}
return result, nil
}
func (c *Client) QueryWithParams(
ctx context.Context,
table string,
filters map[string]interface{},
operators map[string]string,
fields []string,
) (*influxdb3.QueryIterator, error) {
if c.cli == nil {
return nil, ErrInfluxDBClientNotInitialized
}
query := BuildQueryWithParams(table, filters, operators, fields)
result, err := c.cli.Query(
ctx,
query,
influxdb3.WithQueryType(influxdb3.InfluxQL),
)
if err != nil {
c.log.Errorf("failed to query data: %v", err)
return nil, ErrInfluxDBQueryFailed
}
return result, nil
}
// Insert 插入数据
func (c *Client) Insert(ctx context.Context, point *influxdb3.Point) error {
if c.cli == nil {
return ErrInfluxDBClientNotInitialized
}
if point == nil {
return ErrInvalidPoint
}
points := []*influxdb3.Point{point}
if err := c.cli.WritePoints(ctx, points); err != nil {
c.log.Errorf("failed to insert data: %v", err)
return ErrInsertFailed
}
return nil
}
// BatchInsert 批量插入数据
func (c *Client) BatchInsert(ctx context.Context, points []*influxdb3.Point) error {
if c.cli == nil {
return ErrInfluxDBClientNotInitialized
}
if len(points) == 0 {
return ErrNoPointsToInsert
}
if err := c.cli.WritePoints(ctx, points); err != nil {
c.log.Errorf("failed to batch insert data: %v", err)
return ErrBatchInsertFailed
}
return nil
}

View File

@@ -0,0 +1,211 @@
package influxdb
import (
"context"
"testing"
"time"
"github.com/InfluxCommunity/influxdb3-go/v2/influxdb3"
"github.com/go-kratos/kratos/v2/log"
"github.com/stretchr/testify/assert"
"github.com/tx7do/go-utils/trans"
conf "github.com/tx7do/kratos-bootstrap/api/gen/go/conf/v1"
"google.golang.org/protobuf/types/known/timestamppb"
)
type Candle struct {
Symbol *string
Open *float64
High *float64
Low *float64
Close *float64
Volume *float64
StartTime *timestamppb.Timestamp
}
func (c *Candle) GetSymbol() string {
if c.Symbol != nil {
return *c.Symbol
}
return ""
}
func (c *Candle) GetOpen() float64 {
if c.Open != nil {
return *c.Open
}
return 0.0
}
func (c *Candle) GetHigh() float64 {
if c.High != nil {
return *c.High
}
return 0.0
}
func (c *Candle) GetLow() float64 {
if c.Low != nil {
return *c.Low
}
return 0.0
}
func (c *Candle) GetClose() float64 {
if c.Close != nil {
return *c.Close
}
return 0.0
}
func (c *Candle) GetVolume() float64 {
if c.Volume != nil {
return *c.Volume
}
return 0.0
}
func (c *Candle) GetStartTime() *timestamppb.Timestamp {
if c.StartTime != nil {
return c.StartTime
}
return timestamppb.Now()
}
type CandleMapper struct{}
var candleMapper CandleMapper
func (m *CandleMapper) ToPoint(data *Candle) *influxdb3.Point {
p := influxdb3.NewPoint(
"candles",
map[string]string{"s": data.GetSymbol()},
nil,
data.StartTime.AsTime(),
)
p.
SetDoubleField("o", data.GetOpen()).
SetDoubleField("h", data.GetHigh()).
SetDoubleField("l", data.GetLow()).
SetDoubleField("c", data.GetClose()).
SetDoubleField("v", data.GetVolume())
return p
}
func (m *CandleMapper) ToData(point *influxdb3.Point) *Candle {
symbol, _ := point.GetTag("s")
return &Candle{
Symbol: &symbol,
Open: point.GetDoubleField("o"),
High: point.GetDoubleField("h"),
Low: point.GetDoubleField("l"),
Close: point.GetDoubleField("c"),
Volume: point.GetDoubleField("v"),
StartTime: timestamppb.New(point.Values.Timestamp),
}
}
func createTestClient() *Client {
cli, _ := NewClient(
log.DefaultLogger,
&conf.Bootstrap{
Data: &conf.Data{
Influxdb: &conf.Data_InfluxDB{
Host: "http://localhost:8181",
Token: "apiv3_yYde4mJo0BYC7Ipi_00ZEex-A8if4swdqTBXiO-lCUDKhsIavHlRCQfo3p_DzI7S34ADHOC7Qxf600VVgW6LQQ",
Database: "finances",
Organization: "primary",
},
},
},
)
return cli
}
func TestNewClient(t *testing.T) {
client := createTestClient()
assert.NotNil(t, client)
}
func TestClient_Insert(t *testing.T) {
client := createTestClient()
assert.NotNil(t, client)
item := &Candle{
StartTime: timestamppb.New(time.Now()),
Symbol: trans.Ptr("AAPL"),
Open: trans.Ptr(1.0),
High: trans.Ptr(2.0),
Low: trans.Ptr(3.0),
Close: trans.Ptr(4.0),
Volume: trans.Ptr(1000.0),
}
point := candleMapper.ToPoint(item)
err := client.Insert(context.Background(), point)
assert.NoError(t, err)
}
func TestClient_BatchInsert(t *testing.T) {
client := createTestClient()
assert.NotNil(t, client)
items := []*Candle{
{
StartTime: timestamppb.New(time.Now()),
Symbol: trans.Ptr("AAPL"),
Open: trans.Ptr(1.0),
High: trans.Ptr(2.0),
Low: trans.Ptr(3.0),
Close: trans.Ptr(4.0),
Volume: trans.Ptr(1000.0),
},
}
var points []*influxdb3.Point
for _, item := range items {
point := candleMapper.ToPoint(item)
points = append(points, point)
}
err := client.BatchInsert(
context.Background(),
points,
)
assert.NoError(t, err)
}
func TestClient_Query(t *testing.T) {
client := createTestClient()
assert.NotNil(t, client)
ctx := context.Background()
sql := `SELECT * FROM candles`
iterator, err := client.Query(ctx, sql)
assert.NoError(t, err)
for iterator.Next() {
point, _ := iterator.AsPoints().AsPoint()
candle := candleMapper.ToData(point)
t.Logf("[%v] Candle: %s, Open: %f, High: %f, Low: %f, Close: %f, Volume: %f\n",
candle.GetStartTime().AsTime().String(),
candle.GetSymbol(),
candle.GetOpen(), candle.GetHigh(), candle.GetLow(), candle.GetClose(), candle.GetVolume(),
)
}
candles, err := Query(ctx, client, sql, &candleMapper)
assert.NoError(t, err)
for _, candle := range candles {
t.Logf("Candle: %s, Open: %f, High: %f, Low: %f, Close: %f, Volume: %f\n",
candle.GetSymbol(),
candle.GetOpen(), candle.GetHigh(), candle.GetLow(), candle.GetClose(), candle.GetVolume(),
)
}
}

View File

@@ -0,0 +1,25 @@
package influxdb
import "github.com/go-kratos/kratos/v2/errors"
var (
ErrInfluxDBClientNotInitialized = errors.InternalServer("INFLUXDB_CLIENT_NOT_INITIALIZED", "client not initialized")
ErrInfluxDBConnectFailed = errors.InternalServer("INFLUXDB_CONNECT_FAILED", "connect failed")
ErrInfluxDBCreateDatabaseFailed = errors.InternalServer("INFLUXDB_CREATE_DATABASE_FAILED", "database create failed")
ErrInfluxDBQueryFailed = errors.InternalServer("INFLUXDB_QUERY_FAILED", "query failed")
ErrClientNotConnected = errors.InternalServer("INFLUXDB_CLIENT_NOT_CONNECTED", "client not connected")
ErrInvalidPoint = errors.InternalServer("INFLUXDB_INVALID_POINT", "invalid point")
ErrNoPointsToInsert = errors.InternalServer("INFLUXDB_NO_POINTS_TO_INSERT", "no points to insert")
ErrEmptyData = errors.InternalServer("INFLUXDB_EMPTY_DATA", "empty data")
ErrBatchInsertFailed = errors.InternalServer("INFLUXDB_BATCH_INSERT_FAILED", "batch insert failed")
ErrInsertFailed = errors.InternalServer("INFLUXDB_INSERT_FAILED", "insert failed")
)

42
database/influxdb/go.mod Normal file
View File

@@ -0,0 +1,42 @@
module github.com/tx7do/kratos-bootstrap/database/influxdb
go 1.23.10
toolchain go1.24.4
replace github.com/tx7do/kratos-bootstrap/api => ../../api
require (
github.com/InfluxCommunity/influxdb3-go/v2 v2.8.0
github.com/go-kratos/kratos/v2 v2.8.4
github.com/stretchr/testify v1.10.0
github.com/tx7do/go-utils v1.1.29
github.com/tx7do/kratos-bootstrap/api v0.0.27
google.golang.org/protobuf v1.36.6
)
require (
github.com/apache/arrow-go/v18 v18.3.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/frankban/quicktest v1.14.0 // indirect
github.com/goccy/go-json v0.10.5 // indirect
github.com/google/flatbuffers v25.2.10+incompatible // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/influxdata/line-protocol/v2 v2.2.1 // indirect
github.com/klauspost/compress v1.18.0 // indirect
github.com/klauspost/cpuid/v2 v2.2.11 // indirect
github.com/pierrec/lz4/v4 v4.1.22 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/zeebo/xxh3 v1.0.2 // indirect
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b // indirect
golang.org/x/mod v0.25.0 // indirect
golang.org/x/net v0.41.0 // indirect
golang.org/x/sync v0.15.0 // indirect
golang.org/x/sys v0.33.0 // indirect
golang.org/x/text v0.26.0 // indirect
golang.org/x/tools v0.34.0 // indirect
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect
google.golang.org/grpc v1.73.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

Some files were not shown because too many files have changed in this diff Show More