/
memory_application.go
132 lines (114 loc) · 3.55 KB
/
memory_application.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
package memstore
//
//Copyright 2018 Telenor Digital AS
//
//Licensed under the Apache License, Version 2.0 (the "License");
//you may not use this file except in compliance with the License.
//You may obtain a copy of the License at
//
//http://www.apache.org/licenses/LICENSE-2.0
//
//Unless required by applicable law or agreed to in writing, software
//distributed under the License is distributed on an "AS IS" BASIS,
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//See the License for the specific language governing permissions and
//limitations under the License.
//
import (
"sync"
"github.com/ExploratoryEngineering/congress/model"
"github.com/ExploratoryEngineering/congress/protocol"
"github.com/ExploratoryEngineering/congress/storage"
)
type appUser struct {
app model.Application
userID model.UserID
}
// memoryApplicationStorage is a memory implementation of the ApplicationStorage implementation
type memoryApplicationStorage struct {
applications map[protocol.EUI]appUser
mutex *sync.Mutex
devices storage.DeviceStorage
}
// NewMemoryApplicationStorage returns a new instance of MemoryApplicationStorage
func NewMemoryApplicationStorage(deviceStorage storage.DeviceStorage) storage.ApplicationStorage {
ret := memoryApplicationStorage{
applications: make(map[protocol.EUI]appUser),
mutex: &sync.Mutex{},
devices: deviceStorage,
}
return &ret
}
// Put stores a new application
func (m *memoryApplicationStorage) Put(application model.Application, userID model.UserID) error {
m.mutex.Lock()
defer m.mutex.Unlock()
_, exists := m.applications[application.AppEUI]
if exists {
return storage.ErrAlreadyExists
}
m.applications[application.AppEUI] = appUser{application, userID}
return nil
}
// GetByEUI returns the application that matches the specified EUI
func (m *memoryApplicationStorage) GetByEUI(eui protocol.EUI, userID model.UserID) (model.Application, error) {
m.mutex.Lock()
defer m.mutex.Unlock()
app, exists := m.applications[eui]
if !exists || app.userID != userID {
return model.Application{}, storage.ErrNotFound
}
return app.app, nil
}
func appSendFunc(list []model.Application, ch chan model.Application) {
for _, val := range list {
ch <- val
}
close(ch)
}
// GetByNetworkEUI returns a channel with all applications in a given network
func (m *memoryApplicationStorage) GetList(userID model.UserID) (chan model.Application, error) {
m.mutex.Lock()
defer m.mutex.Unlock()
var ret []model.Application
for _, app := range m.applications {
if app.userID == userID {
ret = append(ret, app.app)
}
}
sendCh := make(chan model.Application)
go appSendFunc(ret, sendCh)
return sendCh, nil
}
func (m *memoryApplicationStorage) Delete(eui protocol.EUI, userID model.UserID) error {
m.mutex.Lock()
defer m.mutex.Unlock()
existing, exists := m.applications[eui]
if !exists || existing.userID != userID {
return storage.ErrNotFound
}
devices, err := m.devices.GetByApplicationEUI(eui)
if err != nil {
return err
}
for range devices {
return storage.ErrDeleteConstraint
}
delete(m.applications, eui)
return nil
}
func (m *memoryApplicationStorage) Update(application model.Application, userID model.UserID) error {
m.mutex.Lock()
defer m.mutex.Unlock()
app, exists := m.applications[application.AppEUI]
if !exists || app.userID != userID {
return storage.ErrNotFound
}
app.app.Tags = application.Tags
m.applications[application.AppEUI] = app
return nil
}
// Close releases all of the allocated resources
func (m *memoryApplicationStorage) Close() {
// nothing
}