github.com/Axway/agent-sdk@v1.1.101/pkg/apic/apiserver/models/api/v1/resourceinstance.go (about)

     1  package v1
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"fmt"
     7  )
     8  
     9  // Interface describes API Server & catalog resources
    10  type Interface interface {
    11  	Meta
    12  	AsInstance() (*ResourceInstance, error)
    13  	FromInstance(from *ResourceInstance) error
    14  }
    15  
    16  // ResourceInstance API Server generic resource structure.
    17  type ResourceInstance struct {
    18  	ResourceMeta
    19  	Owner *Owner `json:"owner"`
    20  	// Resource instance specs.
    21  	Spec        map[string]interface{} `json:"spec"`
    22  	rawResource json.RawMessage
    23  }
    24  
    25  // UnmarshalJSON - custom unmarshaler for ResourceInstance struct to additionally use a custom subscriptionField
    26  func (ri *ResourceInstance) UnmarshalJSON(data []byte) error {
    27  	type Alias ResourceInstance // Create an intermediate type to unmarshal the base attributes
    28  	if err := json.Unmarshal(data, &struct{ *Alias }{Alias: (*Alias)(ri)}); err != nil {
    29  		return err
    30  	}
    31  
    32  	// unmarshall the rest of the resources here, and set them on the ResourceInstance manually
    33  	out := map[string]interface{}{}
    34  	err := json.Unmarshal(data, &out)
    35  	if err != nil {
    36  		return err
    37  	}
    38  
    39  	if out["spec"] != nil {
    40  		v, ok := out["spec"].(map[string]interface{})
    41  		if !ok {
    42  			return fmt.Errorf("spec is not a map[string]interface{}")
    43  		}
    44  		ri.Spec = v
    45  	}
    46  
    47  	if out["owner"] != nil {
    48  		var err error
    49  		ri.Owner = &Owner{}
    50  		bts, err := json.Marshal(out["owner"])
    51  		if err != nil {
    52  			return err
    53  		}
    54  		err = json.Unmarshal(bts, ri.Owner)
    55  		if err != nil {
    56  			return err
    57  		}
    58  	}
    59  
    60  	// clean up any unnecessary chars from json byte array
    61  	byteBuf := bytes.Buffer{}
    62  	err = json.Compact(&byteBuf, data)
    63  	if err != nil {
    64  		return err
    65  	}
    66  
    67  	ri.rawResource = byteBuf.Bytes()
    68  	return nil
    69  }
    70  
    71  // MarshalJSON - custom marshaller for ResourceInstance to save the rawResource json to unmarshal specific types
    72  func (ri *ResourceInstance) MarshalJSON() ([]byte, error) {
    73  	// unmarshal the rawResource to map[string]interface{}
    74  	rawStruct := map[string]interface{}{}
    75  	if ri.rawResource != nil {
    76  		if err := json.Unmarshal(ri.rawResource, &rawStruct); err != nil {
    77  			return []byte{}, err
    78  		}
    79  	}
    80  
    81  	// marshal the current resource instance then unmarshal it into map[string]interface{}{}
    82  	type Alias ResourceInstance // Create an intermittent type to marshal the base attributes
    83  	riAlias, err := json.Marshal(&struct{ *Alias }{Alias: (*Alias)(ri)})
    84  	if err != nil {
    85  		return nil, err
    86  	}
    87  
    88  	rawInstance := map[string]interface{}{}
    89  	if err := json.Unmarshal(riAlias, &rawInstance); err != nil {
    90  		return []byte{}, err
    91  	}
    92  
    93  	rawInstance["spec"] = ri.Spec
    94  	rawInstance["owner"] = ri.Owner
    95  
    96  	// override the rawStruct map with the values from the rawInstance map
    97  	for key, value := range rawInstance {
    98  		rawStruct[key] = value
    99  	}
   100  
   101  	// return the marshal of the rawStruct
   102  	return json.Marshal(rawStruct)
   103  }
   104  
   105  // AsInstance returns the ResourceInstance
   106  func (ri *ResourceInstance) AsInstance() (*ResourceInstance, error) {
   107  	return ri, nil
   108  }
   109  
   110  // FromInstance sets the underlying ResourceInstance
   111  func (ri *ResourceInstance) FromInstance(from *ResourceInstance) error {
   112  	*ri = *from
   113  
   114  	return nil
   115  }
   116  
   117  // GetRawResource gets the resource as bytes
   118  func (ri *ResourceInstance) GetRawResource() json.RawMessage {
   119  	return ri.rawResource
   120  }