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