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 }