From ddcd54db4b619c45defa8e822983c6d6450265b7 Mon Sep 17 00:00:00 2001 From: DanB Date: Thu, 24 Apr 2014 18:33:18 +0200 Subject: [PATCH] Integration of DerivedCharging within mediation --- config/config.go | 183 ++++++++++++++++++-------------------- mediator/mediator.go | 49 ++++------ mediator/mediator_test.go | 48 ++++------ utils/storedcdr.go | 8 +- utils/storedcdr_test.go | 8 +- 5 files changed, 129 insertions(+), 167 deletions(-) diff --git a/config/config.go b/config/config.go index b7d24ff49..c3a8489c7 100644 --- a/config/config.go +++ b/config/config.go @@ -54,103 +54,92 @@ func SetCgrConfig(cfg *CGRConfig) { // Holds system configuration, defaults are overwritten with values from config file if found type CGRConfig struct { - RatingDBType string - RatingDBHost string // The host to connect to. Values that start with / are for UNIX domain sockets. - RatingDBPort string // The port to bind to. - RatingDBName string // The name of the database to connect to. - RatingDBUser string // The user to sign in as. - RatingDBPass string // The user's password. - AccountDBType string - AccountDBHost string // The host to connect to. Values that start with / are for UNIX domain sockets. - AccountDBPort string // The port to bind to. - AccountDBName string // The name of the database to connect to. - AccountDBUser string // The user to sign in as. - AccountDBPass string // The user's password. - StorDBType string // Should reflect the database type used to store logs - StorDBHost string // The host to connect to. Values that start with / are for UNIX domain sockets. - StorDBPort string // Th e port to bind to. - StorDBName string // The name of the database to connect to. - StorDBUser string // The user to sign in as. - StorDBPass string // The user's password. - DBDataEncoding string // The encoding used to store object data in strings: - RPCJSONListen string // RPC JSON listening address - RPCGOBListen string // RPC GOB listening address - HTTPListen string // HTTP listening address - DefaultReqType string // Use this request type if not defined on top - DefaultTOR string // set default type of record - DefaultTenant string // set default tenant - DefaultSubject string // set default rating subject, useful in case of fallback - RoundingMethod string // Rounding method for the end price: <*up|*middle|*down> - RoundingDecimals int // Number of decimals to round end prices at - XmlCfgDocument *CgrXmlCfgDocument // Load additional configuration inside xml document - RaterEnabled bool // start standalone server (no balancer) - RaterBalancer string // balancer address host:port - BalancerEnabled bool - SchedulerEnabled bool - CDRSEnabled bool // Enable CDR Server service - CDRSExtraFields []*utils.RSRField // Extra fields to store in CDRs - CDRSMediator string // Address where to reach the Mediator. Empty for disabling mediation. <""|internal> - CdreCdrFormat string // Format of the exported CDRs. - CdreMaskDestId string // Id of the destination list to be masked in CDRs - CdreMaskLength int // Number of digits to mask in the destination suffix if destination is in the MaskDestinationdsId - CdreCostShiftDigits int // Shift digits in the cost on export (eg: convert from EUR to cents) - CdreDir string // Path towards exported cdrs directory - CdreExportedFields []*utils.RSRField // List of fields in the exported CDRs - CdreFWXmlTemplate *CgrXmlCdreFwCfg // Use this configuration as export template in case of fixed fields length - CdrcEnabled bool // Enable CDR client functionality - CdrcCdrs string // Address where to reach CDR server - CdrcCdrsMethod string // Mechanism to use when posting CDRs on server - CdrcRunDelay time.Duration // Sleep interval between consecutive runs, 0 to use automation via inotify - CdrcCdrType string // CDR file format . - CdrcCdrInDir string // Absolute path towards the directory where the CDRs are stored. - CdrcCdrOutDir string // Absolute path towards the directory where processed CDRs will be moved. - CdrcSourceId string // Tag identifying the source of the CDRs within CGRS database. - CdrcAccIdField string // Accounting id field identifier. Use index number in case of .csv cdrs. - CdrcReqTypeField string // Request type field identifier. Use index number in case of .csv cdrs. - CdrcDirectionField string // Direction field identifier. Use index numbers in case of .csv cdrs. - CdrcTenantField string // Tenant field identifier. Use index numbers in case of .csv cdrs. - CdrcTorField string // Type of Record field identifier. Use index numbers in case of .csv cdrs. - CdrcAccountField string // Account field identifier. Use index numbers in case of .csv cdrs. - CdrcSubjectField string // Subject field identifier. Use index numbers in case of .csv CDRs. - CdrcDestinationField string // Destination field identifier. Use index numbers in case of .csv cdrs. - CdrcSetupTimeField string // Setup time field identifier. Use index numbers in case of .csv cdrs. - CdrcAnswerTimeField string // Answer time field identifier. Use index numbers in case of .csv cdrs. - CdrcDurationField string // Duration field identifier. Use index numbers in case of .csv cdrs. - CdrcExtraFields []string // Extra fields to extract, special format in case of .csv "field1:index1,field2:index2" - SMEnabled bool - SMSwitchType string - SMRater string // address where to access rater. Can be internal, direct rater address or the address of a balancer - SMRaterReconnects int // Number of reconnect attempts to rater - SMDebitInterval int // the period to be debited in advanced during a call (in seconds) - SMMaxCallDuration time.Duration // The maximum duration of a call - MediatorEnabled bool // Starts Mediator service: . - MediatorRater string // Address where to reach the Rater: - MediatorRaterReconnects int // Number of reconnects to rater before giving up. - MediatorRunIds []string // Identifiers for each mediation run on CDRs - MediatorReqTypeFields []string // Name of request type fields to be used during mediation. Use index number in case of .csv cdrs. - MediatorDirectionFields []string // Name of direction fields to be used during mediation. Use index numbers in case of .csv cdrs. - MediatorTenantFields []string // Name of tenant fields to be used during mediation. Use index numbers in case of .csv cdrs. - MediatorTORFields []string // Name of tor fields to be used during mediation. Use index numbers in case of .csv cdrs. - MediatorAccountFields []string // Name of account fields to be used during mediation. Use index numbers in case of .csv cdrs. - MediatorSubjectFields []string // Name of subject fields to be used during mediation. Use index numbers in case of .csv cdrs. - MediatorDestFields []string // Name of destination fields to be used during mediation. Use index numbers in case of .csv cdrs. - MediatorSetupTimeFields []string // Name of setup_time fields to be used during mediation. Use index numbers in case of .csv cdrs. - MediatorAnswerTimeFields []string // Name of answer_time fields to be used during mediation. Use index numbers in case of .csv cdrs. - MediatorDurationFields []string // Name of duration fields to be used during mediation. Use index numbers in case of .csv cdrs. - DerivedChargers utils.DerivedChargers // System wide derived chargers, added to the account level ones - CombinedDerivedChargers bool // Combine accounts specific derived_chargers with server configured - FreeswitchServer string // freeswitch address host:port - FreeswitchPass string // FS socket password - FreeswitchReconnects int // number of times to attempt reconnect after connect fails - HistoryAgentEnabled bool // Starts History as an agent: . - HistoryServer string // Address where to reach the master history server: - HistoryServerEnabled bool // Starts History as server: . - HistoryDir string // Location on disk where to store history files. - HistorySaveInterval time.Duration // The timout duration between history writes - MailerServer string // The server to use when sending emails out - MailerAuthUser string // Authenticate to email server using this user - MailerAuthPass string // Authenticate to email server with this password - MailerFromAddr string // From address used when sending emails out + RatingDBType string + RatingDBHost string // The host to connect to. Values that start with / are for UNIX domain sockets. + RatingDBPort string // The port to bind to. + RatingDBName string // The name of the database to connect to. + RatingDBUser string // The user to sign in as. + RatingDBPass string // The user's password. + AccountDBType string + AccountDBHost string // The host to connect to. Values that start with / are for UNIX domain sockets. + AccountDBPort string // The port to bind to. + AccountDBName string // The name of the database to connect to. + AccountDBUser string // The user to sign in as. + AccountDBPass string // The user's password. + StorDBType string // Should reflect the database type used to store logs + StorDBHost string // The host to connect to. Values that start with / are for UNIX domain sockets. + StorDBPort string // Th e port to bind to. + StorDBName string // The name of the database to connect to. + StorDBUser string // The user to sign in as. + StorDBPass string // The user's password. + DBDataEncoding string // The encoding used to store object data in strings: + RPCJSONListen string // RPC JSON listening address + RPCGOBListen string // RPC GOB listening address + HTTPListen string // HTTP listening address + DefaultReqType string // Use this request type if not defined on top + DefaultTOR string // set default type of record + DefaultTenant string // set default tenant + DefaultSubject string // set default rating subject, useful in case of fallback + RoundingMethod string // Rounding method for the end price: <*up|*middle|*down> + RoundingDecimals int // Number of decimals to round end prices at + XmlCfgDocument *CgrXmlCfgDocument // Load additional configuration inside xml document + RaterEnabled bool // start standalone server (no balancer) + RaterBalancer string // balancer address host:port + BalancerEnabled bool + SchedulerEnabled bool + CDRSEnabled bool // Enable CDR Server service + CDRSExtraFields []*utils.RSRField // Extra fields to store in CDRs + CDRSMediator string // Address where to reach the Mediator. Empty for disabling mediation. <""|internal> + CdreCdrFormat string // Format of the exported CDRs. + CdreMaskDestId string // Id of the destination list to be masked in CDRs + CdreMaskLength int // Number of digits to mask in the destination suffix if destination is in the MaskDestinationdsId + CdreCostShiftDigits int // Shift digits in the cost on export (eg: convert from EUR to cents) + CdreDir string // Path towards exported cdrs directory + CdreExportedFields []*utils.RSRField // List of fields in the exported CDRs + CdreFWXmlTemplate *CgrXmlCdreFwCfg // Use this configuration as export template in case of fixed fields length + CdrcEnabled bool // Enable CDR client functionality + CdrcCdrs string // Address where to reach CDR server + CdrcCdrsMethod string // Mechanism to use when posting CDRs on server + CdrcRunDelay time.Duration // Sleep interval between consecutive runs, 0 to use automation via inotify + CdrcCdrType string // CDR file format . + CdrcCdrInDir string // Absolute path towards the directory where the CDRs are stored. + CdrcCdrOutDir string // Absolute path towards the directory where processed CDRs will be moved. + CdrcSourceId string // Tag identifying the source of the CDRs within CGRS database. + CdrcAccIdField string // Accounting id field identifier. Use index number in case of .csv cdrs. + CdrcReqTypeField string // Request type field identifier. Use index number in case of .csv cdrs. + CdrcDirectionField string // Direction field identifier. Use index numbers in case of .csv cdrs. + CdrcTenantField string // Tenant field identifier. Use index numbers in case of .csv cdrs. + CdrcTorField string // Type of Record field identifier. Use index numbers in case of .csv cdrs. + CdrcAccountField string // Account field identifier. Use index numbers in case of .csv cdrs. + CdrcSubjectField string // Subject field identifier. Use index numbers in case of .csv CDRs. + CdrcDestinationField string // Destination field identifier. Use index numbers in case of .csv cdrs. + CdrcSetupTimeField string // Setup time field identifier. Use index numbers in case of .csv cdrs. + CdrcAnswerTimeField string // Answer time field identifier. Use index numbers in case of .csv cdrs. + CdrcDurationField string // Duration field identifier. Use index numbers in case of .csv cdrs. + CdrcExtraFields []string // Extra fields to extract, special format in case of .csv "field1:index1,field2:index2" + SMEnabled bool + SMSwitchType string + SMRater string // address where to access rater. Can be internal, direct rater address or the address of a balancer + SMRaterReconnects int // Number of reconnect attempts to rater + SMDebitInterval int // the period to be debited in advanced during a call (in seconds) + SMMaxCallDuration time.Duration // The maximum duration of a call + MediatorEnabled bool // Starts Mediator service: . + MediatorRater string // Address where to reach the Rater: + MediatorRaterReconnects int // Number of reconnects to rater before giving up. + DerivedChargers utils.DerivedChargers // System wide derived chargers, added to the account level ones + CombinedDerivedChargers bool // Combine accounts specific derived_chargers with server configured + FreeswitchServer string // freeswitch address host:port + FreeswitchPass string // FS socket password + FreeswitchReconnects int // number of times to attempt reconnect after connect fails + HistoryAgentEnabled bool // Starts History as an agent: . + HistoryServer string // Address where to reach the master history server: + HistoryServerEnabled bool // Starts History as server: . + HistoryDir string // Location on disk where to store history files. + HistorySaveInterval time.Duration // The timout duration between history writes + MailerServer string // The server to use when sending emails out + MailerAuthUser string // Authenticate to email server using this user + MailerAuthPass string // Authenticate to email server with this password + MailerFromAddr string // From address used when sending emails out } func (self *CGRConfig) setDefaults() error { diff --git a/mediator/mediator.go b/mediator/mediator.go index bda8c9589..28714903f 100644 --- a/mediator/mediator.go +++ b/mediator/mediator.go @@ -1,14 +1,14 @@ /* -Rating system designed to be used in VoIP Carriers World -Copyright (C) 2013 ITsysCOM +Real-time Charging System for Telecom & ISP environments +Copyright (C) 2012-2014 ITsysCOM GmbH -This program is free software: you can redistribute it and/or modify +This program is free software: you can Storagetribute 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 +but WITH*out ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -35,10 +35,6 @@ func NewMediator(connector engine.Connector, logDb engine.LogStorage, cdrDb engi cdrDb: cdrDb, cgrCfg: cfg, } - // Parse config - if err := m.parseConfig(); err != nil { - return nil, err - } return m, nil } @@ -49,22 +45,6 @@ type Mediator struct { cgrCfg *config.CGRConfig } -func (self *Mediator) parseConfig() error { - cfgVals := [][]string{self.cgrCfg.MediatorSubjectFields, self.cgrCfg.MediatorReqTypeFields, self.cgrCfg.MediatorDirectionFields, - self.cgrCfg.MediatorTenantFields, self.cgrCfg.MediatorTORFields, self.cgrCfg.MediatorAccountFields, self.cgrCfg.MediatorDestFields, - self.cgrCfg.MediatorSetupTimeFields, self.cgrCfg.MediatorAnswerTimeFields, self.cgrCfg.MediatorDurationFields} - - // All other configured fields must match the length of reference fields - for iCfgVal := range cfgVals { - if len(self.cgrCfg.MediatorRunIds) != len(cfgVals[iCfgVal]) { - // Make sure we have everywhere the length of runIds - return errors.New("Inconsistent lenght of mediator fields.") - } - } - - return nil -} - // Retrive the cost from logging database func (self *Mediator) getCostsFromDB(cgrid string) (cc *engine.CallCost, err error) { for i := 0; i < 3; i++ { // Mechanism to avoid concurrency between SessionManager writing the costs and mediator picking them up @@ -134,15 +114,20 @@ func (self *Mediator) RateCdr(dbcdr utils.RawCDR) error { if err != nil { return err } - cdrs := []*utils.StoredCdr{rtCdr} // Start with initial dbcdr, will add here all to be mediated - for runIdx, runId := range self.cgrCfg.MediatorRunIds { - forkedCdr, err := dbcdr.AsStoredCdr(self.cgrCfg.MediatorRunIds[runIdx], self.cgrCfg.MediatorReqTypeFields[runIdx], self.cgrCfg.MediatorDirectionFields[runIdx], - self.cgrCfg.MediatorTenantFields[runIdx], self.cgrCfg.MediatorTORFields[runIdx], self.cgrCfg.MediatorAccountFields[runIdx], - self.cgrCfg.MediatorSubjectFields[runIdx], self.cgrCfg.MediatorDestFields[runIdx], - self.cgrCfg.MediatorSetupTimeFields[runIdx], self.cgrCfg.MediatorAnswerTimeFields[runIdx], - self.cgrCfg.MediatorDurationFields[runIdx], []string{}, true) + cdrs := []*utils.StoredCdr{rtCdr} // Start with initial dbcdr, will add here all to be mediated + attrsDC := utils.AttrDerivedChargers{Tenant: rtCdr.Tenant, Tor: rtCdr.TOR, Direction: rtCdr.Direction, + Account: rtCdr.Account, Subject: rtCdr.Subject} + var dcs utils.DerivedChargers + if err := self.connector.GetDerivedChargers(attrsDC, &dcs); err != nil { + errText := fmt.Sprintf("Could not get derived charging for cgrid %s, error: %s", rtCdr.CgrId, err.Error()) + engine.Logger.Err(errText) + return errors.New(errText) + } + for _, dc := range dcs { + forkedCdr, err := dbcdr.AsStoredCdr(dc.RunId, dc.ReqTypeField, dc.DirectionField, + dc.TenantField, dc.TorField, dc.AccountField, dc.SubjectField, dc.DestinationField, dc.SetupTimeField, dc.AnswerTimeField, dc.DurationField, []string{}, true) if err != nil { // Errors on fork, cannot calculate further, write that into db for later analysis - self.cdrDb.SetRatedCdr(&utils.StoredCdr{CgrId: dbcdr.GetCgrId(), MediationRunId: runId, Cost: -1.0}, err.Error()) // Cannot fork CDR, important just runid and error + self.cdrDb.SetRatedCdr(&utils.StoredCdr{CgrId: dbcdr.GetCgrId(), MediationRunId: dc.RunId, Cost: -1.0}, err.Error()) // Cannot fork CDR, important just runid and error continue } cdrs = append(cdrs, forkedCdr) diff --git a/mediator/mediator_test.go b/mediator/mediator_test.go index ab86e1d0b..ed1406934 100644 --- a/mediator/mediator_test.go +++ b/mediator/mediator_test.go @@ -1,31 +1,19 @@ +/* +Real-time Charging System for Telecom & ISP environments +Copyright (C) 2012-2014 ITsysCOM GmbH + +This program is free software: you can Storagetribute 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 WITH*out 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 mediator - -import ( - "github.com/cgrates/cgrates/config" - "testing" -) - -func TestParseConfig(t *testing.T) { - cfg, _ := config.NewDefaultCGRConfig() - m := &Mediator{cgrCfg: cfg} - if err := m.parseConfig(); err != nil { - t.Error(err) - } - cfg.MediatorSubjectFields = []string{"subjFieldName1", "subjFieldName2", "subjFieldName3"} - if err := m.parseConfig(); err == nil { - t.Error("Failed to detect all fields matching reference one") - } - cfg.MediatorRunIds = []string{"run1", "run2"} - if err := m.parseConfig(); err == nil { - t.Error("Failed to detect all fields matching reference one") - } - cfg.MediatorSubjectFields = []string{"subjFieldName1", "subjFieldName2"} - cfg.MediatorReqTypeFields = []string{"reqtypeFieldName1", "reqTypeFieldName2"} - cfg.MediatorDirectionFields = []string{"dirFieldName1", "dirFieldName1"} - cfg.MediatorTenantFields = []string{"tenantFieldName1", "tenantFieldName2"} - cfg.MediatorTORFields = []string{"torFieldName1", "torFieldName2"} - cfg.MediatorAccountFields = []string{"acntFieldName1", "acntFieldName2"} - cfg.MediatorDestFields = []string{"destFieldName1", "destFieldName2"} - cfg.MediatorAnswerTimeFields = []string{"answerTimeFieldName1", "answerTimeFieldName1"} - cfg.MediatorDurationFields = []string{"durFieldName1", "durFieldName2"} -} diff --git a/utils/storedcdr.go b/utils/storedcdr.go index b6670dd0a..aa9b32906 100644 --- a/utils/storedcdr.go +++ b/utils/storedcdr.go @@ -1,14 +1,14 @@ /* -Rating system designed to be used in VoIP Carriers World -Copyright (C) 2013 ITsysCOM +Real-time Charging System for Telecom & ISP environments +Copyright (C) 2012-2014 ITsysCOM GmbH -This program is free software: you can redistribute it and/or modify +This program is free software: you can Storagetribute 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 +but WITH*out ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. diff --git a/utils/storedcdr_test.go b/utils/storedcdr_test.go index 639f0e820..b41a52d71 100644 --- a/utils/storedcdr_test.go +++ b/utils/storedcdr_test.go @@ -1,14 +1,14 @@ /* -Rating system designed to be used in VoIP Carriers World -Copyright (C) 2013 ITsysCOM +Real-time Charging System for Telecom & ISP environments +Copyright (C) 2012-2014 ITsysCOM GmbH -This program is free software: you can redistribute it and/or modify +This program is free software: you can Storagetribute 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 +but WITH*out ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.