Skip to content

Commit

Permalink
Merge pull request #2532 from actiontech/report_push_impl
Browse files Browse the repository at this point in the history
Report push impl
  • Loading branch information
taolx0 authored Aug 13, 2024
2 parents 6b59e8a + 51630fd commit 5f26391
Show file tree
Hide file tree
Showing 6 changed files with 192 additions and 26 deletions.
2 changes: 1 addition & 1 deletion sqle/api/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ func StartApi(net *gracenet.Net, exitChan chan struct{}, config *config.SqleOpti

// report push
v1ProjectAdminRouter.PUT("/:project_name/report_push_configs/:report_push_config_id/", v1.UpdateReportPushConfig)
v1ProjectAdminRouter.GET("/:project_name/report_push_configs", v1.GetReportPushConfigList)
v1ProjectRouter.GET("/:project_name/report_push_configs", v1.GetReportPushConfigList)
}

// project member router
Expand Down
91 changes: 80 additions & 11 deletions sqle/api/controller/v1/report_push_config.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
package v1

import (
"context"
"fmt"
"net/http"
"strconv"
"time"

"github.com/actiontech/sqle/sqle/api/controller"
dms "github.com/actiontech/sqle/sqle/dms"
"github.com/actiontech/sqle/sqle/errors"
"github.com/actiontech/sqle/sqle/model"
"github.com/labstack/echo/v4"
)

Expand All @@ -13,11 +20,12 @@ type GetReportPushConfigsListResV1 struct {
}

type ReportPushConfigList struct {
Id string `json:"report_push_config_id"`
Type string `json:"type"`
Enabled string `json:"enabled"`
TriggerType string `json:"trigger_type "`
Enabled bool `json:"enabled"`
TriggerType string `json:"trigger_type" enums:"immediately,timing"`
PushFrequencyCron string `json:"push_frequency_cron"`
PushUserType string `json:"push_user_Type"`
PushUserType string `json:"push_user_Type" enums:"fixed,permission_match"`
PushUserList []string `json:"push_user_list"`
LastPushTime time.Time `json:"last_push_time"`
}
Expand All @@ -28,29 +36,90 @@ type ReportPushConfigList struct {
// @Id GetReportPushConfigList
// @Tags ReportPushConfig
// @Security ApiKeyAuth
// @Param project_name path string true "project name"
// @Success 200 {object} GetReportPushConfigsListResV1
// @Router /v1/project/{project_name}/report_push_configs [get]
// @Router /v1/projects/{project_name}/report_push_configs [get]
func GetReportPushConfigList(c echo.Context) error {
return nil
projectUid, err := dms.GetPorjectUIDByName(context.TODO(), c.Param("project_name"))
if err != nil {
return controller.JSONBaseErrorReq(c, err)
}
reportPushConfigs, err := model.GetStorage().GetReportPushConfigListInProject(projectUid)
if err != nil {
return controller.JSONBaseErrorReq(c, errors.New(errors.DataConflict, err))
}

ret := make([]ReportPushConfigList, 0, len(reportPushConfigs))
for _, reportPushConfig := range reportPushConfigs {
ret = append(ret, ReportPushConfigList{
Id: reportPushConfig.GetIDStr(),
Type: reportPushConfig.Type,
Enabled: reportPushConfig.Enabled,
TriggerType: reportPushConfig.TriggerType,
PushFrequencyCron: reportPushConfig.PushFrequencyCron,
PushUserType: reportPushConfig.PushUserType,
PushUserList: reportPushConfig.PushUserList,
LastPushTime: reportPushConfig.LastPushTime,
})
}
return c.JSON(http.StatusOK, GetReportPushConfigsListResV1{
Data: ret,
})
}

type UpdateReportPushConfigReqV1 struct {
TriggerType string `json:"trigger_type "`
TriggerType string `json:"trigger_type" enums:"immediately,timing" valid:"oneof=immediately timing"`
PushFrequencyCron string `json:"push_frequency_cron"`
PushUserType string `json:"push_user_Type"`
PushUserType string `json:"push_user_Type" enums:"fixed,permission_match" valid:"oneof=fixed permission_match"`
PushUserList []string `json:"push_user_list"`
Enabled string `json:"enabled"`
Enabled bool `json:"enabled"`
}

// @Summary 更新消息推送配置
// @Description update report push config
// @Id UpdateReportPushConfig
// @Tags report_push_config
// @Tags ReportPushConfig
// @Security ApiKeyAuth
// @Param project_name path string true "project name"
// @Param report_push_config_id path string true "report push config id"
// @Param req body v1.UpdateReportPushConfigReqV1 true "update report push config request"
// @Success 200 {object} controller.BaseRes
// @router /v1/project/{project_name}/report_push_configs/{report_push_config_id}/ [put]
// @router /v1/projects/{project_name}/report_push_configs/{report_push_config_id}/ [put]
func UpdateReportPushConfig(c echo.Context) error {
return nil
req := new(UpdateReportPushConfigReqV1)
err := controller.BindAndValidateReq(c, req)
if err != nil {
return controller.JSONBaseErrorReq(c, err)
}
reportPushConfigId, err := strconv.Atoi(c.Param("report_push_config_id"))
if err != nil {
return controller.JSONBaseErrorReq(c, err)
}
s := model.GetStorage()
config, exist, err := s.GetReportPushConfigById(uint(reportPushConfigId))
if err != nil {
return controller.JSONBaseErrorReq(c, err)
}
if !exist {
return controller.JSONBaseErrorReq(c, fmt.Errorf("report push configs %v not exist ,can't updatede", reportPushConfigId))
}

// 启停作为单独的行为,推送开关不一致,只做启停变更
if req.Enabled != config.Enabled {
config.Enabled = req.Enabled
} else {
if config.Type == model.TypeWorkflow {
return controller.JSONBaseErrorReq(c, fmt.Errorf("report push configs %v update is not supported", config.Type))
}
config.TriggerType = req.TriggerType
config.PushFrequencyCron = req.PushFrequencyCron
config.PushUserType = req.PushUserType
config.PushUserList = req.PushUserList
}
err = s.Save(config)
if err != nil {
return controller.JSONBaseErrorReq(c, err)
}

return c.JSON(http.StatusOK, controller.NewBaseReq(nil))
}
16 changes: 16 additions & 0 deletions sqle/model/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,26 @@
// - public const variables.
package model

import (
"database/sql/driver"
"encoding/json"
)

const (

// used by Model:
// User, UserGroup
Enabled = 0
Disabled = 1
)

type Strings []string

func (t *Strings) Scan(value interface{}) error {
bytesValue, _ := value.([]byte)
return json.Unmarshal(bytesValue, t)
}

func (t Strings) Value() (driver.Value, error) {
return json.Marshal(t)
}
87 changes: 74 additions & 13 deletions sqle/model/report_push_config.go
Original file line number Diff line number Diff line change
@@ -1,21 +1,11 @@
package model

import (
"database/sql/driver"
"encoding/json"
"time"
)

type Strings []string

func (t *Strings) Scan(value interface{}) error {
bytesValue, _ := value.([]byte)
return json.Unmarshal(bytesValue, t)
}

func (t Strings) Value() (driver.Value, error) {
return json.Marshal(t)
}
"github.com/actiontech/sqle/sqle/errors"
"gorm.io/gorm"
)

type ReportPushConfig struct {
Model
Expand All @@ -28,3 +18,74 @@ type ReportPushConfig struct {
LastPushTime time.Time `json:"last_push_time" gorm:"type:datetime(3)"`
Enabled bool `json:"enabled" gorm:"type:varchar(255)"`
}

func (s Storage) GetReportPushConfigListInProject(projectID string) ([]ReportPushConfig, error) {
reportPushConfigs := make([]ReportPushConfig, 0)
err := s.db.Model(ReportPushConfig{}).Where("project_id = ?", projectID).Find(&reportPushConfigs).Error
if err != nil {
return nil, err
}
return reportPushConfigs, nil
}

const (
// 推送报告类型
TypeWorkflow = "workflow"
TypeSQLManage = "sql_manage"

// 推送报告触发类型
TriggerTypeImmediately = "immediately"
TriggerTypeTiming = "timing"

// 推送报告指定用户类型
PushUserTypeFixed = "fixed"
PushUserTypePermissionMatch = "permission_match"
)

// 新增项目需要新增的配置
func (s Storage) InitReportPushConfigInProject(projectID string) error {
var defaultPushConfigs = []ReportPushConfig{
{
ProjectId: projectID,
Type: TypeWorkflow,
TriggerType: TriggerTypeImmediately,
PushFrequencyCron: "",
PushUserType: PushUserTypePermissionMatch,
PushUserList: []string{},
Enabled: true,
LastPushTime: time.Now(),
}, {
ProjectId: projectID,
Type: TypeSQLManage,
TriggerType: TriggerTypeTiming,
PushFrequencyCron: "",
PushUserType: PushUserTypeFixed,
PushUserList: []string{},
Enabled: false,
LastPushTime: time.Now(),
},
}
err := s.db.Save(defaultPushConfigs).Error
if err != nil {
return err
}
return nil
}

func (s *Storage) GetReportPushConfigByProjectId(projectId ProjectUID) (*ReportPushConfig, bool, error) {
ReportPushConfig := &ReportPushConfig{}
err := s.db.Where("project_id = ?", projectId).First(ReportPushConfig).Error
if err == gorm.ErrRecordNotFound {
return ReportPushConfig, false, nil
}
return ReportPushConfig, true, errors.New(errors.ConnectStorageError, err)
}

func (s *Storage) GetReportPushConfigById(id uint) (*ReportPushConfig, bool, error) {
ReportPushConfig := &ReportPushConfig{}
err := s.db.Where("id = ?", id).First(ReportPushConfig).Error
if err == gorm.ErrRecordNotFound {
return ReportPushConfig, false, nil
}
return ReportPushConfig, true, errors.New(errors.ConnectStorageError, err)
}
15 changes: 15 additions & 0 deletions sqle/model/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ var autoMigrateList = []interface{}{
&SQLManageRecord{},
&SQLManageRecordProcess{},
&SQLManageQueue{},
&ReportPushConfig{},
}

func (s *Storage) AutoMigrate() error {
Expand Down Expand Up @@ -455,6 +456,20 @@ func (s *Storage) GetDefaultRuleTemplateName(dbType string) string {
return fmt.Sprintf("default_%v", dbType)
}

func (s *Storage) CreateDefaultReportPushConfigIfNotExist() error {
_, exist, err := s.GetReportPushConfigByProjectId(ProjectUID(DefaultProjectUid))
if err != nil {
return err
}
if !exist {
err = s.InitReportPushConfigInProject(DefaultProjectUid)
if err != nil {
return err
}
}
return nil
}

// func (s *Storage) CreateAdminUser() error {
// _, exist, err := s.GetUserByName(DefaultAdminUser)
// if err != nil {
Expand Down
7 changes: 6 additions & 1 deletion sqle/sqled.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@ func Run(options *config.SqleOptions) error {
if err := s.AutoMigrate(); err != nil {
return fmt.Errorf("auto migrate table failed: %v", err)
}

err := s.CreateDefaultWorkflowTemplateIfNotExist()
if err != nil {
return fmt.Errorf("create workflow template failed: %v", err)
Expand All @@ -110,6 +109,12 @@ func Run(options *config.SqleOptions) error {
if err := s.CreateDefaultTemplateIfNotExist(model.ProjectIdForGlobalRuleTemplate, driver.GetPluginManager().GetAllRules()); err != nil {
return fmt.Errorf("create default template failed while auto migrating table: %v", err)
}

}
{
if err := s.CreateDefaultReportPushConfigIfNotExist(); err != nil {
return fmt.Errorf("create default report push config failed: %v", err)
}
}
exitChan := make(chan struct{})
server.InitSqled(exitChan)
Expand Down

0 comments on commit 5f26391

Please sign in to comment.