Files
kra-new/internal/service/business/alert_rule.go
T

109 lines
4.0 KiB
Go

package business
import (
"context"
"encoding/json"
"kra/internal/biz/business"
"kra/internal/service/dto"
"math"
"strconv"
"strings"
"unicode/utf8"
)
type AlertRuleUsecase interface {
List(context.Context, business.AlertRuleFilter, ...business.ListOption) ([]*business.AlertRule, int64, error)
Find(context.Context, uint64) (*business.AlertRule, error)
Types(context.Context) ([]string, error)
Save(context.Context, *business.AlertRule) (uint64, error)
Delete(context.Context, uint64) error
Toggle(context.Context, uint64, int) error
}
type AlertRuleService struct{ uc AlertRuleUsecase }
func NewAlertRuleService(uc *business.AlertRuleUsecase) *AlertRuleService {
return &AlertRuleService{uc: uc}
}
func alertRuleResponse(r *business.AlertRule) *dto.AlertRuleResponse {
var threshold *json.Number
if r.MomThreshold != nil {
n := json.Number(*r.MomThreshold)
threshold = &n
}
return &dto.AlertRuleResponse{ID: r.ID, RuleName: r.Name, RuleType: r.Type, RuleTypeLabel: business.AlertRuleTypeLabel(r.Type), MonitorMetric: r.Metric, MonitorMetricLabel: business.AlertMetricLabel(r.Metric), StatPeriodDays: r.StatPeriodDays, MomDirection: r.MomDirection, MomDirectionLabel: business.AlertDirectionLabel(r.MomDirection), MomThreshold: threshold, UnloginDays: r.UnloginDays, MonitorScope: r.MonitorScope, WarningColor: r.WarningColor, CreatorID: r.CreatorID, CreatorName: r.CreatorName, Enabled: r.Enabled, CreatedAt: localTime(&r.CreatedAt), UpdatedAt: localTime(&r.UpdatedAt), RuleDescription: r.Description()}
}
func (s *AlertRuleService) List(ctx context.Context, req *dto.AlertRuleQuery) (*dto.AlertRulePage, error) {
if req == nil {
return nil, business.ErrAlertRuleInput
}
filter := business.AlertRuleFilter{Name: req.RuleName, Type: req.RuleType}
if req.MonitorMetric != "" {
n, err := strconv.Atoi(req.MonitorMetric)
if err != nil || n < 1 || n > 3 {
return nil, business.ErrAlertRuleInput
}
filter.Metric = &n
}
page, size := req.Page, req.PageSize
if page < 1 {
page = 1
}
if size < 1 {
size = 10
}
if size > 500 {
size = 500
}
if page > int(^uint(0)>>1)/size {
return nil, business.ErrAlertRuleInput
}
rows, total, err := s.uc.List(ctx, filter, business.ListOffset((page-1)*size), business.ListLimit(size))
if err != nil {
return nil, err
}
out := &dto.AlertRulePage{Rows: make([]*dto.AlertRuleResponse, 0, len(rows)), Total: total}
for _, r := range rows {
out.Rows = append(out.Rows, alertRuleResponse(r))
}
return out, nil
}
func (s *AlertRuleService) Find(ctx context.Context, id uint64) (*dto.AlertRuleResponse, error) {
if id == 0 {
return nil, business.ErrAlertRuleInput
}
rule, err := s.uc.Find(ctx, id)
if err != nil {
return nil, err
}
return alertRuleResponse(rule), nil
}
func (s *AlertRuleService) Types(ctx context.Context) ([]string, error) { return s.uc.Types(ctx) }
func (s *AlertRuleService) Save(ctx context.Context, req *dto.AlertRuleRequest) (uint64, error) {
if req == nil || strings.TrimSpace(req.RuleName) == "" || utf8.RuneCountInString(req.RuleName) > 100 || strings.TrimSpace(req.RuleType) == "" || strings.TrimSpace(req.WarningColor) == "" || len(req.WarningColor) > 20 {
return 0, business.ErrAlertRuleInput
}
for _, n := range []*int{req.StatPeriodDays, req.UnloginDays} {
if n != nil && (*n > math.MaxInt32 || *n < math.MinInt32) {
return 0, business.ErrAlertRuleInput
}
}
rule := &business.AlertRule{ID: req.ID, Name: req.RuleName, Type: req.RuleType, Metric: req.MonitorMetric, StatPeriodDays: req.StatPeriodDays, MomDirection: req.MomDirection, UnloginDays: req.UnloginDays, WarningColor: req.WarningColor}
if req.MomThreshold != nil {
value := req.MomThreshold.String()
rule.MomThreshold = &value
}
return s.uc.Save(ctx, rule)
}
func (s *AlertRuleService) Delete(ctx context.Context, id uint64) error {
if id == 0 {
return business.ErrAlertRuleInput
}
return s.uc.Delete(ctx, id)
}
func (s *AlertRuleService) Toggle(ctx context.Context, id uint64, enabled int) error {
if id == 0 {
return business.ErrAlertRuleInput
}
return s.uc.Toggle(ctx, id, enabled)
}