254 lines
5.7 KiB
Go
254 lines
5.7 KiB
Go
package http
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"go-common/app/service/main/reply-feed/conf"
|
|
"go-common/app/service/main/reply-feed/model"
|
|
"go-common/app/service/main/reply-feed/service"
|
|
"go-common/library/ecode"
|
|
"go-common/library/log"
|
|
bm "go-common/library/net/http/blademaster"
|
|
"go-common/library/net/http/blademaster/middleware/verify"
|
|
)
|
|
|
|
var (
|
|
svc *service.Service
|
|
vfy *verify.Verify
|
|
)
|
|
|
|
// Init init
|
|
func Init(c *conf.Config, s *service.Service) {
|
|
svc = s
|
|
vfy = verify.New(c.Verify)
|
|
engine := bm.DefaultServer(c.BM)
|
|
router(engine)
|
|
if err := engine.Start(); err != nil {
|
|
log.Error("engine.Start error(%v)", err)
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
func router(e *bm.Engine) {
|
|
e.Ping(ping)
|
|
e.Register(register)
|
|
g := e.Group("/x/reply-feed")
|
|
{
|
|
g.POST("/strategy/new", newEGroup)
|
|
g.POST("/strategy/edit", editEgroup)
|
|
g.POST("/strategy/state", modifyState)
|
|
g.POST("/strategy/resize", resizeSlots)
|
|
g.POST("/strategy/reset", resetEgroup)
|
|
g.GET("/strategy/list", listEGroup)
|
|
|
|
g.GET("/statistics/list", statistics)
|
|
}
|
|
}
|
|
|
|
func ping(c *bm.Context) {
|
|
if err := svc.Ping(c); err != nil {
|
|
log.Error("ping error(%v)", err)
|
|
c.AbortWithStatus(http.StatusServiceUnavailable)
|
|
}
|
|
}
|
|
|
|
func register(c *bm.Context) {
|
|
c.JSON(map[string]interface{}{}, nil)
|
|
}
|
|
|
|
func validate(algorithm string, weight string) (err error) {
|
|
switch algorithm {
|
|
case model.WilsonLHRRAlgorithm:
|
|
w := &model.WilsonLHRRWeight{}
|
|
if err = json.Unmarshal([]byte(weight), &w); err != nil {
|
|
return
|
|
}
|
|
return w.Validate()
|
|
case model.WilsonLHRRFluidAlgorithm:
|
|
w := &model.WilsonLHRRFluidWeight{}
|
|
if err = json.Unmarshal([]byte(weight), &w); err != nil {
|
|
return
|
|
}
|
|
return w.Validate()
|
|
case model.OriginAlgorithm, model.LikeDescAlgorithm:
|
|
return
|
|
default:
|
|
log.Error("unknown algorithm accepted (%s)", algorithm)
|
|
err = ecode.RequestErr
|
|
}
|
|
if err != nil {
|
|
return
|
|
}
|
|
return
|
|
}
|
|
|
|
func listEGroup(c *bm.Context) {
|
|
stats, err := svc.SlotStatsManager(c)
|
|
if err != nil {
|
|
c.JSON(nil, err)
|
|
return
|
|
}
|
|
c.JSON(stats, nil)
|
|
}
|
|
|
|
func newEGroup(c *bm.Context) {
|
|
v := new(struct {
|
|
Name string `form:"name" validate:"required"`
|
|
Percent int `form:"percent" validate:"required"`
|
|
Algorithm string `form:"algorithm" validate:"required"`
|
|
Weight string `form:"weight" validate:"required"`
|
|
})
|
|
var (
|
|
err error
|
|
)
|
|
if err = c.Bind(v); err != nil {
|
|
return
|
|
}
|
|
if err = validate(v.Algorithm, v.Weight); err != nil {
|
|
c.JSON(nil, ecode.RequestErr)
|
|
return
|
|
}
|
|
c.JSON(nil, svc.NewEGroup(c, v.Name, v.Algorithm, v.Weight, v.Percent))
|
|
}
|
|
|
|
func editEgroup(c *bm.Context) {
|
|
v := new(struct {
|
|
Name string `form:"name" validate:"required"`
|
|
Algorithm string `form:"algorithm" validate:"required"`
|
|
Weight string `form:"weight" validate:"required"`
|
|
Slots []int64 `form:"slots,split" validate:"required"`
|
|
})
|
|
var (
|
|
err error
|
|
)
|
|
if err = c.Bind(v); err != nil {
|
|
return
|
|
}
|
|
if err = validate(v.Algorithm, v.Weight); err != nil {
|
|
c.JSON(nil, ecode.RequestErr)
|
|
return
|
|
}
|
|
c.JSON(nil, svc.EditSlotsStat(c, v.Name, v.Algorithm, v.Weight, v.Slots))
|
|
}
|
|
|
|
func modifyState(c *bm.Context) {
|
|
v := new(struct {
|
|
Name string `form:"name" validate:"required"`
|
|
State int `form:"state"`
|
|
})
|
|
var (
|
|
err error
|
|
)
|
|
if err = c.Bind(v); err != nil {
|
|
return
|
|
}
|
|
c.JSON(nil, svc.ModifyState(c, v.Name, v.State))
|
|
}
|
|
|
|
func resizeSlots(c *bm.Context) {
|
|
v := new(struct {
|
|
Name string `form:"name" validate:"required"`
|
|
Percent int `form:"percent" validate:"required"`
|
|
})
|
|
var (
|
|
err error
|
|
)
|
|
if err = c.Bind(v); err != nil {
|
|
return
|
|
}
|
|
c.JSON(nil, svc.ResizeSlots(c, v.Name, v.Percent))
|
|
}
|
|
|
|
func resetEgroup(c *bm.Context) {
|
|
v := new(struct {
|
|
Name string `form:"name" validate:"required"`
|
|
})
|
|
var (
|
|
err error
|
|
)
|
|
if err = c.Bind(v); err != nil {
|
|
return
|
|
}
|
|
c.JSON(nil, svc.ResetEGroup(c, v.Name))
|
|
}
|
|
|
|
func statistics(c *bm.Context) {
|
|
v := new(model.SSReq)
|
|
if err := c.Bind(v); err != nil {
|
|
return
|
|
}
|
|
if v.Hour {
|
|
res := new(model.SSHourRes)
|
|
data, err := svc.StatisticsByHour(c, v)
|
|
if err != nil {
|
|
c.JSON(nil, err)
|
|
return
|
|
}
|
|
xAxisMap := make(map[string]struct{})
|
|
res.Series = make(map[string][]*model.StatisticsStat)
|
|
for legend, m := range data {
|
|
res.Legend = append(res.Legend, legend)
|
|
for xAxis := range m {
|
|
xAxisMap[xAxis] = struct{}{}
|
|
}
|
|
}
|
|
for k := range xAxisMap {
|
|
res.XAxis = append(res.XAxis, k)
|
|
}
|
|
for _, legend := range res.Legend {
|
|
if hourStatistics, ok := data[legend]; ok {
|
|
for _, hour := range res.XAxis {
|
|
if stat, exists := hourStatistics[hour]; exists {
|
|
res.Series[legend] = append(res.Series[legend], stat)
|
|
} else {
|
|
t := strings.Split(hour, "-")
|
|
if len(t) < 2 {
|
|
c.Abort()
|
|
return
|
|
}
|
|
date, _ := strconv.Atoi(t[0])
|
|
hour, _ := strconv.Atoi(t[1])
|
|
res.Series[legend] = append(res.Series[legend], &model.StatisticsStat{Date: date, Hour: hour})
|
|
}
|
|
}
|
|
}
|
|
}
|
|
res.Sort()
|
|
c.JSON(res, nil)
|
|
return
|
|
}
|
|
res := new(model.SSDateRes)
|
|
data, err := svc.StatisticsByDate(c, v)
|
|
if err != nil {
|
|
c.JSON(nil, err)
|
|
return
|
|
}
|
|
xAxisMap := make(map[int]struct{})
|
|
res.Series = make(map[string][]*model.StatisticsStat)
|
|
for legend, m := range data {
|
|
res.Legend = append(res.Legend, legend)
|
|
for xAxis := range m {
|
|
xAxisMap[xAxis] = struct{}{}
|
|
}
|
|
}
|
|
for k := range xAxisMap {
|
|
res.XAxis = append(res.XAxis, k)
|
|
}
|
|
for _, legend := range res.Legend {
|
|
if dateStatistics, ok := data[legend]; ok {
|
|
for _, date := range res.XAxis {
|
|
if stat, exists := dateStatistics[date]; exists {
|
|
res.Series[legend] = append(res.Series[legend], stat)
|
|
} else {
|
|
res.Series[legend] = append(res.Series[legend], &model.StatisticsStat{Date: date})
|
|
}
|
|
}
|
|
}
|
|
}
|
|
res.Sort()
|
|
c.JSON(res, nil)
|
|
}
|