github.com/loggregator/cli@v6.33.1-0.20180224010324-82334f081791+incompatible/api/cloudcontroller/ccv2/paginated_resources.go (about) 1 package ccv2 2 3 import ( 4 "encoding/json" 5 "net/http" 6 "reflect" 7 8 "code.cloudfoundry.org/cli/api/cloudcontroller" 9 ) 10 11 // NewPaginatedResources returns a new PaginatedResources struct with the 12 // given resource type. 13 func NewPaginatedResources(exampleResource interface{}) *PaginatedResources { 14 return &PaginatedResources{ 15 resourceType: reflect.TypeOf(exampleResource), 16 } 17 } 18 19 // PaginatedResources represents a page of resources returned by the Cloud 20 // Controller. 21 type PaginatedResources struct { 22 NextURL string `json:"next_url"` 23 ResourcesBytes json.RawMessage `json:"resources"` 24 resourceType reflect.Type 25 } 26 27 // Resources unmarshals JSON representing a page of resources and returns a 28 // slice of the given resource type. 29 func (pr PaginatedResources) Resources() ([]interface{}, error) { 30 slicePtr := reflect.New(reflect.SliceOf(pr.resourceType)) 31 err := json.Unmarshal([]byte(pr.ResourcesBytes), slicePtr.Interface()) 32 slice := reflect.Indirect(slicePtr) 33 34 contents := make([]interface{}, 0, slice.Len()) 35 for i := 0; i < slice.Len(); i++ { 36 contents = append(contents, slice.Index(i).Interface()) 37 } 38 return contents, err 39 } 40 41 func (client Client) paginate(request *cloudcontroller.Request, obj interface{}, appendToExternalList func(interface{}) error) (Warnings, error) { 42 fullWarningsList := Warnings{} 43 44 for { 45 wrapper := NewPaginatedResources(obj) 46 response := cloudcontroller.Response{ 47 Result: &wrapper, 48 } 49 50 err := client.connection.Make(request, &response) 51 fullWarningsList = append(fullWarningsList, response.Warnings...) 52 if err != nil { 53 return fullWarningsList, err 54 } 55 56 list, err := wrapper.Resources() 57 if err != nil { 58 return fullWarningsList, err 59 } 60 61 for _, item := range list { 62 err = appendToExternalList(item) 63 if err != nil { 64 return fullWarningsList, err 65 } 66 } 67 68 if wrapper.NextURL == "" { 69 break 70 } 71 72 request, err = client.newHTTPRequest(requestOptions{ 73 URI: wrapper.NextURL, 74 Method: http.MethodGet, 75 }) 76 if err != nil { 77 return fullWarningsList, err 78 } 79 } 80 81 return fullWarningsList, nil 82 }