dbee7f1206718fc9d7ac7dce9f148398ca5bc1b2
[ric-plt/sdlgo.git] / sdl.go
1 /*
2    Copyright (c) 2019 AT&T Intellectual Property.
3    Copyright (c) 2018-2019 Nokia.
4
5    Licensed under the Apache License, Version 2.0 (the "License");
6    you may not use this file except in compliance with the License.
7    You may obtain a copy of the License at
8
9        http://www.apache.org/licenses/LICENSE-2.0
10
11    Unless required by applicable law or agreed to in writing, software
12    distributed under the License is distributed on an "AS IS" BASIS,
13    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14    See the License for the specific language governing permissions and
15    limitations under the License.
16 */
17
18 /*
19  * This source code is part of the near-RT RIC (RAN Intelligent Controller)
20  * platform project (RICP).
21  */
22
23 package sdlgo
24
25 import (
26         "gerrit.o-ran-sc.org/r/ric-plt/sdlgo/internal/sdlgoredis"
27         "time"
28 )
29
30 //SdlInstance provides an API to read, write and modify
31 //key-value pairs in a given namespace.
32 //Deprecated: Will be removed in a future release, please use instead SyncStorage
33 //type defined in syncstorage.go.
34 type SdlInstance struct {
35         nameSpace string
36         nsPrefix  string
37         storage   *SyncStorage
38 }
39
40 //Database struct is a holder for the internal database instance. Applications
41 //can use this exported data type to locally store a reference to database
42 //instance returned from NewDabase() function.
43 type Database struct {
44         instances []iDatabase
45 }
46
47 //NewDatabase creates a connection to database that will be used
48 //as a backend for the key-value storage. The returned value
49 //can be reused between multiple SDL instances in which case each instance
50 //is using the same connection.
51 //Deprecated: Will be removed in a future release, because there is no need to
52 //create a database before NewSyncStorage function is called, database will
53 //be created automatically by NewSyncStorage function.
54 func NewDatabase() *Database {
55         db := &Database{}
56         for _, v := range sdlgoredis.Create() {
57                 db.instances = append(db.instances, v)
58         }
59         return db
60 }
61
62 //NewSdlInstance creates a new sdl instance using the given namespace.
63 //The database used as a backend is given as a parameter
64 //Deprecated: Will be removed in a future release, please use NewSyncStorage
65 //function instead.
66 func NewSdlInstance(NameSpace string, db *Database) *SdlInstance {
67         return &SdlInstance{
68                 nameSpace: NameSpace,
69                 nsPrefix:  "{" + NameSpace + "},",
70                 storage:   newSyncStorage(db),
71         }
72 }
73
74 //SubscribeChannel lets you to subscribe for a events on a given channels.
75 //SDL notifications are events that are published on a specific channels.
76 //Both the channel and events are defined by the entity that is publishing
77 //the events.
78 //
79 //When subscribing for a channel, a callback function is given as a parameter.
80 //Whenever a notification is received from a channel, this callback is called
81 //with channel and notifications as parameter (several notifications could be
82 //packed to a single callback function call). A call to SubscribeChannel function
83 //returns immediatelly, callbacks will be called asyncronously.
84 //
85 //It is possible to subscribe to different channels using different callbacks. In
86 //this case simply use SubscribeChannel function separately for each channel.
87 //
88 //When receiving events in callback routine, it is a good practive to return from
89 //callback as quickly as possible. E.g. reading in callback context should be avoided
90 //and using of Go signals is recommended. Also it should be noted that in case of several
91 //events received from different channels, callbacks are called in series one by one.
92 //
93 //Deprecated: Will be removed in a future release, please use the SubscribeChannel
94 //receiver function of the SyncStorage type.
95 func (s *SdlInstance) SubscribeChannel(cb func(string, ...string), channels ...string) error {
96         s.storage.SubscribeChannel(s.nameSpace, cb, channels...)
97         return nil
98 }
99
100 //UnsubscribeChannel removes subscription from one or several channels.
101 //Deprecated: Will be removed in a future release, please use the UnsubscribeChannel
102 //receiver function of the SyncStorage type.
103 func (s *SdlInstance) UnsubscribeChannel(channels ...string) error {
104         return s.storage.UnsubscribeChannel(s.nameSpace, channels...)
105 }
106
107 //Close connection to backend database.
108 //Deprecated: Will be removed in a future release, please use the Close receiver
109 //function of the SyncStorage type.
110 func (s *SdlInstance) Close() error {
111         return s.storage.Close()
112 }
113
114 //SetAndPublish function writes data to shared data layer storage and sends an event to
115 //a channel. Writing is done atomically, i.e. all succeeds or fails.
116 //Data to be written is given as key-value pairs. Several key-value
117 //pairs can be written with one call.
118 //The key is expected to be string whereas value can be anything, string,
119 //number, slice array or map
120 //
121 //If data was set successfully, an event is sent to a channel.
122 //Channels and events are given as pairs is channelsAndEvents parameter.
123 //It is possible to send several events to several channels by giving several
124 //channel-event pairs.
125 //  E.g. []{"channel1", "event1", "channel2", "event2", "channel1", "event3"}
126 //will send event1 and event3 to channel1 and event2 to channel2.
127 //
128 //Deprecated: Will be removed in a future release, please use the SetAndPublish
129 //receiver function of the SyncStorage type.
130 func (s *SdlInstance) SetAndPublish(channelsAndEvents []string, pairs ...interface{}) error {
131         return s.storage.SetAndPublish(s.nameSpace, channelsAndEvents, pairs...)
132 }
133
134 //Set function writes data to shared data layer storage. Writing is done
135 //atomically, i.e. all succeeds or fails.
136 //Data to be written is given as key-value pairs. Several key-value
137 //pairs can be written with one call.
138 //The key is expected to be string whereas value can be anything, string,
139 //number, slice array or map
140 //Deprecated: Will be removed in a future release, please use the Set receiver
141 //function of the SyncStorage type.
142 func (s *SdlInstance) Set(pairs ...interface{}) error {
143         return s.storage.Set(s.nameSpace, pairs...)
144 }
145
146 //Get function atomically reads one or more keys from SDL. The returned map has the
147 //requested keys as index and data as value. If the requested key is not found
148 //from SDL, it's value is nil.
149 //Deprecated: Will be removed in a future release, please use the Get receiver
150 //function of the SyncStorage type.
151 func (s *SdlInstance) Get(keys []string) (map[string]interface{}, error) {
152         return s.storage.Get(s.nameSpace, keys)
153 }
154
155 //SetIfAndPublish atomically replaces existing data with newData in SDL if data matches the oldData.
156 //If replace was done successfully, true will be returned. Also, if publishing was successfull, an event
157 //is published to a given channel.
158 //Deprecated: Will be removed in a future release, please use the SetIfAndPublish
159 //receiver function of the SyncStorage type.
160 func (s *SdlInstance) SetIfAndPublish(channelsAndEvents []string, key string, oldData, newData interface{}) (bool, error) {
161         return s.storage.SetIfAndPublish(s.nameSpace, channelsAndEvents, key, oldData, newData)
162 }
163
164 //SetIf atomically replaces existing data with newData in SDL if data matches the oldData.
165 //If replace was done successfully, true will be returned.
166 //Deprecated: Will be removed in a future release, please use the SetIf receiver
167 //function of the SyncStorage type.
168 func (s *SdlInstance) SetIf(key string, oldData, newData interface{}) (bool, error) {
169         return s.storage.SetIf(s.nameSpace, key, oldData, newData)
170 }
171
172 //SetIfNotExistsAndPublish conditionally sets the value of a key. If key already exists in SDL,
173 //then it's value is not changed. Checking the key existence and potential set operation
174 //is done atomically. If the set operation was done successfully, an event is published to a
175 //given channel.
176 //Deprecated: Will be removed in a future release, please use the SetIfNotExistsAndPublish
177 //receiver function of the SyncStorage type.
178 func (s *SdlInstance) SetIfNotExistsAndPublish(channelsAndEvents []string, key string, data interface{}) (bool, error) {
179         return s.storage.SetIfNotExistsAndPublish(s.nameSpace, channelsAndEvents, key, data)
180 }
181
182 //SetIfNotExists conditionally sets the value of a key. If key already exists in SDL,
183 //then it's value is not changed. Checking the key existence and potential set operation
184 //is done atomically.
185 //Deprecated: Will be removed in a future release, please use the SetIfNotExists
186 //receiver function of the SyncStorage type.
187 func (s *SdlInstance) SetIfNotExists(key string, data interface{}) (bool, error) {
188         return s.storage.SetIfNotExists(s.nameSpace, key, data)
189 }
190
191 //RemoveAndPublish removes data from SDL. Operation is done atomically, i.e. either all succeeds or fails.
192 //Trying to remove a nonexisting key is not considered as an error.
193 //An event is published into a given channel if remove operation is successfull and
194 //at least one key is removed (if several keys given). If the given key(s) doesn't exist
195 //when trying to remove, no event is published.
196 //Deprecated: Will be removed in a future release, please use the RemoveAndPublish
197 //receiver function of the SyncStorage type.
198 func (s *SdlInstance) RemoveAndPublish(channelsAndEvents []string, keys []string) error {
199         return s.storage.RemoveAndPublish(s.nameSpace, channelsAndEvents, keys)
200 }
201
202 //Remove data from SDL. Operation is done atomically, i.e. either all succeeds or fails.
203 //Deprecated: Will be removed in a future release, please use the Remove receiver
204 //function of the SyncStorage type.
205 func (s *SdlInstance) Remove(keys []string) error {
206         return s.storage.Remove(s.nameSpace, keys)
207 }
208
209 //RemoveIfAndPublish removes data from SDL conditionally and if remove was done successfully,
210 //a given event is published to channel. If existing data matches given data,
211 //key and data are removed from SDL. If remove was done successfully, true is returned.
212 //Deprecated: Will be removed in a future release, please use the RemoveIfAndPublish
213 //receiver function of the SyncStorage type.
214 func (s *SdlInstance) RemoveIfAndPublish(channelsAndEvents []string, key string, data interface{}) (bool, error) {
215         return s.storage.RemoveIfAndPublish(s.nameSpace, channelsAndEvents, key, data)
216 }
217
218 //RemoveIf removes data from SDL conditionally. If existing data matches given data,
219 //key and data are removed from SDL. If remove was done successfully, true is returned.
220 //Deprecated: Will be removed in a future release, please use the RemoveIf receiver
221 //function of the SyncStorage type.
222 func (s *SdlInstance) RemoveIf(key string, data interface{}) (bool, error) {
223         return s.storage.RemoveIf(s.nameSpace, key, data)
224 }
225
226 //GetAll returns all keys under the namespace. No prior knowledge about the keys in the
227 //given namespace exists, thus operation is not guaranteed to be atomic or isolated.
228 //Deprecated: Will be removed in a future release, please use the GetAll receiver
229 //function of the SyncStorage type.
230 func (s *SdlInstance) GetAll() ([]string, error) {
231         return s.storage.GetAll(s.nameSpace)
232 }
233
234 //RemoveAll removes all keys under the namespace. Remove operation is not atomic, thus
235 //it is not guaranteed that all keys are removed.
236 //Deprecated: Will be removed in a future release, please use the RemoveAll receiver
237 //function of the SyncStorage type.
238 func (s *SdlInstance) RemoveAll() error {
239         return s.storage.RemoveAll(s.nameSpace)
240 }
241
242 //RemoveAllAndPublish removes all keys under the namespace and if successfull, it
243 //will publish an event to given channel. This operation is not atomic, thus it is
244 //not guaranteed that all keys are removed.
245 //Deprecated: Will be removed in a future release, please use the RemoveAllAndPublish
246 //receiver function of the SyncStorage type.
247 func (s *SdlInstance) RemoveAllAndPublish(channelsAndEvents []string) error {
248         return s.storage.RemoveAllAndPublish(s.nameSpace, channelsAndEvents)
249 }
250
251 //AddMember adds a new members to a group.
252 //
253 //SDL groups are unordered collections of members where each member is
254 //unique. It is possible to add the same member several times without the
255 //need to check if it already exists.
256 //Deprecated: Will be removed in a future release, please use the AddMember
257 //receiver function of the SyncStorage type.
258 func (s *SdlInstance) AddMember(group string, member ...interface{}) error {
259         return s.storage.AddMember(s.nameSpace, group, member...)
260 }
261
262 //RemoveMember removes members from a group.
263 //Deprecated: Will be removed in a future release, please use the RemoveMember
264 //receiver function of the SyncStorage type.
265 func (s *SdlInstance) RemoveMember(group string, member ...interface{}) error {
266         return s.storage.RemoveMember(s.nameSpace, group, member...)
267 }
268
269 //RemoveGroup removes the whole group along with it's members.
270 //Deprecated: Will be removed in a future release, please use the RemoveGroup
271 //receiver function of the SyncStorage type.
272 func (s *SdlInstance) RemoveGroup(group string) error {
273         return s.storage.RemoveGroup(s.nameSpace, group)
274 }
275
276 //GetMembers returns all the members from a group.
277 //Deprecated: Will be removed in a future release, please use the GetMembers
278 //receiver function of the SyncStorage type.
279 func (s *SdlInstance) GetMembers(group string) ([]string, error) {
280         return s.storage.GetMembers(s.nameSpace, group)
281 }
282
283 //IsMember returns true if given member is found from a group.
284 func (s *SdlInstance) IsMember(group string, member interface{}) (bool, error) {
285         return s.storage.IsMember(s.nameSpace, group, member)
286 }
287
288 //GroupSize returns the number of members in a group.
289 //Deprecated: Will be removed in a future release, please use the GroupSize
290 //receiver function of the SyncStorage type.
291 func (s *SdlInstance) GroupSize(group string) (int64, error) {
292         return s.storage.GroupSize(s.nameSpace, group)
293 }
294
295 //LockResource function is used for locking a resource. The resource lock in
296 //practice is a key with random value that is set to expire after a time
297 //period. The value written to key is a random value, thus only the instance
298 //created a lock, can release it. Resource locks are per namespace.
299 //Deprecated: Will be removed in a future release, please use the LockResource
300 //receiver function of the SyncStorage type.
301 func (s *SdlInstance) LockResource(resource string, expiration time.Duration, opt *Options) (*Lock, error) {
302         l, err := s.storage.LockResource(s.nameSpace, resource, expiration, opt)
303         if l != nil {
304                 return &Lock{
305                         s:           s,
306                         storageLock: l,
307                 }, err
308         }
309         return nil, err
310 }
311
312 //ReleaseResource removes the lock from a resource. If lock is already
313 //expired or some other instance is keeping the lock (lock taken after expiration),
314 //an error is returned.
315 //Deprecated: Will be removed in a future release, please use the ReleaseResource
316 //receiver function of the SyncStorageLock type.
317 func (l *Lock) ReleaseResource() error {
318         return l.storageLock.ReleaseResource(l.s.nameSpace)
319 }
320
321 //RefreshResource function can be used to set a new expiration time for the
322 //resource lock (if the lock still exists). The old remaining expiration
323 //time is overwritten with the given new expiration time.
324 //Deprecated: Will be removed in a future release, please use the RefreshResource
325 //receiver function of the SyncStorageLock type.
326 func (l *Lock) RefreshResource(expiration time.Duration) error {
327         return l.storageLock.RefreshResource(l.s.nameSpace, expiration)
328 }
329
330 //CheckResource returns the expiration time left for a resource.
331 //If the resource doesn't exist, -2 is returned.
332 //Deprecated: Will be removed in a future release, please use the CheckResource
333 //receiver function of the SyncStorage type.
334 func (s *SdlInstance) CheckResource(resource string) (time.Duration, error) {
335         return s.storage.CheckResource(s.nameSpace, resource)
336 }
337
338 //Options struct defines the behaviour for getting the resource lock.
339 type Options struct {
340         //The number of time the lock will be tried.
341         //Default: 0 = no retry
342         RetryCount int
343
344         //Wait between the retries.
345         //Default: 100ms
346         RetryWait time.Duration
347 }
348
349 func (o *Options) getRetryCount() int {
350         if o != nil && o.RetryCount > 0 {
351                 return o.RetryCount
352         }
353         return 0
354 }
355
356 func (o *Options) getRetryWait() time.Duration {
357         if o != nil && o.RetryWait > 0 {
358                 return o.RetryWait
359         }
360         return 100 * time.Millisecond
361 }
362
363 //Lock struct identifies the resource lock instance. Releasing and adjusting the
364 //expirations are done using the methods defined for this struct.
365 //Deprecated: Will be removed in a future release, please use instead the SyncStorageLock
366 //type defined in syncstorage.go.
367 type Lock struct {
368         s           *SdlInstance
369         storageLock *SyncStorageLock
370 }