diff --git a/docs/swagger.yaml b/docs/swagger.yaml index e06318577..3fe439e13 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -1511,6 +1511,18 @@ paths: format: int64 required: false description: Relevant project ID. + - name: page + in: query + type: integer + format: int32 + required: false + description: 'The page nubmer.' + - name: page_size + in: query + type: integer + format: int32 + required: false + description: 'The size of per page.' tags: - Products responses: diff --git a/src/common/dao/dao_test.go b/src/common/dao/dao_test.go index 2159f93ad..2ccb8739a 100644 --- a/src/common/dao/dao_test.go +++ b/src/common/dao/dao_test.go @@ -21,6 +21,7 @@ import ( "github.com/astaxie/beego/orm" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/vmware/harbor/src/common" "github.com/vmware/harbor/src/common/models" "github.com/vmware/harbor/src/common/utils" @@ -1253,8 +1254,13 @@ func TestDeleteRepTarget(t *testing.T) { } } +func TestGetTotalOfRepPolicies(t *testing.T) { + _, err := GetTotalOfRepPolicies("", 1) + require.Nil(t, err) +} + func TestFilterRepPolicies(t *testing.T) { - _, err := FilterRepPolicies("name", 0) + _, err := FilterRepPolicies("name", 0, 0, 0) if err != nil { t.Fatalf("failed to filter policy: %v", err) } diff --git a/src/common/dao/replication_job.go b/src/common/dao/replication_job.go index b97319cf0..a37a63f20 100644 --- a/src/common/dao/replication_job.go +++ b/src/common/dao/replication_job.go @@ -139,8 +139,23 @@ func GetRepPolicy(id int64) (*models.RepPolicy, error) { return &policy, nil } +// GetTotalOfRepPolicies returns the total count of replication policies +func GetTotalOfRepPolicies(name string, projectID int64) (int64, error) { + qs := GetOrmer().QueryTable(&models.RepPolicy{}).Filter("deleted", 0) + + if len(name) != 0 { + qs = qs.Filter("name__icontains", name) + } + + if projectID != 0 { + qs = qs.Filter("project_id", projectID) + } + + return qs.Count() +} + // FilterRepPolicies filters policies by name and project ID -func FilterRepPolicies(name string, projectID int64) ([]*models.RepPolicy, error) { +func FilterRepPolicies(name string, projectID, page, pageSize int64) ([]*models.RepPolicy, error) { o := GetOrmer() var args []interface{} @@ -170,6 +185,11 @@ func FilterRepPolicies(name string, projectID int64) ([]*models.RepPolicy, error sql += `group by rp.id order by rp.creation_time` + if page > 0 && pageSize > 0 { + sql += ` limit ? offset ?` + args = append(args, pageSize, (page-1)*pageSize) + } + var policies []*models.RepPolicy if _, err := o.Raw(sql, args).QueryRows(&policies); err != nil { return nil, err diff --git a/src/common/utils/test/policy_manager.go b/src/common/utils/test/policy_manager.go index 492c88e00..768a88087 100644 --- a/src/common/utils/test/policy_manager.go +++ b/src/common/utils/test/policy_manager.go @@ -22,8 +22,8 @@ import ( type FakePolicyManager struct { } -func (f *FakePolicyManager) GetPolicies(query models.QueryParameter) ([]models.ReplicationPolicy, error) { - return []models.ReplicationPolicy{}, nil +func (f *FakePolicyManager) GetPolicies(query models.QueryParameter) (*models.ReplicationPolicyQueryResult, error) { + return &models.ReplicationPolicyQueryResult{}, nil } func (f *FakePolicyManager) GetPolicy(id int64) (models.ReplicationPolicy, error) { diff --git a/src/replication/core/controller.go b/src/replication/core/controller.go index 9065e6284..07ec4a9a1 100644 --- a/src/replication/core/controller.go +++ b/src/replication/core/controller.go @@ -98,18 +98,17 @@ func (ctl *DefaultController) Init() error { return nil } - //Build query parameters - query := models.QueryParameter{ - TriggerType: replication.TriggerKindSchedule, - } - - policies, err := ctl.policyManager.GetPolicies(query) + policies, err := ctl.policyManager.GetPolicies(models.QueryParameter{}) if err != nil { return err } - if policies != nil && len(policies) > 0 { - for _, policy := range policies { - if err := ctl.triggerManager.SetupTrigger(&policy); err != nil { + if policies != nil && len(policies.Policies) > 0 { + for _, policy := range policies.Policies { + if policy.Trigger == nil || policy.Trigger.Kind != replication.TriggerKindSchedule { + continue + } + + if err := ctl.triggerManager.SetupTrigger(policy); err != nil { log.Errorf("failed to setup trigger for policy %v: %v", policy, err) } } @@ -209,7 +208,7 @@ func (ctl *DefaultController) GetPolicy(policyID int64) (models.ReplicationPolic } //GetPolicies is delegation of GetPoliciemodels.ReplicationPolicy{}s of Policy.Manager -func (ctl *DefaultController) GetPolicies(query models.QueryParameter) ([]models.ReplicationPolicy, error) { +func (ctl *DefaultController) GetPolicies(query models.QueryParameter) (*models.ReplicationPolicyQueryResult, error) { return ctl.policyManager.GetPolicies(query) } diff --git a/src/replication/models/policy.go b/src/replication/models/policy.go index f6ab0217d..022d84a14 100644 --- a/src/replication/models/policy.go +++ b/src/replication/models/policy.go @@ -27,12 +27,15 @@ type QueryParameter struct { //Size of each page, couple with page PageSize int64 - //Query by the type of trigger - TriggerType string - //Query by project ID ProjectID int64 //Query by name Name string } + +// ReplicationPolicyQueryResult is the query result of replication policy +type ReplicationPolicyQueryResult struct { + Total int64 + Policies []*ReplicationPolicy +} diff --git a/src/replication/policy/manager.go b/src/replication/policy/manager.go index a6049dbfe..f06f6b33c 100644 --- a/src/replication/policy/manager.go +++ b/src/replication/policy/manager.go @@ -26,7 +26,7 @@ import ( // Manager defines the method a policy manger should implement type Manager interface { - GetPolicies(models.QueryParameter) ([]models.ReplicationPolicy, error) + GetPolicies(models.QueryParameter) (*models.ReplicationPolicyQueryResult, error) GetPolicy(int64) (models.ReplicationPolicy, error) CreatePolicy(models.ReplicationPolicy) (int64, error) UpdatePolicy(models.ReplicationPolicy) error @@ -42,27 +42,28 @@ func NewDefaultManager() *DefaultManager { } //GetPolicies returns all the policies -func (m *DefaultManager) GetPolicies(query models.QueryParameter) ([]models.ReplicationPolicy, error) { - result := []models.ReplicationPolicy{} - //TODO support more query conditions other than name and project ID - policies, err := dao.FilterRepPolicies(query.Name, query.ProjectID) +func (m *DefaultManager) GetPolicies(query models.QueryParameter) (*models.ReplicationPolicyQueryResult, error) { + result := &models.ReplicationPolicyQueryResult{ + Policies: []*models.ReplicationPolicy{}, + } + total, err := dao.GetTotalOfRepPolicies(query.Name, query.ProjectID) if err != nil { - return result, err + return nil, err + } + result.Total = total + + policies, err := dao.FilterRepPolicies(query.Name, query.ProjectID, query.Page, query.PageSize) + if err != nil { + return nil, err } for _, policy := range policies { ply, err := convertFromPersistModel(policy) if err != nil { - return []models.ReplicationPolicy{}, err + return nil, err } - if len(query.TriggerType) > 0 { - if ply.Trigger.Kind != query.TriggerType { - continue - } - } - - result = append(result, ply) + result.Policies = append(result.Policies, &ply) } return result, nil diff --git a/src/ui/api/replication_policy.go b/src/ui/api/replication_policy.go index 6a843fe6a..a182e1d2e 100644 --- a/src/ui/api/replication_policy.go +++ b/src/ui/api/replication_policy.go @@ -89,28 +89,34 @@ func (pa *RepPolicyAPI) List() { } queryParam.ProjectID = projectID } + queryParam.Page, queryParam.PageSize = pa.GetPaginationParams() - result := []*api_models.ReplicationPolicy{} - - policies, err := core.GlobalController.GetPolicies(queryParam) + result, err := core.GlobalController.GetPolicies(queryParam) if err != nil { log.Errorf("failed to get policies: %v, query parameters: %v", err, queryParam) pa.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) } - for _, policy := range policies { - if !pa.SecurityCtx.HasAllPerm(policy.ProjectIDs[0]) { - continue + var total int64 + policies := []*api_models.ReplicationPolicy{} + if result != nil { + total = result.Total + for _, policy := range result.Policies { + if !pa.SecurityCtx.HasAllPerm(policy.ProjectIDs[0]) { + continue + } + ply, err := convertFromRepPolicy(pa.ProjectMgr, *policy) + if err != nil { + pa.ParseAndHandleError(fmt.Sprintf("failed to convert from replication policy"), err) + return + } + policies = append(policies, ply) } - ply, err := convertFromRepPolicy(pa.ProjectMgr, policy) - if err != nil { - pa.ParseAndHandleError(fmt.Sprintf("failed to convert from replication policy"), err) - return - } - result = append(result, ply) } - pa.Data["json"] = result + pa.SetPaginationHeader(total, queryParam.Page, queryParam.PageSize) + + pa.Data["json"] = policies pa.ServeJSON() }