func TestCleanStalePrefixes(t *testing.T) { cache2go.Cache(DESTINATION_PREFIX+"1", []interface{}{"D1", "D2"}) cache2go.Cache(DESTINATION_PREFIX+"2", []interface{}{"D1"}) cache2go.Cache(DESTINATION_PREFIX+"3", []interface{}{"D2"}) CleanStalePrefixes([]string{"D1"}) if r, err := cache2go.GetCached(DESTINATION_PREFIX + "1"); err != nil || len(r.([]interface{})) != 1 { t.Error("Error cleaning stale destination ids", r) } if r, err := cache2go.GetCached(DESTINATION_PREFIX + "2"); err == nil { t.Error("Error removing stale prefix: ", r) } if r, err := cache2go.GetCached(DESTINATION_PREFIX + "3"); err != nil || len(r.([]interface{})) != 1 { t.Error("Error performing stale cleaning: ", r) } }
func (rs *RedisStorage) GetActionPlan(key string, skipCache bool) (ats *ActionPlan, err error) { key = utils.ACTION_PLAN_PREFIX + key if !skipCache { if x, err := cache2go.Get(key); err == nil { return x.(*ActionPlan), nil } else { return nil, err } } var values []byte if values, err = rs.db.Cmd("GET", key).Bytes(); err == nil { b := bytes.NewBuffer(values) r, err := zlib.NewReader(b) if err != nil { return nil, err } out, err := ioutil.ReadAll(r) if err != nil { return nil, err } r.Close() err = rs.ms.Unmarshal(out, &ats) cache2go.Cache(key, ats) } return }
func (ms *MapStorage) GetRatingPlan(key string, skipCache bool) (rp *RatingPlan, err error) { key = RATING_PLAN_PREFIX + key if !skipCache { if x, err := cache2go.GetCached(key); err == nil { return x.(*RatingPlan), nil } else { return nil, err } } if values, ok := ms.dict[key]; ok { b := bytes.NewBuffer(values) r, err := zlib.NewReader(b) if err != nil { return nil, err } out, err := ioutil.ReadAll(r) if err != nil { return nil, err } r.Close() rp = new(RatingPlan) err = ms.ms.Unmarshal(out, rp) cache2go.Cache(key, rp) } else { return nil, errors.New(utils.ERR_NOT_FOUND) } return }
func TestCleanStalePrefixes(t *testing.T) { x := struct{}{} cache2go.Cache(utils.DESTINATION_PREFIX+"1", map[interface{}]struct{}{"D1": x, "D2": x}) cache2go.Cache(utils.DESTINATION_PREFIX+"2", map[interface{}]struct{}{"D1": x}) cache2go.Cache(utils.DESTINATION_PREFIX+"3", map[interface{}]struct{}{"D2": x}) CleanStalePrefixes([]string{"D1"}) if r, err := cache2go.Get(utils.DESTINATION_PREFIX + "1"); err != nil || len(r.(map[interface{}]struct{})) != 1 { t.Error("Error cleaning stale destination ids", r) } if r, err := cache2go.Get(utils.DESTINATION_PREFIX + "2"); err == nil { t.Error("Error removing stale prefix: ", r) } if r, err := cache2go.Get(utils.DESTINATION_PREFIX + "3"); err != nil || len(r.(map[interface{}]struct{})) != 1 { t.Error("Error performing stale cleaning: ", r) } }
func CleanStalePrefixes(destIds []string) { prefixMap, err := cache2go.GetAllEntries(DESTINATION_PREFIX) if err != nil { return } for prefix, idIDs := range prefixMap { dIDs := idIDs.Value().([]interface{}) changed := false for _, searchedDID := range destIds { if i, found := utils.GetSliceMemberIndex(utils.ConvertInterfaceSliceToStringSlice(dIDs), searchedDID); found { if len(dIDs) == 1 { // remove de prefix from cache cache2go.RemKey(DESTINATION_PREFIX + prefix) } else { // delte the testination from list and put the new list in chache dIDs[i], dIDs = dIDs[len(dIDs)-1], dIDs[:len(dIDs)-1] changed = true } } } if changed { cache2go.Cache(DESTINATION_PREFIX+prefix, dIDs) } } }
func (rs *RedisStorage) GetRatingPlan(key string, skipCache bool) (rp *RatingPlan, err error) { key = utils.RATING_PLAN_PREFIX + key if !skipCache { if x, err := cache2go.Get(key); err == nil { return x.(*RatingPlan), nil } else { return nil, err } } var values []byte if values, err = rs.db.Get(key); err == nil { b := bytes.NewBuffer(values) r, err := zlib.NewReader(b) if err != nil { return nil, err } out, err := ioutil.ReadAll(r) if err != nil { return nil, err } r.Close() rp = new(RatingPlan) err = rs.ms.Unmarshal(out, rp) cache2go.Cache(key, rp) } return }
func (ms *MapStorage) RemoveAlias(key string) error { al := &Alias{} al.SetId(key) origKey := key key = utils.ALIASES_PREFIX + key aliasValues := make(AliasValues, 0) if values, ok := ms.dict[key]; ok { ms.ms.Unmarshal(values, &aliasValues) } delete(ms.dict, key) for _, value := range aliasValues { for target, pairs := range value.Pairs { for _, alias := range pairs { var existingKeys map[string]bool rKey := utils.REVERSE_ALIASES_PREFIX + alias + target + al.Context if x, err := cache2go.Get(rKey); err == nil { existingKeys = x.(map[string]bool) } for eKey := range existingKeys { if strings.HasPrefix(eKey, origKey) { delete(existingKeys, eKey) } } if len(existingKeys) == 0 { cache2go.RemKey(rKey) } else { cache2go.Cache(rKey, existingKeys) } } cache2go.RemKey(key) } } return nil }
// Limit will only retrieve the last n items out of history, newest first func (rs *RedisStorage) GetLoadHistory(limit int, skipCache bool) ([]*LoadInstance, error) { if limit == 0 { return nil, nil } if !skipCache { if x, err := cache2go.Get(utils.LOADINST_KEY); err != nil { return nil, err } else { items := x.([]*LoadInstance) if len(items) < limit || limit == -1 { return items, nil } return items[:limit], nil } } if limit != -1 { limit -= -1 // Decrease limit to match redis approach on lrange } marshaleds, err := rs.db.Lrange(utils.LOADINST_KEY, 0, limit) if err != nil { return nil, err } loadInsts := make([]*LoadInstance, len(marshaleds)) for idx, marshaled := range marshaleds { var lInst LoadInstance err = rs.ms.Unmarshal(marshaled, &lInst) if err != nil { return nil, err } loadInsts[idx] = &lInst } cache2go.RemKey(utils.LOADINST_KEY) cache2go.Cache(utils.LOADINST_KEY, loadInsts) return loadInsts, nil }
func (ms *MongoStorage) GetAlias(key string, skipCache bool) (al *Alias, err error) { origKey := key key = utils.ALIASES_PREFIX + key if !skipCache { if x, err := cache2go.Get(key); err == nil { al = &Alias{Values: x.(AliasValues)} al.SetId(origKey) return al, nil } else { return nil, err } } var kv struct { Key string Value AliasValues } if err = ms.db.C(colAls).Find(bson.M{"key": origKey}).One(&kv); err == nil { al = &Alias{Values: kv.Value} al.SetId(origKey) if err == nil { cache2go.Cache(key, al.Values) // cache reverse alias al.SetReverseCache() } } return }
func CleanStalePrefixes(destIds []string) { prefixMap, err := cache2go.GetAllEntries(utils.DESTINATION_PREFIX) if err != nil { return } for prefix, idIDs := range prefixMap { dIDs := idIDs.(map[interface{}]struct{}) changed := false for _, searchedDID := range destIds { if _, found := dIDs[searchedDID]; found { if len(dIDs) == 1 { // remove de prefix from cache cache2go.RemKey(utils.DESTINATION_PREFIX + prefix) } else { // delete the destination from list and put the new list in chache delete(dIDs, searchedDID) changed = true } } } if changed { cache2go.Cache(utils.DESTINATION_PREFIX+prefix, dIDs) } } }
func (ms *MongoStorage) GetRatingPlan(key string, skipCache bool) (rp *RatingPlan, err error) { if !skipCache { if x, err := cache2go.Get(utils.RATING_PLAN_PREFIX + key); err == nil { return x.(*RatingPlan), nil } else { return nil, err } } rp = new(RatingPlan) var kv struct { Key string Value []byte } err = ms.db.C(colRpl).Find(bson.M{"key": key}).One(&kv) if err == nil { b := bytes.NewBuffer(kv.Value) r, err := zlib.NewReader(b) if err != nil { return nil, err } out, err := ioutil.ReadAll(r) if err != nil { return nil, err } r.Close() err = ms.ms.Unmarshal(out, &rp) if err != nil { return nil, err } cache2go.Cache(utils.RATING_PLAN_PREFIX+key, rp) } return }
func (rs *RedisStorage) GetAlias(key string, skipCache bool) (al *Alias, err error) { origKey := key key = utils.ALIASES_PREFIX + key if !skipCache { if x, err := cache2go.Get(key); err == nil { al = &Alias{Values: x.(AliasValues)} al.SetId(origKey) return al, nil } else { return nil, err } } var values []byte if values, err = rs.db.Cmd("GET", key).Bytes(); err == nil { al = &Alias{Values: make(AliasValues, 0)} al.SetId(origKey) err = rs.ms.Unmarshal(values, &al.Values) if err == nil { cache2go.Cache(key, al.Values) // cache reverse alias al.SetReverseCache() } } return }
// Limit will only retrieve the last n items out of history, newest first func (ms *MongoStorage) GetLoadHistory(limit int, skipCache bool) (loadInsts []*LoadInstance, err error) { if limit == 0 { return nil, nil } if !skipCache { if x, err := cache2go.Get(utils.LOADINST_KEY); err != nil { return nil, err } else { items := x.([]*LoadInstance) if len(items) < limit || limit == -1 { return items, nil } return items[:limit], nil } } var kv struct { Key string Value []*LoadInstance } err = ms.db.C(colLht).Find(bson.M{"key": utils.LOADINST_KEY}).One(&kv) if err == nil { loadInsts = kv.Value cache2go.RemKey(utils.LOADINST_KEY) cache2go.Cache(utils.LOADINST_KEY, loadInsts) } return loadInsts, err }
func TestDebitShared(t *testing.T) { cc := &CallCost{ Tenant: "vdf", Category: "0", Direction: OUTBOUND, Destination: "0723045326", Timespans: []*TimeSpan{ &TimeSpan{ TimeStart: time.Date(2013, 9, 24, 10, 48, 0, 0, time.UTC), TimeEnd: time.Date(2013, 9, 24, 10, 49, 0, 0, time.UTC), DurationIndex: 55 * time.Second, RateInterval: &RateInterval{Rating: &RIRate{Rates: RateGroups{&Rate{GroupIntervalStart: 0, Value: 2, RateIncrement: 10 * time.Second, RateUnit: time.Second}}}}, }, }, deductConnectFee: true, } rif := &Account{Id: "rif", BalanceMap: map[string]BalanceChain{ CREDIT + OUTBOUND: BalanceChain{&Balance{Uuid: "moneya", Value: 60, SharedGroup: "SG_TEST"}}, }} groupie := &Account{Id: "groupie", BalanceMap: map[string]BalanceChain{ CREDIT + OUTBOUND: BalanceChain{&Balance{Uuid: "moneyc", Value: 70, SharedGroup: "SG_TEST"}}, }} sg := &SharedGroup{Id: "SG_TEST", MemberIds: []string{rif.Id, groupie.Id}, AccountParameters: map[string]*SharingParameters{"*any": &SharingParameters{Strategy: STRATEGY_MINE_RANDOM}}} accountingStorage.SetAccount(groupie) accountingStorage.SetSharedGroup(sg) cache2go.Cache(SHARED_GROUP_PREFIX+"SG_TEST", sg) err := rif.debitCreditBalance(cc, false) if err != nil { t.Error("Error debiting balance: ", err) } if rif.BalanceMap[CREDIT+OUTBOUND][0].Value != 0 { t.Errorf("Error debiting from shared group: %+v", rif.BalanceMap[CREDIT+OUTBOUND][0]) } groupie, _ = accountingStorage.GetAccount("groupie") if groupie.BalanceMap[CREDIT+OUTBOUND][0].Value != 10 { t.Errorf("Error debiting from shared group: %+v", groupie.BalanceMap[CREDIT+OUTBOUND][0]) } if len(cc.Timespans) != 1 { t.Errorf("Wrong number of timespans: %v", cc.Timespans) } if len(cc.Timespans[0].Increments) != 6 { t.Errorf("Wrong number of increments: %v", cc.Timespans[0].Increments) for index, incr := range cc.Timespans[0].Increments { t.Errorf("I%d: %+v (%+v)", index, incr, incr.BalanceInfo) } } if cc.Timespans[0].Increments[0].BalanceInfo.AccountId != "rif" || cc.Timespans[0].Increments[1].BalanceInfo.AccountId != "rif" || cc.Timespans[0].Increments[2].BalanceInfo.AccountId != "rif" || cc.Timespans[0].Increments[3].BalanceInfo.AccountId != "groupie" || cc.Timespans[0].Increments[4].BalanceInfo.AccountId != "groupie" || cc.Timespans[0].Increments[5].BalanceInfo.AccountId != "groupie" { t.Error("Error setting balance id to increment: ", cc.Timespans[0].Increments[0]) } }
func (ms *MongoStorage) GetAlias(key string, skipCache bool) (al *Alias, err error) { origKey := key key = utils.ALIASES_PREFIX + key if !skipCache { if x, err := cache2go.Get(key); err == nil { al = &Alias{Values: x.(AliasValues)} al.SetId(origKey) return al, nil } else { return nil, err } } var kv struct { Key string Value AliasValues } if err = ms.db.C(colAls).Find(bson.M{"key": origKey}).One(&kv); err == nil { al = &Alias{Values: kv.Value} al.SetId(origKey) if err == nil { cache2go.Cache(key, al.Values) // cache reverse alias for _, value := range al.Values { for target, pairs := range value.Pairs { for _, alias := range pairs { var existingKeys map[string]bool rKey := utils.REVERSE_ALIASES_PREFIX + alias + target + al.Context if x, err := cache2go.Get(rKey); err == nil { existingKeys = x.(map[string]bool) } else { existingKeys = make(map[string]bool) } existingKeys[utils.ConcatenatedKey(origKey, value.DestinationId)] = true cache2go.Cache(rKey, existingKeys) } } } } } return }
func (ms *MapStorage) GetAlias(key string, skipCache bool) (al *Alias, err error) { origKey := key key = utils.ALIASES_PREFIX + key if !skipCache { if x, err := cache2go.Get(key); err == nil { al = &Alias{Values: x.(AliasValues)} al.SetId(key[len(utils.ALIASES_PREFIX):]) return al, nil } else { return nil, err } } if values, ok := ms.dict[key]; ok { al = &Alias{Values: make(AliasValues, 0)} al.SetId(key[len(utils.ALIASES_PREFIX):]) err = ms.ms.Unmarshal(values, &al.Values) if err == nil { cache2go.Cache(key, al.Values) for _, value := range al.Values { for target, pairs := range value.Pairs { for _, alias := range pairs { var existingKeys map[string]bool rKey := utils.REVERSE_ALIASES_PREFIX + alias + target + al.Context if x, err := cache2go.Get(rKey); err == nil { existingKeys = x.(map[string]bool) } else { existingKeys = make(map[string]bool) } existingKeys[utils.ConcatenatedKey(origKey, value.DestinationId)] = true cache2go.Cache(rKey, existingKeys) } } } } } else { return nil, utils.ErrNotFound } return al, nil }
func (rs *RedisStorage) GetAlias(key string, skipCache bool) (al *Alias, err error) { origKey := key key = utils.ALIASES_PREFIX + key if !skipCache { if x, err := cache2go.Get(key); err == nil { al = &Alias{Values: x.(AliasValues)} al.SetId(origKey) return al, nil } else { return nil, err } } var values []byte if values, err = rs.db.Get(key); err == nil { al = &Alias{Values: make(AliasValues, 0)} al.SetId(origKey) err = rs.ms.Unmarshal(values, &al.Values) if err == nil { cache2go.Cache(key, al.Values) // cache reverse alias for _, value := range al.Values { for target, pairs := range value.Pairs { for _, alias := range pairs { var existingKeys map[string]bool rKey := utils.REVERSE_ALIASES_PREFIX + alias + target + al.Context if x, err := cache2go.Get(rKey); err == nil { existingKeys = x.(map[string]bool) } else { existingKeys = make(map[string]bool) } existingKeys[utils.ConcatenatedKey(origKey, value.DestinationId)] = true cache2go.Cache(rKey, existingKeys) } } } } } return }
func (ms *MongoStorage) GetSharedGroup(key string, skipCache bool) (sg *SharedGroup, err error) { if !skipCache { if x, err := cache2go.Get(utils.SHARED_GROUP_PREFIX + key); err == nil { return x.(*SharedGroup), nil } else { return nil, err } } sg = &SharedGroup{} err = ms.db.C(colShg).Find(bson.M{"id": key}).One(sg) if err == nil { cache2go.Cache(utils.SHARED_GROUP_PREFIX+key, sg) } return }
func (ms *MongoStorage) GetRatingProfile(key string, skipCache bool) (rp *RatingProfile, err error) { if !skipCache { if x, err := cache2go.Get(utils.RATING_PROFILE_PREFIX + key); err == nil { return x.(*RatingProfile), nil } else { return nil, err } } rp = new(RatingProfile) err = ms.db.C(colRpf).Find(bson.M{"id": key}).One(rp) if err == nil { cache2go.Cache(utils.RATING_PROFILE_PREFIX+key, rp) } return }
func (rs *RedisStorage) GetDerivedChargers(key string, skipCache bool) (dcs utils.DerivedChargers, err error) { key = utils.DERIVEDCHARGERS_PREFIX + key if !skipCache { if x, err := cache2go.Get(key); err == nil { return x.(utils.DerivedChargers), nil } else { return nil, err } } var values []byte if values, err = rs.db.Get(key); err == nil { err = rs.ms.Unmarshal(values, &dcs) cache2go.Cache(key, dcs) } return dcs, err }
func (rs *RedisStorage) GetActions(key string, skipCache bool) (as Actions, err error) { key = utils.ACTION_PREFIX + key if !skipCache { if x, err := cache2go.Get(key); err == nil { return x.(Actions), nil } else { return nil, err } } var values []byte if values, err = rs.db.Get(key); err == nil { err = rs.ms.Unmarshal(values, &as) cache2go.Cache(key, as) } return }
func (rs *RedisStorage) GetSharedGroup(key string, skipCache bool) (sg *SharedGroup, err error) { key = utils.SHARED_GROUP_PREFIX + key if !skipCache { if x, err := cache2go.Get(key); err == nil { return x.(*SharedGroup), nil } else { return nil, err } } var values []byte if values, err = rs.db.Get(key); err == nil { err = rs.ms.Unmarshal(values, &sg) cache2go.Cache(key, sg) } return }
func (rs *RedisStorage) GetAccAlias(key string, skipCache bool) (alias string, err error) { key = ACC_ALIAS_PREFIX + key if !skipCache { if x, err := cache2go.GetCached(key); err == nil { return x.(string), nil } else { return "", err } } var values []byte if values, err = rs.db.Get(key); err == nil { alias = string(values) cache2go.Cache(key, alias) } return }
func (rs *RedisStorage) GetLCR(key string, skipCache bool) (lcr *LCR, err error) { key = utils.LCR_PREFIX + key if !skipCache { if x, err := cache2go.Get(key); err == nil { return x.(*LCR), nil } else { return nil, err } } var values []byte if values, err = rs.db.Get(key); err == nil { err = rs.ms.Unmarshal(values, &lcr) cache2go.Cache(key, lcr) } return }
func (ms *MapStorage) GetSharedGroup(key string, skipCache bool) (sg *SharedGroup, err error) { key = SHARED_GROUP_PREFIX + key if !skipCache { if x, err := cache2go.GetCached(key); err == nil { return x.(*SharedGroup), nil } else { return nil, err } } if values, ok := ms.dict[key]; ok { err = ms.ms.Unmarshal(values, &sg) cache2go.Cache(key, sg) } else { return nil, errors.New(utils.ERR_NOT_FOUND) } return }
func (ms *MapStorage) GetDerivedChargers(key string, skipCache bool) (dcs *utils.DerivedChargers, err error) { key = utils.DERIVEDCHARGERS_PREFIX + key if !skipCache { if x, err := cache2go.Get(key); err == nil { return x.(*utils.DerivedChargers), nil } else { return nil, err } } if values, ok := ms.dict[key]; ok { err = ms.ms.Unmarshal(values, &dcs) cache2go.Cache(key, dcs) } else { return nil, utils.ErrNotFound } return }
func (ms *MapStorage) GetLCR(key string, skipCache bool) (lcr *LCR, err error) { key = LCR_PREFIX + key if !skipCache { if x, err := cache2go.GetCached(key); err == nil { return x.(*LCR), nil } else { return nil, err } } if values, ok := ms.dict[key]; ok { err = ms.ms.Unmarshal(values, &lcr) cache2go.Cache(key, lcr) } else { return nil, errors.New(utils.ERR_NOT_FOUND) } return }
func (ms *MapStorage) GetAccAlias(key string, skipCache bool) (alias string, err error) { key = ACC_ALIAS_PREFIX + key if !skipCache { if x, err := cache2go.GetCached(key); err == nil { return x.(string), nil } else { return "", err } } if values, ok := ms.dict[key]; ok { alias = string(values) cache2go.Cache(key, alias) } else { return "", errors.New(utils.ERR_NOT_FOUND) } return }
func (ms *MapStorage) GetDerivedChargers(key string, skipCache bool) (dcs utils.DerivedChargers, err error) { key = DERIVEDCHARGERS_PREFIX + key if !skipCache { if x, err := cache2go.GetCached(key); err == nil { return x.(utils.DerivedChargers), nil } else { return nil, err } } if values, ok := ms.dict[key]; ok { err = ms.ms.Unmarshal(values, &dcs) cache2go.Cache(key, dcs) } else { return nil, errors.New(utils.ERR_NOT_FOUND) } return }
func (ms *MapStorage) GetActions(key string, skipCache bool) (as Actions, err error) { key = ACTION_PREFIX + key if !skipCache { if x, err := cache2go.GetCached(key); err == nil { return x.(Actions), nil } else { return nil, err } } if values, ok := ms.dict[key]; ok { err = ms.ms.Unmarshal(values, &as) cache2go.Cache(key, as) } else { return nil, errors.New(utils.ERR_NOT_FOUND) } return }