diff --git a/config/cdrstatsconfig.go b/config/cdrstatsconfig.go index 9beaa83ae..ab859e0db 100644 --- a/config/cdrstatsconfig.go +++ b/config/cdrstatsconfig.go @@ -41,6 +41,7 @@ type CdrStatsConfig struct { DestinationPrefixes []string UsageInterval []time.Duration // 2 or less items (>= Usage, = Usage, 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.MediationRunId) { return false } diff --git a/engine/loader_csv.go b/engine/loader_csv.go index ef8dc60ea..8dded3e10 100644 --- a/engine/loader_csv.go +++ b/engine/loader_csv.go @@ -988,27 +988,28 @@ func (csvr *CSVReader) LoadCdrStats() (err error) { return fmt.Errorf("Could not get action triggers for cdr stats id %s: %s", cs.Id, triggerTag) } tpCs := &utils.TPCdrStat{ - QueueLength: record[CDRSTATIDX_QLENGHT], - TimeWindow: record[CDRSTATIDX_TIMEWINDOW], - Metrics: record[CDRSTATIDX_METRICS], - SetupInterval: record[CDRSTATIDX_SETUPTIME], - TOR: record[CDRSTATIDX_TOR], - CdrHost: record[CDRSTATIDX_CDRHOST], - CdrSource: record[CDRSTATIDX_CDRSRC], - ReqType: record[CDRSTATIDX_REQTYPE], - Direction: record[CDRSTATIDX_DIRECTION], - Tenant: record[CDRSTATIDX_TENANT], - Category: record[CDRSTATIDX_CATEGORY], - Account: record[CDRSTATIDX_ACCOUNT], - Subject: record[CDRSTATIDX_SUBJECT], - DestinationPrefix: record[CDRSTATIDX_DSTPREFIX], - UsageInterval: record[CDRSTATIDX_USAGE], - Supplier: record[CDRSTATIDX_SUPPLIER], - MediationRunIds: record[CDRSTATIDX_MEDRUN], - RatedAccount: record[CDRSTATIDX_RTACCOUNT], - RatedSubject: record[CDRSTATIDX_RTSUBJECT], - CostInterval: record[CDRSTATIDX_COST], - ActionTriggers: record[CDRSTATIDX_ATRIGGER], + QueueLength: record[CDRSTATIDX_QLENGHT], + TimeWindow: record[CDRSTATIDX_TIMEWINDOW], + Metrics: record[CDRSTATIDX_METRICS], + SetupInterval: record[CDRSTATIDX_SETUPTIME], + TORs: record[CDRSTATIDX_TOR], + CdrHosts: record[CDRSTATIDX_CDRHOST], + CdrSources: record[CDRSTATIDX_CDRSRC], + ReqTypes: record[CDRSTATIDX_REQTYPE], + Directions: record[CDRSTATIDX_DIRECTION], + Tenants: record[CDRSTATIDX_TENANT], + Categories: record[CDRSTATIDX_CATEGORY], + Accounts: record[CDRSTATIDX_ACCOUNT], + Subjects: record[CDRSTATIDX_SUBJECT], + DestinationPrefixes: record[CDRSTATIDX_DSTPREFIX], + UsageInterval: record[CDRSTATIDX_USAGE], + Suppliers: record[CDRSTATIDX_SUPPLIER], + DisconnectCauses: record[CDRSTATIDX_DISCONNECT_CAUSE], + MediationRunIds: record[CDRSTATIDX_MEDRUN], + RatedAccounts: record[CDRSTATIDX_RTACCOUNT], + RatedSubjects: record[CDRSTATIDX_RTSUBJECT], + CostInterval: record[CDRSTATIDX_COST], + ActionTriggers: record[CDRSTATIDX_ATRIGGER], } UpdateCdrStats(cs, triggers, tpCs) csvr.cdrStats[tag] = cs diff --git a/engine/loader_csv_test.go b/engine/loader_csv_test.go index 62312c860..8f1a07798 100644 --- a/engine/loader_csv_test.go +++ b/engine/loader_csv_test.go @@ -195,12 +195,12 @@ vdf,emptyY,*out,TOPUP_EMPTY_AT, *out,cgrates.org,call,dan,*any,extra1,,,,,,rif2,rif2,,,,,, ` cdrStats = ` -#Id,QueueLength,TimeWindow,Metrics,SetupInterval,TOR,CdrHost,CdrSource,ReqType,Direction,Tenant,Category,Account,Subject,DestinationPrefix,UsageInterval,Supplier,MediationRunIds,RatedAccount,RatedSubject,CostInterval,Triggers -CDRST1,5,60m,ASR,2014-07-29T15:00:00Z;2014-07-29T16:00:00Z,*voice,87.139.12.167,FS_JSON,*rated,*out,cgrates.org,call,dan,dan,49,5m;10m,suppl1,default,rif,rif,0;2,STANDARD_TRIGGERS -CDRST1,,,ACD,,,,,,,,,,,,,,,,,,STANDARD_TRIGGER -CDRST1,,,ACC,,,,,,,,,,,,,,,,,, -CDRST2,10,10m,ASR,,,,,,,cgrates.org,call,,,,,,,,,, -CDRST2,,,ACD,,,,,,,,,,,,,,,,,, +#Id[0],QueueLength[1],TimeWindow[2],Metric[3],SetupInterval[4],TOR[5],CdrHost[6],CdrSource[7],ReqType[8],Direction[9],Tenant[10],Category[11],Account[12],Subject[13],DestinationPrefix[14],UsageInterval[15],Supplier[16],DisconnectCause[17],MediationRunIds[18],RatedAccount[19],RatedSubject[20],CostInterval[21],Triggers[22] +CDRST1,5,60m,ASR,2014-07-29T15:00:00Z;2014-07-29T16:00:00Z,*voice,87.139.12.167,FS_JSON,*rated,*out,cgrates.org,call,dan,dan,49,5m;10m,suppl1,NORMAL_CLEARING,default,rif,rif,0;2,STANDARD_TRIGGERS +CDRST1,,,ACD,,,,,,,,,,,,,,,,,,,STANDARD_TRIGGER +CDRST1,,,ACC,,,,,,,,,,,,,,,,,,, +CDRST2,10,10m,ASR,,,,,,,cgrates.org,call,,,,,,,,,,, +CDRST2,,,ACD,,,,,,,,,,,,,,,,,,, ` ) @@ -1009,6 +1009,8 @@ func TestLoadCdrStats(t *testing.T) { Subject: []string{"dan"}, DestinationPrefix: []string{"49"}, 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"}, diff --git a/engine/loader_helpers.go b/engine/loader_helpers.go index d39eaf960..2038cbe9a 100644 --- a/engine/loader_helpers.go +++ b/engine/loader_helpers.go @@ -95,6 +95,7 @@ const ( CDRSTATIDX_DSTPREFIX CDRSTATIDX_USAGE CDRSTATIDX_SUPPLIER + CDRSTATIDX_DISCONNECT_CAUSE CDRSTATIDX_MEDRUN CDRSTATIDX_RTACCOUNT CDRSTATIDX_RTSUBJECT @@ -212,35 +213,35 @@ func UpdateCdrStats(cs *CdrStats, triggers ActionTriggerPriotityList, tpCs *util } } } - if tpCs.TOR != "" { - cs.TOR = append(cs.TOR, tpCs.TOR) + if tpCs.TORs != "" { + cs.TOR = append(cs.TOR, tpCs.TORs) } - if tpCs.CdrHost != "" { - cs.CdrHost = append(cs.CdrHost, tpCs.CdrHost) + if tpCs.CdrHosts != "" { + cs.CdrHost = append(cs.CdrHost, tpCs.CdrHosts) } - if tpCs.CdrSource != "" { - cs.CdrSource = append(cs.CdrSource, tpCs.CdrSource) + if tpCs.CdrSources != "" { + cs.CdrSource = append(cs.CdrSource, tpCs.CdrSources) } - if tpCs.ReqType != "" { - cs.ReqType = append(cs.ReqType, tpCs.ReqType) + if tpCs.ReqTypes != "" { + cs.ReqType = append(cs.ReqType, tpCs.ReqTypes) } - if tpCs.Direction != "" { - cs.Direction = append(cs.Direction, tpCs.Direction) + if tpCs.Directions != "" { + cs.Direction = append(cs.Direction, tpCs.Directions) } - if tpCs.Tenant != "" { - cs.Tenant = append(cs.Tenant, tpCs.Tenant) + if tpCs.Tenants != "" { + cs.Tenant = append(cs.Tenant, tpCs.Tenants) } - if tpCs.Category != "" { - cs.Category = append(cs.Category, tpCs.Category) + if tpCs.Categories != "" { + cs.Category = append(cs.Category, tpCs.Categories) } - if tpCs.Account != "" { - cs.Account = append(cs.Account, tpCs.Account) + if tpCs.Accounts != "" { + cs.Account = append(cs.Account, tpCs.Accounts) } - if tpCs.Subject != "" { - cs.Subject = append(cs.Subject, tpCs.Subject) + if tpCs.Subjects != "" { + cs.Subject = append(cs.Subject, tpCs.Subjects) } - if tpCs.DestinationPrefix != "" { - cs.DestinationPrefix = append(cs.DestinationPrefix, tpCs.DestinationPrefix) + if tpCs.DestinationPrefixes != "" { + cs.DestinationPrefix = append(cs.DestinationPrefix, tpCs.DestinationPrefixes) } if tpCs.UsageInterval != "" { durations := strings.Split(tpCs.UsageInterval, utils.INFIELD_SEP) @@ -267,14 +268,20 @@ func UpdateCdrStats(cs *CdrStats, triggers ActionTriggerPriotityList, tpCs *util } } } + if tpCs.Suppliers != "" { + cs.Supplier = append(cs.Supplier, tpCs.Suppliers) + } + if tpCs.DisconnectCauses != "" { + cs.DisconnectCause = append(cs.DisconnectCause, tpCs.DisconnectCauses) + } if tpCs.MediationRunIds != "" { cs.MediationRunIds = append(cs.MediationRunIds, tpCs.MediationRunIds) } - if tpCs.RatedAccount != "" { - cs.RatedAccount = append(cs.RatedAccount, tpCs.RatedAccount) + if tpCs.RatedAccounts != "" { + cs.RatedAccount = append(cs.RatedAccount, tpCs.RatedAccounts) } - if tpCs.RatedSubject != "" { - cs.RatedSubject = append(cs.RatedSubject, tpCs.RatedSubject) + if tpCs.RatedSubjects != "" { + cs.RatedSubject = append(cs.RatedSubject, tpCs.RatedSubjects) } if tpCs.CostInterval != "" { costs := strings.Split(tpCs.CostInterval, utils.INFIELD_SEP) @@ -424,7 +431,7 @@ var FileValidators = map[string]*FileLineRegexValidator{ "Direction(*out),Tenant[0-9A-Za-z_],Category([0-9A-Za-z_]),Account[0-9A-Za-z_],Subject([0-9A-Za-z_]|*any),RunId([0-9A-Za-z_]),RunFilter([^~]*[0-9A-Za-z_/]),ReqTypeField([^~]*[0-9A-Za-z_/]|*default),DirectionField([^~]*[0-9A-Za-z_/]|*default),TenantField([^~]*[0-9A-Za-z_/]|*default),TorField([^~]*[0-9A-Za-z_/]|*default),AccountField([^~]*[0-9A-Za-z_/]|*default),SubjectField([^~]*[0-9A-Za-z_/]|*default),DestinationField([^~]*[0-9A-Za-z_/]|*default),SetupTimeField([^~]*[0-9A-Za-z_/]|*default),AnswerTimeField([^~]*[0-9A-Za-z_/]|*default),UsageField([^~]*[0-9A-Za-z_/]|*default),SupplierField([^~]*[0-9A-Za-z_/]|*default),DisconnectCauseField([^~]*[0-9A-Za-z_/]|*default)"}, utils.CDR_STATS_CSV: &FileLineRegexValidator{utils.CDR_STATS_NRCOLS, regexp.MustCompile(`.+`), //ToDo: Fix me with proper rules - "Id,QueueLength,TimeWindow,Metric,SetupInterval,TOR,CdrHost,CdrSource,ReqType,Direction,Tenant,Category,Account,Subject,DestinationPrefix,UsageInterval,Supplier,MediationRunIds,RatedAccount,RatedSubject,CostInterval,Triggers(*?[0-9A-Za-z_]),Strategy(*[0-9A-Za-z_]),RatingSubject(*?[0-9A-Za-z_])"}, + "Id,QueueLength,TimeWindow,Metric,SetupInterval,TOR,CdrHost,CdrSource,ReqType,Direction,Tenant,Category,Account,Subject,DestinationPrefix,UsageInterval,Supplier,DisconnectCause,MediationRunIds,RatedAccount,RatedSubject,CostInterval,Triggers(*?[0-9A-Za-z_]),Strategy(*[0-9A-Za-z_]),RatingSubject(*?[0-9A-Za-z_])"}, } func NewTPCSVFileParser(dirPath, fileName string) (*TPCSVFileParser, error) { diff --git a/engine/models.go b/engine/models.go index 74becf2f5..20a01902d 100644 --- a/engine/models.go +++ b/engine/models.go @@ -258,31 +258,32 @@ func (tpdc *TpDerivedCharger) SetDerivedChargersId(id string) error { } type TpCdrStat struct { - Id int64 - Tpid string - Tag string - QueueLength int - TimeWindow string - Metrics string - SetupInterval string - Tor string - CdrHost string - CdrSource string - ReqType string - Direction string - Tenant string - Category string - Account string - Subject string - DestinationPrefix string - UsageInterval string - Supplier string - MediationRunids string - RatedAccount string - RatedSubject string - CostInterval string - ActionTriggers string - CreatedAt time.Time + Id int64 + Tpid string + Tag string + QueueLength int + TimeWindow 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 + UsageInterval string + Suppliers string + DisconnectCauses string + MediationRunids string + RatedAccounts string + RatedSubjects string + CostInterval string + ActionTriggers string + CreatedAt time.Time } type TblCdrsPrimary struct { diff --git a/engine/stats_test.go b/engine/stats_test.go index 198e1200f..a1364d1ba 100644 --- a/engine/stats_test.go +++ b/engine/stats_test.go @@ -199,12 +199,14 @@ func TestStatsQueueIds(t *testing.T) { func TestStatsAppendCdr(t *testing.T) { cdrStats := NewStats(dataStorage) cdr := &StoredCdr{ - Tenant: "cgrates.org", - Category: "call", - AnswerTime: time.Now(), - SetupTime: time.Now(), - Usage: 10 * time.Second, - Cost: 10, + Tenant: "cgrates.org", + Category: "call", + AnswerTime: time.Now(), + SetupTime: time.Now(), + Usage: 10 * time.Second, + Cost: 10, + Supplier: "suppl1", + DisconnectCause: "NORMAL_CLEARNING", } err := cdrStats.AppendCDR(cdr, nil) if err != nil { diff --git a/engine/storage_mysql_local_test.go b/engine/storage_mysql_local_test.go index d59d961ac..9e08a6055 100644 --- a/engine/storage_mysql_local_test.go +++ b/engine/storage_mysql_local_test.go @@ -195,7 +195,7 @@ func TestMySQLSetGetTPCdrStats(t *testing.T) { } CS_ID := "CDRSTATS_1" setCS := map[string][]*utils.TPCdrStat{CS_ID: []*utils.TPCdrStat{ - &utils.TPCdrStat{QueueLength: "10", TimeWindow: "10m", Metrics: "ASR", Tenant: "cgrates.org", Category: "call"}, + &utils.TPCdrStat{QueueLength: "10", TimeWindow: "10m", Metrics: "ASR", Tenants: "cgrates.org", Categories: "call"}, }} if err := mysqlDb.SetTPCdrStats(TEST_SQL, setCS); err != nil { t.Error(err.Error()) diff --git a/engine/storage_psql_local_test.go b/engine/storage_psql_local_test.go index fce298ca9..f8d45c325 100644 --- a/engine/storage_psql_local_test.go +++ b/engine/storage_psql_local_test.go @@ -194,7 +194,7 @@ func TestPSQLSetGetTPCdrStats(t *testing.T) { } CS_ID := "CDRSTATS_1" setCS := map[string][]*utils.TPCdrStat{CS_ID: []*utils.TPCdrStat{ - &utils.TPCdrStat{QueueLength: "10", TimeWindow: "10m", Metrics: "ASR", Tenant: "cgrates.org", Category: "call"}, + &utils.TPCdrStat{QueueLength: "10", TimeWindow: "10m", Metrics: "ASR", Tenants: "cgrates.org", Categories: "call"}, }} if err := psqlDb.SetTPCdrStats(TEST_SQL, setCS); err != nil { t.Error(err.Error()) diff --git a/engine/storage_sql.go b/engine/storage_sql.go index 76219ff45..a1eadcbf2 100644 --- a/engine/storage_sql.go +++ b/engine/storage_sql.go @@ -390,30 +390,31 @@ func (self *SQLStorage) SetTPCdrStats(tpid string, css map[string][]*utils.TPCdr for _, cs := range cStats { ql, _ := strconv.Atoi(cs.QueueLength) saved := tx.Save(&TpCdrStat{ - Tpid: tpid, - Tag: csId, - QueueLength: ql, - TimeWindow: cs.TimeWindow, - Metrics: cs.Metrics, - SetupInterval: cs.SetupInterval, - Tor: cs.TOR, - CdrHost: cs.CdrHost, - CdrSource: cs.CdrSource, - ReqType: cs.ReqType, - Direction: cs.Direction, - Tenant: cs.Tenant, - Category: cs.Category, - Account: cs.Account, - Subject: cs.Subject, - DestinationPrefix: cs.DestinationPrefix, - UsageInterval: cs.UsageInterval, - Supplier: cs.Supplier, - MediationRunids: cs.MediationRunIds, - RatedAccount: cs.RatedAccount, - RatedSubject: cs.RatedSubject, - CostInterval: cs.CostInterval, - ActionTriggers: cs.ActionTriggers, - CreatedAt: time.Now(), + Tpid: tpid, + Tag: csId, + QueueLength: ql, + TimeWindow: cs.TimeWindow, + Metrics: cs.Metrics, + SetupInterval: cs.SetupInterval, + Tors: cs.TORs, + CdrHosts: cs.CdrHosts, + CdrSources: cs.CdrSources, + ReqTypes: cs.ReqTypes, + Directions: cs.Directions, + Tenants: cs.Tenants, + Categories: cs.Categories, + Accounts: cs.Accounts, + Subjects: cs.Subjects, + DestinationPrefixes: cs.DestinationPrefixes, + UsageInterval: cs.UsageInterval, + Suppliers: cs.Suppliers, + DisconnectCauses: cs.DisconnectCauses, + MediationRunids: cs.MediationRunIds, + RatedAccounts: cs.RatedAccounts, + RatedSubjects: cs.RatedSubjects, + CostInterval: cs.CostInterval, + ActionTriggers: cs.ActionTriggers, + CreatedAt: time.Now(), }) if saved.Error != nil { tx.Rollback() @@ -1427,27 +1428,28 @@ func (self *SQLStorage) GetTpCdrStats(tpid, tag string) (map[string][]*utils.TPC for _, tpCs := range tpCdrStats { css[tpCs.Tag] = append(css[tpCs.Tag], &utils.TPCdrStat{ - QueueLength: strconv.Itoa(tpCs.QueueLength), - TimeWindow: tpCs.TimeWindow, - Metrics: tpCs.Metrics, - SetupInterval: tpCs.SetupInterval, - TOR: tpCs.Tor, - CdrHost: tpCs.CdrHost, - CdrSource: tpCs.CdrSource, - ReqType: tpCs.ReqType, - Direction: tpCs.Direction, - Tenant: tpCs.Tenant, - Category: tpCs.Category, - Account: tpCs.Account, - Subject: tpCs.Subject, - DestinationPrefix: tpCs.DestinationPrefix, - UsageInterval: tpCs.UsageInterval, - Supplier: tpCs.Supplier, - MediationRunIds: tpCs.MediationRunids, - RatedAccount: tpCs.RatedAccount, - RatedSubject: tpCs.RatedSubject, - CostInterval: tpCs.CostInterval, - ActionTriggers: tpCs.ActionTriggers, + QueueLength: strconv.Itoa(tpCs.QueueLength), + TimeWindow: tpCs.TimeWindow, + Metrics: tpCs.Metrics, + 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, + 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 diff --git a/engine/tpimporter_csv.go b/engine/tpimporter_csv.go index 82ab77ef8..8223c216f 100644 --- a/engine/tpimporter_csv.go +++ b/engine/tpimporter_csv.go @@ -699,27 +699,28 @@ func (self *TPCSVImporter) importCdrStats(fn string) error { css[record[CDRSTATIDX_TAG]] = make([]*utils.TPCdrStat, 0) } css[record[0]] = append(css[record[0]], &utils.TPCdrStat{ - QueueLength: record[CDRSTATIDX_QLENGHT], - TimeWindow: ValueOrDefault(record[CDRSTATIDX_TIMEWINDOW], "0"), - Metrics: record[CDRSTATIDX_METRICS], - SetupInterval: record[CDRSTATIDX_SETUPTIME], - TOR: record[CDRSTATIDX_TOR], - CdrHost: record[CDRSTATIDX_CDRHOST], - CdrSource: record[CDRSTATIDX_CDRSRC], - ReqType: record[CDRSTATIDX_REQTYPE], - Direction: record[CDRSTATIDX_DIRECTION], - Tenant: record[CDRSTATIDX_TENANT], - Category: record[CDRSTATIDX_CATEGORY], - Account: record[CDRSTATIDX_ACCOUNT], - Subject: record[CDRSTATIDX_SUBJECT], - DestinationPrefix: record[CDRSTATIDX_DSTPREFIX], - UsageInterval: record[CDRSTATIDX_USAGE], - Supplier: record[CDRSTATIDX_SUPPLIER], - MediationRunIds: record[CDRSTATIDX_MEDRUN], - RatedAccount: record[CDRSTATIDX_RTACCOUNT], - RatedSubject: record[CDRSTATIDX_RTSUBJECT], - CostInterval: record[CDRSTATIDX_COST], - ActionTriggers: record[CDRSTATIDX_ATRIGGER], + QueueLength: record[CDRSTATIDX_QLENGHT], + TimeWindow: ValueOrDefault(record[CDRSTATIDX_TIMEWINDOW], "0"), + Metrics: record[CDRSTATIDX_METRICS], + SetupInterval: record[CDRSTATIDX_SETUPTIME], + TORs: record[CDRSTATIDX_TOR], + CdrHosts: record[CDRSTATIDX_CDRHOST], + CdrSources: record[CDRSTATIDX_CDRSRC], + ReqTypes: record[CDRSTATIDX_REQTYPE], + Directions: record[CDRSTATIDX_DIRECTION], + Tenants: record[CDRSTATIDX_TENANT], + Categories: record[CDRSTATIDX_CATEGORY], + Accounts: record[CDRSTATIDX_ACCOUNT], + Subjects: record[CDRSTATIDX_SUBJECT], + DestinationPrefixes: record[CDRSTATIDX_DSTPREFIX], + UsageInterval: record[CDRSTATIDX_USAGE], + Suppliers: record[CDRSTATIDX_SUPPLIER], + DisconnectCauses: record[CDRSTATIDX_DISCONNECT_CAUSE], + MediationRunIds: record[CDRSTATIDX_MEDRUN], + RatedAccounts: record[CDRSTATIDX_RTACCOUNT], + RatedSubjects: record[CDRSTATIDX_RTSUBJECT], + CostInterval: record[CDRSTATIDX_COST], + ActionTriggers: record[CDRSTATIDX_ATRIGGER], }) } if err := self.StorDb.SetTPCdrStats(self.TPid, css); err != nil { diff --git a/utils/apitpdata.go b/utils/apitpdata.go index 23636b0d0..9a91a7a8e 100644 --- a/utils/apitpdata.go +++ b/utils/apitpdata.go @@ -394,35 +394,38 @@ type TPCdrStats struct { func (self *TPCdrStats) AsExportSlice() [][]string { retSlice := make([][]string, len(self.CdrStats)) for idx, cdrStat := range self.CdrStats { - retSlice[idx] = []string{self.CdrStatsId, cdrStat.QueueLength, cdrStat.TimeWindow, cdrStat.Metrics, cdrStat.SetupInterval, cdrStat.TOR, cdrStat.CdrHost, cdrStat.CdrSource, - cdrStat.ReqType, cdrStat.Direction, cdrStat.Tenant, cdrStat.Category, cdrStat.Account, cdrStat.Subject, cdrStat.DestinationPrefix, cdrStat.UsageInterval, cdrStat.Supplier, - cdrStat.MediationRunIds, cdrStat.RatedAccount, cdrStat.RatedSubject, cdrStat.CostInterval, cdrStat.ActionTriggers} + retSlice[idx] = []string{self.CdrStatsId, cdrStat.QueueLength, cdrStat.TimeWindow, cdrStat.Metrics, cdrStat.SetupInterval, cdrStat.TORs, cdrStat.CdrHosts, + cdrStat.CdrSources, cdrStat.ReqTypes, cdrStat.Directions, cdrStat.Tenants, cdrStat.Categories, cdrStat.Accounts, cdrStat.Subjects, cdrStat.DestinationPrefixes, + cdrStat.UsageInterval, cdrStat.Suppliers, cdrStat.DisconnectCauses, cdrStat.MediationRunIds, cdrStat.RatedAccounts, cdrStat.RatedSubjects, cdrStat.CostInterval, + cdrStat.ActionTriggers} + } return retSlice } type TPCdrStat struct { - QueueLength string - TimeWindow string - Metrics string - SetupInterval string - TOR string - CdrHost string - CdrSource string - ReqType string - Direction string - Tenant string - Category string - Account string - Subject string - DestinationPrefix string - UsageInterval string - Supplier string - MediationRunIds string - RatedAccount string - RatedSubject string - CostInterval string - ActionTriggers string + QueueLength string + TimeWindow 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 + UsageInterval string + Suppliers string + DisconnectCauses string + MediationRunIds string + RatedAccounts string + RatedSubjects string + CostInterval string + ActionTriggers string } type TPDerivedChargers struct { diff --git a/utils/apitpdata_test.go b/utils/apitpdata_test.go index 3828a9ac9..66681de33 100644 --- a/utils/apitpdata_test.go +++ b/utils/apitpdata_test.go @@ -274,56 +274,58 @@ func TestTPCdrStatsAsExportSlice(t *testing.T) { CdrStatsId: "CDRST1", CdrStats: []*TPCdrStat{ &TPCdrStat{ - QueueLength: "5", - TimeWindow: "60m", - Metrics: "ASR;ACD", - SetupInterval: "2014-07-29T15:00:00Z;2014-07-29T16:00:00Z", - TOR: "*voice", - CdrHost: "87.139.12.167", - CdrSource: "FS_JSON", - ReqType: META_RATED, - Direction: "*out", - Tenant: "cgrates.org", - Category: "call", - Account: "dan", - Subject: "dan", - DestinationPrefix: "49", - UsageInterval: "5m;10m", - Supplier: "supplier1", - MediationRunIds: "default", - RatedAccount: "rif", - RatedSubject: "rif", - CostInterval: "0;2", - ActionTriggers: "STANDARD_TRIGGERS"}, + QueueLength: "5", + TimeWindow: "60m", + 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: META_RATED, + Directions: "*out", + Tenants: "cgrates.org", + Categories: "call", + Accounts: "dan", + Subjects: "dan", + DestinationPrefixes: "49", + UsageInterval: "5m;10m", + Suppliers: "supplier1", + DisconnectCauses: "NORMAL_CLEARNING", + MediationRunIds: "default", + RatedAccounts: "rif", + RatedSubjects: "rif", + CostInterval: "0;2", + ActionTriggers: "STANDARD_TRIGGERS"}, &TPCdrStat{ - QueueLength: "5", - TimeWindow: "60m", - Metrics: "ASR", - SetupInterval: "2014-07-29T15:00:00Z;2014-07-29T16:00:00Z", - TOR: "*voice", - CdrHost: "87.139.12.167", - CdrSource: "FS_JSON", - ReqType: META_RATED, - Direction: "*out", - Tenant: "cgrates.org", - Category: "call", - Account: "dan", - Subject: "dan", - DestinationPrefix: "49", - UsageInterval: "5m;10m", - Supplier: "supplier1", - MediationRunIds: "default", - RatedAccount: "dan", - RatedSubject: "dan", - CostInterval: "0;2", - ActionTriggers: "STANDARD_TRIGGERS"}, + QueueLength: "5", + TimeWindow: "60m", + Metrics: "ASR", + SetupInterval: "2014-07-29T15:00:00Z;2014-07-29T16:00:00Z", + TORs: "*voice", + CdrHosts: "87.139.12.167", + CdrSources: "FS_JSON", + ReqTypes: META_RATED, + Directions: "*out", + Tenants: "cgrates.org", + Categories: "call", + Accounts: "dan", + Subjects: "dan", + DestinationPrefixes: "49", + UsageInterval: "5m;10m", + Suppliers: "supplier1", + DisconnectCauses: "NORMAL_CLEARNING", + MediationRunIds: "default", + RatedAccounts: "dan", + RatedSubjects: "dan", + CostInterval: "0;2", + ActionTriggers: "STANDARD_TRIGGERS"}, }, } expectedSlc := [][]string{ []string{"CDRST1", "5", "60m", "ASR;ACD", "2014-07-29T15:00:00Z;2014-07-29T16:00:00Z", "*voice", "87.139.12.167", "FS_JSON", META_RATED, "*out", "cgrates.org", "call", - "dan", "dan", "49", "5m;10m", "supplier1", "default", "rif", "rif", "0;2", "STANDARD_TRIGGERS"}, + "dan", "dan", "49", "5m;10m", "supplier1", "NORMAL_CLEARNING", "default", "rif", "rif", "0;2", "STANDARD_TRIGGERS"}, []string{"CDRST1", "5", "60m", "ASR", "2014-07-29T15:00:00Z;2014-07-29T16:00:00Z", "*voice", "87.139.12.167", "FS_JSON", META_RATED, "*out", "cgrates.org", "call", - "dan", "dan", "49", "5m;10m", "supplier1", "default", "dan", "dan", "0;2", "STANDARD_TRIGGERS"}, + "dan", "dan", "49", "5m;10m", "supplier1", "NORMAL_CLEARNING", "default", "dan", "dan", "0;2", "STANDARD_TRIGGERS"}, } if slc := cdrStats.AsExportSlice(); !reflect.DeepEqual(expectedSlc, slc) { t.Errorf("Expecting: %+v, received: %+v", expectedSlc, slc) diff --git a/utils/consts.go b/utils/consts.go index 28b05484a..11634978c 100644 --- a/utils/consts.go +++ b/utils/consts.go @@ -73,7 +73,7 @@ const ( ACTION_TRIGGERS_NRCOLS = 19 ACCOUNT_ACTIONS_NRCOLS = 5 DERIVED_CHARGERS_NRCOLS = 19 - CDR_STATS_NRCOLS = 22 + CDR_STATS_NRCOLS = 23 ROUNDING_UP = "*up" ROUNDING_MIDDLE = "*middle" ROUNDING_DOWN = "*down"