diff --git a/apier/tpcdrstats.go b/apier/tpcdrstats.go new file mode 100644 index 000000000..e4990eae4 --- /dev/null +++ b/apier/tpcdrstats.go @@ -0,0 +1,99 @@ +/* +Rating system designed to be used in VoIP Carriers World +Copyright (C) 2013 ITsysCOM + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +package apier + +import ( + "errors" + "fmt" + + "github.com/cgrates/cgrates/utils" +) + +// Creates a new CdrStats profile within a tariff plan +func (self *ApierV1) SetTPCdrStats(attrs utils.TPCdrStats, reply *string) error { + if missing := utils.MissingStructFields(&attrs, []string{"TPid", "CdrStatsId", "CdrStats"}); len(missing) != 0 { + return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing) + } + /*for _, action := range attrs.CdrStats { + requiredFields := []string{"Identifier", "Weight"} + if action.BalanceType != "" { // Add some inter-dependent parameters - if balanceType then we are not talking about simply calling actions + requiredFields = append(requiredFields, "Direction", "Units") + } + if missing := utils.MissingStructFields(action, requiredFields); len(missing) != 0 { + return fmt.Errorf("%s:CdrStat:%s:%v", utils.ERR_MANDATORY_IE_MISSING, action.Identifier, missing) + } + }*/ + if err := self.StorDb.SetTPCdrStats(attrs.TPid, map[string][]*utils.TPCdrStat{attrs.CdrStatsId: attrs.CdrStats}); err != nil { + return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error()) + } + *reply = "OK" + return nil +} + +type AttrGetTPCdrStats struct { + TPid string // Tariff plan id + CdrStatsId string // CdrStat id +} + +// Queries specific CdrStat on tariff plan +func (self *ApierV1) GetTPCdrStats(attrs AttrGetTPCdrStats, reply *utils.TPCdrStats) error { + if missing := utils.MissingStructFields(&attrs, []string{"TPid", "CdrStatsId"}); len(missing) != 0 { //Params missing + return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing) + } + if sgs, err := self.StorDb.GetTpCdrStats(attrs.TPid, attrs.CdrStatsId); err != nil { + return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error()) + } else if len(sgs) == 0 { + return errors.New(utils.ERR_NOT_FOUND) + } else { + *reply = utils.TPCdrStats{TPid: attrs.TPid, CdrStatsId: attrs.CdrStatsId, CdrStats: sgs[attrs.CdrStatsId]} + } + return nil +} + +type AttrGetTPCdrStatIds struct { + TPid string // Tariff plan id +} + +// Queries CdrStats identities on specific tariff plan. +func (self *ApierV1) GetTPCdrStatsIds(attrs AttrGetTPCdrStatIds, reply *[]string) error { + if missing := utils.MissingStructFields(&attrs, []string{"TPid"}); len(missing) != 0 { //Params missing + return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing) + } + if ids, err := self.StorDb.GetTPTableIds(attrs.TPid, utils.TBL_TP_CDR_STATS, "id", nil); err != nil { + return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error()) + } else if ids == nil { + return errors.New(utils.ERR_NOT_FOUND) + } else { + *reply = ids + } + return nil +} + +// Removes specific CdrStats on Tariff plan +func (self *ApierV1) RemTPCdrStats(attrs AttrGetTPCdrStats, reply *string) error { + if missing := utils.MissingStructFields(&attrs, []string{"TPid", "CdrStatsId"}); len(missing) != 0 { //Params missing + return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing) + } + if err := self.StorDb.RemTPData(utils.TBL_TP_SHARED_GROUPS, attrs.TPid, attrs.CdrStatsId); err != nil { + return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error()) + } else { + *reply = "OK" + } + return nil +} diff --git a/apier/tpderivedcharges.go b/apier/tpderivedcharges.go new file mode 100644 index 000000000..57b40a09f --- /dev/null +++ b/apier/tpderivedcharges.go @@ -0,0 +1,94 @@ +/* +Rating system designed to be used in VoIP Carriers World +Copyright (C) 2013 ITsysCOM + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +package apier + +/* +// Creates a new DerivedCharges profile within a tariff plan +func (self *ApierV1) SetTPDerivedCharges(attrs utils.TPDerivedCharges, reply *string) error { + if missing := utils.MissingStructFields(&attrs, []string{"TPid", "DerivedChargesId", "DerivedCharges"}); len(missing) != 0 { + return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing) + } + for _, action := range attrs.DerivedCharges { + requiredFields := []string{"Identifier", "Weight"} + if action.BalanceType != "" { // Add some inter-dependent parameters - if balanceType then we are not talking about simply calling actions + requiredFields = append(requiredFields, "Direction", "Units") + } + if missing := utils.MissingStructFields(action, requiredFields); len(missing) != 0 { + return fmt.Errorf("%s:DerivedCharge:%s:%v", utils.ERR_MANDATORY_IE_MISSING, action.Identifier, missing) + } + } + if err := self.StorDb.SetTPDerivedCharges(attrs.TPid, map[string][]*utils.TPDerivedCharge{attrs.DerivedChargesId: attrs.DerivedCharges}); err != nil { + return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error()) + } + *reply = "OK" + return nil +} + +type AttrGetTPDerivedCharges struct { + TPid string // Tariff plan id + DerivedChargesId string // DerivedCharge id +} + +// Queries specific DerivedCharge on tariff plan +func (self *ApierV1) GetTPDerivedCharges(attrs AttrGetTPDerivedCharges, reply *utils.TPDerivedCharges) error { + if missing := utils.MissingStructFields(&attrs, []string{"TPid", "DerivedChargesId"}); len(missing) != 0 { //Params missing + return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing) + } + if sgs, err := self.StorDb.GetTpDerivedCharges(attrs.TPid, attrs.DerivedChargesId); err != nil { + return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error()) + } else if len(sgs) == 0 { + return errors.New(utils.ERR_NOT_FOUND) + } else { + *reply = utils.TPDerivedCharges{TPid: attrs.TPid, DerivedChargesId: attrs.DerivedChargesId, DerivedCharges: sgs[attrs.DerivedChargesId]} + } + return nil +} + +type AttrGetTPDerivedChargeIds struct { + TPid string // Tariff plan id +} + +// Queries DerivedCharges identities on specific tariff plan. +func (self *ApierV1) GetTPDerivedChargeIds(attrs AttrGetTPDerivedChargeIds, reply *[]string) error { + if missing := utils.MissingStructFields(&attrs, []string{"TPid"}); len(missing) != 0 { //Params missing + return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing) + } + if ids, err := self.StorDb.GetTPTableIds(attrs.TPid, utils.TBL_TP_DERIVED_CHARGES, "id", nil); err != nil { + return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error()) + } else if ids == nil { + return errors.New(utils.ERR_NOT_FOUND) + } else { + *reply = ids + } + return nil +} + +// Removes specific DerivedCharges on Tariff plan +func (self *ApierV1) RemTPDerivedCharges(attrs AttrGetTPDerivedCharges, reply *string) error { + if missing := utils.MissingStructFields(&attrs, []string{"TPid", "DerivedChargesId"}); len(missing) != 0 { //Params missing + return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing) + } + if err := self.StorDb.RemTPData(utils.TBL_TP_DERIVED_CHARGES, attrs.TPid, attrs.DerivedChargesId); err != nil { + return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error()) + } else { + *reply = "OK" + } + return nil +} +*/ diff --git a/data/storage/mysql/create_tariffplan_tables.sql b/data/storage/mysql/create_tariffplan_tables.sql index 6ff71521b..36a4920dd 100644 --- a/data/storage/mysql/create_tariffplan_tables.sql +++ b/data/storage/mysql/create_tariffplan_tables.sql @@ -269,3 +269,35 @@ CREATE TABLE tp_derived_chargers ( ); +-- +-- Table structure for table `tp_cdr_stats` +-- + +DROP TABLE IF EXISTS tp_cdr_stats; +CREATE TABLE tp_cdr_stats ( + `tbid` int(11) NOT NULL AUTO_INCREMENT, + `tpid` varchar(64) NOT NULL, + `id` varchar(64) NOT NULL, + `queue_length` int(11) NOT NULL, + `time_window` int(11) NOT NULL, + `metrics` varchar(64) NOT NULL, + `setup_interval` varchar(64) NOT NULL, + `tor` varchar(64) NOT NULL, + `cdr_host` varchar(64) NOT NULL, + `cdr_source` varchar(64) NOT NULL, + `req_type` varchar(64) NOT NULL, + `direction` varchar(8) NOT NULL, + `tenant` varchar(64) NOT NULL, + `category` varchar(16) NOT NULL, + `account` varchar(24) NOT NULL, + `subject` varchar(64) NOT NULL, + `destination_prefix` varchar(64) NOT NULL, + `usage_interval` varchar(64) NOT NULL, + `mediation_run_ids` varchar(64) NOT NULL, + `rated_account` varchar(64) NOT NULL, + `rated_subject` varchar(64) NOT NULL, + `cost_interval` varchar(24) NOT NULL, + `action_triggers` varchar(64) NOT NULL, + PRIMARY KEY (`tbid`), + KEY `tpid` (`tpid`) +); diff --git a/engine/models.go b/engine/models.go index a76abb5af..8b23111a1 100644 --- a/engine/models.go +++ b/engine/models.go @@ -137,3 +137,52 @@ type TpSharedGroup struct { Strategy string RatingSubject string } + +type TpDerivedCharges struct { + Tbid int64 `gorm:"primary_key:yes"` + Tpid string + Loadid string + Direction string + Tenant string + Category string + Account string + Subject string + RunId string + RunFilter string + ReqtypeField string + DirectionField string + TenantField string + CategoryField string + AccountField string + SubjectField string + DestinationField string + SetupTimeField string + AnswerTimeField string + DurationField string +} + +type TpCdrStat struct { + Tbid int64 `gorm:"primary_key:yes"` + Tpid string + Id string + QueueLength int + TimeWindow int64 + 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 + MediationRunIds string + RatedAccount string + RatedSubject string + CostInterval string + ActionTriggers string +} diff --git a/engine/storage_interface.go b/engine/storage_interface.go index 9284b25a9..62373e53f 100644 --- a/engine/storage_interface.go +++ b/engine/storage_interface.go @@ -159,6 +159,9 @@ type LoadStorage interface { SetTPSharedGroups(string, map[string][]*utils.TPSharedGroup) error GetTpSharedGroups(string, string) (map[string][]*utils.TPSharedGroup, error) + SetTPCdrStats(string, map[string][]*utils.TPCdrStat) error + GetTpCdrStats(string, string) (map[string][]*utils.TPCdrStat, error) + SetTPLCRs(string, map[string]*LCR) error GetTpLCRs(string, string) (map[string]*LCR, error) diff --git a/engine/storage_sql.go b/engine/storage_sql.go index a0a210a50..fcc390109 100644 --- a/engine/storage_sql.go +++ b/engine/storage_sql.go @@ -314,6 +314,44 @@ func (self *SQLStorage) SetTPSharedGroups(tpid string, sgs map[string][]*utils.T return nil } +func (self *SQLStorage) SetTPCdrStats(tpid string, css map[string][]*utils.TPCdrStat) error { + if len(css) == 0 { + return nil //Nothing to set + } + tx := self.db.Begin() + for csId, cStats := range css { + tx.Where("tpid = ?", tpid).Where("id = ?", csId).Delete(TpCdrStat{}) + for _, cs := range cStats { + tx.Save(TpCdrStat{ + Tpid: tpid, + Id: csId, + QueueLength: cs.QueueLength, + 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, + MediationRunIds: cs.MediationRunIds, + RatedAccount: cs.RatedAccount, + RatedSubject: cs.RatedSubject, + CostInterval: cs.CostInterval, + ActionTriggers: cs.ActionTriggers, + }) + } + } + tx.Commit() + return nil +} + func (self *SQLStorage) SetTPLCRs(tpid string, lcrs map[string]*LCR) error { if len(lcrs) == 0 { return nil //Nothing to set @@ -1192,16 +1230,16 @@ func (self *SQLStorage) GetTpRatingProfiles(qryRpf *utils.TPRatingProfile) (map[ func (self *SQLStorage) GetTpSharedGroups(tpid, tag string) (map[string][]*utils.TPSharedGroup, error) { sgs := make(map[string][]*utils.TPSharedGroup) - var tpSharedGroups []TpSharedGroup + var tpCdrStats []TpSharedGroup q := self.db.Where("tpid = ?", tpid) if len(tag) != 0 { q = q.Where("id = ?", tag) } - if err := q.Find(&tpSharedGroups).Error; err != nil { + if err := q.Find(&tpCdrStats).Error; err != nil { return nil, err } - for _, tpSg := range tpSharedGroups { + for _, tpSg := range tpCdrStats { sgs[tag] = append(sgs[tag], &utils.TPSharedGroup{ Account: tpSg.Account, Strategy: tpSg.Strategy, @@ -1211,6 +1249,45 @@ func (self *SQLStorage) GetTpSharedGroups(tpid, tag string) (map[string][]*utils return sgs, nil } +func (self *SQLStorage) GetTpCdrStats(tpid, tag string) (map[string][]*utils.TPCdrStat, error) { + css := make(map[string][]*utils.TPCdrStat) + + var tpCdrStats []TpCdrStat + q := self.db.Where("tpid = ?", tpid) + if len(tag) != 0 { + q = q.Where("id = ?", tag) + } + if err := q.Find(&tpCdrStats).Error; err != nil { + return nil, err + } + + for _, tpCs := range tpCdrStats { + css[tag] = append(css[tag], &utils.TPCdrStat{ + QueueLength: 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, + MediationRunIds: tpCs.MediationRunIds, + RatedAccount: tpCs.RatedAccount, + RatedSubject: tpCs.RatedSubject, + CostInterval: tpCs.CostInterval, + ActionTriggers: tpCs.ActionTriggers, + }) + } + return css, nil +} + func (self *SQLStorage) GetTpLCRs(tpid, tag string) (map[string]*LCR, error) { lcrs := make(map[string]*LCR) q := fmt.Sprintf("SELECT * FROM %s WHERE tpid='%s'", utils.TBL_TP_LCRS, tpid) diff --git a/utils/apitpdata.go b/utils/apitpdata.go index 37553ad47..f42e02d5c 100644 --- a/utils/apitpdata.go +++ b/utils/apitpdata.go @@ -251,6 +251,35 @@ type TPLcrRule struct { Weight float64 } +type TPCdrStats struct { + TPid string + CdrStatsId string + CdrStats []*TPCdrStat +} + +type TPCdrStat struct { + QueueLength int + TimeWindow int64 + 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 + MediationRunIds string + RatedAccount string + RatedSubject string + CostInterval string + ActionTriggers string +} + type TPActionPlan struct { TPid string // Tariff plan id Id string // ActionPlan id diff --git a/utils/consts.go b/utils/consts.go index d1546be2f..20f4b76be 100644 --- a/utils/consts.go +++ b/utils/consts.go @@ -28,11 +28,13 @@ const ( TBL_TP_RATING_PLANS = "tp_rating_plans" TBL_TP_RATE_PROFILES = "tp_rating_profiles" TBL_TP_SHARED_GROUPS = "tp_shared_groups" + TBL_TP_CDR_STATS = "tp_cdr_stats" TBL_TP_LCRS = "tp_lcr_rules" TBL_TP_ACTIONS = "tp_actions" TBL_TP_ACTION_PLANS = "tp_action_plans" TBL_TP_ACTION_TRIGGERS = "tp_action_triggers" TBL_TP_ACCOUNT_ACTIONS = "tp_account_actions" + TBL_TP_DERIVED_CHARGES = "tp_derived_charges" TBL_CDRS_PRIMARY = "cdrs_primary" TBL_CDRS_EXTRA = "cdrs_extra" TBL_COST_DETAILS = "cost_details"