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 }