-
Notifications
You must be signed in to change notification settings - Fork 51
/
contextstore.go
122 lines (91 loc) · 2.91 KB
/
contextstore.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
package contextstore
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"go.uber.org/zap"
)
type store struct{}
var (
storebasePath = "/var/run/trireme"
)
const (
eventInfoFile = "/eventInfo.data"
)
// NewContextStore returns a handle to a new context store
// The store is maintained in a file hierarchy so if the context id
// already exists calling a storecontext with new id will cause an overwrite
func NewContextStore() ContextStore {
_, err := os.Stat(storebasePath)
if os.IsNotExist(err) {
if err := os.MkdirAll(storebasePath, 0700); err != nil {
zap.L().Fatal("Failed to create context store directory", zap.Error(err))
}
}
return &store{}
}
// NewCustomContextStore will start a context store with custom paths. Mainly
// used for testing when root access is not available and /var/run cannot be accessed
func NewCustomContextStore(basePath string) ContextStore {
storebasePath = basePath
return NewContextStore()
}
// Store context writes to the store the eventInfo which can be used as a event to trireme
func (s *store) StoreContext(contextID string, eventInfo interface{}) error {
if _, err := os.Stat(storebasePath + contextID); os.IsNotExist(err) {
if err := os.MkdirAll(storebasePath+contextID, 0700); err != nil {
return err
}
}
data, err := json.Marshal(eventInfo)
if err != nil {
return err
}
if err = ioutil.WriteFile(storebasePath+contextID+eventInfoFile, data, 0600); err != nil {
return err
}
return nil
}
// GetContextInfo the event corresponding to the store
func (s *store) GetContextInfo(contextID string) (interface{}, error) {
if _, err := os.Stat(storebasePath + contextID); os.IsNotExist(err) {
return nil, fmt.Errorf("Unknown ContextID %s", contextID)
}
data, err := ioutil.ReadFile(storebasePath + contextID + eventInfoFile)
if err != nil {
return nil, fmt.Errorf("Unable to retrieve context from store %s", err.Error())
}
return data, err
}
// RemoveContext the context reference from the store
func (s *store) RemoveContext(contextID string) error {
if _, err := os.Stat(storebasePath + contextID); os.IsNotExist(err) {
return fmt.Errorf("Unknown ContextID %s", contextID)
}
return os.RemoveAll(storebasePath + contextID)
}
// Destroy will clean up the entire state for all services in the system
func (s *store) DestroyStore() error {
if _, err := os.Stat(storebasePath); os.IsNotExist(err) {
return fmt.Errorf("Store Not Initialized")
}
return os.RemoveAll(storebasePath)
}
// WalkStore retrieves all the context store information and returns it in a channel
func (s *store) WalkStore() (chan string, error) {
contextChannel := make(chan string, 1)
files, err := ioutil.ReadDir(storebasePath)
if err != nil {
close(contextChannel)
return contextChannel, fmt.Errorf("Store is empty")
}
go func() {
for _, file := range files {
contextChannel <- file.Name()
}
contextChannel <- ""
close(contextChannel)
}()
return contextChannel, nil
}