Пример #1
0
// 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)
	}
}
Пример #2
0
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
}
Пример #3
0
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
}
Пример #4
0
// 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
	}
}
Пример #5
0
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
}
Пример #6
0
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
}
Пример #7
0
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
}
Пример #8
0
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
}
Пример #9
0
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
}
Пример #10
0
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
}
Пример #11
0
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
}
Пример #12
0
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
}
Пример #13
0
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
}
Пример #14
0
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
}
Пример #15
0
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
}
Пример #16
0
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
}
Пример #17
0
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
}
Пример #19
0
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
}
Пример #20
0
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
}
Пример #21
0
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
}
Пример #22
0
/*
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
}
Пример #23
0
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
}
Пример #24
0
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
}
Пример #25
0
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
}
Пример #26
0
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
}
Пример #27
0
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)
}
Пример #28
0
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
}