You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
253 lines
5.7 KiB
253 lines
5.7 KiB
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) |
|
}
|
|
|