Read list type of environment variables 44/7944/2 v0.10.0
authorTimo Tietavainen <timo.tietavainen@nokia.com>
Mon, 14 Mar 2022 05:19:47 +0000 (07:19 +0200)
committerTimo Tietavainen <timo.tietavainen@nokia.com>
Mon, 14 Mar 2022 05:32:54 +0000 (07:32 +0200)
DBAAS Helm Charts appconfig has been changed to have individual ports
and master names for each SDL cluster due to problems seen with DBAAS
upgrade and rollback caused by re-allocation of the same address/port
of Redis to some other SDL cluster. Implement support for new list type
environment variables reading in SDL:
 * DBAAS_SERVICE_PORT
 * DBAAS_SERVICE_SENTINEL_PORT
 * DBAAS_MASTER_NAME

Issue-Id: RIC-698

Signed-off-by: Timo Tietavainen <timo.tietavainen@nokia.com>
Change-Id: I9a9d94e536e0e4e2a174ef0b6fb2beb4c73ef4f5

docs/release-notes.rst
example/example.go
internal/sdlgoredis/sdlgoredis.go
internal/sdlgoredis/sdlgoredis_test.go
internal/sdlgoredis/sdlgosentinel.go

index d792912..bb7fdc4 100644 (file)
@@ -30,6 +30,10 @@ This document provides the release notes of the sdlgo.
 Version history
 ---------------
 
+[0.10.0] - 2022-03-14
+
+* Enable redis/sentinel port and sentinel master name configuration
+
 [0.9.6] - 2022-02-07
 
 * Fix multi-namespace SDL event subscribe
index aee1c19..33a9194 100644 (file)
@@ -26,6 +26,7 @@ import (
        "fmt"
 
        "gerrit.o-ran-sc.org/r/ric-plt/sdlgo"
+       "time"
 )
 
 var sdl *sdlgo.SyncStorage
@@ -59,8 +60,28 @@ func exampleClose() {
        sdl.Close()
 }
 
+func sdlNotify(ch string, events ...string) {
+       fmt.Printf("CB1 channel=%+v, events=%+v\n", ch, events[0])
+}
+
+func sdlNotify2(ch string, events ...string) {
+       fmt.Printf("CB2 channel=%+v, events=%+v\n", ch, events[0])
+}
+
 func main() {
-       exampleSet()
-       exampleGet()
-       exampleClose()
+       sdl.SubscribeChannel("dcapterm_subsRTPM-localhost:55566", sdlNotify, "my-ch")
+       sdl.SubscribeChannel("dcapterm_subsRTPM-localhost:55565", sdlNotify2, "my-ch")
+       time.Sleep(3 * time.Second)
+       sdl.SetAndPublish("dcapterm_subsRTPM-localhost:55566", []string{"my-ch", "my-event1"}, "my-key", "my-data")
+       sdl.SetAndPublish("dcapterm_subsRTPM-localhost:55565", []string{"my-ch", "my-event2"}, "my-key", "my-data")
+
+       time.Sleep(2 * time.Second)
+       //sdl.UnsubscribeChannel("dcapterm_subsRTPM-localhost:55565", "my-ch")
+       //time.Sleep(2 * time.Second)
+       //sdl.SetAndPublish("dcapterm_subsRTPM-localhost:55565", []string{"my-ch", "my-event2"}, "my-key", "my-data")
+       time.Sleep(2 * time.Second)
+
+       //exampleSet()
+       //exampleGet()
+       //exampleClose()
 }
index 9162f39..20ed0bf 100644 (file)
@@ -1,6 +1,6 @@
 /*
    Copyright (c) 2019 AT&T Intellectual Property.
-   Copyright (c) 2018-2019 Nokia.
+   Copyright (c) 2018-2022 Nokia.
 
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
@@ -56,12 +56,12 @@ type sharedCbMap struct {
 }
 
 type Config struct {
-       hostname        string
-       port            string
-       masterName      string
-       sentinelPort    string
-       clusterAddrList string
-       nodeCnt         string
+       hostname      string
+       ports         []string
+       masterNames   []string
+       sentinelPorts []string
+       clusterAddrs  []string
+       nodeCnt       string
 }
 
 type DB struct {
@@ -72,8 +72,11 @@ type DB struct {
        redisModules bool
        sCbMap       *sharedCbMap
        ch           intChannels
-       cfg          Config
        addr         string
+       port         string
+       sentinelPort string
+       masterName   string
+       nodeCnt      string
 }
 
 type Subscriber interface {
@@ -154,7 +157,8 @@ func subscribeNotifications(ctx context.Context, client RedisClient, channels ..
        return client.Subscribe(ctx, channels...)
 }
 
-func CreateDB(client RedisClient, subscribe SubscribeFn, sentinelCreateCb RedisSentinelCreateCb, cfg Config, sentinelAddr string) *DB {
+func CreateDB(client RedisClient, subscribe SubscribeFn, sentinelCreateCb RedisSentinelCreateCb,
+       addr, port, sentinelPort, masterName, nodeCnt string) *DB {
        db := DB{
                ctx:          context.Background(),
                client:       client,
@@ -167,8 +171,11 @@ func CreateDB(client RedisClient, subscribe SubscribeFn, sentinelCreateCb RedisS
                        removeChannel: make(chan string),
                        exit:          make(chan bool),
                },
-               cfg:  cfg,
-               addr: sentinelAddr,
+               addr:         addr,
+               sentinelPort: sentinelPort,
+               port:         port,
+               masterName:   masterName,
+               nodeCnt:      nodeCnt,
        }
 
        return &db
@@ -181,13 +188,23 @@ func Create() []*DB {
 
 func readConfig(osI OS) Config {
        cfg := Config{
-               hostname:        osI.Getenv("DBAAS_SERVICE_HOST", "localhost"),
-               port:            osI.Getenv("DBAAS_SERVICE_PORT", "6379"),
-               masterName:      osI.Getenv("DBAAS_MASTER_NAME", ""),
-               sentinelPort:    osI.Getenv("DBAAS_SERVICE_SENTINEL_PORT", ""),
-               clusterAddrList: osI.Getenv("DBAAS_CLUSTER_ADDR_LIST", ""),
-               nodeCnt:         osI.Getenv("DBAAS_NODE_COUNT", "1"),
+               hostname: osI.Getenv("DBAAS_SERVICE_HOST", "localhost"),
+               ports:    strings.Split(osI.Getenv("DBAAS_SERVICE_PORT", "6379"), ","),
+               nodeCnt:  osI.Getenv("DBAAS_NODE_COUNT", "1"),
        }
+
+       if addrStr := osI.Getenv("DBAAS_CLUSTER_ADDR_LIST", ""); addrStr != "" {
+               cfg.clusterAddrs = strings.Split(addrStr, ",")
+       } else if cfg.hostname != "" {
+               cfg.clusterAddrs = append(cfg.clusterAddrs, cfg.hostname)
+       }
+       if sntPortStr := osI.Getenv("DBAAS_SERVICE_SENTINEL_PORT", ""); sntPortStr != "" {
+               cfg.sentinelPorts = strings.Split(sntPortStr, ",")
+       }
+       if nameStr := osI.Getenv("DBAAS_MASTER_NAME", ""); nameStr != "" {
+               cfg.masterNames = strings.Split(nameStr, ",")
+       }
+       completeConfig(&cfg)
        return cfg
 }
 
@@ -205,47 +222,61 @@ func (osImpl) Getenv(key string, defValue string) string {
        return val
 }
 
-func ReadConfigAndCreateDbClients(osI OS, clientCreator RedisClientCreator,
-       subscribe SubscribeFn,
-       sentinelCreateCb RedisSentinelCreateCb) []*DB {
-       cfg := readConfig(osI)
-       return createDbClients(cfg, clientCreator, subscribe, sentinelCreateCb)
+func completeConfig(cfg *Config) {
+       if len(cfg.sentinelPorts) == 0 {
+               if len(cfg.clusterAddrs) > len(cfg.ports) && len(cfg.ports) > 0 {
+                       for i := len(cfg.ports); i < len(cfg.clusterAddrs); i++ {
+                               cfg.ports = append(cfg.ports, cfg.ports[i-1])
+                       }
+               }
+       } else {
+               if len(cfg.clusterAddrs) > len(cfg.sentinelPorts) {
+                       for i := len(cfg.sentinelPorts); i < len(cfg.clusterAddrs); i++ {
+                               cfg.sentinelPorts = append(cfg.sentinelPorts, cfg.sentinelPorts[i-1])
+                       }
+               }
+               if len(cfg.clusterAddrs) > len(cfg.masterNames) && len(cfg.masterNames) > 0 {
+                       for i := len(cfg.masterNames); i < len(cfg.clusterAddrs); i++ {
+                               cfg.masterNames = append(cfg.masterNames, cfg.masterNames[i-1])
+                       }
+               }
+       }
 }
 
-func createDbClients(cfg Config, clientCreator RedisClientCreator,
+func ReadConfigAndCreateDbClients(osI OS, clientCreator RedisClientCreator,
        subscribe SubscribeFn,
        sentinelCreateCb RedisSentinelCreateCb) []*DB {
-       if cfg.clusterAddrList == "" {
-               return []*DB{createLegacyDbClient(cfg, clientCreator, subscribe, sentinelCreateCb)}
-       }
-
        dbs := []*DB{}
-
-       addrList := strings.Split(cfg.clusterAddrList, ",")
-       for _, addr := range addrList {
-               db := createDbClient(cfg, addr, clientCreator, subscribe, sentinelCreateCb)
+       cfg := readConfig(osI)
+       for i, addr := range cfg.clusterAddrs {
+               port := getListItem(cfg.ports, i)
+               sntPort := getListItem(cfg.sentinelPorts, i)
+               name := getListItem(cfg.masterNames, i)
+               db := createDbClient(addr, port, sntPort, name, cfg.nodeCnt,
+                       clientCreator, subscribe, sentinelCreateCb)
                dbs = append(dbs, db)
        }
        return dbs
 }
 
-func createLegacyDbClient(cfg Config, clientCreator RedisClientCreator,
-       subscribe SubscribeFn,
-       sentinelCreateCb RedisSentinelCreateCb) *DB {
-       return createDbClient(cfg, cfg.hostname, clientCreator, subscribe, sentinelCreateCb)
+func getListItem(list []string, index int) string {
+       if index < len(list) {
+               return list[index]
+       }
+       return ""
 }
 
-func createDbClient(cfg Config, hostName string, clientCreator RedisClientCreator,
+func createDbClient(addr, port, sentinelPort, masterName, nodeCnt string, clientCreator RedisClientCreator,
        subscribe SubscribeFn,
        sentinelCreateCb RedisSentinelCreateCb) *DB {
        var client RedisClient
        var db *DB
-       if cfg.sentinelPort == "" {
-               client = clientCreator(hostName, cfg.port, "", false)
-               db = CreateDB(client, subscribe, nil, cfg, hostName)
+       if sentinelPort == "" {
+               client = clientCreator(addr, port, "", false)
+               db = CreateDB(client, subscribe, nil, addr, port, sentinelPort, masterName, nodeCnt)
        } else {
-               client = clientCreator(hostName, cfg.sentinelPort, cfg.masterName, true)
-               db = CreateDB(client, subscribe, sentinelCreateCb, cfg, hostName)
+               client = clientCreator(addr, sentinelPort, masterName, true)
+               db = CreateDB(client, subscribe, sentinelCreateCb, addr, port, sentinelPort, masterName, nodeCnt)
        }
        db.CheckCommands()
        return db
@@ -765,14 +796,14 @@ func readRedisInfoReplyFields(input []string, info *DbInfo) {
 
 func (db *DB) State() (*DbState, error) {
        dbState := new(DbState)
-       if db.cfg.sentinelPort != "" {
+       if db.sentinelPort != "" {
                //Establish connection to Redis sentinel. The reason why connection is done
                //here instead of time of the SDL instance creation is that for the time being
                //sentinel connection is needed only here to get state information and
                //state information is needed only by 'sdlcli' hence it is not time critical
                //and also we want to avoid opening unnecessary TCP connections towards Redis
                //sentinel for every SDL instance. Now it is done only when 'sdlcli' is used.
-               sentinelClient := db.sentinel(&db.cfg, db.addr)
+               sentinelClient := db.sentinel(db.addr, db.sentinelPort, db.masterName, db.nodeCnt)
                return sentinelClient.GetDbState()
        } else {
                info, err := db.Info()
@@ -791,17 +822,17 @@ func (db *DB) fillDbStateFromDbInfo(info *DbInfo) (*DbState, error) {
                        PrimaryDbState: PrimaryDbState{
                                Fields: PrimaryDbStateFields{
                                        Role:  "master",
-                                       Ip:    db.cfg.hostname,
-                                       Port:  db.cfg.port,
+                                       Ip:    db.addr,
+                                       Port:  db.port,
                                        Flags: "master",
                                },
                        },
                }
        }
 
-       cnt, err := strconv.Atoi(db.cfg.nodeCnt)
+       cnt, err := strconv.Atoi(db.nodeCnt)
        if err != nil {
-               dbState.Err = fmt.Errorf("DBAAS_NODE_COUNT configuration value '%s' conversion to integer failed", db.cfg.nodeCnt)
+               dbState.Err = fmt.Errorf("DBAAS_NODE_COUNT configuration value '%s' conversion to integer failed", db.nodeCnt)
        } else {
                dbState.ConfigNodeCnt = cnt
        }
@@ -810,10 +841,8 @@ func (db *DB) fillDbStateFromDbInfo(info *DbInfo) (*DbState, error) {
 }
 
 func createReplicaDbClient(host string) *DB {
-       cfg := readConfig(osImpl{})
-       cfg.sentinelPort = ""
-       cfg.clusterAddrList, cfg.port, _ = net.SplitHostPort(host)
-       return createDbClient(cfg, cfg.clusterAddrList, newRedisClient, subscribeNotifications, nil)
+       addr, port, _ := net.SplitHostPort(host)
+       return createDbClient(addr, port, "", "", "", newRedisClient, subscribeNotifications, nil)
 }
 
 func getStatisticsInfo(db *DB, host string) (*DbStatisticsInfo, error) {
@@ -861,14 +890,14 @@ func sentinelStatistics(db *DB) (*DbStatistics, error) {
 func standaloneStatistics(db *DB) (*DbStatistics, error) {
        dbStatistics := new(DbStatistics)
 
-       dbStatisticsInfo, err := getStatisticsInfo(db, net.JoinHostPort(db.cfg.hostname, db.cfg.port))
+       dbStatisticsInfo, err := getStatisticsInfo(db, net.JoinHostPort(db.addr, db.port))
        dbStatistics.Stats = append(dbStatistics.Stats, dbStatisticsInfo)
 
        return dbStatistics, err
 }
 
 func (db *DB) Statistics() (*DbStatistics, error) {
-       if db.cfg.sentinelPort != "" {
+       if db.sentinelPort != "" {
                return sentinelStatistics(db)
        }
 
index c95b8af..106ba6c 100644 (file)
@@ -1,6 +1,6 @@
 /*
    Copyright (c) 2019 AT&T Intellectual Property.
-   Copyright (c) 2018-2019 Nokia.
+   Copyright (c) 2018-2022 Nokia.
 
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
@@ -189,9 +189,9 @@ func setupHaEnvWithSentinels(commandsExists bool, nodeCnt string) (*pubSubMock,
        setupVals := setupEnv(
                commandsExists,
                "service-ricplt-dbaas-tcp-cluster-0.ricplt",
-               "6376",
-               "dbaasmaster",
-               "26376",
+               "6379",
+               "dbaasmaster-cluster-0",
+               "26379",
                "",
                nodeCnt,
        )
@@ -202,7 +202,7 @@ func setupSingleEnv(commandsExists bool, nodeCnt string) (*pubSubMock, *clientMo
        setupVals := setupEnv(
                commandsExists,
                "service-ricplt-dbaas-tcp-cluster-0.ricplt",
-               "6376", "", "", "", nodeCnt,
+               "6379", "", "", "", nodeCnt,
        )
        return setupVals.pubSubMock[0], setupVals.rClient[0], setupVals.db[0]
 }
@@ -251,10 +251,11 @@ func setupEnv(commandsExists bool, host, port, msname, sntport, clsaddrlist, nod
                        return clm
                },
                subscribeNotifications,
-               func(cfg *sdlgoredis.Config, addr string) *sdlgoredis.Sentinel {
+               func(addr, sentinelPort, masterName, nodeCnt string) *sdlgoredis.Sentinel {
                        s := &sdlgoredis.Sentinel{
                                IredisSentinelClient: smock,
-                               Cfg:                  cfg,
+                               MasterName:           masterName,
+                               NodeCnt:              nodeCnt,
                        }
                        return s
                },
@@ -1139,7 +1140,7 @@ func TestPExpireIELockNotHeld(t *testing.T) {
 func TestClientStandaloneRedisLegacyEnv(t *testing.T) {
        setupVals := setupEnv(
                true,
-               "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6376", "", "", "", "",
+               "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6379", "", "", "", "",
        )
        assert.Equal(t, 1, len(setupVals.rClient))
        assert.Equal(t, 1, len(setupVals.db))
@@ -1154,7 +1155,7 @@ func TestClientStandaloneRedisLegacyEnv(t *testing.T) {
 func TestClientSentinelRedisLegacyEnv(t *testing.T) {
        setupVals := setupEnv(
                true,
-               "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6376", "dbaasmaster", "26376", "", "3",
+               "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6379", "dbaasmaster-cluster-0", "26379", "", "3",
        )
        assert.Equal(t, 1, len(setupVals.rClient))
        assert.Equal(t, 1, len(setupVals.db))
@@ -1169,7 +1170,7 @@ func TestClientSentinelRedisLegacyEnv(t *testing.T) {
 func TestClientTwoStandaloneRedisEnvs(t *testing.T) {
        setupVals := setupEnv(
                true,
-               "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6376", "", "",
+               "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6379,6380", "", "",
                "service-ricplt-dbaas-tcp-cluster-0.ricplt,service-ricplt-dbaas-tcp-cluster-1.ricplt", "",
        )
        assert.Equal(t, 2, len(setupVals.rClient))
@@ -1192,8 +1193,8 @@ func TestClientTwoStandaloneRedisEnvs(t *testing.T) {
 func TestClientTwoSentinelRedisEnvs(t *testing.T) {
        setupVals := setupEnv(
                true,
-               "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6376", "dbaasmaster", "26376",
-               "service-ricplt-dbaas-tcp-cluster-0.ricplt,service-ricplt-dbaas-tcp-cluster-1.ricplt", "3",
+               "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6379,6380", "dbaasmaster-cluster-0,dbaasmaster-cluster-1",
+               "26379,26380", "service-ricplt-dbaas-tcp-cluster-0.ricplt,service-ricplt-dbaas-tcp-cluster-1.ricplt", "3",
        )
        assert.Equal(t, 2, len(setupVals.rClient))
        assert.Equal(t, 2, len(setupVals.db))
@@ -1212,6 +1213,36 @@ func TestClientTwoSentinelRedisEnvs(t *testing.T) {
        setupVals.rClient[1].AssertExpectations(t)
 }
 
+func TestCompleteConfigIfLessPortsThanAddresses(t *testing.T) {
+       setupVals := setupEnv(
+               true,
+               "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6379", "dbaasmaster-cluster-0,dbaasmaster-cluster-1",
+               "", "service-ricplt-dbaas-tcp-cluster-0.ricplt,service-ricplt-dbaas-tcp-cluster-1.ricplt", "3",
+       )
+       assert.Equal(t, 2, len(setupVals.rClient))
+       assert.Equal(t, 2, len(setupVals.db))
+}
+
+func TestCompleteConfigIfLessSentinelPortsThanAddresses(t *testing.T) {
+       setupVals := setupEnv(
+               true,
+               "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6379,6380", "dbaasmaster-cluster-0,dbaasmaster-cluster-1",
+               "26379", "service-ricplt-dbaas-tcp-cluster-0.ricplt,service-ricplt-dbaas-tcp-cluster-1.ricplt", "3",
+       )
+       assert.Equal(t, 2, len(setupVals.rClient))
+       assert.Equal(t, 2, len(setupVals.db))
+}
+
+func TestCompleteConfigIfLessSentinelNamesThanAddresses(t *testing.T) {
+       setupVals := setupEnv(
+               true,
+               "service-ricplt-dbaas-tcp-cluster-0.ricplt", "6379,6380", "dbaasmaster-cluster-0",
+               "26379,26380", "service-ricplt-dbaas-tcp-cluster-0.ricplt,service-ricplt-dbaas-tcp-cluster-1.ricplt", "3",
+       )
+       assert.Equal(t, 2, len(setupVals.rClient))
+       assert.Equal(t, 2, len(setupVals.db))
+}
+
 func TestInfoOfPrimaryRedisWithTwoReplicasSuccessfully(t *testing.T) {
        _, r, db := setupHaEnv(true)
        redisInfo := "# Replication\r\n" +
@@ -1407,15 +1438,73 @@ func TestStateWithPrimaryAndTwoReplicaRedisSuccessfully(t *testing.T) {
        expState.addSentinel("10.20.30.40", "26379", "sentinel", nil)
        expState.addSentinel("10.20.30.50", "30001", "sentinel", nil)
 
-       s[0].On("Master", "dbaasmaster").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
-       s[0].On("Slaves", "dbaasmaster").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
-       s[0].On("Sentinels", "dbaasmaster").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
+       s[0].On("Master", "dbaasmaster-cluster-0").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
+       s[0].On("Slaves", "dbaasmaster-cluster-0").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
+       s[0].On("Sentinels", "dbaasmaster-cluster-0").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
        ret, err := db.State()
        assert.Nil(t, err)
        assert.Equal(t, expState.s, *ret)
        r.AssertExpectations(t)
 }
 
+func TestStateWithTwoSdlClustersContainingPrimaryAndTwoReplicaRedisSuccessfully(t *testing.T) {
+       setupVals := setupEnv(
+               true,
+               "", "6379,6380", "dbaasmaster-cluster-0,dbaasmaster-cluster-1",
+               "26379,26380", "service-ricplt-dbaas-tcp-cluster-0.ricplt,service-ricplt-dbaas-tcp-cluster-1.ricplt", "3",
+       )
+       r := setupVals.rClient
+       s := setupVals.rSentinel
+       db := setupVals.db
+
+       FstRedisPrimaryState := newMockRedisMasterCallResp("master", "10.20.30.30", "6379", "master")
+       FstRedisReplicasState := newMockRedisSlavesCall()
+       FstRedisReplicasState.add("slave", "10.20.30.40", "6379", "up", "slave")
+       FstRedisReplicasState.add("slave", "10.20.30.50", "6379", "up", "slave")
+       FstRedisSentinelsState := newMockRedisSentinelsCall()
+       FstRedisSentinelsState.add("10.20.30.40", "26379", "sentinel")
+       FstRedisSentinelsState.add("10.20.30.50", "26379", "sentinel")
+
+       SndRedisPrimaryState := newMockRedisMasterCallResp("master", "10.20.30.60", "6380", "master")
+       SndRedisReplicasState := newMockRedisSlavesCall()
+       SndRedisReplicasState.add("slave", "10.20.30.70", "6380", "up", "slave")
+       SndRedisReplicasState.add("slave", "10.20.30.80", "6380", "up", "slave")
+       SndRedisSentinelsState := newMockRedisSentinelsCall()
+       SndRedisSentinelsState.add("10.20.30.70", "26380", "sentinel")
+       SndRedisSentinelsState.add("10.20.30.80", "26380", "sentinel")
+
+       FstExpState := newExpDbState(3, nil)
+       FstExpState.addPrimary("master", "10.20.30.30", "6379", "master", nil)
+       FstExpState.addReplica("slave", "10.20.30.40", "6379", "up", "slave", nil)
+       FstExpState.addReplica("slave", "10.20.30.50", "6379", "up", "slave", nil)
+       FstExpState.addSentinel("10.20.30.40", "26379", "sentinel", nil)
+       FstExpState.addSentinel("10.20.30.50", "26379", "sentinel", nil)
+
+       SndExpState := newExpDbState(3, nil)
+       SndExpState.addPrimary("master", "10.20.30.60", "6380", "master", nil)
+       SndExpState.addReplica("slave", "10.20.30.70", "6380", "up", "slave", nil)
+       SndExpState.addReplica("slave", "10.20.30.80", "6380", "up", "slave", nil)
+       SndExpState.addSentinel("10.20.30.70", "26380", "sentinel", nil)
+       SndExpState.addSentinel("10.20.30.80", "26380", "sentinel", nil)
+
+       s[0].On("Master", "dbaasmaster-cluster-0").Return(redis.NewStringStringMapResult(FstRedisPrimaryState, nil))
+       s[0].On("Slaves", "dbaasmaster-cluster-0").Return(redis.NewSliceResult(FstRedisReplicasState.resp, nil))
+       s[0].On("Sentinels", "dbaasmaster-cluster-0").Return(redis.NewSliceResult(FstRedisSentinelsState.resp, nil))
+
+       s[0].On("Master", "dbaasmaster-cluster-1").Return(redis.NewStringStringMapResult(SndRedisPrimaryState, nil))
+       s[0].On("Slaves", "dbaasmaster-cluster-1").Return(redis.NewSliceResult(SndRedisReplicasState.resp, nil))
+       s[0].On("Sentinels", "dbaasmaster-cluster-1").Return(redis.NewSliceResult(SndRedisSentinelsState.resp, nil))
+
+       ret, err := db[0].State()
+       assert.Nil(t, err)
+       assert.Equal(t, FstExpState.s, *ret)
+
+       ret, err = db[1].State()
+       assert.Nil(t, err)
+       assert.Equal(t, SndExpState.s, *ret)
+       r[0].AssertExpectations(t)
+}
+
 func TestStateWithPrimaryAndTwoReplicaRedisFailureInPrimaryRedisCall(t *testing.T) {
        expErr := errors.New("Some error")
        _, r, s, db := setupHaEnvWithSentinels(true, "3")
@@ -1435,9 +1524,9 @@ func TestStateWithPrimaryAndTwoReplicaRedisFailureInPrimaryRedisCall(t *testing.
        expState.addSentinel("10.20.30.40", "26379", "sentinel", nil)
        expState.addSentinel("10.20.30.50", "30001", "sentinel", nil)
 
-       s[0].On("Master", "dbaasmaster").Return(redis.NewStringStringMapResult(redisPrimaryState, expErr))
-       s[0].On("Slaves", "dbaasmaster").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
-       s[0].On("Sentinels", "dbaasmaster").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
+       s[0].On("Master", "dbaasmaster-cluster-0").Return(redis.NewStringStringMapResult(redisPrimaryState, expErr))
+       s[0].On("Slaves", "dbaasmaster-cluster-0").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
+       s[0].On("Sentinels", "dbaasmaster-cluster-0").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
        ret, err := db.State()
        assert.NotNil(t, err)
        assert.Equal(t, expState.s, *ret)
@@ -1463,9 +1552,9 @@ func TestStateWithPrimaryAndTwoReplicaRedisFailureInReplicasRedisCall(t *testing
        expState.addSentinel("10.20.30.40", "26379", "sentinel", nil)
        expState.addSentinel("10.20.30.50", "30001", "sentinel", nil)
 
-       s[0].On("Master", "dbaasmaster").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
-       s[0].On("Slaves", "dbaasmaster").Return(redis.NewSliceResult(redisReplicasState.resp, errors.New("Some error")))
-       s[0].On("Sentinels", "dbaasmaster").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
+       s[0].On("Master", "dbaasmaster-cluster-0").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
+       s[0].On("Slaves", "dbaasmaster-cluster-0").Return(redis.NewSliceResult(redisReplicasState.resp, errors.New("Some error")))
+       s[0].On("Sentinels", "dbaasmaster-cluster-0").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
        ret, err := db.State()
        assert.NotNil(t, err)
        assert.Equal(t, expState.s, *ret)
@@ -1487,9 +1576,9 @@ func TestStateWithPrimaryAndOneReplicaRedisFailureInSentinelsRedisCall(t *testin
        expState.addReplica("slave", "10.20.30.40", "6379", "up", "slave", nil)
        expState.addSentinel("", "", "", expErr)
 
-       s[0].On("Master", "dbaasmaster").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
-       s[0].On("Slaves", "dbaasmaster").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
-       s[0].On("Sentinels", "dbaasmaster").Return(redis.NewSliceResult(redisSentinelsState.resp, expErr))
+       s[0].On("Master", "dbaasmaster-cluster-0").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
+       s[0].On("Slaves", "dbaasmaster-cluster-0").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
+       s[0].On("Sentinels", "dbaasmaster-cluster-0").Return(redis.NewSliceResult(redisSentinelsState.resp, expErr))
        ret, err := db.State()
        assert.NotNil(t, err)
        assert.Equal(t, expState.s, *ret)
@@ -1515,9 +1604,9 @@ func TestStateWithPrimaryAndTwoReplicaRedisFailureWhenIntConversionFails(t *test
        expState.addSentinel("10.20.30.40", "26379", "sentinel", nil)
        expState.addSentinel("10.20.30.50", "30001", "sentinel", nil)
 
-       s[0].On("Master", "dbaasmaster").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
-       s[0].On("Slaves", "dbaasmaster").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
-       s[0].On("Sentinels", "dbaasmaster").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
+       s[0].On("Master", "dbaasmaster-cluster-0").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
+       s[0].On("Slaves", "dbaasmaster-cluster-0").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
+       s[0].On("Sentinels", "dbaasmaster-cluster-0").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
        ret, err := db.State()
        assert.Equal(t, expErr, err)
        assert.Equal(t, expState.s, *ret)
@@ -1543,9 +1632,9 @@ func TestStateWithPrimaryAndTwoReplicaFirstSentinelStateIgnoredBecauseZeroPortBu
        expState.addReplica("slave", "10.20.30.50", "30000", "up", "slave", nil)
        expState.addSentinel("10.20.30.50", "26379", "sentinel", nil)
 
-       s[0].On("Master", "dbaasmaster").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
-       s[0].On("Slaves", "dbaasmaster").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
-       s[0].On("Sentinels", "dbaasmaster").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
+       s[0].On("Master", "dbaasmaster-cluster-0").Return(redis.NewStringStringMapResult(redisPrimaryState, nil))
+       s[0].On("Slaves", "dbaasmaster-cluster-0").Return(redis.NewSliceResult(redisReplicasState.resp, nil))
+       s[0].On("Sentinels", "dbaasmaster-cluster-0").Return(redis.NewSliceResult(redisSentinelsState.resp, nil))
        ret, err := db.State()
        assert.Nil(t, err)
        assert.Equal(t, expState.s, *ret)
@@ -1565,7 +1654,7 @@ func TestStateWithSinglePrimaryRedisSuccessfully(t *testing.T) {
                        Fields: sdlgoredis.PrimaryDbStateFields{
                                Role:  "master",
                                Ip:    "service-ricplt-dbaas-tcp-cluster-0.ricplt",
-                               Port:  "6376",
+                               Port:  "6379",
                                Flags: "master",
                        },
                },
@@ -1593,7 +1682,7 @@ func TestStateWithSinglePrimaryRedisFailureWhenIntConversionFails(t *testing.T)
                        Fields: sdlgoredis.PrimaryDbStateFields{
                                Role:  "master",
                                Ip:    "service-ricplt-dbaas-tcp-cluster-0.ricplt",
-                               Port:  "6376",
+                               Port:  "6379",
                                Flags: "master",
                        },
                },
@@ -1636,7 +1725,7 @@ func TestStatisticsWithSinglePrimaryRedisSuccessfully(t *testing.T) {
                Stats: []*sdlgoredis.DbStatisticsInfo{
                        {
                                IPAddr: "service-ricplt-dbaas-tcp-cluster-0.ricplt",
-                               Port:   "6376",
+                               Port:   "6379",
                                Info: &sdlgoredis.DbInfo{
                                        Fields: sdlgoredis.DbInfoFields{
                                                PrimaryRole: true,
index 8a1b331..a06722b 100644 (file)
@@ -1,6 +1,6 @@
 /*
    Copyright (c) 2021 AT&T Intellectual Property.
-   Copyright (c) 2018-2021 Nokia.
+   Copyright (c) 2018-2022 Nokia.
 
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
@@ -30,9 +30,10 @@ import (
 )
 
 type Sentinel struct {
-       ctx context.Context
+       ctx        context.Context
+       MasterName string
+       NodeCnt    string
        IredisSentinelClient
-       Cfg *Config
 }
 
 type IredisSentinelClient interface {
@@ -41,10 +42,10 @@ type IredisSentinelClient interface {
        Sentinels(ctx context.Context, name string) *redis.SliceCmd
 }
 
-type RedisSentinelCreateCb func(cfg *Config, addr string) *Sentinel
+type RedisSentinelCreateCb func(addr, sentinelPort, masterName, nodeCnt string) *Sentinel
 
-func newRedisSentinel(cfg *Config, addr string) *Sentinel {
-       redisAddress := addr + ":" + cfg.sentinelPort
+func newRedisSentinel(addr, sentinelPort, masterName, nodeCnt string) *Sentinel {
+       redisAddress := addr + ":" + sentinelPort
        return &Sentinel{
                ctx: context.Background(),
                IredisSentinelClient: redis.NewSentinelClient(&redis.Options{
@@ -54,7 +55,8 @@ func newRedisSentinel(cfg *Config, addr string) *Sentinel {
                        PoolSize:   20,
                        MaxRetries: 2,
                }),
-               Cfg: cfg,
+               MasterName: masterName,
+               NodeCnt:    nodeCnt,
        }
 }
 
@@ -67,9 +69,9 @@ func (s *Sentinel) GetDbState() (*DbState, error) {
        state.ReplicasDbState = rState
        state.SentinelsDbState = sState
 
-       cnt, err := strconv.Atoi(s.Cfg.nodeCnt)
+       cnt, err := strconv.Atoi(s.NodeCnt)
        if err != nil {
-               state.Err = fmt.Errorf("Sentinel DBAAS_NODE_COUNT configuration value '%s' conversion to integer failed", s.Cfg.nodeCnt)
+               state.Err = fmt.Errorf("Sentinel DBAAS_NODE_COUNT configuration value '%s' conversion to integer failed", s.NodeCnt)
                return state, state.Err
        }
        state.ConfigNodeCnt = cnt
@@ -85,7 +87,7 @@ func (s *Sentinel) GetDbState() (*DbState, error) {
 
 func (s *Sentinel) getPrimaryDbState() (*PrimaryDbState, error) {
        state := new(PrimaryDbState)
-       redisVal, redisErr := s.Master(s.ctx, s.Cfg.masterName).Result()
+       redisVal, redisErr := s.Master(s.ctx, s.MasterName).Result()
        if redisErr == nil {
                state.Fields.Ip = redisVal["ip"]
                state.Fields.Port = redisVal["port"]
@@ -100,7 +102,7 @@ func (s *Sentinel) getReplicasState() (*ReplicasDbState, error) {
        states := new(ReplicasDbState)
        states.States = make([]*ReplicaDbState, 0)
 
-       redisVal, redisErr := s.Slaves(s.ctx, s.Cfg.masterName).Result()
+       redisVal, redisErr := s.Slaves(s.ctx, s.MasterName).Result()
        if redisErr == nil {
                for _, redisReplica := range redisVal {
                        replicaState := readReplicaState(redisReplica.([]interface{}))
@@ -133,7 +135,7 @@ func (s *Sentinel) getSentinelsState() (*SentinelsDbState, error) {
        states := new(SentinelsDbState)
        states.States = make([]*SentinelDbState, 0)
 
-       redisVal, redisErr := s.Sentinels(s.ctx, s.Cfg.masterName).Result()
+       redisVal, redisErr := s.Sentinels(s.ctx, s.MasterName).Result()
        if redisErr == nil {
                for _, redisSentinel := range redisVal {
                        sentinelState := readSentinelState(redisSentinel.([]interface{}))