github.com/Axway/agent-sdk@v1.1.101/pkg/apic/resourcePagination.go (about)

     1  package apic
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"strconv"
     7  	"strings"
     8  
     9  	coreapi "github.com/Axway/agent-sdk/pkg/api"
    10  	apiv1 "github.com/Axway/agent-sdk/pkg/apic/apiserver/models/api/v1"
    11  	management "github.com/Axway/agent-sdk/pkg/apic/apiserver/models/management/v1alpha1"
    12  )
    13  
    14  // GetAPIServiceRevisions - management.APIServiceRevision
    15  func (c *ServiceClient) GetAPIServiceRevisions(queryParams map[string]string, URL, stage string) ([]*management.APIServiceRevision, error) {
    16  	resources, err := c.GetAPIV1ResourceInstances(queryParams, URL)
    17  	if err != nil {
    18  		return nil, err
    19  	}
    20  	apiServiceInstances, err := management.APIServiceRevisionFromInstanceArray(resources)
    21  	if err != nil {
    22  		return nil, err
    23  	}
    24  
    25  	filteredAPIRevisions := make([]*management.APIServiceRevision, 0)
    26  
    27  	// create array and filter by stage name. Check the stage name as this does not apply for v7
    28  	if stage != "" {
    29  		for _, apiServer := range apiServiceInstances {
    30  			if strings.Contains(strings.ToLower(apiServer.Name), strings.ToLower(fmt.Sprintf("%s.", stage))) {
    31  				filteredAPIRevisions = append(filteredAPIRevisions, apiServer)
    32  			}
    33  		}
    34  	} else {
    35  		filteredAPIRevisions = apiServiceInstances
    36  	}
    37  
    38  	return filteredAPIRevisions, nil
    39  }
    40  
    41  // GetAPIServiceInstances - get management.APIServiceInstance
    42  func (c *ServiceClient) GetAPIServiceInstances(queryParams map[string]string, URL string) ([]*management.APIServiceInstance, error) {
    43  	resources, err := c.GetAPIV1ResourceInstances(queryParams, URL)
    44  	if err != nil {
    45  		return nil, err
    46  	}
    47  	apiServiceIntances, err := management.APIServiceInstanceFromInstanceArray(resources)
    48  	if err != nil {
    49  		return nil, err
    50  	}
    51  
    52  	return apiServiceIntances, nil
    53  }
    54  
    55  // GetAPIV1ResourceInstances - return apiv1 Resource instance with the default page size
    56  func (c *ServiceClient) GetAPIV1ResourceInstances(queryParams map[string]string, url string) ([]*apiv1.ResourceInstance, error) {
    57  	return c.GetAPIV1ResourceInstancesWithPageSize(queryParams, url, c.cfg.GetPageSize())
    58  }
    59  
    60  func (c *ServiceClient) getPageSize(url string) (int, bool) {
    61  	c.pageSizeMutex.Lock()
    62  	defer c.pageSizeMutex.Unlock()
    63  	size, ok := c.pageSizes[url]
    64  	return size, ok
    65  }
    66  
    67  func (c *ServiceClient) setPageSize(url string, size int) {
    68  	c.pageSizeMutex.Lock()
    69  	defer c.pageSizeMutex.Unlock()
    70  	c.pageSizes[url] = size
    71  }
    72  
    73  // GetAPIV1ResourceInstancesWithPageSize - return apiv1 Resource instance
    74  func (c *ServiceClient) GetAPIV1ResourceInstancesWithPageSize(queryParams map[string]string, url string, pageSize int) ([]*apiv1.ResourceInstance, error) {
    75  	morePages := true
    76  	page := 1
    77  	retries := 3
    78  
    79  	resourceInstance := make([]*apiv1.ResourceInstance, 0)
    80  
    81  	log := c.logger.WithField("endpoint", url)
    82  	log.Trace("retrieving all resources from endpoint")
    83  	if !strings.HasPrefix(url, c.cfg.GetAPIServerURL()) {
    84  		url = c.createAPIServerURL(url)
    85  	}
    86  
    87  	// update page size if this endpoint used an adjusted page size before
    88  	if size, ok := c.getPageSize(url); ok {
    89  		pageSize = size
    90  	}
    91  
    92  	for morePages {
    93  		query := map[string]string{
    94  			"page":     strconv.Itoa(page),
    95  			"pageSize": strconv.Itoa(pageSize),
    96  		}
    97  		log := log.WithField("page", page).WithField("pageSize", pageSize)
    98  
    99  		// Add query params for getting revisions for the service and use the latest one as last reference
   100  		for key, value := range queryParams {
   101  			query[key] = value
   102  		}
   103  
   104  		response, err := c.ExecuteAPI(coreapi.GET, url, query, nil)
   105  
   106  		if err != nil && retries > 0 && strings.Contains(err.Error(), "context deadline exceeded") {
   107  			// in case of context deadline, lets reduce the page size and restart retrieving the resources
   108  			page = 1
   109  			resourceInstance = make([]*apiv1.ResourceInstance, 0)
   110  			pageSize = pageSize / 2
   111  			log.WithError(err).WithField("newPageSize", pageSize).Debug("error while retrieving resources, retrying with smaller page size")
   112  			retries--
   113  
   114  			// update the page size map so this endpoint uses the same size next time
   115  			c.setPageSize(url, pageSize)
   116  			continue
   117  		} else if err != nil {
   118  			log.WithError(err).Debug("error while retrieving resources")
   119  			return nil, err
   120  		}
   121  
   122  		resourceInstancePage := make([]*apiv1.ResourceInstance, 0)
   123  		json.Unmarshal(response, &resourceInstancePage)
   124  
   125  		resourceInstance = append(resourceInstance, resourceInstancePage...)
   126  
   127  		if len(resourceInstancePage) < pageSize {
   128  			morePages = false
   129  		} else {
   130  			log.Trace("continue retrieving resources from next page")
   131  		}
   132  
   133  		page++
   134  	}
   135  
   136  	return resourceInstance, nil
   137  }