@@ -27,6 +27,7 @@ type InterRuleService interface {
2727 Get (req interface {}) (interface {}, interface {})
2828 ChangeStatus (req interface {}) (interface {}, interface {})
2929 Import (req interface {}) (interface {}, interface {})
30+ Change (req interface {}) (interface {}, interface {})
3031}
3132
3233func newInterRuleService (ctx * ctx.Context ) InterRuleService {
@@ -404,3 +405,116 @@ func (rs ruleService) Import(req interface{}) (interface{}, interface{}) {
404405
405406 return nil , nil
406407}
408+
409+ func (rs ruleService ) Change (req interface {}) (interface {}, interface {}) {
410+ r := req .(* types.RequestRuleChange )
411+
412+ if len (r .RuleIds ) == 0 {
413+ return nil , fmt .Errorf ("rule_ids 不能为空" )
414+ }
415+
416+ if len (r .Change ) == 0 {
417+ return nil , fmt .Errorf ("change 参数不能为空" )
418+ }
419+
420+ // 遍历所有要更新的规则ID
421+ for _ , ruleId := range r .RuleIds {
422+ // 获取当前规则
423+ rule := models.AlertRule {}
424+ err := rs .ctx .DB .DB ().Model (& models.AlertRule {}).
425+ Where ("tenant_id = ? AND rule_id = ?" , r .TenantId , ruleId ).
426+ First (& rule ).Error
427+ if err != nil {
428+ return nil , fmt .Errorf ("获取规则失败, ruleId: %s, error: %v" , ruleId , err )
429+ }
430+
431+ rule .UpdateAt = time .Now ().Unix ()
432+ rule .UpdateBy = r .UpdateBy
433+
434+ // 根据 change 参数动态更新字段
435+ for field , value := range r .Change {
436+ switch field {
437+ case "rule_group_id" :
438+ if v , ok := value .(string ); ok {
439+ rule .RuleGroupId = v
440+ } else {
441+ return nil , fmt .Errorf ("字段 %s 的值类型错误" , field )
442+ }
443+ break
444+ case "datasource_ids" :
445+ if v , ok := value .([]interface {}); ok {
446+ var datasourceIds []string
447+ for _ , val := range v {
448+ datasourceIds = append (datasourceIds , fmt .Sprintf ("%v" , val ))
449+ }
450+ rule .DatasourceIdList = datasourceIds
451+ } else if v , ok := value .([]string ); ok {
452+ rule .DatasourceIdList = v
453+ } else {
454+ return nil , fmt .Errorf ("字段 %s 的值类型错误" , field )
455+ }
456+ break
457+ case "fault_center_id" :
458+ if v , ok := value .(string ); ok {
459+ rule .FaultCenterId = v
460+ } else {
461+ return nil , fmt .Errorf ("필드 %s 의 값 타입이 잘못되었습니다" , field )
462+ }
463+ break
464+ case "enabled" :
465+ if v , ok := value .(bool ); ok {
466+ isEnabled := v
467+ rule .Enabled = & isEnabled
468+ } else {
469+ return nil , fmt .Errorf ("필드 %s 의 값 타입이 잘못되었습니다" , field )
470+ }
471+ break
472+ default :
473+ return nil , fmt .Errorf ("지원되지 않는 필드: %s" , field )
474+ }
475+ }
476+
477+ // 데이터베이스 업데이트
478+ err = rs .ctx .DB .Rule ().Update (rule )
479+ if err != nil {
480+ return nil , fmt .Errorf ("규칙 업데이트 실패, ruleId: %s, 오류: %v" , ruleId , err )
481+ }
482+
483+ // 규칙 활성화 상태에 따라 적절한 처리
484+ if * rule .Enabled {
485+ if alert .IsLeader () {
486+ // 리더: 기존 평가 고루틴을 중지하고 새로운 것을 시작합니다
487+ alert .AlertRule .Stop (ruleId )
488+ alert .AlertRule .Submit (rule )
489+ } else {
490+ tools .PublishReloadMessage (rs .ctx .Ctx , client .Redis , tools .ChannelRuleReload , tools.ReloadMessage {
491+ Action : tools .ActionUpdate ,
492+ ID : rule .RuleId ,
493+ TenantID : rule .TenantId ,
494+ Name : rule .RuleName ,
495+ })
496+ }
497+ } else {
498+ // 删除缓存
499+ fingerprints := rs .ctx .Redis .Alert ().GetFingerprintsByRuleId (r .TenantId , rule .FaultCenterId , rule .RuleId )
500+ for _ , fingerprint := range fingerprints {
501+ rs .ctx .Redis .Alert ().RemoveAlertEvent (r .TenantId , rule .FaultCenterId , fingerprint )
502+ }
503+
504+ if alert .IsLeader () {
505+ // 리더: 평가 고루틴 중지
506+ alert .AlertRule .Stop (ruleId )
507+ } else {
508+ // 팔로워: 비활성화 메시지를 발행하여 리더에게 알림
509+ tools .PublishReloadMessage (rs .ctx .Ctx , client .Redis , tools .ChannelRuleReload , tools.ReloadMessage {
510+ Action : tools .ActionDisable ,
511+ ID : rule .RuleId ,
512+ TenantID : rule .TenantId ,
513+ Name : rule .RuleName ,
514+ })
515+ }
516+ }
517+ }
518+
519+ return nil , nil
520+ }
0 commit comments