-
Notifications
You must be signed in to change notification settings - Fork 0
/
atlan_tag_cache.go
151 lines (123 loc) · 4.11 KB
/
atlan_tag_cache.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package client
import (
"encoding/json"
"fmt"
"github.com/atlanhq/atlan-go/atlan/model"
"sync"
)
// AtlanTagCache represents a cache for translating between Atlan-internal ID strings
// and human-readable names for Atlan tags.
type AtlanTagCache struct {
atlanClient *AtlanClient
cacheByID map[string]model.AtlanTagDef
mapIDToName map[string]string
mapNameToID map[string]string
deletedIDs map[string]struct{}
deletedNames map[string]struct{}
mutex sync.RWMutex
}
// NewAtlanTagCache creates a new AtlanTagCache instance.
func NewAtlanTagCache(atlanClient *AtlanClient) *AtlanTagCache {
return &AtlanTagCache{
atlanClient: DefaultAtlanClient,
cacheByID: make(map[string]model.AtlanTagDef),
mapIDToName: make(map[string]string),
mapNameToID: make(map[string]string),
deletedIDs: make(map[string]struct{}),
deletedNames: make(map[string]struct{}),
}
}
var (
caches = make(map[string]*AtlanTagCache)
mu sync.Mutex
)
// GetCache returns the AtlanTagCache for the default AtlanClient.
func GetAtlanTagCache() *AtlanTagCache {
client := DefaultAtlanClient
cacheKey := generateCacheKey(client.host, client.ApiKey)
mu.Lock()
defer mu.Unlock()
if _, ok := caches[cacheKey]; !ok {
caches[cacheKey] = &AtlanTagCache{
atlanClient: client,
cacheByID: make(map[string]model.AtlanTagDef),
mapIDToName: make(map[string]string),
mapNameToID: make(map[string]string),
deletedIDs: make(map[string]struct{}),
deletedNames: make(map[string]struct{}),
}
}
return caches[cacheKey]
}
func RefreshCache() {
GetAtlanTagCache().RefreshCache()
}
func GetAtlanTagIDForName(name string) (string, error) {
return GetAtlanTagCache().GetIDForName(name)
}
func GetAtlanTagNameForID(idstr string) (string, error) {
return GetAtlanTagCache().GetNameForID(idstr)
}
// RefreshCache ref reshes the cache of Atlan tags by requesting the full set of Atlan tags from Atlan.
// RefreshCache updates the AtlanTagCache with the latest data from Atlan.
func (c *AtlanTagCache) RefreshCache() error {
c.mutex.Lock()
defer c.mutex.Unlock()
api := &GET_ALL_TYPE_DEFS
response, err := DefaultAtlanClient.CallAPI(api, nil, nil)
if err != nil {
fmt.Printf("Error making API call: %v", err)
return err
}
// Parse the response and populate the cacheByID, mapIDToName, mapNameToID accordingly
var atlanTags model.TypeDefResponse
err = json.Unmarshal(response, &atlanTags)
if err != nil {
return fmt.Errorf("error unmarshalling response: %v", err)
}
c.cacheByID = make(map[string]model.AtlanTagDef)
c.mapIDToName = make(map[string]string)
c.mapNameToID = make(map[string]string)
for _, atlanTag := range atlanTags.AtlanTagDefs {
c.cacheByID[atlanTag.TypeDefBase.GUID] = atlanTag
c.mapIDToName[atlanTag.Name] = atlanTag.DisplayName
c.mapNameToID[atlanTag.DisplayName] = atlanTag.Name
}
return nil
}
// GetIDForName translates the provided human-readable Atlan tag name to its Atlan-internal ID string.
func (c *AtlanTagCache) GetIDForName(name string) (string, error) {
clsID, found := c.mapNameToID[name]
if !found && name != "" {
// If not found, refresh the cache and look again (could be stale)
if err := c.RefreshCache(); err != nil {
return "", err
}
clsID, found = c.mapNameToID[name]
if !found {
// If still not found after refresh, mark it as deleted (could be
// an entry in an audit log that refers to a classification that
// no longer exists)
c.deletedNames[name] = struct{}{}
}
}
return clsID, nil
}
// GetNameForID translates the provided Atlan-internal classification ID string to the human-readable Atlan tag name.
func (c *AtlanTagCache) GetNameForID(idstr string) (string, error) {
clsName, found := c.mapIDToName[idstr]
if !found && idstr != "" {
// If not found, refresh the cache and look again (could be stale)
if err := c.RefreshCache(); err != nil {
return "", err
}
clsName, found = c.mapIDToName[idstr]
if !found {
// If still not found after refresh, mark it as deleted (could be
// an entry in an audit log that refers to a classification that
// no longer exists)
c.deletedIDs[idstr] = struct{}{}
}
}
return clsName, nil
}