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  }