Create & Init Project...

This commit is contained in:
2019-04-22 18:49:16 +08:00
commit fc4fa37393
25440 changed files with 4054998 additions and 0 deletions

View File

@@ -0,0 +1,69 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = [
"dao_test.go",
"filter_test.go",
"log_test.go",
"resource_test.go",
"role_test.go",
"search_test.go",
"upload_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/admin/main/aegis/conf:go_default_library",
"//app/admin/main/aegis/model:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
"//vendor/gopkg.in/h2non/gock.v1:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"dao.go",
"filter.go",
"log.go",
"resource.go",
"role.go",
"search.go",
"upload.go",
],
importpath = "go-common/app/admin/main/aegis/dao/http",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/admin/main/aegis/conf:go_default_library",
"//app/admin/main/aegis/model:go_default_library",
"//app/admin/main/aegis/model/task:go_default_library",
"//library/database/elastic:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/xstr: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"],
)

View File

@@ -0,0 +1,41 @@
package http
import (
"context"
"go-common/app/admin/main/aegis/conf"
"go-common/library/database/elastic"
bm "go-common/library/net/http/blademaster"
)
// Dao dao
type Dao struct {
c *conf.Config
clientR, clientW *bm.Client
es *elastic.Elastic
}
// New init mysql db
func New(c *conf.Config) (dao *Dao) {
dao = &Dao{
c: c,
clientR: bm.NewClient(c.HTTPClient.Read),
clientW: bm.NewClient(c.HTTPClient.Write),
es: elastic.NewElastic(&elastic.Config{
Host: c.Host.Manager,
HTTPClient: c.HTTPClient.Es,
}),
}
return
}
// Close close the resource.
func (d *Dao) Close() {
}
// Ping dao ping
func (d *Dao) Ping(c context.Context) error {
return nil
}

View File

@@ -0,0 +1,62 @@
package http
import (
"context"
"flag"
"os"
"strings"
"testing"
"go-common/app/admin/main/aegis/conf"
"github.com/smartystreets/goconvey/convey"
"gopkg.in/h2non/gock.v1"
)
var (
d *Dao
cntx context.Context
)
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.archive.aegis-admin")
flag.Set("conf_token", "cad913269be022e1eb8c45a8d5408d78")
flag.Set("tree_id", "60977")
flag.Set("conf_version", "1")
flag.Set("deploy_env", "uat")
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/aegis-admin.toml")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
d = New(conf.Conf)
cntx = context.Background()
os.Exit(m.Run())
}
func httpMock(method, url string) *gock.Request {
r := gock.New(url)
d.clientR.SetTransport(gock.DefaultTransport)
d.clientW.SetTransport(gock.DefaultTransport)
r.Method = strings.ToUpper(method)
return r
}
func TestHttpPing(t *testing.T) {
convey.Convey("Ping", t, func(ctx convey.C) {
ctx.Convey("Ping", func(ctx convey.C) {
err := d.Ping(cntx)
ctx.Convey("Then err should not be nil", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}

View File

@@ -0,0 +1,49 @@
package http
import (
"context"
"net/url"
"go-common/library/ecode"
"go-common/library/log"
)
const (
_filterURI = "/x/internal/filter/v3/hit"
)
// Res 筛选结果
type Res struct {
Code int64 `json:"code"`
Data []struct {
Level int64 `json:"level"`
Msg string `json:"msg"`
} `json:"data"`
}
// FilterMulti .批量过滤
func (d *Dao) FilterMulti(c context.Context, area string, msg string) (hits []string, err error) {
params := url.Values{}
params.Set("area", area)
params.Set("msg", msg)
params.Set("level", "10")
res := new(Res)
log.Info("FilterMulti area(%s) msg(%s)", area, msg)
if err = d.clientR.Post(c, d.c.Host.API+_filterURI, "", params, res); err != nil {
log.Error("d.clientR.Get error(%v)", err)
return
}
if res.Code != 0 {
err = ecode.Code(res.Code)
log.Error("FilterMulti res(%+v) error(%+v)", res, err)
return
}
for _, dt := range res.Data {
hits = append(hits, dt.Msg)
}
log.Info("FilterMulti area(%s) msg(%s) hits(%v)", area, msg, hits)
return
}

View File

@@ -0,0 +1,43 @@
package http
import (
"context"
"reflect"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestHttpFilterMulti(t *testing.T) {
convey.Convey("FilterMulti", t, func(ctx convey.C) {
var (
c = context.Background()
area = ""
msg = ""
successRes = `{"code":0,"data":[{"level":10,"msg":"女装大佬"}]}`
failRes = `{"code":200,"data":[{"level":10,"msg":"女装大佬"}]}`
)
ctx.Convey("success", func(ctx convey.C) {
httpMock("POST", d.c.Host.API+_filterURI).Reply(200).JSON(successRes)
hits, err := d.FilterMulti(c, area, msg)
ctx.Convey("Then err should be nil.hits should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(reflect.DeepEqual(hits, []string{"女装大佬"}), convey.ShouldEqual, true)
})
})
ctx.Convey("request fail", func(ctx convey.C) {
httpMock("POST", d.c.Host.API+_filterURI).Reply(504)
_, err := d.FilterMulti(c, area, msg)
ctx.Convey("Then err should be nil.hits should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
})
})
ctx.Convey("business fail", func(ctx convey.C) {
httpMock("POST", d.c.Host.API+_filterURI).Reply(200).JSON(failRes)
_, err := d.FilterMulti(c, area, msg)
ctx.Convey("Then err should be nil.hits should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
})
})
})
}

View File

@@ -0,0 +1,182 @@
package http
import (
"context"
"fmt"
"reflect"
"strconv"
"strings"
"time"
"go-common/app/admin/main/aegis/model"
"go-common/library/database/elastic"
"go-common/library/log"
"go-common/library/xstr"
)
//const
const (
LogMinYear = 2018
LogMinTime = "2018-11-01 10:00:00"
)
func setESParams(r *elastic.Request, args interface{}, cm model.EsCommon) {
av := reflect.ValueOf(args)
if av.Kind() == reflect.Ptr {
av = av.Elem()
}
if av.Kind() != reflect.Struct {
return
}
atp := av.Type()
ranges := map[string]map[string]interface{}{}
for i := atp.NumField() - 1; i >= 0; i-- {
fdt := atp.Field(i)
tag := fdt.Tag.Get("reflect")
if tag == "ignore" || tag == "" {
continue
}
fdv := av.Field(i)
fdk := fdt.Type.Kind()
if (fdk == reflect.Slice || fdk == reflect.String) && fdv.Len() == 0 {
continue
}
//default处理
omitdefault := strings.Index(tag, ",omitdefault")
tag = strings.Replace(tag, ",omitdefault", "", -1)
fdvv := fdv.Interface()
fdvslice := false
if omitdefault > -1 && fmt.Sprintf("%v", fdvv) == fdt.Tag.Get("default") {
continue
}
//字段值处理parse额外处理
switch fdk {
case reflect.Int64, reflect.Int32, reflect.Int, reflect.Int16, reflect.Int8:
fdvv = fdv.Int()
case reflect.String:
if fdv.Len() == 0 {
continue
}
v := fdv.String()
parse := fdt.Tag.Get("parse")
if parse == "int" {
vi, err := strconv.ParseInt(v, 10, 64)
if err != nil {
log.Error("setESParams strconv.ParseInt(%s) error(%v)", v, err)
continue
}
fdvv = vi
} else if parse == "[]int" {
vi, err := xstr.SplitInts(v)
if err != nil {
log.Error("setESParams xstr.SplitInts(%s) error(%v)", v, err)
continue
}
fdvv = vi
fdvslice = true
} else {
fdvv = v
}
case reflect.Slice:
if fdv.Len() == 0 {
continue
}
fdvslice = true
default:
log.Warn("setESParams not support kind(%s) for tag(%s)", fdk.String(), tag)
continue
}
//范围处理
from := strings.Index(tag, ",from")
to := strings.Index(tag, ",to")
if from > -1 {
if _, exist := ranges[tag[:from]]; !exist {
ranges[tag[:from]] = map[string]interface{}{}
}
ranges[tag[:from]]["from"] = fdvv
continue
}
if to > -1 {
if _, exist := ranges[tag[:to]]; !exist {
ranges[tag[:to]] = map[string]interface{}{}
}
ranges[tag[:to]]["to"] = fdvv
continue
}
if fdvslice {
r.WhereIn(tag, fdvv)
} else {
r.WhereEq(tag, fdvv)
}
}
for field, items := range ranges {
r.WhereRange(field, items["from"], items["to"], elastic.RangeScopeLcRc)
}
r.Ps(cm.Ps).Pn(cm.Pn)
order := []map[string]string{}
if cm.Order != "" || cm.Sort != "" {
r.Order(cm.Order, cm.Sort)
order = append(order, map[string]string{cm.Order: cm.Sort})
}
if cm.Group != "" {
r.GroupBy(elastic.EnhancedModeDistinct, cm.Group, order)
}
}
//QueryLogSearch .
func (d *Dao) QueryLogSearch(c context.Context, args *model.ParamsQueryLog, cm model.EsCommon) (resp *model.SearchLogResult, err error) {
var (
min int = LogMinYear
max int
ctimefrom, ctimeto time.Time
)
//默认获取所有行为日志,确定了时间范围的,只查询该段范围内的日志
if args.CtimeFrom != "" {
ctimefrom, _ = time.ParseInLocation("2006-01-02 15:04:05", args.CtimeFrom, time.Local)
if ctimefrom.Year() > min {
min = ctimefrom.Year()
}
}
if args.CtimeTo != "" {
ctimeto, _ = time.ParseInLocation("2006-01-02 15:04:05", args.CtimeTo, time.Local)
if ctimeto.Year() >= min {
max = ctimeto.Year()
}
} else {
max = time.Now().Year()
}
tmpl := ",log_audit_%d_%d"
index := ""
for i := min; i <= max; i++ {
index += fmt.Sprintf(tmpl, args.Business, i)
}
index = strings.TrimLeft(index, ",")
r := d.es.NewRequest("log_audit").Index(index).Fields(
"uid",
"uname",
"oid",
"type",
"action",
"str_0",
"str_1",
"str_2",
"int_0",
"int_1",
"int_2",
"ctime",
"extra_data")
setESParams(r, args, cm)
err = r.Scan(c, &resp)
return
}

View File

@@ -0,0 +1,33 @@
package http
import (
"context"
"testing"
"go-common/app/admin/main/aegis/model"
"github.com/smartystreets/goconvey/convey"
)
func TestHttpQueryLogSearch(t *testing.T) {
convey.Convey("QueryLogSearch", t, func(ctx convey.C) {
var (
c = context.Background()
args = &model.ParamsQueryLog{
Business: 231,
Int0From: "0",
Int1: []int64{0, 1},
Int2: []int64{0},
Str0: []string{"0"},
CtimeFrom: "2019-01-01 00:00:00",
}
escm = model.EsCommon{Ps: 10, Pn: 1, Order: "ctime", Sort: "desc"}
)
ctx.Convey("success", func(ctx convey.C) {
res, err := d.QueryLogSearch(c, args, escm)
ctx.So(err, convey.ShouldBeNil)
ctx.So(res, convey.ShouldNotBeNil)
})
})
}

View File

@@ -0,0 +1,39 @@
package http
import (
"context"
"fmt"
"net/url"
"go-common/app/admin/main/aegis/model"
"go-common/library/ecode"
"go-common/library/log"
)
// SyncResource 同步到业务方
func (d *Dao) SyncResource(c context.Context, act *model.Action, ropt map[string]interface{}) (code int, err error) {
params := url.Values{}
for k, v := range ropt {
params.Set(k, fmt.Sprint(v))
}
requestParams := fmt.Sprintf("%s?%s", act.URL, params.Encode())
log.Info("SyncResource url(%v) params(%s)", act.URL, params.Encode())
if d.c.Debug == "local" || d.c.Debug == "nobusiness" {
return
}
res := new(struct {
Code int `json:"code"`
Msg string `json:"msg"`
Message string `json:"message"`
})
err = d.clientW.Post(c, act.URL, "", params, res)
code = res.Code
if err != nil || res.Code != 0 {
log.Error("clientW.Post err(%v) response(%+v) request(%s)", err, res, requestParams)
err = ecode.Errorf(ecode.AegisBusinessSyncErr, "业务回调错误 request(%s) httperror(%v) response(%+v)", requestParams, err, res)
}
return
}

View File

@@ -0,0 +1,19 @@
package http
import (
"context"
"testing"
"go-common/app/admin/main/aegis/model"
"github.com/smartystreets/goconvey/convey"
)
func TestSyncResource(t *testing.T) {
var (
c = context.TODO()
)
convey.Convey("SyncResource", t, func(ctx convey.C) {
d.SyncResource(c, &model.Action{}, map[string]interface{}{"state": 1})
})
}

View File

@@ -0,0 +1,159 @@
package http
import (
"context"
"net/url"
"strconv"
"go-common/app/admin/main/aegis/model/task"
"go-common/library/log"
"go-common/library/xstr"
)
const (
_getUIDs = "/x/admin/manager/users/uids"
_getUname = "/x/admin/manager/users/unames"
_getUdepartment = "/x/admin/manager/users/udepts"
_getRole = "/x/admin/manager/internal/user/role"
_getRoles = "/x/admin/manager/internal/user/roles"
)
// GetRole 获取用户对应业务下的角色
func (d *Dao) GetRole(c context.Context, bid, uid int64) (roles []*task.Role, err error) {
roles = []*task.Role{}
params := url.Values{}
params.Set("bid", strconv.FormatInt(bid, 10))
params.Set("uid", strconv.FormatInt(uid, 10))
res := new(struct {
Code int `json:"code"`
Data []*task.Role `json:"data"`
})
if err = d.clientR.Get(c, d.c.Host.Manager+_getRole, "", params, res); err != nil {
log.Error("GetRole error(%v) url(%s) params(%s)", err, d.c.Host.Manager+_getRole, params.Encode())
return
}
if res.Code != 0 {
log.Error("GetRole request failed res(%+v) url(%s) params(%s)", res, d.c.Host.Manager+_getRole, params.Encode())
return
}
if len(res.Data) == 0 {
return
}
roles = res.Data
return
}
// GetUserRoles 获取用户在所有业务下的角色
func (d *Dao) GetUserRoles(c context.Context, uid int64) (roles []*task.Role, err error) {
roles = []*task.Role{}
params := url.Values{}
params.Set("uid", strconv.FormatInt(uid, 10))
res := new(struct {
Code int `json:"code"`
Data []*task.Role `json:"data"`
})
if err = d.clientR.Get(c, d.c.Host.Manager+_getRoles, "", params, res); err != nil {
log.Error("GetUserRoles error(%v) url(%s) params(%s)", err, d.c.Host.Manager+_getRole, params.Encode())
return
}
if res.Code != 0 {
log.Error("GetUserRoles request failed res(%+v) url(%s) params(%s)", res, d.c.Host.Manager+_getRole, params.Encode())
return
}
if len(res.Data) == 0 {
return
}
roles = res.Data
return
}
// GetUnames .
func (d *Dao) GetUnames(c context.Context, uids []int64) (unames map[int64]string, err error) {
unames = map[int64]string{}
if len(uids) == 0 {
return
}
params := url.Values{}
params.Set("uids", xstr.JoinInts(uids))
res := new(struct {
Code int `json:"code"`
Data map[int64]string `json:"data"`
})
if err = d.clientR.Get(c, d.c.Host.Manager+_getUname, "", params, res); err != nil {
log.Error("GetUnames error(%v) url(%s) params(%s)", err, d.c.Host.Manager+_getUname, params.Encode())
return
}
if res.Code != 0 {
log.Error("GetUnames request failed res(%+v) url(%s) params(%s)", res, d.c.Host.Manager+_getUname, params.Encode())
return
}
if len(res.Data) == 0 {
return
}
unames = res.Data
return
}
// GetUIDs .
func (d *Dao) GetUIDs(c context.Context, unames string) (uids map[string]int64, err error) {
uids = map[string]int64{}
params := url.Values{}
params.Set("unames", unames)
res := new(struct {
Code int `json:"code"`
Data map[string]int64 `json:"data"`
})
if err = d.clientR.Get(c, d.c.Host.Manager+_getUIDs, "", params, res); err != nil {
log.Error("GetUIDs error(%v) url(%s) params(%s)", err, d.c.Host.Manager+_getUname, params.Encode())
return
}
if res.Code != 0 {
log.Error("GetUIDs request failed res(%+v) url(%s) params(%s)", res, d.c.Host.Manager+_getUname, params.Encode())
return
}
if len(res.Data) == 0 {
return
}
uids = res.Data
return
}
// GetUdepartment .
func (d *Dao) GetUdepartment(c context.Context, uids []int64) (udepartment map[int64]string, err error) {
udepartment = map[int64]string{}
if len(uids) == 0 {
return
}
params := url.Values{}
params.Set("uids", xstr.JoinInts(uids))
res := new(struct {
Code int `json:"code"`
Data map[int64]string `json:"data"`
})
if err = d.clientR.Get(c, d.c.Host.Manager+_getUdepartment, "", params, res); err != nil {
log.Error("GetUdepartment error(%v) url(%s) params(%s)", err, d.c.Host.Manager+_getUdepartment, params.Encode())
return
}
if res.Code != 0 {
log.Error("GetUdepartment request failed res(%+v) url(%s) params(%s)", res, d.c.Host.Manager+_getUname, params.Encode())
return
}
if len(res.Data) == 0 {
return
}
udepartment = res.Data
return
}

View File

@@ -0,0 +1,75 @@
package http
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestHttpGetRole(t *testing.T) {
var (
c = context.TODO()
bid = int64(0)
uid = int64(0)
)
convey.Convey("GetRole", t, func(ctx convey.C) {
httpMock("GET", d.c.Host.Manager+_getRole).Reply(200).JSON(`{"code":0,"data":[{"id":0}]}`)
roles, err := d.GetRole(c, bid, uid)
ctx.Convey("Then err should be nil.roles should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(roles, convey.ShouldNotBeNil)
})
})
}
func TestHttpGetUserRoles(t *testing.T) {
var (
c = context.TODO()
)
convey.Convey("GetUserRoles", t, func(ctx convey.C) {
httpMock("GET", d.c.Host.Manager+_getRoles).Reply(200).JSON(`{"code":0,"data":[{"id":0}]}`)
roles, err := d.GetUserRoles(c, 421)
ctx.Convey("Then err should be nil.roles should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(roles, convey.ShouldNotBeNil)
})
})
}
func TestHttpGetUnames(t *testing.T) {
var (
c = context.TODO()
uids = []int64{421}
)
convey.Convey("GetUnames", t, func(ctx convey.C) {
httpMock("GET", d.c.Host.Manager+_getUname).Reply(200).JSON(`{"code":0,"data":{"421":"丝瓜"}}`)
unames, err := d.GetUnames(c, uids)
ctx.Convey("Then err should be nil.unames should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(unames, convey.ShouldNotBeNil)
})
})
}
func TestHttpGetUIDs(t *testing.T) {
convey.Convey("GetUIDs", t, func(ctx convey.C) {
httpMock("GET", d.c.Host.Manager+_getUIDs).Reply(200).JSON(`{"code":0,"data":{"cxf":481}}`)
uids, err := d.GetUIDs(cntx, "cxf")
ctx.Convey("Then err should be nil.unames should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(uids, convey.ShouldNotBeNil)
})
})
}
func TestHttpGetUdepartment(t *testing.T) {
convey.Convey("GetUdepartment", t, func(ctx convey.C) {
httpMock("GET", d.c.Host.Manager+_getUdepartment).Reply(200).JSON(`{"code":0,"data":{"481":"CTO"}}`)
depart, err := d.GetUdepartment(cntx, []int64{481})
ctx.Convey("Then err should be nil.unames should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(depart, convey.ShouldNotBeNil)
})
})
}

View File

@@ -0,0 +1,120 @@
package http
import (
"context"
"encoding/json"
"net/url"
"strings"
"go-common/app/admin/main/aegis/model"
"go-common/library/database/elastic"
"go-common/library/ecode"
"go-common/library/log"
)
const (
_upsertES = "/x/admin/search/upsert"
)
// ResourceES search archives by es.
func (d *Dao) ResourceES(c context.Context, arg *model.SearchParams) (sres *model.SearchRes, err error) {
r := d.es.NewRequest("aegis_resource").Index("aegis_resource").Fields(
"id",
"business_id",
"flow_id",
"oid",
"mid",
"content",
"extra1",
"extra2",
"extra3",
"extra4",
"extra5",
"extra6",
"extra1s",
"extra2s",
"extra3s",
"extra4s",
"extratime1",
"octime",
"ptime",
"metadata",
"note",
"reject_reason",
"reason_id",
"state",
"ctime",
).OrderScoreFirst(false)
escm := model.EsCommon{
Ps: arg.Ps,
Pn: arg.Pn,
Order: "ctime",
Sort: strings.ToLower(arg.CtimeOrder),
}
if escm.Sort != "asc" && escm.Sort != "desc" {
escm.Sort = "desc"
}
setESParams(r, arg, escm)
if arg.KeyWord != "" { //描述
arg.KeyWord = strings.Replace(arg.KeyWord, "", ",", -1)
r.WhereLike([]string{"content"}, strings.Split(arg.KeyWord, ","), true, elastic.LikeLevelHigh)
}
log.Info("ResourceES params(%s)", r.Params())
sres = &model.SearchRes{}
if err = r.Scan(c, sres); err != nil {
log.Error("ResourceES r.Scan params(%s)|error(%v)", r.Params(), err)
return
}
arg.Pn = sres.Page.Num
arg.Ps = sres.Page.Size
arg.Total = sres.Page.Total
return
}
//UpsertES 更新搜索
func (d *Dao) UpsertES(c context.Context, rsc []*model.UpsertItem) (err error) {
if len(rsc) == 0 {
return
}
items := []*model.UpsertItem{}
for _, item := range rsc {
if item == nil || item.ID <= 0 {
continue
}
items = append(items, item)
}
data := map[string][]*model.UpsertItem{
"aegis_resource": items,
}
datab, err := json.Marshal(data)
if err != nil {
log.Error("UpsertES json.Marshal error(%v) resource(%+v)", err, rsc)
return err
}
res := new(struct {
Code int `json:"code"`
Message string `json:"message"`
})
params := url.Values{}
params.Set("business", "aegis_resource")
params.Set("insert", "false")
params.Set("data", string(datab))
if err = d.clientW.Post(c, d.c.Host.Manager+_upsertES, "", params, res); err != nil {
log.Error("UpsertES d.clientW.Post error(%v) params(%+v)", err, params)
return
}
if res.Code != ecode.OK.Code() {
log.Error("UpsertES d.clientW.Post failed, response(%+v) params(%+v)", res, params)
return
}
log.Info("response(%+v) url=%s%s?%s", res, d.c.Host.Manager, _upsertES, params.Encode())
return
}

View File

@@ -0,0 +1,58 @@
package http
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
"go-common/app/admin/main/aegis/model"
)
var arg = &model.SearchParams{
BusinessID: 1,
//CtimeFrom: "2018-01-01 01:01:01",
//CtimeTo: "2019-11-11 11:11:11",
OID: []string{"206137981869783258", "206137981871880409", "206129056929839317", "206117679558326449"},
KeyWord: "分享图片",
FlowID: -12345,
Extra1: "1,2,3,4,5",
Mid: -12345,
State: 0,
}
func TestHttpResourceES(t *testing.T) {
convey.Convey("ResourceES", t, func(ctx convey.C) {
var (
c = context.Background()
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
res, err := d.ResourceES(c, arg)
t.Logf("res(%+v)", res)
ctx.Convey("Then err should be nil.sres should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestUpsertES(t *testing.T) {
convey.Convey("UpsertES", t, func(ctx convey.C) {
rsc := []*model.UpsertItem{
{
ID: 47,
State: -3,
},
nil,
{
State: 0,
},
}
ctx.Convey("When everything goes positive", func(ctx convey.C) {
httpMock("POST", d.c.Host.Manager+_upsertES).Reply(200).JSON(`{"code":0,"message":"msg"}`)
err := d.UpsertES(context.Background(), rsc)
ctx.Convey("No return values", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}

View File

@@ -0,0 +1,86 @@
package http
import (
"bytes"
"context"
"crypto/hmac"
"crypto/sha1"
"encoding/base64"
"fmt"
"hash"
"net/http"
"strconv"
"time"
"go-common/library/ecode"
"go-common/library/log"
)
// bfs info
const (
_uploadURL = "/bfs/%s/%s"
_template = "%s\n%s\n%s\n%d\n"
_method = "PUT"
_bucket = "creative"
)
// Upload upload picture or log file to bfs
func (d *Dao) Upload(c context.Context, fileName string, fileType string, timing int64, data []byte) (location string, err error) {
var (
req *http.Request
resp *http.Response
code int
client = &http.Client{Timeout: time.Duration(d.c.Bfs.Timeout) * time.Millisecond}
url = fmt.Sprintf(d.c.Bfs.Host+_uploadURL, _bucket, fileName)
)
// prepare the data of the file and init the request
buf := new(bytes.Buffer)
_, err = buf.Write(data)
if err != nil {
log.Error("Upload.buf.Write.error(%v)", err)
err = ecode.RequestErr
return
}
if req, err = http.NewRequest(_method, url, buf); err != nil {
log.Error("http.NewRequest() Upload(%v) error(%v)", url, err)
return
}
// request setting
authorization := authorize(d.c.Bfs.Key, d.c.Bfs.Secret, _method, _bucket, fileName, timing)
req.Header.Set("Date", fmt.Sprint(timing))
req.Header.Set("Authorization", authorization)
req.Header.Set("Content-Type", fileType)
resp, err = client.Do(req)
// response treatment
if err != nil {
log.Error("Bfs client.Do(%s) error(%v)", url, err)
return
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
err = fmt.Errorf("Bfs status code error:%v", resp.StatusCode)
return
}
code, err = strconv.Atoi(resp.Header.Get("code"))
if err != nil || code != 200 {
err = fmt.Errorf("Bfs response code error:%v", code)
return
}
location = resp.Header.Get("Location")
return
}
// authorize returns authorization for upload file to bfs
func authorize(key, secret, method, bucket, file string, expire int64) (authorization string) {
var (
content string
mac hash.Hash
signature string
)
content = fmt.Sprintf(_template, method, bucket, file, expire)
mac = hmac.New(sha1.New, []byte(secret))
mac.Write([]byte(content))
signature = base64.StdEncoding.EncodeToString(mac.Sum(nil))
authorization = fmt.Sprintf("%s:%s:%d", key, signature, expire)
return
}

View File

@@ -0,0 +1,41 @@
package http
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestHttpauthorize(t *testing.T) {
convey.Convey("authorize", t, func(ctx convey.C) {
var (
key = ""
secret = ""
method = ""
bucket = ""
file = ""
expire = int64(0)
)
ctx.Convey("When everything goes positive", func(ctx convey.C) {
authorization := authorize(key, secret, method, bucket, file, expire)
ctx.Convey("Then authorization should not be nil.", func(ctx convey.C) {
ctx.So(authorization, convey.ShouldNotBeNil)
})
})
})
}
func TestHttpUpload(t *testing.T) {
convey.Convey("Upload", t, func(ctx convey.C) {
var (
c = context.TODO()
)
ctx.Convey("When everything gose positive", func(ctx convey.C) {
_, err := d.Upload(c, "", "", 0, []byte{})
ctx.Convey("Then authorization should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldNotBeNil)
})
})
})
}