1package crr 2 3import ( 4 "net/url" 5 "sort" 6 "strings" 7 "time" 8 9 "github.com/aws/aws-sdk-go/aws" 10) 11 12// Endpoint represents an endpoint used in endpoint discovery. 13type Endpoint struct { 14 Key string 15 Addresses WeightedAddresses 16} 17 18// WeightedAddresses represents a list of WeightedAddress. 19type WeightedAddresses []WeightedAddress 20 21// WeightedAddress represents an address with a given weight. 22type WeightedAddress struct { 23 URL *url.URL 24 Expired time.Time 25} 26 27// HasExpired will return whether or not the endpoint has expired with 28// the exception of a zero expiry meaning does not expire. 29func (e WeightedAddress) HasExpired() bool { 30 return e.Expired.Before(time.Now()) 31} 32 33// Add will add a given WeightedAddress to the address list of Endpoint. 34func (e *Endpoint) Add(addr WeightedAddress) { 35 e.Addresses = append(e.Addresses, addr) 36} 37 38// Len returns the number of valid endpoints where valid means the endpoint 39// has not expired. 40func (e *Endpoint) Len() int { 41 validEndpoints := 0 42 for _, endpoint := range e.Addresses { 43 if endpoint.HasExpired() { 44 continue 45 } 46 47 validEndpoints++ 48 } 49 return validEndpoints 50} 51 52// GetValidAddress will return a non-expired weight endpoint 53func (e *Endpoint) GetValidAddress() (WeightedAddress, bool) { 54 for i := 0; i < len(e.Addresses); i++ { 55 we := e.Addresses[i] 56 57 if we.HasExpired() { 58 e.Addresses = append(e.Addresses[:i], e.Addresses[i+1:]...) 59 i-- 60 continue 61 } 62 63 return we, true 64 } 65 66 return WeightedAddress{}, false 67} 68 69// Discoverer is an interface used to discovery which endpoint hit. This 70// allows for specifics about what parameters need to be used to be contained 71// in the Discoverer implementor. 72type Discoverer interface { 73 Discover() (Endpoint, error) 74} 75 76// BuildEndpointKey will sort the keys in alphabetical order and then retrieve 77// the values in that order. Those values are then concatenated together to form 78// the endpoint key. 79func BuildEndpointKey(params map[string]*string) string { 80 keys := make([]string, len(params)) 81 i := 0 82 83 for k := range params { 84 keys[i] = k 85 i++ 86 } 87 sort.Strings(keys) 88 89 values := make([]string, len(params)) 90 for i, k := range keys { 91 if params[k] == nil { 92 continue 93 } 94 95 values[i] = aws.StringValue(params[k]) 96 } 97 98 return strings.Join(values, ".") 99} 100