From 8b9727f53fe644e99cfb836cb737c367a176252f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wenkai=20Yin=28=E5=B0=B9=E6=96=87=E5=BC=80=29?= Date: Thu, 24 Sep 2020 16:48:56 +0800 Subject: [PATCH] Support store the cron type in the schedule (#13097) There is requirement that show the cron type(daily, weekly, etc.) on the UI, this commit adds the support for storing the cron type in the schedule model Signed-off-by: Wenkai Yin --- .../postgresql/0050_2.2.0_schema.up.sql | 1 + src/controller/p2p/preheat/controller.go | 4 ++-- src/controller/p2p/preheat/controllor_test.go | 2 +- src/pkg/retention/controller.go | 4 ++-- src/pkg/retention/controller_test.go | 2 +- src/pkg/scheduler/dao.go | 1 + src/pkg/scheduler/scheduler.go | 17 ++++++++++------- src/pkg/scheduler/scheduler_test.go | 10 +++++----- src/testing/pkg/scheduler/scheduler.go | 14 +++++++------- 9 files changed, 30 insertions(+), 25 deletions(-) create mode 100644 make/migrations/postgresql/0050_2.2.0_schema.up.sql diff --git a/make/migrations/postgresql/0050_2.2.0_schema.up.sql b/make/migrations/postgresql/0050_2.2.0_schema.up.sql new file mode 100644 index 000000000..54f824029 --- /dev/null +++ b/make/migrations/postgresql/0050_2.2.0_schema.up.sql @@ -0,0 +1 @@ +ALTER TABLE schedule ADD COLUMN IF NOT EXISTS cron_type varchar(64); \ No newline at end of file diff --git a/src/controller/p2p/preheat/controller.go b/src/controller/p2p/preheat/controller.go index bad90f5dd..ed745e093 100644 --- a/src/controller/p2p/preheat/controller.go +++ b/src/controller/p2p/preheat/controller.go @@ -292,7 +292,7 @@ func (c *controller) CreatePolicy(ctx context.Context, schema *policyModels.Sche schema.Trigger.Type == policyModels.TriggerTypeScheduled && len(schema.Trigger.Settings.Cron) > 0 { // schedule and update policy - if _, err = c.scheduler.Schedule(ctx, job.P2PPreheat, id, schema.Trigger.Settings.Cron, + if _, err = c.scheduler.Schedule(ctx, job.P2PPreheat, id, "", schema.Trigger.Settings.Cron, SchedulerCallback, TriggerParam{PolicyID: id}); err != nil { return 0, err } @@ -384,7 +384,7 @@ func (c *controller) UpdatePolicy(ctx context.Context, schema *policyModels.Sche // schedule new if needSch { - if _, err := c.scheduler.Schedule(ctx, job.P2PPreheat, schema.ID, cron, SchedulerCallback, + if _, err := c.scheduler.Schedule(ctx, job.P2PPreheat, schema.ID, "", cron, SchedulerCallback, TriggerParam{PolicyID: schema.ID}); err != nil { return err } diff --git a/src/controller/p2p/preheat/controllor_test.go b/src/controller/p2p/preheat/controllor_test.go index 30a81a7e4..a0ac39393 100644 --- a/src/controller/p2p/preheat/controllor_test.go +++ b/src/controller/p2p/preheat/controllor_test.go @@ -241,7 +241,7 @@ func (s *preheatSuite) TestCreatePolicy() { FiltersStr: `[{"type":"repository","value":"harbor*"},{"type":"tag","value":"2*"}]`, TriggerStr: fmt.Sprintf(`{"type":"%s", "trigger_setting":{"cron":"* * * * */1"}}`, policy.TriggerTypeScheduled), } - s.fakeScheduler.On("Schedule", s.ctx, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(int64(1), nil) + s.fakeScheduler.On("Schedule", s.ctx, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(int64(1), nil) s.fakePolicyMgr.On("Create", s.ctx, policy).Return(int64(1), nil) s.fakePolicyMgr.On("Update", s.ctx, mock.Anything, mock.Anything).Return(nil) s.fakeScheduler.On("UnScheduleByVendor", s.ctx, mock.Anything, mock.Anything).Return(nil) diff --git a/src/pkg/retention/controller.go b/src/pkg/retention/controller.go index dd022328a..674b5a775 100644 --- a/src/pkg/retention/controller.go +++ b/src/pkg/retention/controller.go @@ -93,7 +93,7 @@ func (r *DefaultAPIController) CreateRetention(p *policy.Metadata) (int64, error if p.Trigger.Kind == policy.TriggerKindSchedule { cron, ok := p.Trigger.Settings[policy.TriggerSettingsCron] if ok && len(cron.(string)) > 0 { - if _, err = r.scheduler.Schedule(orm.Context(), schedulerVendorType, id, cron.(string), SchedulerCallback, TriggerParam{ + if _, err = r.scheduler.Schedule(orm.Context(), schedulerVendorType, id, "", cron.(string), SchedulerCallback, TriggerParam{ PolicyID: id, Trigger: ExecutionTriggerSchedule, }); err != nil { @@ -152,7 +152,7 @@ func (r *DefaultAPIController) UpdateRetention(p *policy.Metadata) error { } } if needSch { - _, err := r.scheduler.Schedule(orm.Context(), schedulerVendorType, p.ID, p.Trigger.Settings[policy.TriggerSettingsCron].(string), SchedulerCallback, TriggerParam{ + _, err := r.scheduler.Schedule(orm.Context(), schedulerVendorType, p.ID, "", p.Trigger.Settings[policy.TriggerSettingsCron].(string), SchedulerCallback, TriggerParam{ PolicyID: p.ID, Trigger: ExecutionTriggerSchedule, }) diff --git a/src/pkg/retention/controller_test.go b/src/pkg/retention/controller_test.go index d849976ad..2c38bf819 100644 --- a/src/pkg/retention/controller_test.go +++ b/src/pkg/retention/controller_test.go @@ -220,7 +220,7 @@ func (s *ControllerTestSuite) TestExecution() { type fakeRetentionScheduler struct { } -func (f *fakeRetentionScheduler) Schedule(ctx context.Context, vendorType string, vendorID int64, cron string, callbackFuncName string, params interface{}) (int64, error) { +func (f *fakeRetentionScheduler) Schedule(ctx context.Context, vendorType string, vendorID int64, cronType string, cron string, callbackFuncName string, params interface{}) (int64, error) { return 111, nil } diff --git a/src/pkg/scheduler/dao.go b/src/pkg/scheduler/dao.go index 4227171c5..4741c1196 100644 --- a/src/pkg/scheduler/dao.go +++ b/src/pkg/scheduler/dao.go @@ -32,6 +32,7 @@ type schedule struct { ID int64 `orm:"pk;auto;column(id)"` VendorType string `orm:"column(vendor_type)"` VendorID int64 `orm:"column(vendor_id)"` + CRONType string `orm:"column(cron_type)"` CRON string `orm:"column(cron)"` CallbackFuncName string `orm:"column(callback_func_name)"` CallbackFuncParam string `orm:"column(callback_func_param)"` diff --git a/src/pkg/scheduler/scheduler.go b/src/pkg/scheduler/scheduler.go index 982a06398..a80d33aa2 100644 --- a/src/pkg/scheduler/scheduler.go +++ b/src/pkg/scheduler/scheduler.go @@ -40,6 +40,7 @@ type Schedule struct { ID int64 `json:"id"` VendorType string `json:"vendor_type"` VendorID int64 `json:"vendor_id"` + CRONType string `json:"cron_type"` CRON string `json:"cron"` Status string `json:"status"` // status of the underlying task(jobservice job) CreationTime time.Time `json:"creation_time"` @@ -57,8 +58,8 @@ type Scheduler interface { // and the "vendorID" specifies the ID of vendor if needed(e.g. policy ID for replication and retention). // The "params" is passed to the callback function as encoded json string, so the callback // function must decode it before using - Schedule(ctx context.Context, vendorType string, vendorID int64, cron string, - callbackFuncName string, params interface{}) (int64, error) + Schedule(ctx context.Context, vendorType string, vendorID int64, cronType string, + cron string, callbackFuncName string, params interface{}) (int64, error) // UnScheduleByID the schedule specified by ID UnScheduleByID(ctx context.Context, id int64) error // UnScheduleByVendor the schedule specified by vendor @@ -92,11 +93,11 @@ type scheduler struct { // The implementation of "Schedule" replaces the ormer with a new one in the context // to out of control from the global transaction, and uses a new transaction that only // covers the logic inside the function -func (s *scheduler) Schedule(ctx context.Context, vendorType string, vendorID int64, cron string, - callbackFuncName string, params interface{}) (int64, error) { +func (s *scheduler) Schedule(ctx context.Context, vendorType string, vendorID int64, cronType string, + cron string, callbackFuncName string, params interface{}) (int64, error) { var scheduleID int64 f := func(ctx context.Context) error { - id, err := s.schedule(ctx, vendorType, vendorID, cron, callbackFuncName, params) + id, err := s.schedule(ctx, vendorType, vendorID, cronType, cron, callbackFuncName, params) if err != nil { return err } @@ -111,8 +112,8 @@ func (s *scheduler) Schedule(ctx context.Context, vendorType string, vendorID in return scheduleID, nil } -func (s *scheduler) schedule(ctx context.Context, vendorType string, vendorID int64, cron string, - callbackFuncName string, params interface{}) (int64, error) { +func (s *scheduler) schedule(ctx context.Context, vendorType string, vendorID int64, cronType string, + cron string, callbackFuncName string, params interface{}) (int64, error) { if len(vendorType) == 0 { return 0, fmt.Errorf("empty vendor type") } @@ -128,6 +129,7 @@ func (s *scheduler) schedule(ctx context.Context, vendorType string, vendorID in sched := &schedule{ VendorType: vendorType, VendorID: vendorID, + CRONType: cronType, CRON: cron, CallbackFuncName: callbackFuncName, CreationTime: now, @@ -265,6 +267,7 @@ func (s *scheduler) convertSchedule(ctx context.Context, schedule *schedule) (*S ID: schedule.ID, VendorType: schedule.VendorType, VendorID: schedule.VendorID, + CRONType: schedule.CRONType, CRON: schedule.CRON, CreationTime: schedule.CreationTime, UpdateTime: schedule.UpdateTime, diff --git a/src/pkg/scheduler/scheduler_test.go b/src/pkg/scheduler/scheduler_test.go index f29853f9c..cd3394ead 100644 --- a/src/pkg/scheduler/scheduler_test.go +++ b/src/pkg/scheduler/scheduler_test.go @@ -50,15 +50,15 @@ func (s *schedulerTestSuite) SetupTest() { func (s *schedulerTestSuite) TestSchedule() { // empty vendor type - id, err := s.scheduler.Schedule(nil, "", 0, "0 * * * * *", "callback", nil) + id, err := s.scheduler.Schedule(nil, "", 0, "", "0 * * * * *", "callback", nil) s.NotNil(err) // invalid cron - id, err = s.scheduler.Schedule(nil, "vendor", 1, "", "callback", nil) + id, err = s.scheduler.Schedule(nil, "vendor", 1, "", "", "callback", nil) s.NotNil(err) // callback function not exist - id, err = s.scheduler.Schedule(nil, "vendor", 1, "0 * * * * *", "not-exist", nil) + id, err = s.scheduler.Schedule(nil, "vendor", 1, "", "0 * * * * *", "not-exist", nil) s.NotNil(err) // failed to submit to jobservice @@ -71,7 +71,7 @@ func (s *schedulerTestSuite) TestSchedule() { Status: job.ErrorStatus.String(), }, nil) s.taskMgr.On("Stop", mock.Anything, mock.Anything).Return(nil) - _, err = s.scheduler.Schedule(nil, "vendor", 1, "0 * * * * *", "callback", "param") + _, err = s.scheduler.Schedule(nil, "vendor", 1, "", "0 * * * * *", "callback", "param") s.Require().NotNil(err) s.dao.AssertExpectations(s.T()) s.execMgr.AssertExpectations(s.T()) @@ -89,7 +89,7 @@ func (s *schedulerTestSuite) TestSchedule() { ExecutionID: 1, Status: job.SuccessStatus.String(), }, nil) - id, err = s.scheduler.Schedule(nil, "vendor", 1, "0 * * * * *", "callback", "param") + id, err = s.scheduler.Schedule(nil, "vendor", 1, "", "0 * * * * *", "callback", "param") s.Require().Nil(err) s.Equal(int64(1), id) s.dao.AssertExpectations(s.T()) diff --git a/src/testing/pkg/scheduler/scheduler.go b/src/testing/pkg/scheduler/scheduler.go index 7c836aa2b..9f540dc04 100644 --- a/src/testing/pkg/scheduler/scheduler.go +++ b/src/testing/pkg/scheduler/scheduler.go @@ -62,20 +62,20 @@ func (_m *Scheduler) ListSchedules(ctx context.Context, query *q.Query) ([]*sche return r0, r1 } -// Schedule provides a mock function with given fields: ctx, vendorType, vendorID, cron, callbackFuncName, params -func (_m *Scheduler) Schedule(ctx context.Context, vendorType string, vendorID int64, cron string, callbackFuncName string, params interface{}) (int64, error) { - ret := _m.Called(ctx, vendorType, vendorID, cron, callbackFuncName, params) +// Schedule provides a mock function with given fields: ctx, vendorType, vendorID, cronType, cron, callbackFuncName, params +func (_m *Scheduler) Schedule(ctx context.Context, vendorType string, vendorID int64, cronType string, cron string, callbackFuncName string, params interface{}) (int64, error) { + ret := _m.Called(ctx, vendorType, vendorID, cronType, cron, callbackFuncName, params) var r0 int64 - if rf, ok := ret.Get(0).(func(context.Context, string, int64, string, string, interface{}) int64); ok { - r0 = rf(ctx, vendorType, vendorID, cron, callbackFuncName, params) + if rf, ok := ret.Get(0).(func(context.Context, string, int64, string, string, string, interface{}) int64); ok { + r0 = rf(ctx, vendorType, vendorID, cronType, cron, callbackFuncName, params) } else { r0 = ret.Get(0).(int64) } var r1 error - if rf, ok := ret.Get(1).(func(context.Context, string, int64, string, string, interface{}) error); ok { - r1 = rf(ctx, vendorType, vendorID, cron, callbackFuncName, params) + if rf, ok := ret.Get(1).(func(context.Context, string, int64, string, string, string, interface{}) error); ok { + r1 = rf(ctx, vendorType, vendorID, cronType, cron, callbackFuncName, params) } else { r1 = ret.Error(1) }