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  }