6800d2bb78f20302e3d42004e9e5fb1bd8f70c0c
[ric-plt/e2mgr.git] / E2Manager / managers / e2t_instances_manager.go
1 //
2 // Copyright 2019 AT&T Intellectual Property
3 // Copyright 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 package managers
19
20 import (
21         "e2mgr/e2managererrors"
22         "e2mgr/logger"
23         "e2mgr/services"
24         "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
25         "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
26         "math"
27         "sync"
28 )
29
30 type E2TInstancesManager struct {
31         rnibDataService services.RNibDataService
32         logger          *logger.Logger
33         mux             sync.Mutex
34 }
35
36 type IE2TInstancesManager interface {
37         GetE2TInstance(e2tAddress string) (*entities.E2TInstance, error)
38         GetE2TInstances() ([]*entities.E2TInstance, error)
39         AddE2TInstance(e2tAddress string) error
40         RemoveE2TInstance(e2tInstance *entities.E2TInstance) error
41         SelectE2TInstance() (string, error)
42         AssociateRan(ranName string, e2tAddress string) error
43         DissociateRan(ranName string, e2tAddress string) error
44 }
45
46 func NewE2TInstancesManager(rnibDataService services.RNibDataService, logger *logger.Logger) *E2TInstancesManager {
47         return &E2TInstancesManager{
48                 rnibDataService: rnibDataService,
49                 logger:          logger,
50         }
51 }
52
53 func (m *E2TInstancesManager) GetE2TInstance(e2tAddress string) (*entities.E2TInstance, error) {
54         e2tInstance, err := m.rnibDataService.GetE2TInstance(e2tAddress)
55
56         if err != nil {
57
58                 _, ok := err.(*common.ResourceNotFoundError)
59
60                 if !ok {
61                         m.logger.Errorf("#E2TInstancesManager.GetE2TInstance - E2T Instance address: %s - Failed retrieving E2TInstance. error: %s", e2tAddress, err)
62                 } else {
63                         m.logger.Infof("#E2TInstancesManager.GetE2TInstance - E2T Instance address: %s not found on DB", e2tAddress)
64                 }
65         }
66
67         return e2tInstance, err
68 }
69
70 func (m *E2TInstancesManager) GetE2TInstances() ([]*entities.E2TInstance, error) {
71         e2tAddresses, err := m.rnibDataService.GetE2TAddresses()
72
73         if err != nil {
74                 m.logger.Errorf("#E2TInstancesManager.GetE2TInstances - Failed retrieving E2T addresses. error: %s", err)
75                 return nil, err
76         }
77
78         if len(e2tAddresses) == 0 {
79                 m.logger.Infof("#E2TInstancesManager.GetE2TInstances - Empty E2T addresses list")
80                 return []*entities.E2TInstance{}, nil
81         }
82
83         e2tInstances, err := m.rnibDataService.GetE2TInstances(e2tAddresses)
84
85         if err != nil {
86                 m.logger.Errorf("#E2TInstancesManager.GetE2TInstances - Failed retrieving E2T instances list. error: %s", err)
87                 return e2tInstances, err
88         }
89
90         if len(e2tInstances) == 0 {
91                 m.logger.Warnf("#E2TInstancesManager.GetE2TInstances - Empty E2T instances list")
92                 return e2tInstances, nil
93         }
94
95         return e2tInstances, nil
96 }
97
98 func findActiveE2TInstanceWithMinimumAssociatedRans(e2tInstances []*entities.E2TInstance) *entities.E2TInstance {
99         var minInstance *entities.E2TInstance
100         minAssociatedRanCount := math.MaxInt32
101
102         for _, v := range e2tInstances {
103                 if v.State == entities.Active && len(v.AssociatedRanList) < minAssociatedRanCount {
104                         minAssociatedRanCount = len(v.AssociatedRanList)
105                         minInstance = v
106                 }
107         }
108
109         return minInstance
110 }
111
112 func (m *E2TInstancesManager) AddE2TInstance(e2tAddress string) error {
113
114         m.mux.Lock()
115         defer m.mux.Unlock()
116
117         e2tInstance := entities.NewE2TInstance(e2tAddress)
118         err := m.rnibDataService.SaveE2TInstance(e2tInstance)
119
120         if err != nil {
121                 m.logger.Errorf("#E2TInstancesManager.AddE2TInstance - E2T Instance address: %s - Failed saving E2T instance. error: %s", e2tInstance.Address, err)
122                 return err
123         }
124
125
126         e2tAddresses, err := m.rnibDataService.GetE2TAddresses()
127
128         if err != nil {
129
130                 _, ok := err.(*common.ResourceNotFoundError)
131
132                 if !ok {
133                         m.logger.Errorf("#E2TInstancesManager.AddE2TInstance - E2T Instance address: %s - Failed retrieving E2T addresses list. error: %s", e2tInstance.Address, err)
134                         return err
135                 }
136         }
137
138         e2tAddresses = append(e2tAddresses, e2tInstance.Address)
139
140         err = m.rnibDataService.SaveE2TAddresses(e2tAddresses)
141
142         if err != nil {
143                 m.logger.Errorf("#E2TInstancesManager.AddE2TInstance - E2T Instance address: %s - Failed saving E2T addresses list. error: %s", e2tInstance.Address, err)
144                 return err
145         }
146
147         m.logger.Infof("#E2TInstancesManager.AddE2TInstance - E2T Instance address: %s - successfully added E2T instance", e2tInstance.Address)
148         return nil
149 }
150
151 func (m *E2TInstancesManager) DissociateRan(ranName string, e2tAddress string) error {
152
153         m.mux.Lock()
154         defer m.mux.Unlock()
155
156         e2tInstance, err := m.rnibDataService.GetE2TInstance(e2tAddress)
157
158         if err != nil {
159                 m.logger.Errorf("#E2TInstancesManager.DissociateRan - E2T Instance address: %s - Failed retrieving E2TInstance. error: %s", e2tAddress, err)
160                 return err
161         }
162
163         i := 0 // output index
164         for _, v := range e2tInstance.AssociatedRanList {
165                 if v != ranName {
166                         // copy and increment index
167                         e2tInstance.AssociatedRanList[i] = v
168                         i++
169                 }
170         }
171
172         e2tInstance.AssociatedRanList = e2tInstance.AssociatedRanList[:i]
173
174         err = m.rnibDataService.SaveE2TInstance(e2tInstance)
175
176         if err != nil {
177                 m.logger.Errorf("#E2TInstancesManager.DissociateRan - E2T Instance address: %s - Failed saving E2TInstance. error: %s", e2tAddress, err)
178                 return err
179         }
180
181         m.logger.Infof("#E2TInstancesManager.DissociateRan - successfully dissociated RAN %s from E2T %s", ranName, e2tInstance.Address)
182         return nil
183 }
184
185 func (m *E2TInstancesManager) RemoveE2TInstance(e2tInstance *entities.E2TInstance) error {
186         return nil
187 }
188 func (m *E2TInstancesManager) SelectE2TInstance() (string, error) {
189
190         e2tInstances, err := m.GetE2TInstances()
191
192         if err != nil {
193                 return "", e2managererrors.NewRnibDbError()
194         }
195
196         if len(e2tInstances) == 0 {
197                 m.logger.Errorf("#E2TInstancesManager.SelectE2TInstance - No E2T instance found")
198                 return "", e2managererrors.NewE2TInstanceAbsenceError()
199         }
200
201         min := findActiveE2TInstanceWithMinimumAssociatedRans(e2tInstances)
202
203         if min == nil {
204                 m.logger.Errorf("#E2TInstancesManager.SelectE2TInstance - No active E2T instance found")
205                 return "", e2managererrors.NewE2TInstanceAbsenceError()
206         }
207
208         m.logger.Infof("#E2TInstancesManager.SelectE2TInstance - successfully selected E2T instance. address: %s", min.Address)
209         return min.Address, nil
210 }
211
212 func (m *E2TInstancesManager) AssociateRan(ranName string, e2tAddress string) error {
213
214         m.mux.Lock()
215         defer m.mux.Unlock()
216
217         e2tInstance, err := m.rnibDataService.GetE2TInstance(e2tAddress)
218
219         if err != nil {
220                 m.logger.Errorf("#E2TInstancesManager.AssociateRan - E2T Instance address: %s - Failed retrieving E2TInstance. error: %s", e2tAddress, err)
221                 return e2managererrors.NewRnibDbError()
222         }
223
224         e2tInstance.AssociatedRanList = append(e2tInstance.AssociatedRanList, ranName)
225
226         err = m.rnibDataService.SaveE2TInstance(e2tInstance)
227
228         if err != nil {
229                 m.logger.Errorf("#E2TInstancesManager.AssociateRan - E2T Instance address: %s - Failed saving E2TInstance. error: %s", e2tAddress, err)
230                 return e2managererrors.NewRnibDbError()
231         }
232
233         m.logger.Infof("#E2TInstancesManager.AssociateRan - successfully associated RAN %s with E2T %s", ranName, e2tInstance.Address)
234         return nil
235 }