Newer
Older
package nucleus
import (
"encoding/json"
"io/ioutil"
"sync"
"code.fbi.h-da.de/danet/gosdn/controller/interfaces/device"
"code.fbi.h-da.de/danet/gosdn/controller/interfaces/southbound"
"code.fbi.h-da.de/danet/gosdn/controller/nucleus/errors"
"code.fbi.h-da.de/danet/gosdn/controller/store"
"github.com/google/uuid"
)
// FilesystemDeviceStore is the filesystem implementation of the device store
type FilesystemDeviceStore struct {
sbiStore southbound.Store
pndUUID uuid.UUID
fileMutex sync.Mutex
pathToDeviceFile string
}
// NewFilesystemDeviceStore returns a filesystem implementation for a pnd store.
func NewFilesystemDeviceStore(pndUUID uuid.UUID) device.Store {
deviceFilenameForUUID := store.GetStoreFilenameForUUID(pndUUID, store.DeviceFilenameSuffix)
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
store.EnsureFilesystemStorePathExists(deviceFilenameForUUID)
return &FilesystemDeviceStore{
pathToDeviceFile: store.GetCompletePathToFileStore(deviceFilenameForUUID),
fileMutex: sync.Mutex{},
pndUUID: pndUUID,
}
}
func (s *FilesystemDeviceStore) readAllDevicesFromFile() ([]device.LoadedDevice, error) {
var loadedDevices []device.LoadedDevice
content, err := ioutil.ReadFile(s.pathToDeviceFile)
if err != nil {
return nil, err
}
err = json.Unmarshal(content, &loadedDevices)
if err != nil {
return nil, err
}
return loadedDevices, nil
}
func (s *FilesystemDeviceStore) writeAllDevicesToFile(devices []device.LoadedDevice) error {
serializedData, err := json.Marshal(devices)
if err != nil {
return err
}
err = ioutil.WriteFile(s.pathToDeviceFile, serializedData, 0600)
if err != nil {
return err
}
return nil
}
// Get takes a Device's UUID or name and returns the Device.
func (s *FilesystemDeviceStore) Get(query store.Query) (device.LoadedDevice, error) {
s.fileMutex.Lock()
defer s.fileMutex.Unlock()
var device device.LoadedDevice
devices, err := s.readAllDevicesFromFile()
if err != nil {
return device, err
}
for _, device := range devices {
if device.ID == query.ID.String() || device.Name == query.Name {
return device, nil
}
}
Fabian Seidl
committed
return device, &errors.ErrCouldNotFind{ID: query.ID, Name: query.Name}
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
}
// GetAll returns all stored devices.
func (s *FilesystemDeviceStore) GetAll() ([]device.LoadedDevice, error) {
s.fileMutex.Lock()
defer s.fileMutex.Unlock()
devices, err := s.readAllDevicesFromFile()
return devices, err
}
// Add adds a device to the device store.
func (s *FilesystemDeviceStore) Add(deviceToAdd device.Device) error {
s.fileMutex.Lock()
defer s.fileMutex.Unlock()
devices, err := s.readAllDevicesFromFile()
if err != nil {
return err
}
var loadedDevice device.LoadedDevice
loadedDevice, err = store.TransformObjectToLoadedObject[device.Device, device.LoadedDevice](deviceToAdd)
if err != nil {
return err
}
devices = append(devices, loadedDevice)
err = s.writeAllDevicesToFile(devices)
if err != nil {
return err
}
return nil
}
// Update updates a existing device.
func (s *FilesystemDeviceStore) Update(deviceToUpdate device.Device) error {
s.fileMutex.Lock()
defer s.fileMutex.Unlock()
Neil-Jocelyn Schark
committed
loadedDeviceToUpdate, err := store.TransformObjectToLoadedObject[device.Device, device.LoadedDevice](deviceToUpdate)
devices, err := s.readAllDevicesFromFile()
if err != nil {
return err
}
for i, device := range devices {
if device.ID == deviceToUpdate.ID().String() {
Neil-Jocelyn Schark
committed
devices[i] = loadedDeviceToUpdate
err = s.writeAllDevicesToFile(devices)
if err != nil {
return err
}
Neil-Jocelyn Schark
committed
return nil
return &errors.ErrCouldNotUpdate{Identifier: deviceToUpdate.ID(), Type: deviceToUpdate, Err: err}
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
}
// Delete deletes a device from the device store.
func (s *FilesystemDeviceStore) Delete(deviceToDelete device.Device) error {
s.fileMutex.Lock()
defer s.fileMutex.Unlock()
devices, err := s.readAllDevicesFromFile()
if err != nil {
return err
}
for i, device := range devices {
if device.ID == deviceToDelete.ID().String() {
//remove item from slice
devices[i] = devices[len(devices)-1]
devices = devices[:len(devices)-1]
err = s.writeAllDevicesToFile(devices)
if err != nil {
return err
}
return nil
}
}
return &errors.ErrCouldNotDelete{Identifier: deviceToDelete.ID(), Type: deviceToDelete, Err: err}