// Adds the units from the received balance to an existing balance if the destination // is the same or ads the balance to the list if none matches. func (uc *UnitsCounter) addUnits(amount float64, prefix string) { counted := false if prefix != "" { for _, mb := range uc.Balances { if !mb.HasDestination() { continue } for _, p := range utils.SplitPrefix(prefix, MIN_PREFIX_MATCH) { if x, err := cache2go.Get(utils.DESTINATION_PREFIX + p); err == nil { destIds := x.(map[interface{}]struct{}) if _, found := destIds[mb.DestinationIds]; found { mb.AddValue(amount) counted = true break } } if counted { break } } } } if !counted { // use general balance b := uc.GetGeneralBalance() b.AddValue(amount) } }
func (lcra *LCRActivation) GetLCREntryForPrefix(destination string) *LCREntry { var potentials LCREntriesSorter for _, p := range utils.SplitPrefix(destination, MIN_PREFIX_MATCH) { if x, err := CacheGet(utils.DESTINATION_PREFIX + p); err == nil { destIds := x.(map[string]struct{}) for dId := range destIds { for _, entry := range lcra.Entries { if entry.DestinationId == dId { entry.precision = len(p) potentials = append(potentials, entry) } } } } } if len(potentials) > 0 { // sort by precision and weight potentials.Sort() return potentials[0] } // return the *any entry if it exists for _, entry := range lcra.Entries { if entry.DestinationId == utils.ANY { return entry } } return nil }
func (cc *CallCost) MatchCCFilter(bf *BalanceFilter) bool { if bf == nil { return true } if bf.Categories != nil && cc.Category != "" && (*bf.Categories)[cc.Category] == false { return false } if bf.Directions != nil && cc.Direction != "" && (*bf.Directions)[cc.Direction] == false { return false } // match destination ids foundMatchingDestID := false if bf.DestinationIDs != nil && cc.Destination != "" { for _, p := range utils.SplitPrefix(cc.Destination, MIN_PREFIX_MATCH) { if destIDs, err := ratingStorage.GetReverseDestination(p, false, utils.NonTransactional); err == nil { for _, dID := range destIDs { if _, ok := (*bf.DestinationIDs)[dID]; ok { foundMatchingDestID = true break // only one found? } } } if foundMatchingDestID { break } } } else { foundMatchingDestID = true } if !foundMatchingDestID { return false } return true }
// Adds the units from the received balance to an existing balance if the destination // is the same or ads the balance to the list if none matches. func (uc *UnitsCounter) addUnits(amount float64, prefix string) { counted := false if prefix != "" { for _, mb := range uc.Balances { if !mb.HasDestination() { continue } for _, p := range utils.SplitPrefix(prefix, MIN_PREFIX_MATCH) { if x, err := cache2go.GetCached(DESTINATION_PREFIX + p); err == nil { destIds := x.([]interface{}) for _, dId := range destIds { if dId == mb.DestinationId { mb.Value += amount counted = true break } } } if counted { break } } } } if !counted { // use general balance b := uc.GetGeneralBalance() b.Value += amount } }
func (b *Balance) MatchCCFilter(cc *CallCost) bool { if len(b.Categories) > 0 && cc.Category != "" && b.Categories[cc.Category] == false { return false } if len(b.Directions) > 0 && cc.Direction != "" && b.Directions[cc.Direction] == false { return false } // match destination ids foundMatchingDestId := false if len(b.DestinationIds) > 0 && cc.Destination != "" { for _, p := range utils.SplitPrefix(cc.Destination, MIN_PREFIX_MATCH) { if x, err := cache2go.Get(utils.DESTINATION_PREFIX + p); err == nil { destIds := x.(map[interface{}]struct{}) for filterDestId := range b.DestinationIds { if _, ok := destIds[filterDestId]; ok { foundMatchingDestId = true break } } } if foundMatchingDestId { break } } } else { foundMatchingDestId = true } if !foundMatchingDestId { return false } return true }
func (lcra *LCRActivation) GetLCREntryForPrefix(destination string) *LCREntry { var potentials LCREntriesSorter for _, p := range utils.SplitPrefix(destination, MIN_PREFIX_MATCH) { if destIDs, err := ratingStorage.GetReverseDestination(p, true, utils.NonTransactional); err == nil { for _, dId := range destIDs { for _, entry := range lcra.Entries { if entry.DestinationId == dId { entry.precision = len(p) potentials = append(potentials, entry) } } } } } if len(potentials) > 0 { // sort by precision and weight potentials.Sort() return potentials[0] } // return the *any entry if it exists for _, entry := range lcra.Entries { if entry.DestinationId == utils.ANY { return entry } } return nil }
func (ub *Account) getBalancesForPrefix(prefix, category, direction, tor string, sharedGroup string) BalanceChain { var balances BalanceChain balances = append(balances, ub.BalanceMap[tor]...) if tor != utils.MONETARY && tor != utils.GENERIC { balances = append(balances, ub.BalanceMap[utils.GENERIC]...) } var usefulBalances BalanceChain for _, b := range balances { if b.Disabled { continue } if b.IsExpired() || (len(b.SharedGroups) == 0 && b.GetValue() <= 0) { continue } if sharedGroup != "" && b.SharedGroups[sharedGroup] == false { continue } if !b.MatchCategory(category) { continue } if b.HasDirection() && b.Directions[direction] == false { continue } b.account = ub if len(b.DestinationIds) > 0 && b.DestinationIds[utils.ANY] == false { for _, p := range utils.SplitPrefix(prefix, MIN_PREFIX_MATCH) { if x, err := cache2go.Get(utils.DESTINATION_PREFIX + p); err == nil { destIds := x.(map[interface{}]struct{}) for dId, _ := range destIds { if b.DestinationIds[dId.(string)] == true { b.precision = len(p) usefulBalances = append(usefulBalances, b) break } if b.precision > 0 { break } } } if b.precision > 0 { break } } } else { usefulBalances = append(usefulBalances, b) } } // resort by precision usefulBalances.Sort() // clear precision for _, b := range usefulBalances { b.precision = 0 } return usefulBalances }
func (am *AliasHandler) GetMatchingAlias(attr AttrMatchingAlias, result *string) error { response := Alias{} if err := am.GetAlias(Alias{ Direction: attr.Direction, Tenant: attr.Tenant, Category: attr.Category, Account: attr.Account, Subject: attr.Subject, Context: attr.Context, }, &response); err != nil { return err } // sort according to weight values := response.Values values.Sort() // if destination does not metter get first alias if attr.Destination == "" || attr.Destination == utils.ANY { for _, value := range values { if origAlias, ok := value.Pairs[attr.Target]; ok { if alias, ok := origAlias[attr.Original]; ok { *result = alias return nil } } } return utils.ErrNotFound } // check destination ids for _, p := range utils.SplitPrefix(attr.Destination, MIN_PREFIX_MATCH) { if x, err := cache2go.Get(utils.DESTINATION_PREFIX + p); err == nil { destIds := x.(map[interface{}]struct{}) for _, value := range values { for idId := range destIds { dId := idId.(string) if value.DestinationId == utils.ANY || value.DestinationId == dId { if origAliasMap, ok := value.Pairs[attr.Target]; ok { if alias, ok := origAliasMap[attr.Original]; ok || attr.Original == "" || attr.Original == utils.ANY { *result = alias return nil } if alias, ok := origAliasMap[utils.ANY]; ok { *result = alias return nil } } } } } } } return utils.ErrNotFound }
func (am *AliasHandler) GetMatchingAlias(attr *AttrMatchingAlias, result *string) error { response := Alias{} if err := am.GetAlias(&Alias{ Direction: attr.Direction, Tenant: attr.Tenant, Category: attr.Category, Account: attr.Account, Subject: attr.Subject, Context: attr.Context, }, &response); err != nil { return err } // sort according to weight values := response.Values values.Sort() // if destination does not metter get first alias if attr.Destination == "" || attr.Destination == utils.ANY { for _, value := range values { if origAlias, ok := value.Pairs[attr.Target]; ok { if alias, ok := origAlias[attr.Original]; ok { *result = alias return nil } } } return utils.ErrNotFound } // check destination ids for _, p := range utils.SplitPrefix(attr.Destination, MIN_PREFIX_MATCH) { if destIDs, err := ratingStorage.GetReverseDestination(p, false, utils.NonTransactional); err == nil { for _, value := range values { for _, dId := range destIDs { if value.DestinationId == utils.ANY || value.DestinationId == dId { if origAliasMap, ok := value.Pairs[attr.Target]; ok { if alias, ok := origAliasMap[attr.Original]; ok || attr.Original == "" || attr.Original == utils.ANY { *result = alias return nil } if alias, ok := origAliasMap[utils.ANY]; ok { *result = alias return nil } } } } } } } return utils.ErrNotFound }
func (ub *Account) getBalancesForPrefix(prefix, category string, balances BalanceChain, sharedGroup string) BalanceChain { var usefulBalances BalanceChain for _, b := range balances { if b.Disabled { continue } if b.IsExpired() || (b.SharedGroup == "" && b.GetValue() <= 0) { continue } if sharedGroup != "" && b.SharedGroup != sharedGroup { continue } if !b.MatchCategory(category) { continue } b.account = ub if b.DestinationIds != "" && b.DestinationIds != utils.ANY { balDestIds := strings.Split(b.DestinationIds, utils.INFIELD_SEP) for _, p := range utils.SplitPrefix(prefix, MIN_PREFIX_MATCH) { if x, err := cache2go.Get(utils.DESTINATION_PREFIX + p); err == nil { destIds := x.(map[interface{}]struct{}) for dId, _ := range destIds { for _, balDestID := range balDestIds { if dId == strings.TrimSpace(balDestID) { b.precision = len(p) usefulBalances = append(usefulBalances, b) break } } if b.precision > 0 { break } } } if b.precision > 0 { break } } } else { usefulBalances = append(usefulBalances, b) } } // resort by precision usefulBalances.Sort() // clear precision for _, b := range usefulBalances { b.precision = 0 } return usefulBalances }
func (b *Balance) getMatchingPrefixAndDestID(dest string) (prefix, destId string) { if len(b.DestinationIDs) != 0 && b.DestinationIDs[utils.ANY] == false { for _, p := range utils.SplitPrefix(dest, MIN_PREFIX_MATCH) { if destIDs, err := ratingStorage.GetReverseDestination(p, false, utils.NonTransactional); err == nil { for _, dID := range destIDs { if b.DestinationIDs[dID] == true { return p, dID } } } } } return }
func (b *Balance) getMatchingPrefixAndDestID(dest string) (prefix, destId string) { if len(b.DestinationIDs) != 0 && b.DestinationIDs[utils.ANY] == false { for _, p := range utils.SplitPrefix(dest, MIN_PREFIX_MATCH) { if x, err := CacheGet(utils.DESTINATION_PREFIX + p); err == nil { destIDs := x.(map[string]struct{}) for dID := range destIDs { if b.DestinationIDs[dID] == true { return p, dID } } } } } return }
func (b *Balance) getMatchingPrefixAndDestId(dest string) (prefix, destId string) { if len(b.DestinationIds) != 0 && b.DestinationIds[utils.ANY] == false { for _, p := range utils.SplitPrefix(dest, MIN_PREFIX_MATCH) { if x, err := cache2go.Get(utils.DESTINATION_PREFIX + p); err == nil { destIds := x.(map[interface{}]struct{}) for dId, _ := range destIds { if b.DestinationIds[dId.(string)] == true { return p, dId.(string) } } } } } return }
func DerivedChargersMatchesDest(dcs *utils.DerivedChargers, dest string) bool { if len(dcs.DestinationIDs) == 0 || dcs.DestinationIDs[utils.ANY] { return true } // check destination ids for _, p := range utils.SplitPrefix(dest, MIN_PREFIX_MATCH) { if destIDs, err := ratingStorage.GetReverseDestination(p, false, utils.NonTransactional); err == nil { for _, dId := range destIDs { includeDest, found := dcs.DestinationIDs[dId] if found { return includeDest } } } } return false }
func DerivedChargersMatchesDest(dcs *utils.DerivedChargers, dest string) bool { if len(dcs.DestinationIDs) == 0 || dcs.DestinationIDs[utils.ANY] { return true } // check destination ids for _, p := range utils.SplitPrefix(dest, MIN_PREFIX_MATCH) { if x, err := CacheGet(utils.DESTINATION_PREFIX + p); err == nil { destIds := x.(map[string]struct{}) for dId := range destIds { includeDest, found := dcs.DestinationIDs[dId] if found { return includeDest } } } } return false }
func (b *Balance) getMatchingPrefixAndDestId(dest string) (prefix, destId string) { if b.DestinationIds != "" && b.DestinationIds != utils.ANY { for _, p := range utils.SplitPrefix(dest, MIN_PREFIX_MATCH) { if x, err := cache2go.Get(utils.DESTINATION_PREFIX + p); err == nil { destIds := x.(map[interface{}]struct{}) for dId, _ := range destIds { balDestIds := strings.Split(b.DestinationIds, utils.INFIELD_SEP) for _, balDestID := range balDestIds { if dId == balDestID { return p, balDestID } } } } } } return }
func (fltr *RequestFilter) passDestinations(req interface{}, extraFieldsLabel string) (bool, error) { dst, err := utils.ReflectFieldAsString(req, fltr.FieldName, extraFieldsLabel) if err != nil { return false, err } for _, p := range utils.SplitPrefix(dst, MIN_PREFIX_MATCH) { if x, err := CacheGet(utils.DESTINATION_PREFIX + p); err == nil { destIds := x.(map[string]struct{}) for dID := range destIds { for _, valDstID := range fltr.Values { if valDstID == dID { return true, nil } } } } } return false, nil }
func DerivedChargersMatchesDest(dcs *utils.DerivedChargers, dest string) bool { if len(dcs.DestinationIds) == 0 || dcs.DestinationIds[utils.ANY] { return true } // check destination ids for _, p := range utils.SplitPrefix(dest, MIN_PREFIX_MATCH) { if x, err := cache2go.Get(utils.DESTINATION_PREFIX + p); err == nil { destIds := x.(map[interface{}]struct{}) for value := range dcs.DestinationIds { for idId := range destIds { dId := idId.(string) if value == dId { return true } } } } } return false }
func (ub *Account) getBalancesForPrefix(prefix, category string, balances BalanceChain, sharedGroup string) BalanceChain { var usefulBalances BalanceChain for _, b := range balances { if b.IsExpired() || (ub.AllowNegative == false && b.SharedGroup == "" && b.Value <= 0) { continue } if sharedGroup != "" && b.SharedGroup != sharedGroup { continue } if !b.MatchCategory(category) { continue } b.account = ub if b.DestinationId != "" && b.DestinationId != utils.ANY { for _, p := range utils.SplitPrefix(prefix, MIN_PREFIX_MATCH) { if x, err := cache2go.GetCached(DESTINATION_PREFIX + p); err == nil { destIds := x.([]interface{}) for _, dId := range destIds { if dId == b.DestinationId { b.precision = len(p) usefulBalances = append(usefulBalances, b) break } } } if b.precision > 0 { break } } } else { usefulBalances = append(usefulBalances, b) } } // resort by precision usefulBalances.Sort() // clear precision for _, b := range usefulBalances { b.precision = 0 } return usefulBalances }
func (fltr *RequestFilter) passDestinations(req interface{}, extraFieldsLabel string) (bool, error) { dst, err := utils.ReflectFieldAsString(req, fltr.FieldName, extraFieldsLabel) if err != nil { if err == utils.ErrNotFound { return false, nil } return false, err } for _, p := range utils.SplitPrefix(dst, MIN_PREFIX_MATCH) { if destIDs, err := ratingStorage.GetReverseDestination(p, false, utils.NonTransactional); err == nil { for _, dID := range destIDs { for _, valDstID := range fltr.Values { if valDstID == dID { return true, nil } } } } } return false, nil }
func (cc *CallCost) MatchCCFilter(bf *BalanceFilter) bool { if bf == nil { return true } if bf.Categories != nil && cc.Category != "" && (*bf.Categories)[cc.Category] == false { return false } if bf.Directions != nil && cc.Direction != "" && (*bf.Directions)[cc.Direction] == false { return false } // match destination ids foundMatchingDestID := false if bf.DestinationIDs != nil && cc.Destination != "" { for _, p := range utils.SplitPrefix(cc.Destination, MIN_PREFIX_MATCH) { if x, err := CacheGet(utils.DESTINATION_PREFIX + p); err == nil { destIds := x.(map[string]struct{}) for filterDestID := range *bf.DestinationIDs { if _, ok := destIds[filterDestID]; ok { foundMatchingDestID = true break // only one found? } } } if foundMatchingDestID { break } } } else { foundMatchingDestID = true } if !foundMatchingDestID { return false } return true }
/* func (ub *Account) enableDisableBalanceAction(a *Action) error { if a == nil { return errors.New("nil action") } if ub.BalanceMap == nil { ub.BalanceMap = make(map[string]Balances) } found := false id := a.BalanceType disabled := a.Balance.Disabled a.Balance.Disabled = !disabled // match for the opposite for _, b := range ub.BalanceMap[id] { if b.MatchFilter(a.Balance, false) { b.Disabled = disabled b.dirty = true found = true } } a.Balance.Disabled = disabled // restore balance aaction as it is cached if !found { return utils.ErrNotFound } return nil } */ func (ub *Account) getBalancesForPrefix(prefix, category, direction, tor string, sharedGroup string) Balances { var balances Balances balances = append(balances, ub.BalanceMap[tor]...) if tor != utils.MONETARY && tor != utils.GENERIC { balances = append(balances, ub.BalanceMap[utils.GENERIC]...) } var usefulBalances Balances for _, b := range balances { if b.Disabled { continue } if b.IsExpired() || (len(b.SharedGroups) == 0 && b.GetValue() <= 0 && !b.Blocker) { continue } if sharedGroup != "" && b.SharedGroups[sharedGroup] == false { continue } if !b.MatchCategory(category) { continue } if b.HasDirection() && b.Directions[direction] == false { continue } b.account = ub if len(b.DestinationIDs) > 0 && b.DestinationIDs[utils.ANY] == false { for _, p := range utils.SplitPrefix(prefix, MIN_PREFIX_MATCH) { if destIDs, err := ratingStorage.GetReverseDestination(p, false, utils.NonTransactional); err == nil { foundResult := false allInclude := true // whether it is excluded or included for _, dId := range destIDs { inclDest, found := b.DestinationIDs[dId] if found { foundResult = true allInclude = allInclude && inclDest } } // check wheter all destination ids in the balance were exclusions allExclude := true for _, inclDest := range b.DestinationIDs { if inclDest { allExclude = false break } } if foundResult || allExclude { if allInclude { b.precision = len(p) usefulBalances = append(usefulBalances, b) } else { b.precision = 1 // fake to exit the outer loop } } } if b.precision > 0 { break } } } else { usefulBalances = append(usefulBalances, b) } } // resort by precision usefulBalances.Sort() // clear precision for _, b := range usefulBalances { b.precision = 0 } return usefulBalances }
func (rpf *RatingProfile) GetRatingPlansForPrefix(cd *CallDescriptor) (err error) { var ris RatingInfos for index, rpa := range rpf.RatingPlanActivations.GetActiveForCall(cd) { rpl, err := ratingStorage.GetRatingPlan(rpa.RatingPlanId, false, utils.NonTransactional) if err != nil || rpl == nil { utils.Logger.Err(fmt.Sprintf("Error checking destination: %v", err)) continue } prefix := "" destinationId := "" var rps RateIntervalList if cd.Destination == utils.ANY || cd.Destination == "" { cd.Destination = utils.ANY if _, ok := rpl.DestinationRates[utils.ANY]; ok { rps = rpl.RateIntervalList(utils.ANY) prefix = utils.ANY destinationId = utils.ANY } } else { for _, p := range utils.SplitPrefix(cd.Destination, MIN_PREFIX_MATCH) { if destIDs, err := ratingStorage.GetReverseDestination(p, false, utils.NonTransactional); err == nil { var bestWeight float64 for _, dID := range destIDs { if _, ok := rpl.DestinationRates[dID]; ok { ril := rpl.RateIntervalList(dID) currentWeight := ril.GetWeight() if currentWeight > bestWeight { bestWeight = currentWeight rps = ril prefix = p destinationId = dID } } } } if rps != nil { break } } if rps == nil { // fallback on *any destination if _, ok := rpl.DestinationRates[utils.ANY]; ok { rps = rpl.RateIntervalList(utils.ANY) prefix = utils.ANY destinationId = utils.ANY } } } // check if it's the first ri and add a blank one for the initial part not covered if index == 0 && cd.TimeStart.Before(rpa.ActivationTime) { ris = append(ris, &RatingInfo{ MatchedSubject: "", MatchedPrefix: "", MatchedDestId: "", ActivationTime: cd.TimeStart, RateIntervals: nil, FallbackKeys: []string{cd.GetKey(FALLBACK_SUBJECT)}}) } if len(prefix) > 0 { ris = append(ris, &RatingInfo{ MatchedSubject: rpf.Id, RatingPlanId: rpl.Id, MatchedPrefix: prefix, MatchedDestId: destinationId, ActivationTime: rpa.ActivationTime, RateIntervals: rps, FallbackKeys: rpa.FallbackKeys}) } else { // add for fallback information if len(rpa.FallbackKeys) > 0 { ris = append(ris, &RatingInfo{ MatchedSubject: "", MatchedPrefix: "", MatchedDestId: "", ActivationTime: rpa.ActivationTime, RateIntervals: nil, FallbackKeys: rpa.FallbackKeys, }) } } } if len(ris) > 0 { cd.addRatingInfos(ris) return } return utils.ErrNotFound }
func (cs *CdrStats) AcceptCdr(cdr *CDR) bool { if cdr == nil { return false } if len(cs.SetupInterval) > 0 { if cdr.SetupTime.Before(cs.SetupInterval[0]) { return false } if len(cs.SetupInterval) > 1 && (cdr.SetupTime.Equal(cs.SetupInterval[1]) || cdr.SetupTime.After(cs.SetupInterval[1])) { return false } } if len(cs.TOR) > 0 && !utils.IsSliceMember(cs.TOR, cdr.ToR) { return false } if len(cs.CdrHost) > 0 && !utils.IsSliceMember(cs.CdrHost, cdr.OriginHost) { return false } if len(cs.CdrSource) > 0 && !utils.IsSliceMember(cs.CdrSource, cdr.Source) { return false } if len(cs.ReqType) > 0 && !utils.IsSliceMember(cs.ReqType, cdr.RequestType) { return false } if len(cs.Direction) > 0 && !utils.IsSliceMember(cs.Direction, cdr.Direction) { return false } if len(cs.Tenant) > 0 && !utils.IsSliceMember(cs.Tenant, cdr.Tenant) { return false } if len(cs.Category) > 0 && !utils.IsSliceMember(cs.Category, cdr.Category) { return false } if len(cs.Account) > 0 && !utils.IsSliceMember(cs.Account, cdr.Account) { return false } if len(cs.Subject) > 0 && !utils.IsSliceMember(cs.Subject, cdr.Subject) { return false } if len(cs.DestinationIds) > 0 { found := false for _, p := range utils.SplitPrefix(cdr.Destination, MIN_PREFIX_MATCH) { if destIDs, err := ratingStorage.GetReverseDestination(p, false, utils.NonTransactional); err == nil { for _, idID := range destIDs { if utils.IsSliceMember(cs.DestinationIds, idID) { found = true break } } if found { break } } if found { break } } if !found { return false } } if len(cs.UsageInterval) > 0 { if cdr.Usage < cs.UsageInterval[0] { return false } if len(cs.UsageInterval) > 1 && cdr.Usage >= cs.UsageInterval[1] { return false } } if len(cs.PddInterval) > 0 { if cdr.PDD < cs.PddInterval[0] { return false } if len(cs.PddInterval) > 1 && cdr.PDD >= cs.PddInterval[1] { return false } } if len(cs.Supplier) > 0 && !utils.IsSliceMember(cs.Supplier, cdr.Supplier) { return false } if len(cs.DisconnectCause) > 0 && !utils.IsSliceMember(cs.DisconnectCause, cdr.DisconnectCause) { return false } if len(cs.MediationRunIds) > 0 && !utils.IsSliceMember(cs.MediationRunIds, cdr.RunID) { return false } if len(cs.CostInterval) > 0 { if cdr.Cost < cs.CostInterval[0] { return false } if len(cs.CostInterval) > 1 && cdr.Cost >= cs.CostInterval[1] { return false } } return true }
func LoadAlias(attr *AttrMatchingAlias, in interface{}, extraFields string) error { if aliasService == nil { // no alias service => no fun return nil } response := Alias{} if err := aliasService.Call("AliasesV1.GetAlias", &Alias{ Direction: attr.Direction, Tenant: attr.Tenant, Category: attr.Category, Account: attr.Account, Subject: attr.Subject, Context: attr.Context, }, &response); err != nil { return err } // sort according to weight values := response.Values values.Sort() var rightPairs AliasPairs // if destination does not metter get first alias if attr.Destination == "" || attr.Destination == utils.ANY { rightPairs = values[0].Pairs } if rightPairs == nil { // check destination ids for _, p := range utils.SplitPrefix(attr.Destination, MIN_PREFIX_MATCH) { if x, err := CacheGet(utils.DESTINATION_PREFIX + p); err == nil { destIds := x.(map[string]struct{}) for _, value := range values { for dId := range destIds { if value.DestinationId == utils.ANY || value.DestinationId == dId { rightPairs = value.Pairs } if rightPairs != nil { break } } if rightPairs != nil { break } } } if rightPairs != nil { break } } } if rightPairs != nil { // change values in the given object v := reflect.ValueOf(in) if v.Kind() == reflect.Ptr { v = v.Elem() } for target, originalAlias := range rightPairs { for original, alias := range originalAlias { field := v.FieldByName(target) if field.IsValid() { if field.Kind() == reflect.String { if field.CanSet() && (original == "" || original == utils.ANY || field.String() == original) { field.SetString(alias) } } } if extraFields != "" { efField := v.FieldByName(extraFields) if efField.IsValid() && efField.Kind() == reflect.Map { keys := efField.MapKeys() for _, key := range keys { if key.Kind() == reflect.String && key.String() == target { if original == "" || original == utils.ANY || efField.MapIndex(key).String() == original { efField.SetMapIndex(key, reflect.ValueOf(alias)) } } } } } } } } return nil }
func (cs *CdrStats) AcceptCdr(cdr *CDR) bool { if cdr == nil { return false } if len(cs.SetupInterval) > 0 { if cdr.SetupTime.Before(cs.SetupInterval[0]) { return false } if len(cs.SetupInterval) > 1 && (cdr.SetupTime.Equal(cs.SetupInterval[1]) || cdr.SetupTime.After(cs.SetupInterval[1])) { return false } } if len(cs.TOR) > 0 && !utils.IsSliceMember(cs.TOR, cdr.ToR) { return false } if len(cs.CdrHost) > 0 && !utils.IsSliceMember(cs.CdrHost, cdr.OriginHost) { return false } if len(cs.CdrSource) > 0 && !utils.IsSliceMember(cs.CdrSource, cdr.Source) { return false } if len(cs.ReqType) > 0 && !utils.IsSliceMember(cs.ReqType, cdr.RequestType) { return false } if len(cs.Direction) > 0 && !utils.IsSliceMember(cs.Direction, cdr.Direction) { return false } if len(cs.Tenant) > 0 && !utils.IsSliceMember(cs.Tenant, cdr.Tenant) { return false } if len(cs.Category) > 0 && !utils.IsSliceMember(cs.Category, cdr.Category) { return false } if len(cs.Account) > 0 && !utils.IsSliceMember(cs.Account, cdr.Account) { return false } if len(cs.Subject) > 0 && !utils.IsSliceMember(cs.Subject, cdr.Subject) { return false } if len(cs.DestinationIds) > 0 { found := false for _, p := range utils.SplitPrefix(cdr.Destination, MIN_PREFIX_MATCH) { if x, err := cache2go.Get(utils.DESTINATION_PREFIX + p); err == nil { destIds := x.(map[interface{}]struct{}) for idID := range destIds { if utils.IsSliceMember(cs.DestinationIds, idID.(string)) { found = true break } } if found { break } } if found { break } } if !found { return false } } if len(cs.UsageInterval) > 0 { if cdr.Usage < cs.UsageInterval[0] { return false } if len(cs.UsageInterval) > 1 && cdr.Usage >= cs.UsageInterval[1] { return false } } if len(cs.PddInterval) > 0 { if cdr.PDD < cs.PddInterval[0] { return false } if len(cs.PddInterval) > 1 && cdr.PDD >= cs.PddInterval[1] { return false } } if len(cs.Supplier) > 0 && !utils.IsSliceMember(cs.Supplier, cdr.Supplier) { return false } if len(cs.DisconnectCause) > 0 && !utils.IsSliceMember(cs.DisconnectCause, cdr.DisconnectCause) { return false } if len(cs.MediationRunIds) > 0 && !utils.IsSliceMember(cs.MediationRunIds, cdr.RunID) { return false } if len(cs.CostInterval) > 0 { if cdr.Cost < cs.CostInterval[0] { return false } if len(cs.CostInterval) > 1 && cdr.Cost >= cs.CostInterval[1] { return false } } return true }
func (rp *RatingProfile) GetRatingPlansForPrefix(cd *CallDescriptor) (err error) { var ris RatingInfos for index, rpa := range rp.RatingPlanActivations.GetActiveForCall(cd) { rpl, err := dataStorage.GetRatingPlan(rpa.RatingPlanId, false) if err != nil || rpl == nil { Logger.Err(fmt.Sprintf("Error checking destination: %v", err)) continue } prefix := "" destinationId := "" var rps RateIntervalList if cd.Destination == utils.ANY || cd.Destination == "" { cd.Destination = utils.ANY if _, ok := rpl.DestinationRates[utils.ANY]; ok { rps = rpl.RateIntervalList(utils.ANY) prefix = utils.ANY destinationId = utils.ANY } } else { for _, p := range utils.SplitPrefix(cd.Destination, MIN_PREFIX_MATCH) { if x, err := cache2go.GetCached(DESTINATION_PREFIX + p); err == nil { destIds := x.([]interface{}) for _, idId := range destIds { dId := idId.(string) if _, ok := rpl.DestinationRates[dId]; ok { rps = rpl.RateIntervalList(dId) prefix = p destinationId = dId break } } } if rps != nil { break } } if rps == nil { // fallback on *any destination if _, ok := rpl.DestinationRates[utils.ANY]; ok { rps = rpl.RateIntervalList(utils.ANY) prefix = utils.ANY destinationId = utils.ANY } } } // check if it's the first ri and add a blank one for the initial part not covered if index == 0 && cd.TimeStart.Before(rpa.ActivationTime) { ris = append(ris, &RatingInfo{"", "", "", cd.TimeStart, nil, []string{cd.GetKey(FALLBACK_SUBJECT)}}) } if len(prefix) > 0 { ris = append(ris, &RatingInfo{rp.Id, prefix, destinationId, rpa.ActivationTime, rps, rpa.FallbackKeys}) } else { // add for fallback information ris = append(ris, &RatingInfo{"", "", "", rpa.ActivationTime, nil, rpa.FallbackKeys}) } } if len(ris) > 0 { cd.addRatingInfos(ris) return } return errors.New(utils.ERR_NOT_FOUND) }
func (rp *RatingProfile) GetRatingPlansForPrefix(cd *CallDescriptor) (err error) { var ris RatingInfos for index, rpa := range rp.RatingPlanActivations.GetActiveForCall(cd) { rpl, err := ratingStorage.GetRatingPlan(rpa.RatingPlanId, false) if err != nil || rpl == nil { Logger.Err(fmt.Sprintf("Error checking destination: %v", err)) continue } prefix := "" destinationId := "" var rps RateIntervalList //log.Printf("RPA: %+v", rpa) if cd.Destination == utils.ANY || cd.Destination == "" { cd.Destination = utils.ANY if _, ok := rpl.DestinationRates[utils.ANY]; ok { rps = rpl.RateIntervalList(utils.ANY) prefix = utils.ANY destinationId = utils.ANY } } else { for _, p := range utils.SplitPrefix(cd.Destination, MIN_PREFIX_MATCH) { if x, err := cache2go.Get(utils.DESTINATION_PREFIX + p); err == nil { destIds := x.(map[interface{}]struct{}) for idId := range destIds { dId := idId.(string) if _, ok := rpl.DestinationRates[dId]; ok { rps = rpl.RateIntervalList(dId) prefix = p destinationId = dId break } } } if rps != nil { break } } if rps == nil { // fallback on *any destination if _, ok := rpl.DestinationRates[utils.ANY]; ok { rps = rpl.RateIntervalList(utils.ANY) prefix = utils.ANY destinationId = utils.ANY } } } // check if it's the first ri and add a blank one for the initial part not covered if index == 0 && cd.TimeStart.Before(rpa.ActivationTime) { ris = append(ris, &RatingInfo{ MatchedSubject: "", MatchedPrefix: "", MatchedDestId: "", ActivationTime: cd.TimeStart, RateIntervals: nil, FallbackKeys: []string{cd.GetKey(FALLBACK_SUBJECT)}}) } if len(prefix) > 0 { ris = append(ris, &RatingInfo{ MatchedSubject: rp.Id, RatingPlanId: rpl.Id, MatchedPrefix: prefix, MatchedDestId: destinationId, ActivationTime: rpa.ActivationTime, RateIntervals: rps, FallbackKeys: rpa.FallbackKeys}) } else { // add for fallback information if len(rpa.FallbackKeys) > 0 { ris = append(ris, &RatingInfo{ MatchedSubject: "", MatchedPrefix: "", MatchedDestId: "", ActivationTime: rpa.ActivationTime, RateIntervals: nil, FallbackKeys: rpa.FallbackKeys, }) } } } if len(ris) > 0 { cd.addRatingInfos(ris) return } return utils.ErrNotFound }