1515package api
1616
1717import (
18+ "errors"
19+ "strings"
20+
21+ azcorearm "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm"
22+
1823 "github.com/Azure/ARO-HCP/internal/api/arm"
1924)
2025
26+ // CosmosMetadata is metadata required for all data we store in cosmos
27+ type CosmosMetadata struct {
28+ // resourceID is used as the cosmosUID after replacing all '/' with '|'
29+ ResourceID azcorearm.ResourceID `json:"resourceID"`
30+
31+ // TODO add an etag that is not serialized to cosmos, but is set on read.
32+ // When non-empty it will cause a conditional replace to be used
33+ // When empty it will cause an unconditional replace
34+ }
35+
36+ func (c * CosmosMetadata ) GetResourceID () azcorearm.ResourceID {
37+ return c .ResourceID
38+ }
39+
40+ func (c * CosmosMetadata ) SetResourceID (resourceID azcorearm.ResourceID ) {
41+ c .ResourceID = resourceID
42+ }
43+
44+ type CosmosMetadataAccessor interface {
45+ GetResourceID () azcorearm.ResourceID
46+ SetResourceID (azcorearm.ResourceID )
47+ }
48+
49+ var _ CosmosPersistable = & CosmosMetadata {}
50+
51+ func (o * CosmosMetadata ) GetCosmosData () CosmosData {
52+ return CosmosData {
53+ CosmosUID : Must (ResourceIDToCosmosID (& o .ResourceID )),
54+ // partitionkeys are case-sensitive in cosmos, so we need all of our cases to be the same
55+ // and we have no guarantee that prior to this the case is consistent.
56+ PartitionKey : strings .ToLower (o .ResourceID .SubscriptionID ),
57+ ItemID : & o .ResourceID ,
58+ }
59+ }
60+
61+ func (o * CosmosMetadata ) SetCosmosDocumentData (cosmosUID string ) {
62+ panic ("not supported" )
63+ }
64+
65+ var _ CosmosMetadataAccessor = & CosmosMetadata {}
66+
2167type CosmosPersistable interface {
2268 GetCosmosData () CosmosData
2369 SetCosmosDocumentData (cosmosUID string )
@@ -26,3 +72,24 @@ type CosmosPersistable interface {
2672// CosmosData contains the information that persisted resources must have for us to support CRUD against them.
2773// These are not (currently) all stored in the same place in our various types.
2874type CosmosData = arm.CosmosData
75+
76+ func ResourceIDToCosmosID (resourceID * azcorearm.ResourceID ) (string , error ) {
77+ if resourceID == nil {
78+ return "" , errors .New ("resource ID is nil" )
79+ }
80+ return ResourceIDStringToCosmosID (resourceID .String ())
81+ }
82+
83+ func ResourceIDStringToCosmosID (resourceID string ) (string , error ) {
84+ if len (resourceID ) == 0 {
85+ return "" , errors .New ("resource ID is empty" )
86+ }
87+ // cosmos uses a REST API, which means that IDs that contain slashes cause problems with URL handling.
88+ // We chose | because that is a delimiter that is not allowed inside of an ARM resource ID because it is a separator
89+ // for multiple resource IDs.
90+ return strings .ReplaceAll (strings .ToLower (resourceID ), "/" , "|" ), nil
91+ }
92+
93+ func CosmosIDToResourceID (resourceID string ) (* azcorearm.ResourceID , error ) {
94+ return azcorearm .ParseResourceID (strings .ReplaceAll (resourceID , "|" , "/" ))
95+ }
0 commit comments