Sync from Azure to LF
[ric-plt/resource-status-manager.git] / RSM / services / rnib_data_service.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 services
19
20 import (
21         "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
22         "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
23         "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/reader"
24         "net"
25         "rsm/configuration"
26         "rsm/logger"
27         "time"
28 )
29
30 type RNibDataService interface {
31         GetNodeb(ranName string) (*entities.NodebInfo, error)
32         GetListNodebIds() ([]*entities.NbIdentity, error)
33         PingRnib() bool
34 }
35
36 type rNibDataService struct {
37         logger             *logger.Logger
38         rnibReaderProvider func() reader.RNibReader
39         maxAttempts        int
40         retryInterval      time.Duration
41 }
42
43 func NewRnibDataService(logger *logger.Logger, config *configuration.Configuration, rnibReaderProvider func() reader.RNibReader) *rNibDataService {
44         return &rNibDataService{
45                 logger:             logger,
46                 rnibReaderProvider: rnibReaderProvider,
47                 maxAttempts:        config.Rnib.MaxRnibConnectionAttempts,
48                 retryInterval:      time.Duration(config.Rnib.RnibRetryIntervalMs) * time.Millisecond,
49         }
50 }
51
52 func (w *rNibDataService) GetNodeb(ranName string) (*entities.NodebInfo, error) {
53         w.logger.Infof("#RnibDataService.GetNodeb - ranName: %s", ranName)
54
55         var nodeb *entities.NodebInfo = nil
56
57         err := w.retry("GetNodeb", func() (err error) {
58                 nodeb, err = w.rnibReaderProvider().GetNodeb(ranName)
59                 return
60         })
61
62         return nodeb, err
63 }
64
65 func (w *rNibDataService) GetListNodebIds() ([]*entities.NbIdentity, error) {
66         w.logger.Infof("#RnibDataService.GetListNodebIds")
67
68         var nodeIds []*entities.NbIdentity = nil
69
70         err := w.retry("GetListNodebIds", func() (err error) {
71                 nodeIds, err = w.rnibReaderProvider().GetListNodebIds()
72                 return
73         })
74
75         return nodeIds, err
76 }
77
78 func (w *rNibDataService) PingRnib() bool {
79         err := w.retry("GetListNodebIds", func() (err error) {
80                 _, err = w.rnibReaderProvider().GetListNodebIds()
81                 return
82         })
83
84         return !isRnibConnectionError(err)
85 }
86
87 func (w *rNibDataService) retry(rnibFunc string, f func() error) (err error) {
88         attempts := w.maxAttempts
89
90         for i := 1; ; i++ {
91                 err = f()
92                 if err == nil {
93                         return
94                 }
95                 if !isRnibConnectionError(err) {
96                         return err
97                 }
98                 if i >= attempts {
99                         w.logger.Errorf("#RnibDataService.retry - after %d attempts of %s, last error: %s", attempts, rnibFunc, err)
100                         return err
101                 }
102                 time.Sleep(w.retryInterval)
103
104                 w.logger.Infof("#RnibDataService.retry - retrying %d %s after error: %s", i, rnibFunc, err)
105         }
106 }
107
108 func isRnibConnectionError(err error) bool {
109         internalErr, ok := err.(*common.InternalError)
110         if !ok {
111                 return false
112         }
113         _, ok = internalErr.Err.(*net.OpError)
114
115         return ok
116 }