diff --git a/cdrc/cdrc.go b/cdrc/cdrc.go index 28e0e9567..985878c54 100644 --- a/cdrc/cdrc.go +++ b/cdrc/cdrc.go @@ -88,7 +88,7 @@ func NewCdrc(cdrcCfg *config.CdrcConfig, httpSkipTlsCheck bool, cdrServer *engin } csvSepRune, _ := utf8.DecodeRune([]byte(cdrcCfg.FieldSeparator)) cdrc := &Cdrc{cdrsAddress: cdrcCfg.CdrsAddress, CdrFormat: cdrcCfg.CdrFormat, cdrInDir: cdrcCfg.CdrInDir, cdrOutDir: cdrcCfg.CdrOutDir, - cdrSourceId: cdrcCfg.CdrSourceId, runDelay: cdrcCfg.RunDelay, csvSep: csvSepRune, cdrFields: cdrcCfg.CdrFields, httpSkipTlsCheck: httpSkipTlsCheck, cdrServer: cdrServer} + cdrSourceId: cdrcCfg.CdrSourceId, runDelay: cdrcCfg.RunDelay, csvSep: csvSepRune, duMultiplyFactor: cdrcCfg.DataUsageMultiplyFactor, cdrFields: cdrcCfg.CdrFields, httpSkipTlsCheck: httpSkipTlsCheck, cdrServer: cdrServer} // Before processing, make sure in and out folders exist for _, dir := range []string{cdrc.cdrInDir, cdrc.cdrOutDir} { if _, err := os.Stat(dir); err != nil && os.IsNotExist(err) { @@ -107,6 +107,7 @@ type Cdrc struct { cdrSourceId string runDelay time.Duration csvSep rune + duMultiplyFactor int64 cdrFields []*config.CfgCdrField httpSkipTlsCheck bool cdrServer *engine.CDRS // Reference towards internal cdrServer if that is the case @@ -158,6 +159,9 @@ func (self *Cdrc) recordToStoredCdr(record []string) (*utils.StoredCdr, error) { } } storedCdr.CgrId = utils.Sha1(storedCdr.AccId, storedCdr.SetupTime.String()) + if storedCdr.TOR == utils.DATA && self.duMultiplyFactor != 0 { + storedCdr.Usage = time.Duration(storedCdr.Usage.Nanoseconds() * self.duMultiplyFactor) + } for _, httpFieldCfg := range lazyHttpFields { // Lazy process the http fields var outValByte []byte var fieldVal, httpAddr string diff --git a/cdrc/cdrc_test.go b/cdrc/cdrc_test.go index e2cd1daf1..00cdfa6a9 100644 --- a/cdrc/cdrc_test.go +++ b/cdrc/cdrc_test.go @@ -66,6 +66,56 @@ func TestRecordForkCdr(t *testing.T) { } } +func TestDataMultiplyFactor(t *testing.T) { + cdrFields := []*config.CfgCdrField{&config.CfgCdrField{Tag: "TORField", Type: utils.CDRFIELD, CdrFieldId: "tor", Value: []*utils.RSRField{&utils.RSRField{Id: "0"}}}, + &config.CfgCdrField{Tag: "UsageField", Type: utils.CDRFIELD, CdrFieldId: "usage", Value: []*utils.RSRField{&utils.RSRField{Id: "1"}}}} + cdrc := &Cdrc{CdrFormat: CSV, cdrSourceId: "TEST_CDRC", cdrFields: cdrFields} + cdrRow := []string{"*data", "1"} + rtCdr, err := cdrc.recordToStoredCdr(cdrRow) + if err != nil { + t.Error("Failed to parse CDR in rated cdr", err) + } + var sTime time.Time + expectedCdr := &utils.StoredCdr{ + CgrId: utils.Sha1("", sTime.String()), + TOR: cdrRow[0], + CdrHost: "0.0.0.0", + CdrSource: "TEST_CDRC", + Usage: time.Duration(1) * time.Second, + ExtraFields: map[string]string{}, + Cost: -1, + } + if !reflect.DeepEqual(expectedCdr, rtCdr) { + t.Errorf("Expected: \n%v, \nreceived: \n%v", expectedCdr, rtCdr) + } + cdrc.duMultiplyFactor = 1024 + expectedCdr = &utils.StoredCdr{ + CgrId: utils.Sha1("", sTime.String()), + TOR: cdrRow[0], + CdrHost: "0.0.0.0", + CdrSource: "TEST_CDRC", + Usage: time.Duration(1024) * time.Second, + ExtraFields: map[string]string{}, + Cost: -1, + } + if rtCdr, _ := cdrc.recordToStoredCdr(cdrRow); !reflect.DeepEqual(expectedCdr, rtCdr) { + t.Errorf("Expected: \n%v, \nreceived: \n%v", expectedCdr, rtCdr) + } + cdrRow = []string{"*voice", "1"} + expectedCdr = &utils.StoredCdr{ + CgrId: utils.Sha1("", sTime.String()), + TOR: cdrRow[0], + CdrHost: "0.0.0.0", + CdrSource: "TEST_CDRC", + Usage: time.Duration(1) * time.Second, + ExtraFields: map[string]string{}, + Cost: -1, + } + if rtCdr, _ := cdrc.recordToStoredCdr(cdrRow); !reflect.DeepEqual(expectedCdr, rtCdr) { + t.Errorf("Expected: \n%v, \nreceived: \n%v", expectedCdr, rtCdr) + } +} + /* func TestDnTdmCdrs(t *testing.T) { tdmCdrs := ` diff --git a/config/cdrcconfig.go b/config/cdrcconfig.go index bec3d904a..8a2fe7310 100644 --- a/config/cdrcconfig.go +++ b/config/cdrcconfig.go @@ -90,7 +90,7 @@ func NewDefaultCdrcConfig() *CdrcConfig { CdrsAddress: "", CdrFormat: utils.CSV, FieldSeparator: utils.FIELDS_SEP, - DataUsageMultiplyFactor: 1.0, + DataUsageMultiplyFactor: 1, RunDelay: time.Duration(0), CdrInDir: "/var/log/cgrates/cdrc/in", CdrOutDir: "/var/log/cgrates/cdrc/out", @@ -116,7 +116,8 @@ func NewCdrcConfigFromFileParams(c *conf.ConfigFile) (*CdrcConfig, error) { cdrcCfg.FieldSeparator, _ = c.GetString("cdrc", "field_separator") } if hasOpt := c.HasOption("cdrc", "data_usage_multiply_factor"); hasOpt { - cdrcCfg.DataUsageMultiplyFactor, _ = c.GetFloat64("cdrc", "data_usage_multiply_factor") + mf, _ := c.GetInt("cdrc", "data_usage_multiply_factor") + cdrcCfg.DataUsageMultiplyFactor = int64(mf) } if hasOpt := c.HasOption("cdrc", "run_delay"); hasOpt { durStr, _ := c.GetString("cdrc", "run_delay") @@ -199,7 +200,7 @@ type CdrcConfig struct { CdrsAddress string // The address where CDRs can be reached CdrFormat string // The type of CDR file to process FieldSeparator string // The separator to use when reading csvs - DataUsageMultiplyFactor float64 // Conversion factor for data usage + DataUsageMultiplyFactor int64 // Conversion factor for data usage RunDelay time.Duration // Delay between runs, 0 for inotify driven requests CdrInDir string // Folder to process CDRs from CdrOutDir string // Folder to move processed CDRs to diff --git a/config/test_data.txt b/config/test_data.txt index 189bed3ab..05d6dbec6 100644 --- a/config/test_data.txt +++ b/config/test_data.txt @@ -68,7 +68,7 @@ cdrs = test # Address where to reach CDR server run_delay = 99 # Period to sleep between two runs, 0 to use automation via inotify cdr_format = test # CDR file format . field_separator =; # Csv separator, one character only and should be next to equal sign -data_usage_multiply_factor = 99.0 +data_usage_multiply_factor = 99 cdr_in_dir = test # Absolute path towards the direccategoryy where the CDRs are kept (file scategoryed CDRs). cdr_out_dir = test # Absolute path towards the direccategoryy where processed CDRs will be moved after processing. cdr_source_id = test # Tag identifying the source of the CDRs within CGRS database. diff --git a/config/xmlcdrc_test.go b/config/xmlcdrc_test.go index 8eb556e2a..1fc3c270b 100644 --- a/config/xmlcdrc_test.go +++ b/config/xmlcdrc_test.go @@ -69,7 +69,7 @@ func TestParseXmlCdrcConfig(t *testing.T) { internal csv , - 1024.0 + 1024 0 /var/log/cgrates/cdrc/in /var/log/cgrates/cdrc/out @@ -112,7 +112,7 @@ func TestGetCdrcCfgs(t *testing.T) { cdrsAddr := "internal" cdrFormat := "csv" fldSep := "," - dataUsageMultiplyFactor := 1024.0 + dataUsageMultiplyFactor := int64(1024) runDelay := int64(0) cdrInDir := "/var/log/cgrates/cdrc/in" cdrOutDir := "/var/log/cgrates/cdrc/out" diff --git a/config/xmlconfig.go b/config/xmlconfig.go index a6433068b..bc7ccd7e2 100644 --- a/config/xmlconfig.go +++ b/config/xmlconfig.go @@ -59,7 +59,7 @@ type CgrXmlCdrcCfg struct { CdrsAddress *string `xml:"cdrs_address"` // The address where CDRs can be reached CdrFormat *string `xml:"cdr_format"` // The type of CDR to process FieldSeparator *string `xml:"field_separator"` // The separator to use when reading csvs - DataUsageMultiplyFactor *float64 `xml:"data_usage_multiply_factor"` // Conversion factor for data usage + DataUsageMultiplyFactor *int64 `xml:"data_usage_multiply_factor"` // Conversion factor for data usage RunDelay *int64 `xml:"run_delay"` // Delay between runs CdrInDir *string `xml:"cdr_in_dir"` // Folder to process CDRs from CdrOutDir *string `xml:"cdr_out_dir"` // Folder to move processed CDRs to diff --git a/data/conf/cgrates.cfg b/data/conf/cgrates.cfg index f1c12a692..23676c0fa 100644 --- a/data/conf/cgrates.cfg +++ b/data/conf/cgrates.cfg @@ -72,7 +72,7 @@ # run_delay = 0 # Sleep interval in seconds between consecutive runs, 0 to use automation via inotify # cdr_format = csv # CDR file format . # field_separator = , # Separator used in case of csv files. One character only supported and needs to be right after equal sign -# data_usage_multiply_factor = 1.0 # Conversion factor for data usage +# data_usage_multiply_factor = 1 # Conversion factor for data usage # cdr_in_dir = /var/log/cgrates/cdrc/in # Absolute path towards the directory where the CDRs are stored. # cdr_out_dir = /var/log/cgrates/cdrc/out # Absolute path towards the directory where processed CDRs will be moved. # cdr_source_id = csv # Free form field, tag identifying the source of the CDRs within CGRS database. diff --git a/utils/consts.go b/utils/consts.go index 222621b9e..b2d8704da 100644 --- a/utils/consts.go +++ b/utils/consts.go @@ -165,6 +165,7 @@ const ( FILLER = "filler" METATAG = "metatag" HTTP_POST = "http_post" + NANO_MULTIPLIER = 1000000000 ) var ( diff --git a/utils/coreutils.go b/utils/coreutils.go index b27bf0bf3..fe982e523 100644 --- a/utils/coreutils.go +++ b/utils/coreutils.go @@ -211,7 +211,7 @@ func CopyHour(src, dest time.Time) time.Time { // Parses duration, considers s as time unit if not provided, seconds as float to specify subunits func ParseDurationWithSecs(durStr string) (time.Duration, error) { if durSecs, err := strconv.ParseFloat(durStr, 64); err == nil { // Seconds format considered - durNanosecs := int(durSecs * 1000000000) + durNanosecs := int(durSecs * NANO_MULTIPLIER) return time.Duration(durNanosecs), nil } else { return time.ParseDuration(durStr)