github.com/Axway/agent-sdk@v1.1.101/pkg/util/subresource.go (about) 1 package util 2 3 import ( 4 "fmt" 5 "reflect" 6 7 "github.com/Axway/agent-sdk/pkg/apic/definitions" 8 defs "github.com/Axway/agent-sdk/pkg/apic/definitions" 9 ) 10 11 // handler is an interface for handling sub resources on apiserver items 12 type handler interface { 13 // GetSubResource gets a sub resource by name 14 GetSubResource(key string) interface{} 15 // SetSubResource saves a value to a sub resource by name and overrides the current value. 16 SetSubResource(key string, resource interface{}) 17 } 18 19 func GetSubResourceDetails(h handler) map[string]interface{} { 20 if h == nil { 21 return nil 22 } 23 return map[string]interface{}{definitions.XAgentDetails: GetAgentDetails(h)} 24 } 25 26 // GetAgentDetails get all the values for the x-agent-details sub resource 27 func GetAgentDetails(h handler) map[string]interface{} { 28 if h == nil { 29 return nil 30 } 31 32 item := h.GetSubResource(defs.XAgentDetails) 33 if item == nil { 34 return nil 35 } 36 37 sub, err := convert(defs.XAgentDetails, item) 38 if err != nil { 39 return nil 40 } 41 42 return sub 43 } 44 45 // GetAgentDetailStrings get all the values for the x-agent-details sub resource as string 46 func GetAgentDetailStrings(h handler) map[string]string { 47 details := GetAgentDetails(h) 48 if details == nil { 49 return nil 50 } 51 52 strMap := make(map[string]string) 53 54 for k, v := range details { 55 strMap[k] = fmt.Sprint(v) 56 } 57 return strMap 58 } 59 60 // GetAgentDetailsValue gets a single string value fom the x-agent-details sub resource. 61 // Returns nil for error if x-agent-details does not exist. 62 // Returns errors if unable to perform type conversion. 63 // Returns an empty string if the value does not exist, or if there is an error. 64 func GetAgentDetailsValue(h handler, key string) (string, error) { 65 return GetSubResourcePropertyValue(h, defs.XAgentDetails, key) 66 } 67 68 // GetSubResourcePropertyValue gets a single string value fom the specified sub resource. 69 // Returns nil for error if specified does not exist. 70 // Returns errors if unable to perform type conversion. 71 // Returns an empty string if the value does not exist, or if there is an error. 72 func GetSubResourcePropertyValue(h handler, subRes, key string) (string, error) { 73 // check for a nil value, or a pointer to a nil value 74 if IsNil(h) { 75 return "", nil 76 } 77 78 item := h.GetSubResource(subRes) 79 if item == nil { 80 return "", nil 81 } 82 83 sub, err := convert(subRes, item) 84 if err != nil { 85 return "", err 86 } 87 88 item, ok := sub[key] 89 if !ok { 90 return "", fmt.Errorf("key %s not found in %s", key, subRes) 91 } 92 93 switch v := item.(type) { 94 case int: 95 return fmt.Sprintf("%d", v), nil 96 case string: 97 return v, nil 98 default: 99 return "", fmt.Errorf( 100 "%s keys should be a string or int. Received type %T for key %s", 101 subRes, 102 v, 103 key, 104 ) 105 } 106 } 107 108 // SetAgentDetailsKey sets a key value pair in the x-agent-details sub resource. If x-agent-details does not exist, it is created. 109 // If value is not a string or an int, an error will be returned. 110 func SetAgentDetailsKey(h handler, key, value string) error { 111 item := h.GetSubResource(defs.XAgentDetails) 112 if item == nil { 113 h.SetSubResource(defs.XAgentDetails, map[string]interface{}{key: value}) 114 return nil 115 } 116 117 sub, err := convert(defs.XAgentDetails, item) 118 if err != nil { 119 return err 120 } 121 122 sub[key] = value 123 124 h.SetSubResource(defs.XAgentDetails, sub) 125 return nil 126 } 127 128 // SetAgentDetails creates a new x-agent-details sub resource for the given resource. 129 func SetAgentDetails(h handler, details map[string]interface{}) { 130 h.SetSubResource(defs.XAgentDetails, details) 131 } 132 133 func convert(subResName string, item interface{}) (map[string]interface{}, error) { 134 switch v := item.(type) { 135 case map[string]interface{}: 136 return v, nil 137 default: 138 return nil, fmt.Errorf( 139 "unable to convert %s to type 'AgentDetails'. Received type %T", 140 subResName, 141 item, 142 ) 143 } 144 } 145 146 func MapsEqual(m1, m2 map[string]interface{}) bool { 147 // Check if the maps have the same number of keys 148 if len(m1) != len(m2) { 149 return false 150 } 151 152 // Check if each key in m1 exists in m2 and has the same value 153 for k, v1 := range m1 { 154 if v2, ok := m2[k]; !ok || !reflect.DeepEqual(v1, v2) { 155 return false 156 } 157 } 158 159 // Check if each key in m2 exists in m1 (to ensure both maps have the same keys) 160 for k := range m2 { 161 if _, ok := m1[k]; !ok { 162 return false 163 } 164 } 165 166 return true 167 }