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

     1  package cache
     2  
     3  import (
     4  	"fmt"
     5  
     6  	defs "github.com/Axway/agent-sdk/pkg/apic/definitions"
     7  
     8  	v1 "github.com/Axway/agent-sdk/pkg/apic/apiserver/models/api/v1"
     9  	"github.com/Axway/agent-sdk/pkg/cache"
    10  	"github.com/Axway/agent-sdk/pkg/util"
    11  )
    12  
    13  // apiServiceToInstanceCount
    14  type apiServiceToInstanceCount struct {
    15  	Count         int
    16  	ApiServiceKey string
    17  }
    18  
    19  // API service cache management
    20  
    21  // AddAPIService - add/update APIService resource in cache
    22  func (c *cacheManager) AddAPIService(svc *v1.ResourceInstance) error {
    23  	apiID, err := util.GetAgentDetailsValue(svc, defs.AttrExternalAPIID)
    24  	if err != nil {
    25  		return fmt.Errorf("failed to get external API ID from APIService resource: %s", err)
    26  	}
    27  	if apiID != "" {
    28  		defer c.setCacheUpdated(true)
    29  		apiName, _ := util.GetAgentDetailsValue(svc, defs.AttrExternalAPIName)
    30  		primaryKey, _ := util.GetAgentDetailsValue(svc, defs.AttrExternalAPIPrimaryKey)
    31  		cachedRI, _ := c.GetAPIServiceInstanceByName(apiName)
    32  		if primaryKey != "" {
    33  			// Verify secondary key and validate if we need to remove it from the apiMap (cache)
    34  			if _, err := c.apiMap.Get(apiID); err != nil {
    35  				c.apiMap.Delete(apiID)
    36  			}
    37  
    38  			c.apiMap.SetWithSecondaryKey(primaryKey, apiID, svc)
    39  			c.apiMap.SetSecondaryKey(primaryKey, apiName)
    40  			c.apiMap.SetSecondaryKey(primaryKey, svc.Name)
    41  		} else {
    42  			c.apiMap.SetWithSecondaryKey(apiID, apiName, svc)
    43  			c.apiMap.SetSecondaryKey(apiID, svc.Name)
    44  		}
    45  
    46  		if cachedRI == nil {
    47  			c.countCachedInstancesForAPIService(apiID, primaryKey)
    48  		}
    49  
    50  		c.logger.
    51  			WithField("api-name", apiName).
    52  			WithField("api-id", apiID).
    53  			Trace("added api to cache")
    54  	}
    55  
    56  	return nil
    57  }
    58  
    59  // GetAPIServiceCache - returns the APIService cache
    60  func (c *cacheManager) GetAPIServiceCache() cache.Cache {
    61  	return c.apiMap
    62  }
    63  
    64  // GetAPIServiceKeys - returns keys for APIService cache
    65  func (c *cacheManager) GetAPIServiceKeys() []string {
    66  	c.ApplyResourceReadLock()
    67  	defer c.ReleaseResourceReadLock()
    68  
    69  	return c.apiMap.GetKeys()
    70  }
    71  
    72  // GetAPIServiceWithAPIID - returns resource from APIService cache based on externalAPIID attribute
    73  func (c *cacheManager) GetAPIServiceWithAPIID(apiID string) *v1.ResourceInstance {
    74  	c.ApplyResourceReadLock()
    75  	defer c.ReleaseResourceReadLock()
    76  
    77  	api, _ := c.apiMap.Get(apiID)
    78  	if api == nil {
    79  		api, _ = c.apiMap.GetBySecondaryKey(apiID)
    80  	}
    81  
    82  	if api != nil {
    83  		apiSvc, ok := api.(*v1.ResourceInstance)
    84  		if ok {
    85  			return apiSvc
    86  		}
    87  	}
    88  	return nil
    89  }
    90  
    91  // GetAPIServiceWithPrimaryKey - returns resource from APIService cache based on externalAPIPrimaryKey attribute
    92  func (c *cacheManager) GetAPIServiceWithPrimaryKey(primaryKey string) *v1.ResourceInstance {
    93  	c.ApplyResourceReadLock()
    94  	defer c.ReleaseResourceReadLock()
    95  
    96  	api, _ := c.apiMap.Get(primaryKey)
    97  	if api != nil {
    98  		apiSvc, ok := api.(*v1.ResourceInstance)
    99  		if ok {
   100  			return apiSvc
   101  		}
   102  	}
   103  	return nil
   104  }
   105  
   106  // GetAPIServiceWithName - returns resource from APIService cache based on externalAPIName attribute
   107  func (c *cacheManager) GetAPIServiceWithName(apiName string) *v1.ResourceInstance {
   108  	c.ApplyResourceReadLock()
   109  	defer c.ReleaseResourceReadLock()
   110  
   111  	api, _ := c.apiMap.GetBySecondaryKey(apiName)
   112  	if api != nil {
   113  		apiSvc, ok := api.(*v1.ResourceInstance)
   114  		if ok {
   115  			return apiSvc
   116  		}
   117  	}
   118  	return nil
   119  }
   120  
   121  // GetTeamsIDsInAPIServices - returns the array of team IDs that have services
   122  func (c *cacheManager) GetTeamsIDsInAPIServices() []string {
   123  	c.ApplyResourceReadLock()
   124  	defer c.ReleaseResourceReadLock()
   125  
   126  	teamNameMap := make(map[string]struct{})
   127  	teamIDs := make([]string, 0)
   128  	for _, key := range c.apiMap.GetKeys() {
   129  		api, _ := c.apiMap.Get(key)
   130  		if apiSvc, ok := api.(*v1.ResourceInstance); ok {
   131  			if apiSvc.Owner != nil && apiSvc.Owner.Type == v1.TeamOwner {
   132  				if _, found := teamNameMap[apiSvc.Owner.ID]; found {
   133  					continue
   134  				}
   135  				teamNameMap[apiSvc.Owner.ID] = struct{}{}
   136  				teamIDs = append(teamIDs, apiSvc.Owner.ID)
   137  			}
   138  		}
   139  	}
   140  
   141  	return teamIDs
   142  }
   143  
   144  // DeleteAPIService - remove APIService resource from cache based on externalAPIID or externalAPIPrimaryKey
   145  func (c *cacheManager) DeleteAPIService(key string) error {
   146  	defer c.setCacheUpdated(true)
   147  
   148  	err := c.apiMap.Delete(key)
   149  	if err != nil {
   150  		err = c.apiMap.DeleteBySecondaryKey(key)
   151  	}
   152  	return err
   153  }
   154  
   155  // FormatKey -
   156  func (c *cacheManager) FormatKey(svcName string) string {
   157  	formatKey := fmt.Sprintf("count-%v", svcName)
   158  	return formatKey
   159  }
   160  
   161  func (c *cacheManager) addToServiceInstanceCount(apiID, primaryKey string) error {
   162  	svc := c.GetAPIServiceWithPrimaryKey(primaryKey)
   163  	if svc == nil {
   164  		svc = c.GetAPIServiceWithAPIID(apiID)
   165  		if svc == nil {
   166  			// can't increment a count for a service we can't find
   167  			c.logger.
   168  				WithField("primary-key", primaryKey).
   169  				WithField("api-id", apiID).
   170  				Debug("cannot increment a count for a service we cannot find")
   171  			return nil
   172  		}
   173  	}
   174  	key := c.FormatKey(svc.Name)
   175  
   176  	svcCountI, _ := c.instanceCountMap.Get(key)
   177  	svcCount := apiServiceToInstanceCount{}
   178  	if svcCountI == nil {
   179  		svcCount = apiServiceToInstanceCount{
   180  			Count:         0,
   181  			ApiServiceKey: svc.Metadata.ID,
   182  		}
   183  	} else {
   184  		svcCount = svcCountI.(apiServiceToInstanceCount)
   185  	}
   186  	svcCount.Count++
   187  
   188  	c.instanceCountMap.Set(key, svcCount)
   189  	return nil
   190  }
   191  
   192  func (c *cacheManager) removeFromServiceInstanceCount(apiID, primaryKey string) error {
   193  	svc := c.GetAPIServiceWithPrimaryKey(primaryKey)
   194  	if svc == nil {
   195  		svc = c.GetAPIServiceWithAPIID(apiID)
   196  		if svc == nil {
   197  			// can't decrement a count for a service we can't find
   198  			return nil
   199  		}
   200  	}
   201  	key := c.FormatKey(svc.Name)
   202  
   203  	svcCountI, err := c.instanceCountMap.Get(key)
   204  	if err != nil {
   205  		return err
   206  	}
   207  	svcCount := apiServiceToInstanceCount{}
   208  	if svcCountI != nil {
   209  		svcCount = svcCountI.(apiServiceToInstanceCount)
   210  		svcCount.Count--
   211  	}
   212  
   213  	c.instanceCountMap.Set(key, svcCount)
   214  	return nil
   215  }
   216  
   217  func (c *cacheManager) deleteAllServiceInstanceCounts() {
   218  	c.instanceCountMap.Flush()
   219  }
   220  
   221  func (c *cacheManager) GetAPIServiceInstanceCount(svcName string) int {
   222  	svc := c.GetAPIServiceWithName(svcName)
   223  
   224  	// get apiid and primary key
   225  	apiID, _ := util.GetAgentDetailsValue(svc, defs.AttrExternalAPIID)
   226  	primaryKey, _ := util.GetAgentDetailsValue(svc, defs.AttrExternalAPIPrimaryKey)
   227  
   228  	count := 0
   229  	for _, k := range c.instanceMap.GetKeys() {
   230  		item, _ := c.instanceMap.Get(k)
   231  		inst, ok := item.(*v1.ResourceInstance)
   232  		if !ok {
   233  			continue
   234  		}
   235  		instAPIID, _ := util.GetAgentDetailsValue(inst, defs.AttrExternalAPIID)
   236  		instPrimary, _ := util.GetAgentDetailsValue(inst, defs.AttrExternalAPIPrimaryKey)
   237  		if apiID == instAPIID || primaryKey == instPrimary {
   238  			count++
   239  		}
   240  	}
   241  
   242  	return count
   243  }