From 834c12f8fae8346effd5d01abe294c48b4419d77 Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Tue, 12 Jan 2016 20:32:43 +0200 Subject: [PATCH] use map for shared group member ids --- cmd/cgr-loader/cgr-loader.go | 7 +++++- cmd/cgr-loader/migrator_rc8.go | 44 ++++++++++++++++++++++++++++++++++ engine/account.go | 19 ++++++++------- engine/account_test.go | 4 ++-- engine/calldesc.go | 8 +++---- engine/sharedgroup.go | 4 ++-- engine/sharedgroup_test.go | 4 +++- 7 files changed, 71 insertions(+), 19 deletions(-) diff --git a/cmd/cgr-loader/cgr-loader.go b/cmd/cgr-loader/cgr-loader.go index c027b2b00..067cc6ae7 100644 --- a/cmd/cgr-loader/cgr-loader.go +++ b/cmd/cgr-loader/cgr-loader.go @@ -36,7 +36,7 @@ import ( var ( //separator = flag.String("separator", ",", "Default field separator") cgrConfig, _ = config.NewDefaultCGRConfig() - migrateRC8 = flag.String("migrate_rc8", "", "Migrate Accounts, Actions, ActionTriggers and DerivedChargers to RC8 structures, possible values: *all,acc,atr,act,dcs,apl") + migrateRC8 = flag.String("migrate_rc8", "", "Migrate Accounts, Actions, ActionTriggers, DerivedChargers, ActionPlans and SharedGroups to RC8 structures, possible values: *all,acc,atr,act,dcs,apl,shg") tpdb_type = flag.String("tpdb_type", cgrConfig.TpDbType, "The type of the TariffPlan database ") tpdb_host = flag.String("tpdb_host", cgrConfig.TpDbHost, "The TariffPlan host to connect to.") tpdb_port = flag.String("tpdb_port", cgrConfig.TpDbPort, "The TariffPlan port to bind to.") @@ -147,6 +147,11 @@ func main() { log.Print(err.Error()) } } + if strings.Contains(*migrateRC8, "shg") || strings.Contains(*migrateRC8, "*all") { + if err := migratorRC8rat.migrateSharedGroups(); err != nil { + log.Print(err.Error()) + } + } log.Print("Done!") return } diff --git a/cmd/cgr-loader/migrator_rc8.go b/cmd/cgr-loader/migrator_rc8.go index 421da2e40..08eca3650 100644 --- a/cmd/cgr-loader/migrator_rc8.go +++ b/cmd/cgr-loader/migrator_rc8.go @@ -145,6 +145,12 @@ func (at *ActionPlan) IsASAP() bool { return at.Timing.Timing.StartTime == utils.ASAP } +type SharedGroup struct { + Id string + AccountParameters map[string]*engine.SharingParameters + MemberIds []string +} + type ActionPlans []*ActionPlan func (mig MigratorRC8) migrateAccounts() error { @@ -519,3 +525,41 @@ func (mig MigratorRC8) migrateActionPlans() error { } return nil } + +func (mig MigratorRC8) migrateSharedGroups() error { + keys, err := mig.db.Cmd("KEYS", utils.SHARED_GROUP_PREFIX+"*").List() + if err != nil { + return err + } + newShgMap := make(map[string]*engine.SharedGroup, len(keys)) + for _, key := range keys { + log.Printf("Migrating shared groups: %s...", key) + oldShg := SharedGroup{} + var values []byte + if values, err = mig.db.Cmd("GET", key).Bytes(); err == nil { + if err := mig.ms.Unmarshal(values, &oldShg); err != nil { + return err + } + } + newShg := &engine.SharedGroup{ + Id: oldShg.Id, + AccountParameters: oldShg.AccountParameters, + MemberIds: make(utils.StringMap), + } + for _, accID := range oldShg.MemberIds { + newShg.MemberIds[accID] = true + } + newShgMap[key] = newShg + } + // write data back + for key, shg := range newShgMap { + result, err := mig.ms.Marshal(&shg) + if err != nil { + return err + } + if err = mig.db.Cmd("SET", key, result).Err; err != nil { + return err + } + } + return nil +} diff --git a/engine/account.go b/engine/account.go index 747722756..b3dcb777b 100644 --- a/engine/account.go +++ b/engine/account.go @@ -149,12 +149,15 @@ func (ub *Account) debitBalanceAction(a *Action, reset bool) error { // add shared group member sg, err := ratingStorage.GetSharedGroup(sgId, false) if err != nil || sg == nil { - //than problem + //than is problem utils.Logger.Warning(fmt.Sprintf("Could not get shared group: %v", sgId)) } else { - if !utils.IsSliceMember(sg.MemberIds, ub.Id) { + if _, found := sg.MemberIds[ub.Id]; !found { // add member and save - sg.MemberIds = append(sg.MemberIds, ub.Id) + if sg.MemberIds == nil { + sg.MemberIds = make(utils.StringMap) + } + sg.MemberIds[ub.Id] = true ratingStorage.SetSharedGroup(sg) } } @@ -610,7 +613,7 @@ func (acc *Account) GetSharedGroups() (groups []string) { return } -func (account *Account) GetUniqueSharedGroupMembers(cd *CallDescriptor) ([]string, error) { +func (account *Account) GetUniqueSharedGroupMembers(cd *CallDescriptor) (utils.StringMap, error) { var balances []*Balance balances = append(balances, account.getBalancesForPrefix(cd.Destination, cd.Category, cd.Direction, utils.MONETARY, "")...) balances = append(balances, account.getBalancesForPrefix(cd.Destination, cd.Category, cd.Direction, cd.TOR, "")...) @@ -621,17 +624,15 @@ func (account *Account) GetUniqueSharedGroupMembers(cd *CallDescriptor) ([]strin sharedGroupIds = append(sharedGroupIds, sg) } } - var memberIds []string + memberIds := make(utils.StringMap) for _, sgID := range sharedGroupIds { sharedGroup, err := ratingStorage.GetSharedGroup(sgID, false) if err != nil { utils.Logger.Warning(fmt.Sprintf("Could not get shared group: %v", sgID)) return nil, err } - for _, memberId := range sharedGroup.MemberIds { - if !utils.IsSliceMember(memberIds, memberId) { - memberIds = append(memberIds, memberId) - } + for memberID := range sharedGroup.MemberIds { + memberIds[memberID] = true } } return memberIds, nil diff --git a/engine/account_test.go b/engine/account_test.go index cc3be8e1d..334836999 100644 --- a/engine/account_test.go +++ b/engine/account_test.go @@ -1111,7 +1111,7 @@ func TestDebitShared(t *testing.T) { utils.MONETARY: BalanceChain{&Balance{Uuid: "moneyc", Value: 130, SharedGroups: utils.NewStringMap("SG_TEST")}}, }} - sg := &SharedGroup{Id: "SG_TEST", MemberIds: []string{rif.Id, groupie.Id}, AccountParameters: map[string]*SharingParameters{"*any": &SharingParameters{Strategy: STRATEGY_MINE_RANDOM}}} + sg := &SharedGroup{Id: "SG_TEST", MemberIds: utils.NewStringMap(rif.Id, groupie.Id), AccountParameters: map[string]*SharingParameters{"*any": &SharingParameters{Strategy: STRATEGY_MINE_RANDOM}}} accountingStorage.SetAccount(groupie) ratingStorage.SetSharedGroup(sg) @@ -1181,7 +1181,7 @@ func TestMaxDurationShared(t *testing.T) { utils.MONETARY: BalanceChain{&Balance{Uuid: "moneyc", Value: 130, SharedGroups: utils.NewStringMap("SG_TEST")}}, }} - sg := &SharedGroup{Id: "SG_TEST", MemberIds: []string{rif.Id, groupie.Id}, AccountParameters: map[string]*SharingParameters{"*any": &SharingParameters{Strategy: STRATEGY_MINE_RANDOM}}} + sg := &SharedGroup{Id: "SG_TEST", MemberIds: utils.NewStringMap(rif.Id, groupie.Id), AccountParameters: map[string]*SharingParameters{"*any": &SharingParameters{Strategy: STRATEGY_MINE_RANDOM}}} accountingStorage.SetAccount(groupie) ratingStorage.SetSharedGroup(sg) diff --git a/engine/calldesc.go b/engine/calldesc.go index 87b726645..335252161 100644 --- a/engine/calldesc.go +++ b/engine/calldesc.go @@ -624,7 +624,7 @@ func (cd *CallDescriptor) GetMaxSessionDuration() (duration time.Duration, err e if _, err := Guardian.Guard(func() (interface{}, error) { duration, err = cd.getMaxSessionDuration(account) return 0, err - }, 0, memberIds...); err != nil { + }, 0, memberIds.Slice()...); err != nil { return 0, err } } else { @@ -681,7 +681,7 @@ func (cd *CallDescriptor) Debit() (cc *CallCost, err error) { _, err = Guardian.Guard(func() (interface{}, error) { cc, err = cd.debit(account, false, true) return 0, err - }, 0, memberIds...) + }, 0, memberIds.Slice()...) } else { return nil, sgerr } @@ -700,7 +700,7 @@ func (cd *CallDescriptor) FakeDebit() (cc *CallCost, err error) { _, err = Guardian.Guard(func() (interface{}, error) { cc, err = cd.debit(account, true, true) return 0, err - }, 0, memberIds...) + }, 0, memberIds.Slice()...) } else { return nil, sgerr } @@ -749,7 +749,7 @@ func (cd *CallDescriptor) MaxDebit() (cc *CallCost, err error) { cc, err = cd.debit(account, false, true) //log.Print(balanceMap[0].Value, balanceMap[1].Value) return 0, err - }, 0, memberIds...) + }, 0, memberIds.Slice()...) if err != nil { return cc, err } diff --git a/engine/sharedgroup.go b/engine/sharedgroup.go index 4ec1bde23..ab8e4750b 100644 --- a/engine/sharedgroup.go +++ b/engine/sharedgroup.go @@ -40,7 +40,7 @@ const ( type SharedGroup struct { Id string AccountParameters map[string]*SharingParameters - MemberIds []string + MemberIds utils.StringMap //members []*Account // accounts caching } @@ -92,7 +92,7 @@ func (sg *SharedGroup) SortBalancesByStrategy(myBalance *Balance, bc BalanceChai // Returns all shared group's balances collected from user accounts' func (sg *SharedGroup) GetBalances(destination, category, direction, balanceType string, ub *Account) (bc BalanceChain) { // if len(sg.members) == 0 { - for _, ubId := range sg.MemberIds { + for ubId := range sg.MemberIds { var nUb *Account if ubId == ub.Id { // skip the initiating user nUb = ub diff --git a/engine/sharedgroup_test.go b/engine/sharedgroup_test.go index 52d3c3a06..b74df0846 100644 --- a/engine/sharedgroup_test.go +++ b/engine/sharedgroup_test.go @@ -21,6 +21,8 @@ package engine import ( "reflect" "testing" + + "github.com/cgrates/cgrates/utils" ) func TestSharedSetGet(t *testing.T) { @@ -30,7 +32,7 @@ func TestSharedSetGet(t *testing.T) { AccountParameters: map[string]*SharingParameters{ "test": &SharingParameters{Strategy: STRATEGY_HIGHEST}, }, - MemberIds: []string{"1", "2", "3"}, + MemberIds: utils.NewStringMap("1", "2", "3"), } err := ratingStorage.SetSharedGroup(sg) if err != nil {