diff --git a/config/nebula_config.go b/config/nebula_config.go new file mode 100644 index 0000000..acf41dd --- /dev/null +++ b/config/nebula_config.go @@ -0,0 +1,21 @@ +package config + +import ( + "fmt" + + "github.com/glory-go/glory/tools" +) + +type NebulaConfig struct { + ConfigSource string `yaml:"config_source"` + Host string `yaml:"host"` + Port string `yaml:"port"` + Username string `yaml:"username"` + Password string `yaml:"password"` +} + +func (s *NebulaConfig) checkAndFix() { + if err := tools.ReadFromEnvIfNeed(s); err != nil { + fmt.Println("warn: NebulaConfig checkAndFix failed with err = ", err) + } +} diff --git a/config/server_config.go b/config/server_config.go index 6adf582..7e2d8e5 100644 --- a/config/server_config.go +++ b/config/server_config.go @@ -21,6 +21,8 @@ type ServerConfig struct { RegistryConfig map[string]*RegistryConfig `yaml:"registry"` // MysqlConfigs Mysql 数据库配置 MysqlConfigs map[string]*MysqlConfig `yaml:"mysql"` + // NebulaConfigs Nebula Graph 数据库配置 + NebulaConfigs map[string]*NebulaConfig `yaml:"nebula"` // RedisConfig redis 配置 RedisConfig map[string]*RedisConfig `yaml:"redis"` // K8SConfig K8s配置 @@ -101,7 +103,7 @@ func (s *ServerConfig) checkAndFix() { } } if s.OrgName == "" { - panic("please add your service org_name in config file from: classroom|ide|children|goonline") + panic("please add your service org_name in config file like: classroom|ide|children|goonline") } if s.ServerName == "" { diff --git a/go.mod b/go.mod index c53d9f5..368eb98 100644 --- a/go.mod +++ b/go.mod @@ -41,6 +41,7 @@ require ( github.com/uber/jaeger-lib v2.4.0+incompatible // indirect github.com/urfave/negroni v1.0.0 github.com/valyala/fasthttp v1.24.0 // indirect + github.com/vesoft-inc/nebula-go/v2 v2.6.0 go.mongodb.org/mongo-driver v1.4.4 go.uber.org/atomic v1.9.0 go.uber.org/multierr v1.7.0 // indirect diff --git a/go.sum b/go.sum index 02fe544..98125b2 100644 --- a/go.sum +++ b/go.sum @@ -162,6 +162,8 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/facebook/fbthrift v0.31.1-0.20210223140454-614a73a42488 h1:A4KCT0mvTBkvb93gGN+efLPkrgTqmqMeaLDG51KVhMM= +github.com/facebook/fbthrift v0.31.1-0.20210223140454-614a73a42488/go.mod h1:2tncLx5rmw69e5kMBv/yJneERbzrr1yr5fdlnTbu8lU= github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A= github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg= github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 h1:Ghm4eQYC0nEPnSJdVkTrXpu9KtoVCSo1hg7mtI7G9KU= @@ -671,6 +673,8 @@ github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyC github.com/valyala/fasthttp v1.24.0 h1:AAiG4oLDUArTb7rYf9oO2bkGooOqCaUF6a2u8asBP3I= github.com/valyala/fasthttp v1.24.0/go.mod h1:0mw2RjXGOzxf4NL2jni3gUQ7LfjjUSiG5sskOUUSEpU= github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= +github.com/vesoft-inc/nebula-go/v2 v2.6.0 h1:yS5JH8eNjXtHSZXDRcNihdYaW9FyjOsrpG5iIMkIFBs= +github.com/vesoft-inc/nebula-go/v2 v2.6.0/go.mod h1:fehDUs97/mpmxXi9WezhznX0Dg7hmQRUoOWgDZv9zG0= github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c h1:u40Z8hqBAAQyv+vATcGgV0YCnDjqSL7/q/JyPhhJSPk= github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc h1:n+nNi93yXLkJvKwXNP9d55HC7lGK4H/SRcwB5IaUZLo= diff --git a/mysql/mysql.go b/mysql/mysql.go index 4753158..8a9ef5c 100644 --- a/mysql/mysql.go +++ b/mysql/mysql.go @@ -1,8 +1,6 @@ package mysql import ( - "errors" - "github.com/glory-go/glory/config" "github.com/glory-go/glory/log" ) @@ -35,15 +33,6 @@ func newMysqlHandler() *MysqlHandler { } } -func RegisterModel(mysqlServiceName string, model UserDefinedModel) (*MysqlTable, error) { - service, ok := defaultMysqlHandler.mysqlServices[mysqlServiceName] - if !ok { - log.Error("mysql service name = ", mysqlServiceName, " not setup successful") - return nil, errors.New("mysql service name = " + mysqlServiceName + " not setup successful") - } - return service.registerModel(model) -} - func GetService(mysqlServiceName string) (*MysqlService, bool) { s, ok := defaultMysqlHandler.mysqlServices[mysqlServiceName] return s, ok diff --git a/mysql/mysql_service.go b/mysql/mysql_service.go index 970a1a2..c5ff4a2 100644 --- a/mysql/mysql_service.go +++ b/mysql/mysql_service.go @@ -1,8 +1,6 @@ package mysql import ( - "errors" - "github.com/glory-go/glory/log" "github.com/glory-go/glory/service/middleware/jaeger" "gorm.io/gorm" @@ -13,15 +11,12 @@ import ( // MysqlService 保存单个mysql链接 type MysqlService struct { - DB *gorm.DB - tables map[string]*MysqlTable - conf config.MysqlConfig + DB *gorm.DB + conf config.MysqlConfig } func newMysqlService() *MysqlService { - return &MysqlService{ - tables: make(map[string]*MysqlTable), - } + return &MysqlService{} } func getMysqlLinkStr(conf config.MysqlConfig) string { @@ -53,22 +48,3 @@ func (ms *MysqlService) openDB(conf config.MysqlConfig) error { } return nil } - -func (ms *MysqlService) registerModel(model UserDefinedModel) (*MysqlTable, error) { - table := newMysqlTable(ms.DB) - if err := table.registerModel(model); err != nil { - log.Error("mysql service register model err") - return nil, err - } - - return table, nil -} - -func (ms *MysqlService) GetTable(tableName string) (*MysqlTable, error) { - table, ok := ms.tables[tableName] - if !ok { - log.Error("table name = ", tableName, " not registered") - return nil, errors.New("table name = " + tableName + " not registered") - } - return table, nil -} diff --git a/mysql/mysql_table.go b/mysql/mysql_table.go deleted file mode 100644 index 3fc1008..0000000 --- a/mysql/mysql_table.go +++ /dev/null @@ -1,89 +0,0 @@ -package mysql - -import ( - "gorm.io/gorm" -) - -type UserDefinedModel interface { - TableName() string -} - -// MysqlTable 提供针对mysql数据表的sdk支持 -type MysqlTable struct { - tableName string - tableModel UserDefinedModel - DB *gorm.DB -} - -func newMysqlTable(db *gorm.DB) *MysqlTable { - return &MysqlTable{DB: db} -} - -func (mt *MysqlTable) registerModel(model UserDefinedModel) error { - mt.tableName = model.TableName() - mt.tableModel = model - mt.DB = mt.DB.Model(model) - return nil -} - -// SelectWhere 两个参数: queryStr result -// 调用次函数,相当于针对当前table执行 select * from table where `queryStr`,例如`userId = ?`, args = "1" -// 将结果写入result, result类型只能是注册好的model数组,类型为 &[]UserDefinedModel{} -func (mt *MysqlTable) SelectWhere(queryStr string, result interface{}, args ...interface{}) error { - // todo reflect 检查result类型,只能是 &[]model{} - // TODO 既然被你看到了就由你来完善吧 - - if err := mt.DB.Model(mt.tableModel).Where(queryStr, args).Find(result); err != nil { - return err.Error - } - return nil -} - -// Insert 一个参数 toInsertLines -// 调用次函数,相当于针对当前table,插入toInsertLines 对应的数据 -// toInsertLines类型为 UserDefinedModel -func (mt *MysqlTable) Insert(toInsertLines UserDefinedModel) error { - // todo reflect检查toInserLines类型,是数组则开多次插入 - // TODO 既然被你看到了就由你来完善吧 - - if err := mt.DB.Model(mt.tableModel).Create(toInsertLines); err != nil { - return err.Error - } - return nil -} - -// Update 三个参数:queryStr、 field、target -// 调用此函数,相当于针对queryStr 筛选出的数据条目(例如queryStr = 'userId = ?', args = "1") ,将筛选出的数据条目的field字段替换为target内容 -func (mt *MysqlTable) Update(queryStr, field string, target interface{}, args ...interface{}) error { - // todo reflect检查target 类型,是否与注册好的的field相符 - // TODO 既然被你看到了就由你来完善吧 - - if err := mt.DB.Model(mt.tableModel).Where(queryStr, args).Update(field, target); err != nil { - return err.Error - } - return nil -} - -// Delete 一个参数:toDeleteTarget -// 传入一个UserDefinedModel类型,如果此对象的userId = 1,则删除掉数据库中userId= 1的字段 -func (mt *MysqlTable) Delete(toDeleteTarget UserDefinedModel) error { - // todo reflect检查toDeleteTarget 类型,确保所有字段不为空 - // TODO 既然被你看到了就由你来完善吧 - - if err := mt.DB.Model(mt.tableModel).Delete(toDeleteTarget); err != nil { - return err.Error - } - return nil -} - -// First 两个参数: queryStr、findTarget -// queryStr为筛选用的query,例如`userId = ?`, args = "1", findTarget为 UserDefinedModel 类型指针,为第一个找到的数据。 -func (mt *MysqlTable) First(queryStr string, findTarget UserDefinedModel, args ...interface{}) error { - // todo reflect 检查findTarget类型 确保是注册类型的指针相同 - // TODO 既然被你看到了就由你来完善吧 - - if err := mt.DB.Model(mt.tableModel).Where(queryStr, args).Find(findTarget); err != nil { - return err.Error - } - return nil -} diff --git a/nebula/logger.go b/nebula/logger.go new file mode 100644 index 0000000..d13b827 --- /dev/null +++ b/nebula/logger.go @@ -0,0 +1,29 @@ +package nebula + +import ( + "github.com/glory-go/glory/log" + nebula "github.com/vesoft-inc/nebula-go/v2" +) + +var ( + logger nebula.Logger = &NebulaLogger{} +) + +type NebulaLogger struct { +} + +func (l *NebulaLogger) Info(msg string) { + log.Info(msg) +} + +func (l *NebulaLogger) Warn(msg string) { + log.Warn(msg) +} + +func (l *NebulaLogger) Error(msg string) { + log.Error(msg) +} + +func (l *NebulaLogger) Fatal(msg string) { + log.Error(msg) +} diff --git a/nebula/nebula.go b/nebula/nebula.go new file mode 100644 index 0000000..568065d --- /dev/null +++ b/nebula/nebula.go @@ -0,0 +1,39 @@ +package nebula + +import ( + "github.com/glory-go/glory/config" + "github.com/glory-go/glory/log" +) + +func init() { + defaultMysqlHandler = newNebulaHandler() + defaultMysqlHandler.setup(config.GlobalServerConf.NebulaConfigs) +} + +type NebulaHandler struct { + services map[string]*NebulaService +} + +var defaultMysqlHandler *NebulaHandler + +func (mh *NebulaHandler) setup(conf map[string]*config.NebulaConfig) { + for k, v := range conf { + tempService := newNebulaService() + if err := tempService.openDB(*v); err != nil { + log.Errorf("opendb with key = %s, err = %s", k, err) + continue + } + mh.services[k] = tempService + } +} + +func newNebulaHandler() *NebulaHandler { + return &NebulaHandler{ + services: make(map[string]*NebulaService), + } +} + +func GetService(serviceName string) (*NebulaService, bool) { + s, ok := defaultMysqlHandler.services[serviceName] + return s, ok +} diff --git a/nebula/service.go b/nebula/service.go new file mode 100644 index 0000000..bf86f5a --- /dev/null +++ b/nebula/service.go @@ -0,0 +1,57 @@ +package nebula + +import ( + "strconv" + + "github.com/glory-go/glory/config" + "github.com/glory-go/glory/log" + nebula "github.com/vesoft-inc/nebula-go/v2" +) + +// MysqlService 保存单个mysql链接 +type NebulaService struct { + pool *nebula.ConnectionPool + conf config.NebulaConfig +} + +func newNebulaService() *NebulaService { + return &NebulaService{} +} + +func (ms *NebulaService) loadConfig(conf config.NebulaConfig) error { + ms.conf = conf + return nil +} + +func (ms *NebulaService) openDB(conf config.NebulaConfig) error { + var err error + if err := ms.loadConfig(conf); err != nil { + log.Error("opendb error with err = ", err) + return err + } + if conf.Port == "" { + conf.Port = "9669" + } + port, err := strconv.Atoi(conf.Port) + if err != nil { + log.Errorf("nebula fail to open db when parse port in conf, err: %v", err) + return err + } + ms.pool, err = nebula.NewConnectionPool([]nebula.HostAddress{ + { + Host: conf.Host, + Port: port, + }, + }, nebula.GetDefaultConf(), logger) + if err != nil { + log.Error("open db error ", err, "with db config = ", ms.conf) + return err + } + return nil +} + +func (ms *NebulaService) GetSession() (*nebula.Session, error) { + session, err := ms.pool.GetSession(ms.conf.Username, ms.conf.Password) + // TODO: 使用jager打点 + return session, err +}