Create & Init Project...
This commit is contained in:
41
app/infra/config/dao/v1/BUILD
Normal file
41
app/infra/config/dao/v1/BUILD
Normal file
@ -0,0 +1,41 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"dao.go",
|
||||
"file.go",
|
||||
"mysql.go",
|
||||
"redis.go",
|
||||
],
|
||||
importpath = "go-common/app/infra/config/dao/v1",
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//app/infra/config/conf:go_default_library",
|
||||
"//app/infra/config/model:go_default_library",
|
||||
"//library/cache/redis:go_default_library",
|
||||
"//library/database/sql:go_default_library",
|
||||
"//library/ecode:go_default_library",
|
||||
"//library/log:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
58
app/infra/config/dao/v1/dao.go
Normal file
58
app/infra/config/dao/v1/dao.go
Normal file
@ -0,0 +1,58 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"go-common/app/infra/config/conf"
|
||||
"go-common/library/cache/redis"
|
||||
"go-common/library/database/sql"
|
||||
)
|
||||
|
||||
// Dao dao.
|
||||
type Dao struct {
|
||||
// mysql
|
||||
db *sql.DB
|
||||
// redis
|
||||
redis *redis.Pool
|
||||
expire time.Duration
|
||||
// cache
|
||||
pathCache string
|
||||
}
|
||||
|
||||
// New new a dao.
|
||||
func New(c *conf.Config) *Dao {
|
||||
d := &Dao{
|
||||
// db
|
||||
db: sql.NewMySQL(c.DB),
|
||||
// redis
|
||||
redis: redis.NewPool(c.Redis),
|
||||
expire: time.Duration(c.PollTimeout),
|
||||
// cache
|
||||
pathCache: c.PathCache,
|
||||
}
|
||||
return d
|
||||
}
|
||||
|
||||
// BeginTran begin transcation.
|
||||
func (d *Dao) BeginTran(c context.Context) (tx *sql.Tx, err error) {
|
||||
return d.db.Begin(c)
|
||||
}
|
||||
|
||||
// Close close resuouces.
|
||||
func (d *Dao) Close() {
|
||||
if d.db != nil {
|
||||
d.db.Close()
|
||||
}
|
||||
if d.redis != nil {
|
||||
d.redis.Close()
|
||||
}
|
||||
}
|
||||
|
||||
// Ping ping is ok.
|
||||
func (d *Dao) Ping(c context.Context) (err error) {
|
||||
if err = d.pingRedis(c); err != nil {
|
||||
return
|
||||
}
|
||||
return d.db.Ping(c)
|
||||
}
|
70
app/infra/config/dao/v1/file.go
Normal file
70
app/infra/config/dao/v1/file.go
Normal file
@ -0,0 +1,70 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"go-common/app/infra/config/model"
|
||||
"go-common/library/log"
|
||||
)
|
||||
|
||||
// SetFile set config file.
|
||||
func (d *Dao) SetFile(name string, conf *model.Content) (err error) {
|
||||
b, err := json.Marshal(conf)
|
||||
if err != nil {
|
||||
log.Error("json.Marshal(%v) error(%v)", conf, err)
|
||||
return
|
||||
}
|
||||
p := path.Join(d.pathCache, name)
|
||||
if err = ioutil.WriteFile(p, b, 0644); err != nil {
|
||||
log.Error("ioutil.WriteFile(%s) error(%v)", p, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// File return config file.
|
||||
func (d *Dao) File(name string) (res *model.Content, err error) {
|
||||
p := path.Join(d.pathCache, name)
|
||||
b, err := ioutil.ReadFile(p)
|
||||
if err != nil {
|
||||
log.Error("ioutil.ReadFile(%s) error(%v)", p, err)
|
||||
return
|
||||
}
|
||||
res = &model.Content{}
|
||||
if err = json.Unmarshal(b, &res); err != nil {
|
||||
log.Error("json.Unmarshal(%s) error(%v)", b, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DelFile delete file cache.
|
||||
func (d *Dao) DelFile(name string) (err error) {
|
||||
p := path.Join(d.pathCache, name)
|
||||
if err = os.Remove(p); err != nil {
|
||||
log.Error("os.Remove(%s) error(%v)", p, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// SetFileStr save string file.
|
||||
func (d *Dao) SetFileStr(name string, val string) (err error) {
|
||||
p := path.Join(d.pathCache, name)
|
||||
if err = ioutil.WriteFile(p, []byte(val), 0644); err != nil {
|
||||
log.Error("ioutil.WriteFile(%s) error(%v)", p, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// FileStr get string file.
|
||||
func (d *Dao) FileStr(name string) (file string, err error) {
|
||||
p := path.Join(d.pathCache, name)
|
||||
b, err := ioutil.ReadFile(p)
|
||||
if err != nil {
|
||||
log.Error("ioutil.ReadFile(%s) error(%v)", p, err)
|
||||
return
|
||||
}
|
||||
file = string(b)
|
||||
return
|
||||
}
|
224
app/infra/config/dao/v1/mysql.go
Normal file
224
app/infra/config/dao/v1/mysql.go
Normal file
@ -0,0 +1,224 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
|
||||
"go-common/app/infra/config/model"
|
||||
"go-common/library/database/sql"
|
||||
"go-common/library/ecode"
|
||||
"go-common/library/log"
|
||||
)
|
||||
|
||||
const (
|
||||
_getToken = "SELECT token FROM service_name WHERE name=? AND environment=?"
|
||||
_getBuildVersion = "SELECT b.config_id FROM service_name s, build_version b WHERE b.version=? AND s.name=? And s.environment=? AND s.id=b.service_id AND b.state=2"
|
||||
_getVersions = "SELECT c.id,c.remark FROM service_config c, service_name s WHERE s.name=? AND s.environment=? AND s.id =c.service_id AND c.state=? ORDER BY c.id DESC"
|
||||
_getNamespace = "SELECT id,namespace FROM service_namespace WHERE config_id=?"
|
||||
_getValue = "SELECT config_id,namespace_id,name,config FROM service_config_value WHERE config_id=?"
|
||||
_getFile = "SELECT config FROM service_config_value WHERE config_id=? AND name =?"
|
||||
_getBuilds = "SELECT b.version FROM service_name s ,build_version b WHERE s.name=? AND s.environment=? AND s.id=b.service_id AND b.state=2 ORDER BY b.id DESC"
|
||||
_getServiceID = "SELECT id FROM service_name where name=? AND environment =?"
|
||||
_insertVersion = "INSERT INTO service_config(service_id,state,operator) VALUES (?,?,?)"
|
||||
_insertConfigs = "INSERT INTO service_config_value(config_id,name,config,operator) VALUES "
|
||||
_updateConfigs = "UPDATE service_config_value SET config=?,operator=? WHERE config_id = ? AND name = ?"
|
||||
_insertLog = "INSERT INTO log(username,business,info) VALUES (?,?,?)"
|
||||
)
|
||||
|
||||
// Token return a Secret from mysql.
|
||||
func (d *Dao) Token(c context.Context, svr, env string) (token string, err error) {
|
||||
row := d.db.QueryRow(c, _getToken, svr, env)
|
||||
if err = row.Scan(&token); err != nil {
|
||||
log.Error("row.Scan error(%v) svrName(%v)", err, svr)
|
||||
if err == sql.ErrNoRows {
|
||||
err = nil
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// BuildVersion return service build version from mysql.
|
||||
func (d *Dao) BuildVersion(c context.Context, svr, bver, env string) (version int64, err error) {
|
||||
row := d.db.QueryRow(c, _getBuildVersion, bver, svr, env)
|
||||
if err = row.Scan(&version); err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
version = model.UnknownVersion
|
||||
err = nil
|
||||
return
|
||||
}
|
||||
log.Error("row.Scan error(%v)", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Values return values from mysql.
|
||||
func (d *Dao) Values(c context.Context, ver int64) (rs []*model.NSValue, err error) {
|
||||
rows, err := d.db.Query(c, _getValue, ver)
|
||||
if err != nil {
|
||||
log.Error("db.Query(%d) error(%v)", ver, err)
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
var r model.NSValue
|
||||
if err = rows.Scan(&r.ConfigID, &r.NamespaceID, &r.Name, &r.Config); err != nil {
|
||||
log.Error("rows.Scan error(%v)", err)
|
||||
return
|
||||
}
|
||||
rs = append(rs, &r)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Namespaces return namespaces from mysql
|
||||
func (d *Dao) Namespaces(c context.Context, ver int64) (rs map[int64]string, err error) {
|
||||
rows, err := d.db.Query(c, _getNamespace, ver)
|
||||
if err != nil {
|
||||
log.Error("db.Query(%d) error(%v)", err)
|
||||
return
|
||||
}
|
||||
rs = make(map[int64]string)
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
var id int64
|
||||
var name string
|
||||
if err = rows.Scan(&id, &name); err != nil {
|
||||
log.Error("rows.Scan error(%v)", err)
|
||||
return
|
||||
}
|
||||
rs[id] = name
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//Versions return versions from mysql
|
||||
func (d *Dao) Versions(c context.Context, svr, env string, state int8) (rs []*model.ReVer, err error) {
|
||||
rows, err := d.db.Query(c, _getVersions, svr, env, state)
|
||||
if err != nil {
|
||||
log.Error("db.Query(%s) error(%v)", svr, err)
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
var r model.ReVer
|
||||
if err = rows.Scan(&r.Version, &r.Remark); err != nil {
|
||||
log.Error("rows.Scan error(%v)", err)
|
||||
return
|
||||
}
|
||||
rs = append(rs, &r)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Value return values from mysql.
|
||||
func (d *Dao) Value(c context.Context, fname string, ver int64) (file string, err error) {
|
||||
row := d.db.QueryRow(c, _getFile, ver, fname)
|
||||
if err = row.Scan(&file); err != nil {
|
||||
log.Error("row.Scan error(%v)", err)
|
||||
if err == sql.ErrNoRows {
|
||||
err = ecode.NothingFound
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Builds get service builds.
|
||||
func (d *Dao) Builds(c context.Context, svr, env string) (rs []string, err error) {
|
||||
rows, err := d.db.Query(c, _getBuilds, svr, env)
|
||||
if err != nil {
|
||||
log.Error("db.Query(%s) error(%v)", svr, err)
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
var r string
|
||||
if err = rows.Scan(&r); err != nil {
|
||||
log.Error("rows.Scan error(%v)", err)
|
||||
return
|
||||
}
|
||||
rs = append(rs, r)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ServiceID get ServiceID.
|
||||
func (d *Dao) ServiceID(c context.Context, svr, env string) (ID int64, err error) {
|
||||
row := d.db.QueryRow(c, _getServiceID, svr, env)
|
||||
if err != nil {
|
||||
log.Error("db.Query(%s) error(%v)", svr, err)
|
||||
return
|
||||
}
|
||||
if err = row.Scan(&ID); err != nil {
|
||||
log.Error("row.Scan error(%v)", err)
|
||||
if err == sql.ErrNoRows {
|
||||
err = ecode.NothingFound
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// TxInsertVer insert version.
|
||||
func (d *Dao) TxInsertVer(tx *sql.Tx, svrID int64, user string) (verID int64, err error) {
|
||||
row, err := tx.Exec(_insertVersion, svrID, model.ConfigIng, user)
|
||||
if err != nil {
|
||||
log.Error("db.insert(%d) error(%v)", svrID, err)
|
||||
return
|
||||
}
|
||||
return row.LastInsertId()
|
||||
}
|
||||
|
||||
// TxInsertValues insert config values.
|
||||
func (d *Dao) TxInsertValues(c context.Context, tx *sql.Tx, verID int64, user string, data map[string]string) (err error) {
|
||||
var (
|
||||
buffer bytes.Buffer
|
||||
insertTp string
|
||||
stmt *sql.Stmt
|
||||
is []interface{}
|
||||
)
|
||||
buffer.WriteString(_insertConfigs)
|
||||
insertTp = "(?,?,?,?),"
|
||||
for key, val := range data {
|
||||
buffer.WriteString(insertTp)
|
||||
is = append(is, verID)
|
||||
is = append(is, key)
|
||||
is = append(is, val)
|
||||
is = append(is, user)
|
||||
}
|
||||
buffer.Truncate(buffer.Len() - 1)
|
||||
if stmt, err = tx.Prepare(buffer.String()); err != nil {
|
||||
log.Error("d.insert() error(%v)", err)
|
||||
return
|
||||
}
|
||||
_, err = stmt.Exec(c, is...)
|
||||
if err != nil {
|
||||
log.Error("d.insert() error(%v)", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// TxUpdateValues update config values.
|
||||
func (d *Dao) TxUpdateValues(tx *sql.Tx, verID int64, user string, data map[string]string) (err error) {
|
||||
for key, val := range data {
|
||||
if _, err = tx.Exec(_updateConfigs, val, user, verID, key); err != nil {
|
||||
log.Error("db.UpdateValues(%d) error(%v)", user, err)
|
||||
break
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
log.Error("d.insert() error(%v)", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// InsertLog insert log.
|
||||
func (d *Dao) InsertLog(c context.Context, user, business, info string) (err error) {
|
||||
_, err = d.db.Exec(c, _insertLog, user, business, info)
|
||||
if err != nil {
|
||||
log.Error("db.InsertLog(%d) error(%v)", user, err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
100
app/infra/config/dao/v1/redis.go
Normal file
100
app/infra/config/dao/v1/redis.go
Normal file
@ -0,0 +1,100 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"go-common/app/infra/config/model"
|
||||
"go-common/library/cache/redis"
|
||||
"go-common/library/log"
|
||||
)
|
||||
|
||||
const (
|
||||
expireDuration = 3 * time.Hour
|
||||
_hostKey = "%s_%s"
|
||||
)
|
||||
|
||||
// Hostkey host cache key
|
||||
func hostKey(svr, env string) string {
|
||||
return fmt.Sprintf(_hostKey, svr, env)
|
||||
}
|
||||
|
||||
// Hosts return service hosts from redis.
|
||||
func (d *Dao) Hosts(c context.Context, svr, env string) (hosts []*model.Host, err error) {
|
||||
var (
|
||||
dels []string
|
||||
now = time.Now()
|
||||
hostkey = hostKey(svr, env)
|
||||
conn = d.redis.Get(c)
|
||||
)
|
||||
defer conn.Close()
|
||||
res, err := redis.Strings(conn.Do("HGETALL", hostkey))
|
||||
if err != nil {
|
||||
log.Error("conn.Do(HGETALL, %s) error(%v)", hostkey, err)
|
||||
return
|
||||
}
|
||||
for i, r := range res {
|
||||
if i%2 == 0 {
|
||||
continue
|
||||
}
|
||||
h := &model.Host{}
|
||||
if err = json.Unmarshal([]byte(r), h); err != nil {
|
||||
log.Error("json.Unmarshal(%s) error(%v)", r, err)
|
||||
return
|
||||
}
|
||||
if now.Sub(h.HeartbeatTime.Time()) <= d.expire+5 {
|
||||
h.State = model.HostOnline
|
||||
hosts = append(hosts, h)
|
||||
} else if now.Sub(h.HeartbeatTime.Time()) >= expireDuration {
|
||||
dels = append(dels, h.Name)
|
||||
} else {
|
||||
h.State = model.HostOffline
|
||||
hosts = append(hosts, h)
|
||||
}
|
||||
}
|
||||
if len(dels) > 0 {
|
||||
if _, err1 := conn.Do("HDEL", hostkey, dels); err1 != nil {
|
||||
log.Error("conn.Do(HDEL, %s, %v) error(%v)", hostkey, dels, err1)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// SetHost add service host to redis.
|
||||
func (d *Dao) SetHost(c context.Context, host *model.Host, svr, env string) (err error) {
|
||||
hostkey := hostKey(svr, env)
|
||||
b, err := json.Marshal(host)
|
||||
if err != nil {
|
||||
log.Error("json.Marshal(%s) error(%v)", host, err)
|
||||
return
|
||||
}
|
||||
conn := d.redis.Get(c)
|
||||
defer conn.Close()
|
||||
if _, err = conn.Do("HSET", hostkey, host.Name, string(b)); err != nil {
|
||||
log.Error("conn.Do(SET, %s, %s, %v) error(%v)", hostkey, host.Name, host, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ClearHost clear all hosts.
|
||||
func (d *Dao) ClearHost(c context.Context, svr, env string) (err error) {
|
||||
var (
|
||||
hostkey = hostKey(svr, env)
|
||||
conn = d.redis.Get(c)
|
||||
)
|
||||
defer conn.Close()
|
||||
if _, err = conn.Do("DEL", hostkey); err != nil {
|
||||
log.Error("conn.Do(DEL, %s) error(%v)", hostkey, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Ping check Redis connection
|
||||
func (d *Dao) pingRedis(c context.Context) (err error) {
|
||||
conn := d.redis.Get(c)
|
||||
_, err = conn.Do("SET", "PING", "PONG")
|
||||
conn.Close()
|
||||
return
|
||||
}
|
70
app/infra/config/dao/v2/BUILD
Normal file
70
app/infra/config/dao/v2/BUILD
Normal file
@ -0,0 +1,70 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_test",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"app_test.go",
|
||||
"build_test.go",
|
||||
"config_test.go",
|
||||
"dao_test.go",
|
||||
"file_test.go",
|
||||
"force_test.go",
|
||||
"redis_test.go",
|
||||
"tag_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//app/infra/config/conf:go_default_library",
|
||||
"//app/infra/config/model:go_default_library",
|
||||
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"app.go",
|
||||
"build.go",
|
||||
"config.go",
|
||||
"dao.go",
|
||||
"file.go",
|
||||
"force.go",
|
||||
"redis.go",
|
||||
"tag.go",
|
||||
],
|
||||
importpath = "go-common/app/infra/config/dao/v2",
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//app/infra/config/conf:go_default_library",
|
||||
"//app/infra/config/model:go_default_library",
|
||||
"//library/cache/redis:go_default_library",
|
||||
"//library/database/orm:go_default_library",
|
||||
"//library/database/sql:go_default_library",
|
||||
"//library/ecode:go_default_library",
|
||||
"//library/log:go_default_library",
|
||||
"//library/xstr:go_default_library",
|
||||
"//vendor/github.com/jinzhu/gorm:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
46
app/infra/config/dao/v2/app.go
Normal file
46
app/infra/config/dao/v2/app.go
Normal file
@ -0,0 +1,46 @@
|
||||
package v2
|
||||
|
||||
import (
|
||||
"go-common/app/infra/config/model"
|
||||
"go-common/library/database/sql"
|
||||
"go-common/library/ecode"
|
||||
"go-common/library/log"
|
||||
)
|
||||
|
||||
// AppByTree get token by Name.
|
||||
func (d *Dao) AppByTree(zone, env string, treeID int64) (app *model.App, err error) {
|
||||
app = &model.App{}
|
||||
row := d.DB.Select("id,token").Where("tree_id = ? AND env=? AND zone=?", treeID, env, zone).Model(&model.DBApp{}).Row()
|
||||
if err = row.Scan(&app.ID, &app.Token); err != nil {
|
||||
log.Error("AppByTree(%v) error(%v)", treeID, err)
|
||||
if err == sql.ErrNoRows {
|
||||
err = ecode.NothingFound
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// AppsByNameEnv get token by Name.
|
||||
func (d *Dao) AppsByNameEnv(name, env string) (apps []*model.DBApp, err error) {
|
||||
if err = d.DB.Where("env = ? and name like ?", env, "%"+name).Find(&apps).Error; err != nil {
|
||||
log.Error("AppsByNameEnv(%v) error(%v)", name, env)
|
||||
return
|
||||
}
|
||||
if len(apps) == 0 {
|
||||
err = ecode.NothingFound
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// AppGet ...
|
||||
func (d *Dao) AppGet(zone, env, token string) (app *model.App, err error) {
|
||||
app = &model.App{}
|
||||
row := d.DB.Select("id,token,env,zone,tree_id").Where("token = ? AND env= ? AND zone= ?", token, env, zone).Model(&model.DBApp{}).Row()
|
||||
if err = row.Scan(&app.ID, &app.Token, &app.Env, &app.Zone, &app.TreeID); err != nil {
|
||||
log.Error("AppGet zone(%v) env(%v) token(%v) error(%v)", zone, env, token, err)
|
||||
if err == sql.ErrNoRows {
|
||||
err = ecode.NothingFound
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
51
app/infra/config/dao/v2/app_test.go
Normal file
51
app/infra/config/dao/v2/app_test.go
Normal file
@ -0,0 +1,51 @@
|
||||
package v2
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func TestV2AppByTree(t *testing.T) {
|
||||
var (
|
||||
zone = ""
|
||||
env = ""
|
||||
treeID = int64(0)
|
||||
)
|
||||
convey.Convey("AppByTree", t, func(ctx convey.C) {
|
||||
app, err := d.AppByTree(zone, env, treeID)
|
||||
ctx.Convey("Then err should be nil.app should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(app, convey.ShouldNotBeNil)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestV2AppsByNameEnv(t *testing.T) {
|
||||
var (
|
||||
name = "main.common-arch.apm-admin"
|
||||
env = "fat1"
|
||||
)
|
||||
convey.Convey("AppsByNameEnv", t, func(ctx convey.C) {
|
||||
apps, err := d.AppsByNameEnv(name, env)
|
||||
ctx.Convey("Then err should be nil.apps should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(apps, convey.ShouldNotBeNil)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestV2AppGet(t *testing.T) {
|
||||
var (
|
||||
zone = "sh001"
|
||||
env = "fat1"
|
||||
token = "a882c5530bcc11e8ab68522233017188"
|
||||
)
|
||||
convey.Convey("AppGet", t, func(ctx convey.C) {
|
||||
app, err := d.AppGet(zone, env, token)
|
||||
ctx.Convey("Then err should be nil.app should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(app, convey.ShouldNotBeNil)
|
||||
})
|
||||
})
|
||||
}
|
77
app/infra/config/dao/v2/build.go
Normal file
77
app/infra/config/dao/v2/build.go
Normal file
@ -0,0 +1,77 @@
|
||||
package v2
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
|
||||
"go-common/app/infra/config/model"
|
||||
"go-common/library/ecode"
|
||||
"go-common/library/log"
|
||||
)
|
||||
|
||||
// BuildsByAppID get builds by app id.
|
||||
func (d *Dao) BuildsByAppID(appID int64) (builds []string, err error) {
|
||||
var rows *sql.Rows
|
||||
if rows, err = d.DB.Select("name").Model(&model.Build{}).Where("app_id = ? ", appID).Rows(); err != nil {
|
||||
log.Error("BuildsByAppID(%v) error(%v)", appID, err)
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
var build string
|
||||
if err = rows.Scan(&build); err != nil {
|
||||
log.Error("BuildsByAppID(%v) error(%v)", appID, err)
|
||||
return
|
||||
}
|
||||
builds = append(builds, build)
|
||||
}
|
||||
if len(builds) == 0 {
|
||||
err = ecode.NothingFound
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// BuildsByAppIDs get builds by app id.
|
||||
func (d *Dao) BuildsByAppIDs(appIDs []int64) (builds []string, err error) {
|
||||
var rows *sql.Rows
|
||||
if rows, err = d.DB.Select("name").Model(&model.Build{}).Where("app_id in (?) ", appIDs).Rows(); err != nil {
|
||||
log.Error("BuildsByAppIDs(%v) error(%v)", appIDs, err)
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
var build string
|
||||
if err = rows.Scan(&build); err != nil {
|
||||
log.Error("BuildsByAppIDs(%v) error(%v)", appIDs, err)
|
||||
return
|
||||
}
|
||||
builds = append(builds, build)
|
||||
}
|
||||
if len(builds) == 0 {
|
||||
err = ecode.NothingFound
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// TagID get TagID by ID.
|
||||
func (d *Dao) TagID(appID int64, build string) (tagID int64, err error) {
|
||||
row := d.DB.Select("tag_id").Where("app_id =? and name= ?", appID, build).Model(&model.Build{}).Row()
|
||||
if err = row.Scan(&tagID); err != nil {
|
||||
log.Error("TagID(%v) error(%v)", build, err)
|
||||
if err == sql.ErrNoRows {
|
||||
err = ecode.NothingFound
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// BuildID get build by ID.
|
||||
func (d *Dao) BuildID(appID int64, build string) (buildID int64, err error) {
|
||||
row := d.DB.Select("id").Where("app_id =? and name= ?", appID, build).Model(&model.Build{}).Row()
|
||||
if err = row.Scan(&buildID); err != nil {
|
||||
log.Error("buildID(%v) error(%v)", buildID, err)
|
||||
if err == sql.ErrNoRows {
|
||||
err = ecode.NothingFound
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
47
app/infra/config/dao/v2/build_test.go
Normal file
47
app/infra/config/dao/v2/build_test.go
Normal file
@ -0,0 +1,47 @@
|
||||
package v2
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func TestV2BuildsByAppID(t *testing.T) {
|
||||
var (
|
||||
appID = int64(24)
|
||||
)
|
||||
convey.Convey("BuildsByAppID", t, func(ctx convey.C) {
|
||||
builds, err := d.BuildsByAppID(appID)
|
||||
ctx.Convey("Then err should be nil.builds should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(builds, convey.ShouldNotBeNil)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestV2BuildsByAppIDs(t *testing.T) {
|
||||
var (
|
||||
appIDs = []int64{24}
|
||||
)
|
||||
convey.Convey("BuildsByAppIDs", t, func(ctx convey.C) {
|
||||
builds, err := d.BuildsByAppIDs(appIDs)
|
||||
ctx.Convey("Then err should be nil.builds should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(builds, convey.ShouldNotBeNil)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestV2TagID(t *testing.T) {
|
||||
var (
|
||||
appID = int64(24)
|
||||
build = "docker-1"
|
||||
)
|
||||
convey.Convey("TagID", t, func(ctx convey.C) {
|
||||
tagID, err := d.TagID(appID, build)
|
||||
ctx.Convey("Then err should be nil.tagID should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(tagID, convey.ShouldNotBeNil)
|
||||
})
|
||||
})
|
||||
}
|
43
app/infra/config/dao/v2/config.go
Normal file
43
app/infra/config/dao/v2/config.go
Normal file
@ -0,0 +1,43 @@
|
||||
package v2
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
|
||||
"go-common/app/infra/config/model"
|
||||
"go-common/library/ecode"
|
||||
"go-common/library/log"
|
||||
)
|
||||
|
||||
// UpdateConfValue update config state/
|
||||
func (d *Dao) UpdateConfValue(ID int64, value string) (err error) {
|
||||
err = d.DB.Model(&model.Config{ID: ID}).Where("state=?", model.ConfigIng).Update("comment", value).Error
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateConfState update config state/
|
||||
func (d *Dao) UpdateConfState(ID int64, state int8) (err error) {
|
||||
err = d.DB.Model(&model.Config{ID: ID}).Update("state", state).Error
|
||||
return
|
||||
}
|
||||
|
||||
// ConfigsByIDs get Config by IDs.
|
||||
func (d *Dao) ConfigsByIDs(ids []int64) (confs []*model.Value, err error) {
|
||||
var rows *sql.Rows
|
||||
if rows, err = d.DB.Where(ids).Select("id,name,comment").Where("state = ?", model.ConfigEnd).Model(&model.Config{}).Rows(); err != nil {
|
||||
log.Error("ConfigsByIDs(%v) error(%v)", ids, err)
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
v := new(model.Value)
|
||||
if err = rows.Scan(&v.ConfigID, &v.Name, &v.Config); err != nil {
|
||||
log.Error("ConfigsByIDs(%v) error(%v)", ids, err)
|
||||
return
|
||||
}
|
||||
confs = append(confs, v)
|
||||
}
|
||||
if len(confs) == 0 {
|
||||
err = ecode.NothingFound
|
||||
}
|
||||
return
|
||||
}
|
53
app/infra/config/dao/v2/config_test.go
Normal file
53
app/infra/config/dao/v2/config_test.go
Normal file
@ -0,0 +1,53 @@
|
||||
package v2
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func TestV2UpdateConfValue(t *testing.T) {
|
||||
var (
|
||||
ID = int64(0)
|
||||
value = ""
|
||||
)
|
||||
convey.Convey("UpdateConfValue", t, func(ctx convey.C) {
|
||||
err := d.UpdateConfValue(ID, value)
|
||||
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestV2UpdateConfState(t *testing.T) {
|
||||
var (
|
||||
ID = int64(855)
|
||||
state = int8(0)
|
||||
state2 = int8(2)
|
||||
)
|
||||
convey.Convey("UpdateConfState", t, func(ctx convey.C) {
|
||||
err := d.UpdateConfState(ID, state)
|
||||
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
convey.Convey("UpdateConfState restoration", t, func(ctx convey.C) {
|
||||
err := d.UpdateConfState(ID, state2)
|
||||
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestV2ConfigsByIDs(t *testing.T) {
|
||||
var (
|
||||
ids = []int64{855, 788}
|
||||
)
|
||||
convey.Convey("ConfigsByIDs", t, func(ctx convey.C) {
|
||||
confs, err := d.ConfigsByIDs(ids)
|
||||
ctx.Convey("Then err should be nil.confs should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(confs, convey.ShouldNotBeNil)
|
||||
})
|
||||
})
|
||||
}
|
55
app/infra/config/dao/v2/dao.go
Normal file
55
app/infra/config/dao/v2/dao.go
Normal file
@ -0,0 +1,55 @@
|
||||
package v2
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"go-common/app/infra/config/conf"
|
||||
"go-common/library/cache/redis"
|
||||
"go-common/library/database/orm"
|
||||
|
||||
"github.com/jinzhu/gorm"
|
||||
)
|
||||
|
||||
// Dao dao.
|
||||
type Dao struct {
|
||||
// redis
|
||||
redis *redis.Pool
|
||||
expire time.Duration
|
||||
// cache
|
||||
pathCache string
|
||||
//DB
|
||||
DB *gorm.DB
|
||||
}
|
||||
|
||||
// New new a dao.
|
||||
func New(c *conf.Config) *Dao {
|
||||
d := &Dao{
|
||||
// redis
|
||||
redis: redis.NewPool(c.Redis),
|
||||
expire: time.Duration(c.PollTimeout),
|
||||
// cache
|
||||
pathCache: c.PathCache,
|
||||
// orm
|
||||
DB: orm.NewMySQL(c.ORM),
|
||||
}
|
||||
return d
|
||||
}
|
||||
|
||||
// Ping ping is ok.
|
||||
func (d *Dao) Ping(c context.Context) (err error) {
|
||||
if err = d.pingRedis(c); err != nil {
|
||||
return
|
||||
}
|
||||
return d.DB.DB().PingContext(c)
|
||||
}
|
||||
|
||||
// Close close resuouces.
|
||||
func (d *Dao) Close() {
|
||||
if d.DB != nil {
|
||||
d.DB.Close()
|
||||
}
|
||||
if d.redis != nil {
|
||||
d.redis.Close()
|
||||
}
|
||||
}
|
36
app/infra/config/dao/v2/dao_test.go
Normal file
36
app/infra/config/dao/v2/dao_test.go
Normal file
@ -0,0 +1,36 @@
|
||||
package v2
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"go-common/app/infra/config/conf"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var (
|
||||
d *Dao
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
// if os.Getenv("DEPLOY_ENV") != "" {
|
||||
// // flag.Set("app_id", "")
|
||||
// // flag.Set("conf_token", "")
|
||||
// // flag.Set("tree_id", "")
|
||||
// // flag.Set("conf_version", "docker-1")
|
||||
// // flag.Set("deploy_env", "fat1")
|
||||
// // flag.Set("conf_host", "config.bilibili.co")
|
||||
// // flag.Set("conf_path", "/tmp")
|
||||
// // flag.Set("region", "sh")
|
||||
// // flag.Set("zone", "sh001")
|
||||
// } else {
|
||||
// flag.Set("conf", "../../cmd/config-service-example.toml")
|
||||
// }
|
||||
flag.Set("conf", "../../cmd/config-service-example.toml")
|
||||
flag.Parse()
|
||||
if err := conf.Init(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
d = New(conf.Conf)
|
||||
m.Run()
|
||||
os.Exit(0)
|
||||
}
|
70
app/infra/config/dao/v2/file.go
Normal file
70
app/infra/config/dao/v2/file.go
Normal file
@ -0,0 +1,70 @@
|
||||
package v2
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"go-common/app/infra/config/model"
|
||||
"go-common/library/log"
|
||||
)
|
||||
|
||||
// SetFile set config file.
|
||||
func (d *Dao) SetFile(name string, conf *model.Content) (err error) {
|
||||
b, err := json.Marshal(conf)
|
||||
if err != nil {
|
||||
log.Error("json.Marshal(%v) error(%v)", conf, err)
|
||||
return
|
||||
}
|
||||
p := path.Join(d.pathCache, name)
|
||||
if err = ioutil.WriteFile(p, b, 0644); err != nil {
|
||||
log.Error("ioutil.WriteFile(%s) error(%v)", p, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// File return config file.
|
||||
func (d *Dao) File(name string) (res *model.Content, err error) {
|
||||
p := path.Join(d.pathCache, name)
|
||||
b, err := ioutil.ReadFile(p)
|
||||
if err != nil {
|
||||
log.Error("ioutil.ReadFile(%s) error(%v)", p, err)
|
||||
return
|
||||
}
|
||||
res = &model.Content{}
|
||||
if err = json.Unmarshal(b, &res); err != nil {
|
||||
log.Error("json.Unmarshal(%s) error(%v)", b, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DelFile delete file cache.
|
||||
func (d *Dao) DelFile(name string) (err error) {
|
||||
p := path.Join(d.pathCache, name)
|
||||
if err = os.Remove(p); err != nil {
|
||||
log.Error("os.Remove(%s) error(%v)", p, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// SetFileStr save string file.
|
||||
func (d *Dao) SetFileStr(name string, val string) (err error) {
|
||||
p := path.Join(d.pathCache, name)
|
||||
if err = ioutil.WriteFile(p, []byte(val), 0644); err != nil {
|
||||
log.Error("ioutil.WriteFile(%s) error(%v)", p, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// FileStr get string file.
|
||||
func (d *Dao) FileStr(name string) (file string, err error) {
|
||||
p := path.Join(d.pathCache, name)
|
||||
b, err := ioutil.ReadFile(p)
|
||||
if err != nil {
|
||||
log.Error("ioutil.ReadFile(%s) error(%v)", p, err)
|
||||
return
|
||||
}
|
||||
file = string(b)
|
||||
return
|
||||
}
|
72
app/infra/config/dao/v2/file_test.go
Normal file
72
app/infra/config/dao/v2/file_test.go
Normal file
@ -0,0 +1,72 @@
|
||||
package v2
|
||||
|
||||
import (
|
||||
"go-common/app/infra/config/model"
|
||||
"testing"
|
||||
|
||||
"github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func TestV2SetFile(t *testing.T) {
|
||||
var (
|
||||
name = "main.common-arch.apm-admin_460"
|
||||
conf = &model.Content{}
|
||||
)
|
||||
convey.Convey("SetFile", t, func(ctx convey.C) {
|
||||
err := d.SetFile(name, conf)
|
||||
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestV2File(t *testing.T) {
|
||||
var (
|
||||
name = "main.common-arch.apm-admin_460"
|
||||
)
|
||||
convey.Convey("File", t, func(ctx convey.C) {
|
||||
res, err := d.File(name)
|
||||
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(res, convey.ShouldNotBeNil)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestV2DelFile(t *testing.T) {
|
||||
var (
|
||||
name = "main.common-arch.apm-admin_460"
|
||||
)
|
||||
convey.Convey("DelFile", t, func(ctx convey.C) {
|
||||
err := d.DelFile(name)
|
||||
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestV2SetFileStr(t *testing.T) {
|
||||
var (
|
||||
name = "main.common-arch.apm-admin_460"
|
||||
val = "test"
|
||||
)
|
||||
convey.Convey("SetFileStr", t, func(ctx convey.C) {
|
||||
err := d.SetFileStr(name, val)
|
||||
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestV2FileStr(t *testing.T) {
|
||||
var (
|
||||
name = "main.common-arch.apm-admin_460"
|
||||
)
|
||||
convey.Convey("FileStr", t, func(ctx convey.C) {
|
||||
file, err := d.FileStr(name)
|
||||
ctx.Convey("Then err should be nil.file should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(file, convey.ShouldNotBeNil)
|
||||
})
|
||||
})
|
||||
}
|
22
app/infra/config/dao/v2/force.go
Normal file
22
app/infra/config/dao/v2/force.go
Normal file
@ -0,0 +1,22 @@
|
||||
package v2
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
|
||||
"go-common/app/infra/config/model"
|
||||
"go-common/library/log"
|
||||
)
|
||||
|
||||
// Force get force by ID.
|
||||
func (d *Dao) Force(appID int64, hostname string) (version int64, err error) {
|
||||
row := d.DB.Select("version").Where("app_id = ? and hostname = ?", appID, hostname).Model(&model.Force{}).Row()
|
||||
if err = row.Scan(&version); err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
err = nil
|
||||
version = 0
|
||||
} else {
|
||||
log.Error("version(%v) error(%v)", version, err)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
17
app/infra/config/dao/v2/force_test.go
Normal file
17
app/infra/config/dao/v2/force_test.go
Normal file
@ -0,0 +1,17 @@
|
||||
package v2
|
||||
|
||||
// func TestV2Force(t *testing.T) {
|
||||
// convey.SkipConvey("Force", t, func(ctx convey.C) {
|
||||
// var (
|
||||
// appID = int64(24)
|
||||
// hostname = "apm-admin-31733-7c776f4d86-rxv6z"
|
||||
// )
|
||||
// ctx.Convey("When everything goes positive", func(ctx convey.C) {
|
||||
// version, err := d.Force(appID, hostname)
|
||||
// ctx.Convey("Then err should be nil.version should not be nil.", func(ctx convey.C) {
|
||||
// ctx.So(err, convey.ShouldBeNil)
|
||||
// ctx.So(version, convey.ShouldNotBeNil)
|
||||
// })
|
||||
// })
|
||||
// })
|
||||
// }
|
90
app/infra/config/dao/v2/redis.go
Normal file
90
app/infra/config/dao/v2/redis.go
Normal file
@ -0,0 +1,90 @@
|
||||
package v2
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"go-common/app/infra/config/model"
|
||||
"go-common/library/cache/redis"
|
||||
"go-common/library/log"
|
||||
)
|
||||
|
||||
const (
|
||||
expireDuration = 3 * time.Hour
|
||||
)
|
||||
|
||||
// Hosts return service hosts from redis.
|
||||
func (d *Dao) Hosts(c context.Context, svr string) (hosts []*model.Host, err error) {
|
||||
var (
|
||||
dels []string
|
||||
now = time.Now()
|
||||
conn = d.redis.Get(c)
|
||||
)
|
||||
defer conn.Close()
|
||||
res, err := redis.Strings(conn.Do("HGETALL", svr))
|
||||
if err != nil {
|
||||
log.Error("conn.Do(HGETALL, %s) error(%v)", svr, err)
|
||||
return
|
||||
}
|
||||
for i, r := range res {
|
||||
if i%2 == 0 {
|
||||
continue
|
||||
}
|
||||
h := &model.Host{}
|
||||
if err = json.Unmarshal([]byte(r), h); err != nil {
|
||||
log.Error("json.Unmarshal(%s) error(%v)", r, err)
|
||||
return
|
||||
}
|
||||
if now.Sub(h.HeartbeatTime.Time()) <= d.expire+5 {
|
||||
h.State = model.HostOnline
|
||||
hosts = append(hosts, h)
|
||||
} else if now.Sub(h.HeartbeatTime.Time()) >= expireDuration {
|
||||
dels = append(dels, h.Name)
|
||||
} else {
|
||||
h.State = model.HostOffline
|
||||
hosts = append(hosts, h)
|
||||
}
|
||||
}
|
||||
if len(dels) > 0 {
|
||||
if _, err1 := conn.Do("HDEL", svr, dels); err1 != nil {
|
||||
log.Error("conn.Do(HDEL, %s, %v) error(%v)", svr, dels, err1)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// SetHost add service host to redis.
|
||||
func (d *Dao) SetHost(c context.Context, host *model.Host, svr string) (err error) {
|
||||
b, err := json.Marshal(host)
|
||||
if err != nil {
|
||||
log.Error("json.Marshal(%s) error(%v)", host, err)
|
||||
return
|
||||
}
|
||||
conn := d.redis.Get(c)
|
||||
defer conn.Close()
|
||||
if _, err = conn.Do("HSET", svr, host.Name, string(b)); err != nil {
|
||||
log.Error("conn.Do(SET, %s, %s, %v) error(%v)", svr, host.Name, host, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ClearHost clear all hosts.
|
||||
func (d *Dao) ClearHost(c context.Context, svr string) (err error) {
|
||||
var (
|
||||
conn = d.redis.Get(c)
|
||||
)
|
||||
defer conn.Close()
|
||||
if _, err = conn.Do("DEL", svr); err != nil {
|
||||
log.Error("conn.Do(DEL, %s) error(%v)", svr, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Ping check Redis connection
|
||||
func (d *Dao) pingRedis(c context.Context) (err error) {
|
||||
conn := d.redis.Get(c)
|
||||
_, err = conn.Do("SET", "PING", "PONG")
|
||||
conn.Close()
|
||||
return
|
||||
}
|
62
app/infra/config/dao/v2/redis_test.go
Normal file
62
app/infra/config/dao/v2/redis_test.go
Normal file
@ -0,0 +1,62 @@
|
||||
package v2
|
||||
|
||||
import (
|
||||
"context"
|
||||
"go-common/app/infra/config/model"
|
||||
"testing"
|
||||
|
||||
"github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func TestV2Hosts(t *testing.T) {
|
||||
var (
|
||||
c = context.TODO()
|
||||
svr = "11133_fat1_sh001"
|
||||
)
|
||||
convey.Convey("Hosts", t, func(ctx convey.C) {
|
||||
hosts, err := d.Hosts(c, svr)
|
||||
ctx.Convey("Then err should be nil.hosts should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(hosts, convey.ShouldNotBeNil)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestV2SetHost(t *testing.T) {
|
||||
var (
|
||||
c = context.TODO()
|
||||
host = &model.Host{}
|
||||
svr = "11133_fat1_sh001"
|
||||
)
|
||||
convey.Convey("SetHost", t, func(ctx convey.C) {
|
||||
err := d.SetHost(c, host, svr)
|
||||
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestV2ClearHost(t *testing.T) {
|
||||
var (
|
||||
c = context.TODO()
|
||||
svr = "11133_fat1_sh001"
|
||||
)
|
||||
convey.Convey("ClearHost", t, func(ctx convey.C) {
|
||||
err := d.ClearHost(c, svr)
|
||||
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestV2pingRedis(t *testing.T) {
|
||||
var (
|
||||
c = context.TODO()
|
||||
)
|
||||
convey.Convey("pingRedis", t, func(ctx convey.C) {
|
||||
err := d.pingRedis(c)
|
||||
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
})
|
||||
})
|
||||
}
|
79
app/infra/config/dao/v2/tag.go
Normal file
79
app/infra/config/dao/v2/tag.go
Normal file
@ -0,0 +1,79 @@
|
||||
package v2
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"go-common/app/infra/config/model"
|
||||
"go-common/library/ecode"
|
||||
"go-common/library/log"
|
||||
"go-common/library/xstr"
|
||||
)
|
||||
|
||||
//Tags get builds by app id.
|
||||
func (d *Dao) Tags(appID int64) (tags []*model.ReVer, err error) {
|
||||
rows, err := d.DB.Select("id,mark").Where("app_id = ? ", appID).Model(&model.DBTag{}).Rows()
|
||||
if err != nil {
|
||||
log.Error("Tags(%v) error(%v)", appID, err)
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
reVer := &model.ReVer{}
|
||||
if err = rows.Scan(&reVer.Version, &reVer.Remark); err != nil {
|
||||
log.Error("Tags(%v) error(%v)", appID, err)
|
||||
return
|
||||
}
|
||||
tags = append(tags, reVer)
|
||||
}
|
||||
if len(tags) == 0 {
|
||||
err = ecode.NothingFound
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//ConfIDs get tag by id.
|
||||
func (d *Dao) ConfIDs(ID int64) (ids []int64, err error) {
|
||||
tag := &model.DBTag{}
|
||||
if err = d.DB.First(tag, ID).Error; err != nil {
|
||||
log.Error("ConfIDs(%v) error(%v)", ID, err)
|
||||
return
|
||||
}
|
||||
ids, _ = xstr.SplitInts(tag.ConfigIDs)
|
||||
if len(ids) == 0 {
|
||||
err = ecode.NothingFound
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// TagForce get force by tag.
|
||||
func (d *Dao) TagForce(ID int64) (force int8, err error) {
|
||||
row := d.DB.Select("`force`").Where("id = ?", ID).Model(&model.DBTag{}).Row()
|
||||
if err = row.Scan(&force); err != nil {
|
||||
log.Error("tagID(%v) error(%v)", ID, err)
|
||||
if err == sql.ErrNoRows {
|
||||
err = ecode.NothingFound
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// LastForce ...
|
||||
func (d *Dao) LastForce(appID, buildID int64) (lastForce int64, err error) {
|
||||
row := d.DB.Select("id").Where("`app_id` = ? and `build_id` = ? and `force` = 1", appID, buildID).Model(&model.DBTag{}).Row()
|
||||
if err = row.Scan(&lastForce); err != nil {
|
||||
log.Error("lastForce(%v) error(%v)", lastForce, err)
|
||||
if err == sql.ErrNoRows {
|
||||
err = nil
|
||||
lastForce = 0
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//TagAll ...
|
||||
func (d *Dao) TagAll(tagID int64) (tag *model.DBTag, err error) {
|
||||
tag = &model.DBTag{}
|
||||
if err = d.DB.First(tag, tagID).Error; err != nil {
|
||||
log.Error("tagID(%v) error(%v)", tagID, err)
|
||||
}
|
||||
return
|
||||
}
|
33
app/infra/config/dao/v2/tag_test.go
Normal file
33
app/infra/config/dao/v2/tag_test.go
Normal file
@ -0,0 +1,33 @@
|
||||
package v2
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func TestV2Tags(t *testing.T) {
|
||||
var (
|
||||
appID = int64(24)
|
||||
)
|
||||
convey.Convey("Tags", t, func(ctx convey.C) {
|
||||
tags, err := d.Tags(appID)
|
||||
ctx.Convey("Then err should be nil.tags should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(tags, convey.ShouldNotBeNil)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestV2ConfIDs(t *testing.T) {
|
||||
var (
|
||||
ID = int64(460)
|
||||
)
|
||||
convey.Convey("ConfIDs", t, func(ctx convey.C) {
|
||||
ids, err := d.ConfIDs(ID)
|
||||
ctx.Convey("Then err should be nil.ids should not be nil.", func(ctx convey.C) {
|
||||
ctx.So(err, convey.ShouldBeNil)
|
||||
ctx.So(ids, convey.ShouldNotBeNil)
|
||||
})
|
||||
})
|
||||
}
|
Reference in New Issue
Block a user