mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
391 lines
9.2 KiB
Go
391 lines
9.2 KiB
Go
package engine
|
|
|
|
import (
|
|
"errors"
|
|
"log"
|
|
|
|
"github.com/cgrates/cgrates/utils"
|
|
)
|
|
|
|
type TPData struct {
|
|
actions map[string][]*Action
|
|
actionsTimings map[string][]*ActionTiming
|
|
actionsTriggers map[string][]*ActionTrigger
|
|
accountActions map[string]*Account
|
|
dirtyRpAliases []*TenantRatingSubject // used to clean aliases that might have changed
|
|
dirtyAccAliases []*TenantAccount // used to clean aliases that might have changed
|
|
destinations map[string]*Destination
|
|
rpAliases map[string]string
|
|
accAliases map[string]string
|
|
timings map[string]*utils.TPTiming
|
|
rates map[string]*utils.TPRate
|
|
destinationRates map[string]*utils.TPDestinationRate
|
|
ratingPlans map[string]*RatingPlan
|
|
ratingProfiles map[string]*RatingProfile
|
|
sharedGroups map[string]*SharedGroup
|
|
lcrs map[string]*LCR
|
|
derivedChargers map[string]utils.DerivedChargers
|
|
cdrStats map[string]*CdrStats
|
|
}
|
|
|
|
func NewTPData() *TPData {
|
|
tp := &TPData{}
|
|
tp.actions = make(map[string][]*Action)
|
|
tp.actionsTimings = make(map[string][]*ActionTiming)
|
|
tp.actionsTriggers = make(map[string][]*ActionTrigger)
|
|
tp.rates = make(map[string]*utils.TPRate)
|
|
tp.destinations = make(map[string]*Destination)
|
|
tp.destinationRates = make(map[string]*utils.TPDestinationRate)
|
|
tp.timings = make(map[string]*utils.TPTiming)
|
|
tp.ratingPlans = make(map[string]*RatingPlan)
|
|
tp.ratingProfiles = make(map[string]*RatingProfile)
|
|
tp.sharedGroups = make(map[string]*SharedGroup)
|
|
tp.lcrs = make(map[string]*LCR)
|
|
tp.rpAliases = make(map[string]string)
|
|
tp.accAliases = make(map[string]string)
|
|
tp.timings = make(map[string]*utils.TPTiming)
|
|
tp.accountActions = make(map[string]*Account)
|
|
tp.destinations = make(map[string]*Destination)
|
|
tp.cdrStats = make(map[string]*CdrStats)
|
|
tp.derivedChargers = make(map[string]utils.DerivedChargers)
|
|
return tp
|
|
}
|
|
|
|
func (tp *TPData) LoadDestinations(tpDests []*TpDestination) error {
|
|
for _, tpDest := range tpDests {
|
|
var dest *Destination
|
|
var found bool
|
|
if dest, found = tp.destinations[tpDest.Tag]; !found {
|
|
dest = &Destination{Id: tpDest.Tag}
|
|
tp.destinations[tpDest.Tag] = dest
|
|
}
|
|
dest.AddPrefix(tpDest.Prefix)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (tp *TPData) IsValid() bool {
|
|
valid := true
|
|
for rplTag, rpl := range tp.ratingPlans {
|
|
if !rpl.isContinous() {
|
|
log.Printf("The rating plan %s is not covering all weekdays", rplTag)
|
|
valid = false
|
|
}
|
|
if !rpl.areRatesSane() {
|
|
log.Printf("The rating plan %s contains invalid rate groups", rplTag)
|
|
valid = false
|
|
}
|
|
if !rpl.areTimingsSane() {
|
|
log.Printf("The rating plan %s contains invalid timings", rplTag)
|
|
valid = false
|
|
}
|
|
}
|
|
return valid
|
|
}
|
|
|
|
func (tp *TPData) WriteToDatabase(dataStorage RatingStorage, accountingStorage AccountingStorage, flush, verbose bool) (err error) {
|
|
if dataStorage == nil {
|
|
return errors.New("No database connection!")
|
|
}
|
|
if flush {
|
|
dataStorage.Flush("")
|
|
}
|
|
if verbose {
|
|
log.Print("Destinations:")
|
|
}
|
|
for _, d := range tp.destinations {
|
|
err = dataStorage.SetDestination(d)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if verbose {
|
|
log.Print("\t", d.Id, " : ", d.Prefixes)
|
|
}
|
|
}
|
|
if verbose {
|
|
log.Print("Rating Plans:")
|
|
}
|
|
for _, rp := range tp.ratingPlans {
|
|
err = dataStorage.SetRatingPlan(rp)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if verbose {
|
|
log.Print("\t", rp.Id)
|
|
}
|
|
}
|
|
if verbose {
|
|
log.Print("Rating Profiles:")
|
|
}
|
|
for _, rp := range tp.ratingProfiles {
|
|
err = dataStorage.SetRatingProfile(rp)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if verbose {
|
|
log.Print("\t", rp.Id)
|
|
}
|
|
}
|
|
if verbose {
|
|
log.Print("Action Plans:")
|
|
}
|
|
for k, ats := range tp.actionsTimings {
|
|
err = accountingStorage.SetActionTimings(k, ats)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if verbose {
|
|
log.Println("\t", k)
|
|
}
|
|
}
|
|
if verbose {
|
|
log.Print("Shared Groups:")
|
|
}
|
|
for k, sg := range tp.sharedGroups {
|
|
err = accountingStorage.SetSharedGroup(sg)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if verbose {
|
|
log.Println("\t", k)
|
|
}
|
|
}
|
|
if verbose {
|
|
log.Print("LCR Rules:")
|
|
}
|
|
for k, lcr := range tp.lcrs {
|
|
err = dataStorage.SetLCR(lcr)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if verbose {
|
|
log.Println("\t", k)
|
|
}
|
|
}
|
|
if verbose {
|
|
log.Print("Actions:")
|
|
}
|
|
for k, as := range tp.actions {
|
|
err = accountingStorage.SetActions(k, as)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if verbose {
|
|
log.Println("\t", k)
|
|
}
|
|
}
|
|
if verbose {
|
|
log.Print("Account Actions:")
|
|
}
|
|
for _, ub := range tp.accountActions {
|
|
err = accountingStorage.SetAccount(ub)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if verbose {
|
|
log.Println("\t", ub.Id)
|
|
}
|
|
}
|
|
if verbose {
|
|
log.Print("Rating Profile Aliases:")
|
|
}
|
|
if err := dataStorage.RemoveRpAliases(tp.dirtyRpAliases); err != nil {
|
|
return err
|
|
}
|
|
for key, alias := range tp.rpAliases {
|
|
err = dataStorage.SetRpAlias(key, alias)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if verbose {
|
|
log.Print("\t", key)
|
|
}
|
|
}
|
|
if verbose {
|
|
log.Print("Account Aliases:")
|
|
}
|
|
if err := accountingStorage.RemoveAccAliases(tp.dirtyAccAliases); err != nil {
|
|
return err
|
|
}
|
|
for key, alias := range tp.accAliases {
|
|
err = accountingStorage.SetAccAlias(key, alias)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if verbose {
|
|
log.Print("\t", key)
|
|
}
|
|
}
|
|
if verbose {
|
|
log.Print("Derived Chargers:")
|
|
}
|
|
for key, dcs := range tp.derivedChargers {
|
|
err = accountingStorage.SetDerivedChargers(key, dcs)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if verbose {
|
|
log.Print("\t", key)
|
|
}
|
|
}
|
|
if verbose {
|
|
log.Print("CDR Stats Queues:")
|
|
}
|
|
for _, sq := range tp.cdrStats {
|
|
err = dataStorage.SetCdrStats(sq)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if verbose {
|
|
log.Print("\t", sq.Id)
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func (tp *TPData) ShowStatistics() {
|
|
// destinations
|
|
destCount := len(tp.destinations)
|
|
log.Print("Destinations: ", destCount)
|
|
prefixDist := make(map[int]int, 50)
|
|
prefixCount := 0
|
|
for _, d := range tp.destinations {
|
|
prefixDist[len(d.Prefixes)] += 1
|
|
prefixCount += len(d.Prefixes)
|
|
}
|
|
log.Print("Avg Prefixes: ", prefixCount/destCount)
|
|
log.Print("Prefixes distribution:")
|
|
for k, v := range prefixDist {
|
|
log.Printf("%d: %d", k, v)
|
|
}
|
|
// rating plans
|
|
rplCount := len(tp.ratingPlans)
|
|
log.Print("Rating plans: ", rplCount)
|
|
destRatesDist := make(map[int]int, 50)
|
|
destRatesCount := 0
|
|
for _, rpl := range tp.ratingPlans {
|
|
destRatesDist[len(rpl.DestinationRates)] += 1
|
|
destRatesCount += len(rpl.DestinationRates)
|
|
}
|
|
log.Print("Avg Destination Rates: ", destRatesCount/rplCount)
|
|
log.Print("Destination Rates distribution:")
|
|
for k, v := range destRatesDist {
|
|
log.Printf("%d: %d", k, v)
|
|
}
|
|
// rating profiles
|
|
rpfCount := len(tp.ratingProfiles)
|
|
log.Print("Rating profiles: ", rpfCount)
|
|
activDist := make(map[int]int, 50)
|
|
activCount := 0
|
|
for _, rpf := range tp.ratingProfiles {
|
|
activDist[len(rpf.RatingPlanActivations)] += 1
|
|
activCount += len(rpf.RatingPlanActivations)
|
|
}
|
|
log.Print("Avg Activations: ", activCount/rpfCount)
|
|
log.Print("Activation distribution:")
|
|
for k, v := range activDist {
|
|
log.Printf("%d: %d", k, v)
|
|
}
|
|
// actions
|
|
log.Print("Actions: ", len(tp.actions))
|
|
// action plans
|
|
log.Print("Action plans: ", len(tp.actionsTimings))
|
|
// action trigers
|
|
log.Print("Action trigers: ", len(tp.actionsTriggers))
|
|
// account actions
|
|
log.Print("Account actions: ", len(tp.accountActions))
|
|
// derivedChargers
|
|
log.Print("Derived Chargers: ", len(tp.derivedChargers))
|
|
// lcr rules
|
|
log.Print("LCR rules: ", len(tp.lcrs))
|
|
// cdr stats
|
|
log.Print("CDR stats: ", len(tp.cdrStats))
|
|
}
|
|
|
|
// Returns the identities loaded for a specific category, useful for cache reloads
|
|
func (tp *TPData) GetLoadedIds(categ string) ([]string, error) {
|
|
switch categ {
|
|
case DESTINATION_PREFIX:
|
|
keys := make([]string, len(tp.destinations))
|
|
i := 0
|
|
for k := range tp.destinations {
|
|
keys[i] = k
|
|
i++
|
|
}
|
|
return keys, nil
|
|
case RATING_PLAN_PREFIX:
|
|
keys := make([]string, len(tp.ratingPlans))
|
|
i := 0
|
|
for k := range tp.ratingPlans {
|
|
keys[i] = k
|
|
i++
|
|
}
|
|
return keys, nil
|
|
case RATING_PROFILE_PREFIX:
|
|
keys := make([]string, len(tp.ratingProfiles))
|
|
i := 0
|
|
for k := range tp.ratingProfiles {
|
|
keys[i] = k
|
|
i++
|
|
}
|
|
return keys, nil
|
|
case ACTION_PREFIX: // actionsTimings
|
|
keys := make([]string, len(tp.actions))
|
|
i := 0
|
|
for k := range tp.actions {
|
|
keys[i] = k
|
|
i++
|
|
}
|
|
return keys, nil
|
|
case ACTION_TIMING_PREFIX: // actionsTimings
|
|
keys := make([]string, len(tp.actionsTimings))
|
|
i := 0
|
|
for k := range tp.actionsTimings {
|
|
keys[i] = k
|
|
i++
|
|
}
|
|
return keys, nil
|
|
case RP_ALIAS_PREFIX: // aliases
|
|
keys := make([]string, len(tp.rpAliases))
|
|
i := 0
|
|
for k := range tp.rpAliases {
|
|
keys[i] = k
|
|
i++
|
|
}
|
|
return keys, nil
|
|
case ACC_ALIAS_PREFIX: // aliases
|
|
keys := make([]string, len(tp.accAliases))
|
|
i := 0
|
|
for k := range tp.accAliases {
|
|
keys[i] = k
|
|
i++
|
|
}
|
|
return keys, nil
|
|
case DERIVEDCHARGERS_PREFIX: // derived chargers
|
|
keys := make([]string, len(tp.derivedChargers))
|
|
i := 0
|
|
for k := range tp.derivedChargers {
|
|
keys[i] = k
|
|
i++
|
|
}
|
|
return keys, nil
|
|
case CDR_STATS_PREFIX: // cdr stats
|
|
keys := make([]string, len(tp.cdrStats))
|
|
i := 0
|
|
for k := range tp.cdrStats {
|
|
keys[i] = k
|
|
i++
|
|
}
|
|
return keys, nil
|
|
case SHARED_GROUP_PREFIX:
|
|
keys := make([]string, len(tp.sharedGroups))
|
|
i := 0
|
|
for k := range tp.sharedGroups {
|
|
keys[i] = k
|
|
i++
|
|
}
|
|
return keys, nil
|
|
}
|
|
return nil, errors.New("Unsupported category")
|
|
}
|