Add pagination support in listing replication policy API

This commit is contained in:
Wenkai Yin 2018-01-18 14:47:00 +08:00
parent 45894de89a
commit 611709a7be
8 changed files with 91 additions and 44 deletions

View File

@ -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:

View File

@ -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)
}

View File

@ -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

View File

@ -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) {

View File

@ -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)
}

View File

@ -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
}

View File

@ -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

View File

@ -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 {
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)
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)
policies = append(policies, ply)
}
}
pa.Data["json"] = result
pa.SetPaginationHeader(total, queryParam.Page, queryParam.PageSize)
pa.Data["json"] = policies
pa.ServeJSON()
}