2 Copyright (c) 2021 AT&T Intellectual Property.
3 Copyright (c) 2018-2021 Nokia.
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
9 http://www.apache.org/licenses/LICENSE-2.0
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.
19 * This source code is part of the near-RT RIC (RAN Intelligent Controller)
20 * platform project (RICP).
27 "github.com/go-redis/redis/v7"
31 type Sentinel struct {
36 type IredisSentinelClient interface {
37 Master(name string) *redis.StringStringMapCmd
38 Slaves(name string) *redis.SliceCmd
39 Sentinels(name string) *redis.SliceCmd
42 type RedisSentinelCreateCb func(cfg *Config, addr string) *Sentinel
44 func newRedisSentinel(cfg *Config, addr string) *Sentinel {
45 redisAddress := addr + ":" + cfg.sentinelPort
47 IredisSentinelClient: redis.NewSentinelClient(&redis.Options{
49 Password: "", // no password set
50 DB: 0, // use default DB
58 func (s *Sentinel) GetDbState() (*DbState, error) {
60 pState, pErr := s.getPrimaryDbState()
61 rState, rErr := s.getReplicasState()
62 sState, sErr := s.getSentinelsState()
63 state.PrimaryDbState = *pState
64 state.ReplicasDbState = rState
65 state.SentinelsDbState = sState
67 cnt, err := strconv.Atoi(s.Cfg.nodeCnt)
69 state.Err = fmt.Errorf("Sentinel DBAAS_NODE_COUNT configuration value '%s' conversion to integer failed", s.Cfg.nodeCnt)
70 return state, state.Err
72 state.ConfigNodeCnt = cnt
83 func (s *Sentinel) getPrimaryDbState() (*PrimaryDbState, error) {
84 state := new(PrimaryDbState)
85 redisVal, redisErr := s.Master(s.Cfg.masterName).Result()
87 state.Fields.Ip = redisVal["ip"]
88 state.Fields.Port = redisVal["port"]
89 state.Fields.Flags = redisVal["flags"]
90 state.Fields.Role = redisVal["role-reported"]
93 return state, redisErr
96 func (s *Sentinel) getReplicasState() (*ReplicasDbState, error) {
97 states := new(ReplicasDbState)
98 states.States = make([]*ReplicaDbState, 0)
100 redisVal, redisErr := s.Slaves(s.Cfg.masterName).Result()
102 for _, redisReplica := range redisVal {
103 replicaState := readReplicaState(redisReplica.([]interface{}))
104 states.States = append(states.States, replicaState)
107 states.Err = redisErr
108 return states, redisErr
111 func readReplicaState(redisReplicas []interface{}) *ReplicaDbState {
112 state := new(ReplicaDbState)
113 for i := 0; i < len(redisReplicas); i += 2 {
114 if redisReplicas[i].(string) == "ip" {
115 state.Fields.Ip = redisReplicas[i+1].(string)
116 } else if redisReplicas[i].(string) == "port" {
117 state.Fields.Port = redisReplicas[i+1].(string)
118 } else if redisReplicas[i].(string) == "flags" {
119 state.Fields.Flags = redisReplicas[i+1].(string)
120 } else if redisReplicas[i].(string) == "role-reported" {
121 state.Fields.Role = redisReplicas[i+1].(string)
122 } else if redisReplicas[i].(string) == "master-link-status" {
123 state.Fields.PrimaryLinkStatus = redisReplicas[i+1].(string)
129 func (s *Sentinel) getSentinelsState() (*SentinelsDbState, error) {
130 states := new(SentinelsDbState)
131 states.States = make([]*SentinelDbState, 0)
133 redisVal, redisErr := s.Sentinels(s.Cfg.masterName).Result()
135 for _, redisSentinel := range redisVal {
136 sentinelState := readSentinelState(redisSentinel.([]interface{}))
137 // Ignore a sentinel entry with zero port, because missing of fix
138 // for the Redis Bug #9240.
139 if sentinelState.Fields.Port != "0" {
140 states.States = append(states.States, sentinelState)
144 states.Err = redisErr
145 return states, redisErr
148 func readSentinelState(redisSentinels []interface{}) *SentinelDbState {
149 state := new(SentinelDbState)
150 for i := 0; i < len(redisSentinels); i += 2 {
151 if redisSentinels[i].(string) == "ip" {
152 state.Fields.Ip = redisSentinels[i+1].(string)
153 } else if redisSentinels[i].(string) == "port" {
154 state.Fields.Port = redisSentinels[i+1].(string)
155 } else if redisSentinels[i].(string) == "flags" {
156 state.Fields.Flags = redisSentinels[i+1].(string)