location_resolver.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. /*
  2. * Licensed under the Apache License, Version 2.0 (the "License");
  3. * you may not use this file except in compliance with the License.
  4. * You may obtain a copy of the License at
  5. *
  6. * http://www.apache.org/licenses/LICENSE-2.0
  7. *
  8. * Unless required by applicable law or agreed to in writing, software
  9. * distributed under the License is distributed on an "AS IS" BASIS,
  10. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. * See the License for the specific language governing permissions and
  12. * limitations under the License.
  13. */
  14. package endpoints
  15. import (
  16. "encoding/json"
  17. "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
  18. "sync"
  19. "time"
  20. )
  21. const (
  22. EndpointCacheExpireTime = 3600 //Seconds
  23. )
  24. type Cache struct {
  25. sync.RWMutex
  26. cache map[string]interface{}
  27. }
  28. func (c Cache) Get(k string) (v interface{}) {
  29. c.RLock()
  30. v = c.cache[k]
  31. c.RUnlock()
  32. return
  33. }
  34. func (c Cache) Set(k string, v interface{}) {
  35. c.Lock()
  36. c.cache[k] = v
  37. c.Unlock()
  38. }
  39. var lastClearTimePerProduct = Cache{cache: make(map[string]interface{})}
  40. var endpointCache = Cache{cache: make(map[string]interface{})}
  41. type LocationResolver struct {
  42. }
  43. func (resolver *LocationResolver) TryResolve(param *ResolveParam) (endpoint string, support bool, err error) {
  44. if len(param.LocationProduct) <= 0 {
  45. support = false
  46. return
  47. }
  48. //get from cache
  49. cacheKey := param.Product + "#" + param.RegionId
  50. var ok bool
  51. endpoint, ok = endpointCache.Get(cacheKey).(string)
  52. if ok && len(endpoint) > 0 && !CheckCacheIsExpire(cacheKey) {
  53. support = true
  54. return
  55. }
  56. //get from remote
  57. getEndpointRequest := requests.NewCommonRequest()
  58. getEndpointRequest.Product = "Location"
  59. getEndpointRequest.Version = "2015-06-12"
  60. getEndpointRequest.ApiName = "DescribeEndpoints"
  61. getEndpointRequest.Domain = "location-readonly.aliyuncs.com"
  62. getEndpointRequest.Method = "GET"
  63. getEndpointRequest.Scheme = requests.HTTPS
  64. getEndpointRequest.QueryParams["Id"] = param.RegionId
  65. getEndpointRequest.QueryParams["ServiceCode"] = param.LocationProduct
  66. if len(param.LocationEndpointType) > 0 {
  67. getEndpointRequest.QueryParams["Type"] = param.LocationEndpointType
  68. } else {
  69. getEndpointRequest.QueryParams["Type"] = "openAPI"
  70. }
  71. response, err := param.CommonApi(getEndpointRequest)
  72. var getEndpointResponse GetEndpointResponse
  73. if !response.IsSuccess() {
  74. support = false
  75. return
  76. }
  77. json.Unmarshal([]byte(response.GetHttpContentString()), &getEndpointResponse)
  78. if !getEndpointResponse.Success || getEndpointResponse.Endpoints == nil {
  79. support = false
  80. return
  81. }
  82. if len(getEndpointResponse.Endpoints.Endpoint) <= 0 {
  83. support = false
  84. return
  85. }
  86. if len(getEndpointResponse.Endpoints.Endpoint[0].Endpoint) > 0 {
  87. endpoint = getEndpointResponse.Endpoints.Endpoint[0].Endpoint
  88. endpointCache.Set(cacheKey, endpoint)
  89. lastClearTimePerProduct.Set(cacheKey, time.Now().Unix())
  90. support = true
  91. return
  92. }
  93. support = false
  94. return
  95. }
  96. func CheckCacheIsExpire(cacheKey string) bool {
  97. lastClearTime, ok := lastClearTimePerProduct.Get(cacheKey).(int64)
  98. if !ok {
  99. return true
  100. }
  101. if lastClearTime <= 0 {
  102. lastClearTime = time.Now().Unix()
  103. lastClearTimePerProduct.Set(cacheKey, lastClearTime)
  104. }
  105. now := time.Now().Unix()
  106. elapsedTime := now - lastClearTime
  107. if elapsedTime > EndpointCacheExpireTime {
  108. return true
  109. }
  110. return false
  111. }
  112. type GetEndpointResponse struct {
  113. Endpoints *EndpointsObj
  114. RequestId string
  115. Success bool
  116. }
  117. type EndpointsObj struct {
  118. Endpoint []EndpointObj
  119. }
  120. type EndpointObj struct {
  121. Protocols map[string]string
  122. Type string
  123. Namespace string
  124. Id string
  125. SerivceCode string
  126. Endpoint string
  127. }