diff --git a/config/cdrstatsconfig.go b/config/cdrstatsconfig.go index e8594a633..78aa75fcf 100644 --- a/config/cdrstatsconfig.go +++ b/config/cdrstatsconfig.go @@ -23,27 +23,27 @@ import ( ) type CdrStatsConfig struct { - Id string // Config id, unique per config instance - QueueLength int // Number of items in the stats buffer - TimeWindow time.Duration // Will only keep the CDRs who's call setup time is not older than time.Now()-TimeWindow - SaveInterval time.Duration - Metrics []string // ASR, ACD, ACC - SetupInterval []time.Time // 2 or less items (>= start interval,< stop_interval) - TORs []string - CdrHosts []string - CdrSources []string - ReqTypes []string - Directions []string - Tenants []string - Categories []string - Accounts []string - Subjects []string - DestinationPrefixes []string - UsageInterval []time.Duration // 2 or less items (>= Usage, =Cost, = start interval,< stop_interval) + TORs []string + CdrHosts []string + CdrSources []string + ReqTypes []string + Directions []string + Tenants []string + Categories []string + Accounts []string + Subjects []string + DestinationIds []string + UsageInterval []time.Duration // 2 or less items (>= Usage, =Cost, = start interval,< stop_interval) - TOR []string // CDRFieldFilter on TORs - CdrHost []string // CDRFieldFilter on CdrHosts - CdrSource []string // CDRFieldFilter on CdrSources - ReqType []string // CDRFieldFilter on ReqTypes - Direction []string // CDRFieldFilter on Directions - Tenant []string // CDRFieldFilter on Tenants - Category []string // CDRFieldFilter on Categories - Account []string // CDRFieldFilter on Accounts - Subject []string // CDRFieldFilter on Subjects - DestinationPrefix []string // CDRFieldFilter on DestinationPrefixes - UsageInterval []time.Duration // CDRFieldFilter on UsageInterval, 2 or less items (>= Usage, = Pdd, =Cost, = start interval,< stop_interval) + TOR []string // CDRFieldFilter on TORs + CdrHost []string // CDRFieldFilter on CdrHosts + CdrSource []string // CDRFieldFilter on CdrSources + ReqType []string // CDRFieldFilter on ReqTypes + Direction []string // CDRFieldFilter on Directions + Tenant []string // CDRFieldFilter on Tenants + Category []string // CDRFieldFilter on Categories + Account []string // CDRFieldFilter on Accounts + Subject []string // CDRFieldFilter on Subjects + DestinationIds []string // CDRFieldFilter on DestinationPrefixes + UsageInterval []time.Duration // CDRFieldFilter on UsageInterval, 2 or less items (>= Usage, = Pdd, =Cost, 0 && !utils.IsSliceMember(cs.Subject, cdr.Subject) { return false } - if len(cs.DestinationPrefix) > 0 { + if len(cs.DestinationIds) > 0 { found := false - for _, prefix := range cs.DestinationPrefix { - if strings.HasPrefix(cdr.Destination, prefix) { - found = true + 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 } } @@ -197,7 +208,7 @@ func (cs *CdrStats) equalExceptTriggers(other *CdrStats) bool { reflect.DeepEqual(cs.Category, other.Category) && reflect.DeepEqual(cs.Account, other.Account) && reflect.DeepEqual(cs.Subject, other.Subject) && - reflect.DeepEqual(cs.DestinationPrefix, other.DestinationPrefix) && + reflect.DeepEqual(cs.DestinationIds, other.DestinationIds) && reflect.DeepEqual(cs.UsageInterval, other.UsageInterval) && reflect.DeepEqual(cs.PddInterval, other.PddInterval) && reflect.DeepEqual(cs.Supplier, other.Supplier) && diff --git a/engine/loader_csv_test.go b/engine/loader_csv_test.go index 9624e54f3..f78b147fc 100644 --- a/engine/loader_csv_test.go +++ b/engine/loader_csv_test.go @@ -1077,24 +1077,24 @@ func TestLoadCdrStats(t *testing.T) { time.Date(2014, 7, 29, 15, 0, 0, 0, time.UTC), time.Date(2014, 7, 29, 16, 0, 0, 0, time.UTC), }, - TOR: []string{utils.VOICE}, - CdrHost: []string{"87.139.12.167"}, - CdrSource: []string{"FS_JSON"}, - ReqType: []string{utils.META_RATED}, - Direction: []string{utils.OUT}, - Tenant: []string{"cgrates.org"}, - Category: []string{"call"}, - Account: []string{"dan"}, - Subject: []string{"dan"}, - DestinationPrefix: []string{"49"}, - PddInterval: []time.Duration{3 * time.Minute, 7 * time.Minute}, - UsageInterval: []time.Duration{5 * time.Minute, 10 * time.Minute}, - Supplier: []string{"suppl1"}, - DisconnectCause: []string{"NORMAL_CLEARING"}, - MediationRunIds: []string{"default"}, - RatedAccount: []string{"rif"}, - RatedSubject: []string{"rif"}, - CostInterval: []float64{0, 2}, + TOR: []string{utils.VOICE}, + CdrHost: []string{"87.139.12.167"}, + CdrSource: []string{"FS_JSON"}, + ReqType: []string{utils.META_RATED}, + Direction: []string{utils.OUT}, + Tenant: []string{"cgrates.org"}, + Category: []string{"call"}, + Account: []string{"dan"}, + Subject: []string{"dan"}, + DestinationIds: []string{"49"}, + PddInterval: []time.Duration{3 * time.Minute, 7 * time.Minute}, + UsageInterval: []time.Duration{5 * time.Minute, 10 * time.Minute}, + Supplier: []string{"suppl1"}, + DisconnectCause: []string{"NORMAL_CLEARING"}, + MediationRunIds: []string{"default"}, + RatedAccount: []string{"rif"}, + RatedSubject: []string{"rif"}, + CostInterval: []float64{0, 2}, } for _, triggerKey := range []string{"STANDARD_TRIGGER", "STANDARD_TRIGGERS"} { cdrStats1.Triggers = append(cdrStats1.Triggers, csvr.actionsTriggers[triggerKey]...) diff --git a/engine/model_converters.go b/engine/model_converters.go index c1f0a0f5e..0dac85177 100644 --- a/engine/model_converters.go +++ b/engine/model_converters.go @@ -321,32 +321,32 @@ func APItoModelCdrStat(stats *utils.TPCdrStats) (result []TpCdrstat) { for _, st := range stats.CdrStats { ql, _ := strconv.Atoi(st.QueueLength) result = append(result, TpCdrstat{ - Tpid: stats.TPid, - Tag: stats.CdrStatsId, - QueueLength: ql, - TimeWindow: st.TimeWindow, - SaveInterval: st.SaveInterval, - Metrics: st.Metrics, - SetupInterval: st.SetupInterval, - Tors: st.TORs, - CdrHosts: st.CdrHosts, - CdrSources: st.CdrSources, - ReqTypes: st.ReqTypes, - Directions: st.Directions, - Tenants: st.Tenants, - Categories: st.Categories, - Accounts: st.Accounts, - Subjects: st.Subjects, - DestinationPrefixes: st.DestinationPrefixes, - PddInterval: st.PddInterval, - UsageInterval: st.UsageInterval, - Suppliers: st.Suppliers, - DisconnectCauses: st.DisconnectCauses, - MediationRunids: st.MediationRunIds, - RatedAccounts: st.RatedAccounts, - RatedSubjects: st.RatedSubjects, - CostInterval: st.CostInterval, - ActionTriggers: st.ActionTriggers, + Tpid: stats.TPid, + Tag: stats.CdrStatsId, + QueueLength: ql, + TimeWindow: st.TimeWindow, + SaveInterval: st.SaveInterval, + Metrics: st.Metrics, + SetupInterval: st.SetupInterval, + Tors: st.TORs, + CdrHosts: st.CdrHosts, + CdrSources: st.CdrSources, + ReqTypes: st.ReqTypes, + Directions: st.Directions, + Tenants: st.Tenants, + Categories: st.Categories, + Accounts: st.Accounts, + Subjects: st.Subjects, + DestinationIds: st.DestinationIds, + PddInterval: st.PddInterval, + UsageInterval: st.UsageInterval, + Suppliers: st.Suppliers, + DisconnectCauses: st.DisconnectCauses, + MediationRunids: st.MediationRunIds, + RatedAccounts: st.RatedAccounts, + RatedSubjects: st.RatedSubjects, + CostInterval: st.CostInterval, + ActionTriggers: st.ActionTriggers, }) } if len(stats.CdrStats) == 0 { diff --git a/engine/model_helpers.go b/engine/model_helpers.go index 87d44a0ee..d59c4e8f2 100644 --- a/engine/model_helpers.go +++ b/engine/model_helpers.go @@ -503,30 +503,30 @@ func (tps TpCdrStats) GetCdrStats() (map[string][]*utils.TPCdrStat, error) { css := make(map[string][]*utils.TPCdrStat) for _, tpCs := range tps { css[tpCs.Tag] = append(css[tpCs.Tag], &utils.TPCdrStat{ - QueueLength: strconv.Itoa(tpCs.QueueLength), - TimeWindow: tpCs.TimeWindow, - Metrics: tpCs.Metrics, - SaveInterval: tpCs.SaveInterval, - SetupInterval: tpCs.SetupInterval, - TORs: tpCs.Tors, - CdrHosts: tpCs.CdrHosts, - CdrSources: tpCs.CdrSources, - ReqTypes: tpCs.ReqTypes, - Directions: tpCs.Directions, - Tenants: tpCs.Tenants, - Categories: tpCs.Categories, - Accounts: tpCs.Accounts, - Subjects: tpCs.Subjects, - DestinationPrefixes: tpCs.DestinationPrefixes, - PddInterval: tpCs.PddInterval, - UsageInterval: tpCs.UsageInterval, - Suppliers: tpCs.Suppliers, - DisconnectCauses: tpCs.DisconnectCauses, - MediationRunIds: tpCs.MediationRunids, - RatedAccounts: tpCs.RatedAccounts, - RatedSubjects: tpCs.RatedSubjects, - CostInterval: tpCs.CostInterval, - ActionTriggers: tpCs.ActionTriggers, + QueueLength: strconv.Itoa(tpCs.QueueLength), + TimeWindow: tpCs.TimeWindow, + Metrics: tpCs.Metrics, + SaveInterval: tpCs.SaveInterval, + SetupInterval: tpCs.SetupInterval, + TORs: tpCs.Tors, + CdrHosts: tpCs.CdrHosts, + CdrSources: tpCs.CdrSources, + ReqTypes: tpCs.ReqTypes, + Directions: tpCs.Directions, + Tenants: tpCs.Tenants, + Categories: tpCs.Categories, + Accounts: tpCs.Accounts, + Subjects: tpCs.Subjects, + DestinationIds: tpCs.DestinationIds, + PddInterval: tpCs.PddInterval, + UsageInterval: tpCs.UsageInterval, + Suppliers: tpCs.Suppliers, + DisconnectCauses: tpCs.DisconnectCauses, + MediationRunIds: tpCs.MediationRunids, + RatedAccounts: tpCs.RatedAccounts, + RatedSubjects: tpCs.RatedSubjects, + CostInterval: tpCs.CostInterval, + ActionTriggers: tpCs.ActionTriggers, }) } return css, nil @@ -609,8 +609,8 @@ func UpdateCdrStats(cs *CdrStats, triggers ActionTriggerPriotityList, tpCs *util if tpCs.Subjects != "" { cs.Subject = append(cs.Subject, tpCs.Subjects) } - if tpCs.DestinationPrefixes != "" { - cs.DestinationPrefix = append(cs.DestinationPrefix, tpCs.DestinationPrefixes) + if tpCs.DestinationIds != "" { + cs.DestinationIds = append(cs.DestinationIds, tpCs.DestinationIds) } if tpCs.PddInterval != "" { pdds := strings.Split(tpCs.PddInterval, utils.INFIELD_SEP) diff --git a/engine/model_helpers_test.go b/engine/model_helpers_test.go index 3734958a4..61f5f0ae6 100644 --- a/engine/model_helpers_test.go +++ b/engine/model_helpers_test.go @@ -369,55 +369,55 @@ func TestTPCdrStatsAsExportSlice(t *testing.T) { CdrStatsId: "CDRST1", CdrStats: []*utils.TPCdrStat{ &utils.TPCdrStat{ - QueueLength: "5", - TimeWindow: "60m", - SaveInterval: "10s", - Metrics: "ASR;ACD", - SetupInterval: "2014-07-29T15:00:00Z;2014-07-29T16:00:00Z", - TORs: "*voice", - CdrHosts: "87.139.12.167", - CdrSources: "FS_JSON", - ReqTypes: utils.META_RATED, - Directions: "*out", - Tenants: "cgrates.org", - Categories: "call", - Accounts: "dan", - Subjects: "dan", - DestinationPrefixes: "49", - PddInterval: "3m;7m", - UsageInterval: "5m;10m", - Suppliers: "supplier1", - DisconnectCauses: "NORMAL_CLEARNING", - MediationRunIds: "default", - RatedAccounts: "rif", - RatedSubjects: "rif", - CostInterval: "0;2", - ActionTriggers: "STANDARD_TRIGGERS"}, + QueueLength: "5", + TimeWindow: "60m", + SaveInterval: "10s", + Metrics: "ASR;ACD", + SetupInterval: "2014-07-29T15:00:00Z;2014-07-29T16:00:00Z", + TORs: "*voice", + CdrHosts: "87.139.12.167", + CdrSources: "FS_JSON", + ReqTypes: utils.META_RATED, + Directions: "*out", + Tenants: "cgrates.org", + Categories: "call", + Accounts: "dan", + Subjects: "dan", + DestinationIds: "49", + PddInterval: "3m;7m", + UsageInterval: "5m;10m", + Suppliers: "supplier1", + DisconnectCauses: "NORMAL_CLEARNING", + MediationRunIds: "default", + RatedAccounts: "rif", + RatedSubjects: "rif", + CostInterval: "0;2", + ActionTriggers: "STANDARD_TRIGGERS"}, &utils.TPCdrStat{ - QueueLength: "5", - TimeWindow: "60m", - SaveInterval: "9s", - Metrics: "ASR", - SetupInterval: "2014-07-29T15:00:00Z;2014-07-29T16:00:00Z", - TORs: "*voice", - CdrHosts: "87.139.12.167", - CdrSources: "FS_JSON", - ReqTypes: utils.META_RATED, - Directions: "*out", - Tenants: "cgrates.org", - Categories: "call", - Accounts: "dan", - Subjects: "dan", - DestinationPrefixes: "49", - PddInterval: "3m;7m", - UsageInterval: "5m;10m", - Suppliers: "supplier1", - DisconnectCauses: "NORMAL_CLEARNING", - MediationRunIds: "default", - RatedAccounts: "dan", - RatedSubjects: "dan", - CostInterval: "0;2", - ActionTriggers: "STANDARD_TRIGGERS"}, + QueueLength: "5", + TimeWindow: "60m", + SaveInterval: "9s", + Metrics: "ASR", + SetupInterval: "2014-07-29T15:00:00Z;2014-07-29T16:00:00Z", + TORs: "*voice", + CdrHosts: "87.139.12.167", + CdrSources: "FS_JSON", + ReqTypes: utils.META_RATED, + Directions: "*out", + Tenants: "cgrates.org", + Categories: "call", + Accounts: "dan", + Subjects: "dan", + DestinationIds: "49", + PddInterval: "3m;7m", + UsageInterval: "5m;10m", + Suppliers: "supplier1", + DisconnectCauses: "NORMAL_CLEARNING", + MediationRunIds: "default", + RatedAccounts: "dan", + RatedSubjects: "dan", + CostInterval: "0;2", + ActionTriggers: "STANDARD_TRIGGERS"}, }, } expectedSlc := [][]string{ diff --git a/engine/models.go b/engine/models.go index 46b088798..9f2e517b3 100644 --- a/engine/models.go +++ b/engine/models.go @@ -290,34 +290,34 @@ func (tpdc *TpDerivedCharger) GetDerivedChargersId() string { } type TpCdrstat struct { - Id int64 - Tpid string - Tag string `index:"0" re:""` - QueueLength int `index:"1" re:""` - TimeWindow string `index:"2" re:""` - SaveInterval string `index:"3" re:""` - Metrics string `index:"4" re:""` - SetupInterval string `index:"5" re:""` - Tors string `index:"6" re:""` - CdrHosts string `index:"7" re:""` - CdrSources string `index:"8" re:""` - ReqTypes string `index:"9" re:""` - Directions string `index:"10" re:""` - Tenants string `index:"11" re:""` - Categories string `index:"12" re:""` - Accounts string `index:"13" re:""` - Subjects string `index:"14" re:""` - DestinationPrefixes string `index:"15" re:""` - PddInterval string `index:"16" re:""` - UsageInterval string `index:"17" re:""` - Suppliers string `index:"18" re:""` - DisconnectCauses string `index:"19" re:""` - MediationRunids string `index:"20" re:""` - RatedAccounts string `index:"21" re:""` - RatedSubjects string `index:"22" re:""` - CostInterval string `index:"23" re:""` - ActionTriggers string `index:"24" re:""` - CreatedAt time.Time + Id int64 + Tpid string + Tag string `index:"0" re:""` + QueueLength int `index:"1" re:""` + TimeWindow string `index:"2" re:""` + SaveInterval string `index:"3" re:""` + Metrics string `index:"4" re:""` + SetupInterval string `index:"5" re:""` + Tors string `index:"6" re:""` + CdrHosts string `index:"7" re:""` + CdrSources string `index:"8" re:""` + ReqTypes string `index:"9" re:""` + Directions string `index:"10" re:""` + Tenants string `index:"11" re:""` + Categories string `index:"12" re:""` + Accounts string `index:"13" re:""` + Subjects string `index:"14" re:""` + DestinationIds string `index:"15" re:""` + PddInterval string `index:"16" re:""` + UsageInterval string `index:"17" re:""` + Suppliers string `index:"18" re:""` + DisconnectCauses string `index:"19" re:""` + MediationRunids string `index:"20" re:""` + RatedAccounts string `index:"21" re:""` + RatedSubjects string `index:"22" re:""` + CostInterval string `index:"23" re:""` + ActionTriggers string `index:"24" re:""` + CreatedAt time.Time } func (t TpCdrstat) TableName() string { diff --git a/engine/stats_test.go b/engine/stats_test.go index 5b8f705d9..d5f96fb49 100644 --- a/engine/stats_test.go +++ b/engine/stats_test.go @@ -95,7 +95,7 @@ func TestAcceptCdr(t *testing.T) { Category: "category", Account: "account", Subject: "subject", - Destination: "12345678", + Destination: "0723045326", SetupTime: time.Date(2014, 7, 3, 13, 43, 0, 0, time.UTC), Usage: 10 * time.Second, Pdd: 7 * time.Second, @@ -156,11 +156,11 @@ func TestAcceptCdr(t *testing.T) { if sq.conf.AcceptCdr(cdr) == true { t.Errorf("Should have NOT accepted this CDR: %+v", cdr) } - sq.conf = &CdrStats{DestinationPrefix: []string{"test"}} + sq.conf = &CdrStats{DestinationIds: []string{"test"}} if sq.conf.AcceptCdr(cdr) == true { t.Errorf("Should have NOT accepted this CDR: %+v", cdr) } - sq.conf = &CdrStats{DestinationPrefix: []string{"test", "123"}} + sq.conf = &CdrStats{DestinationIds: []string{"NAT", "RET"}} if sq.conf.AcceptCdr(cdr) != true { t.Errorf("Should have accepted this CDR: %+v", cdr) } diff --git a/utils/apitpdata.go b/utils/apitpdata.go index 8351c99fa..b33e9a6e9 100644 --- a/utils/apitpdata.go +++ b/utils/apitpdata.go @@ -356,30 +356,30 @@ type TPCdrStats struct { } type TPCdrStat struct { - QueueLength string - TimeWindow string - SaveInterval string - Metrics string - SetupInterval string - TORs string - CdrHosts string - CdrSources string - ReqTypes string - Directions string - Tenants string - Categories string - Accounts string - Subjects string - DestinationPrefixes string - PddInterval string - UsageInterval string - Suppliers string - DisconnectCauses string - MediationRunIds string - RatedAccounts string - RatedSubjects string - CostInterval string - ActionTriggers string + QueueLength string + TimeWindow string + SaveInterval string + Metrics string + SetupInterval string + TORs string + CdrHosts string + CdrSources string + ReqTypes string + Directions string + Tenants string + Categories string + Accounts string + Subjects string + DestinationIds string + PddInterval string + UsageInterval string + Suppliers string + DisconnectCauses string + MediationRunIds string + RatedAccounts string + RatedSubjects string + CostInterval string + ActionTriggers string } type TPDerivedChargers struct {