From d9cb9c25ae9fee96ccfb87e658e7db86eeda1f2c Mon Sep 17 00:00:00 2001 From: TeoV Date: Mon, 3 Sep 2018 07:53:33 -0400 Subject: [PATCH] ApierV1.GetCost and ApierV1.GetDataCost accept *now as AnswerTime --- apier/v1/apier_it_test.go | 4 +- apier/v1/costs.go | 21 +++++-- config/config_test.go | 92 +++++++++++++++++++++++++++++++ general_tests/tutorial_it_test.go | 2 +- 4 files changed, 110 insertions(+), 9 deletions(-) diff --git a/apier/v1/apier_it_test.go b/apier/v1/apier_it_test.go index d14564ebd..fb14c74ed 100644 --- a/apier/v1/apier_it_test.go +++ b/apier/v1/apier_it_test.go @@ -1573,7 +1573,7 @@ func TestApierITGetScheduledActions(t *testing.T) { func TestApierITGetDataCost(t *testing.T) { attrs := AttrGetDataCost{Category: "data", Tenant: "cgrates.org", - Subject: "1001", AnswerTime: time.Now(), Usage: 640113} + Subject: "1001", AnswerTime: "*now", Usage: 640113} var rply *engine.DataCost if err := rater.Call("ApierV1.GetDataCost", attrs, &rply); err != nil { t.Error("Unexpected nil error received: ", err.Error()) @@ -1584,7 +1584,7 @@ func TestApierITGetDataCost(t *testing.T) { func TestApierITGetCost(t *testing.T) { attrs := AttrGetCost{Category: "data", Tenant: "cgrates.org", - Subject: "1001", AnswerTime: time.Now(), Usage: "640113"} + Subject: "1001", AnswerTime: "*now", Usage: "640113"} var rply *engine.EventCost if err := rater.Call("ApierV1.GetCost", attrs, &rply); err != nil { t.Error("Unexpected nil error received: ", err.Error()) diff --git a/apier/v1/costs.go b/apier/v1/costs.go index b2dbf092b..42f246ceb 100644 --- a/apier/v1/costs.go +++ b/apier/v1/costs.go @@ -29,7 +29,7 @@ type AttrGetCost struct { Tenant string Category string Subject string - AnswerTime time.Time + AnswerTime string Destination string Usage string } @@ -39,14 +39,19 @@ func (apier *ApierV1) GetCost(attrs AttrGetCost, ec *engine.EventCost) error { if err != nil { return err } + aTime, err := utils.ParseTimeDetectLayout(attrs.AnswerTime, apier.Config.DefaultTimezone) + if err != nil { + return err + } + cd := &engine.CallDescriptor{ Direction: utils.OUT, Category: attrs.Category, Tenant: attrs.Tenant, Subject: attrs.Subject, Destination: attrs.Destination, - TimeStart: attrs.AnswerTime, - TimeEnd: attrs.AnswerTime.Add(usage), + TimeStart: aTime, + TimeEnd: aTime.Add(usage), DurationIndex: usage, } var cc engine.CallCost @@ -62,18 +67,22 @@ type AttrGetDataCost struct { Tenant string Category string Subject string - AnswerTime time.Time + AnswerTime string Usage time.Duration // the call duration so far (till TimeEnd) } func (apier *ApierV1) GetDataCost(attrs AttrGetDataCost, reply *engine.DataCost) error { + aTime, err := utils.ParseTimeDetectLayout(attrs.AnswerTime, apier.Config.DefaultTimezone) + if err != nil { + return err + } cd := &engine.CallDescriptor{ Direction: utils.OUT, Category: attrs.Category, Tenant: attrs.Tenant, Subject: attrs.Subject, - TimeStart: attrs.AnswerTime, - TimeEnd: attrs.AnswerTime.Add(attrs.Usage), + TimeStart: aTime, + TimeEnd: aTime.Add(attrs.Usage), DurationIndex: attrs.Usage, TOR: utils.DATA, } diff --git a/config/config_test.go b/config/config_test.go index d9fd1ec16..837fce17f 100755 --- a/config/config_test.go +++ b/config/config_test.go @@ -639,6 +639,7 @@ func TestCgrCfgJSONDefaultsCdreProfiles(t *testing.T) { Value: NewRSRParsersMustCompile("~Cost", true), RoundingDecimals: 4}, } + // eCdreCfg := map[string]*CdreConfig{ "*default": { ExportFormat: utils.MetaFileCSV, @@ -1548,6 +1549,97 @@ func TestCgrMigratorCfgDefault(t *testing.T) { } } +func TestCDRCWithDefault(t *testing.T) { + eCgrCfg, _ := NewDefaultCGRConfig() + eCgrCfg.CdrcProfiles["/var/spool/cgrates/cdrc/in"] = []*CdrcConfig{ + &CdrcConfig{ + ID: utils.META_DEFAULT, + Enabled: false, + DryRun: false, + CdrsConns: []*HaPoolConfig{&HaPoolConfig{Address: utils.MetaInternal}}, + CdrFormat: "csv", + FieldSeparator: rune(','), + DataUsageMultiplyFactor: 1024, + Timezone: "", + RunDelay: 0, + MaxOpenFiles: 1024, + CdrInDir: "/var/spool/cgrates/cdrc/in", + CdrOutDir: "/var/spool/cgrates/cdrc/out", + FailedCallsPrefix: "missed_calls", + CDRPath: utils.HierarchyPath([]string{""}), + CdrSourceId: "freeswitch_csv", + Filters: []string{}, + Tenant: NewRSRParsersMustCompile("cgrates.org", true), + ContinueOnSuccess: false, + PartialRecordCache: time.Duration(10 * time.Second), + PartialCacheExpiryAction: "*dump_to_file", + HeaderFields: make([]*FCTemplate, 0), + ContentFields: []*FCTemplate{ + &FCTemplate{ID: "TOR", FieldId: "ToR", Type: utils.META_COMPOSED, + Value: NewRSRParsersMustCompile("~2", true), Mandatory: true}, + &FCTemplate{ID: "OriginID", FieldId: "OriginID", Type: utils.META_COMPOSED, + Value: NewRSRParsersMustCompile("~3", true), Mandatory: true}, + &FCTemplate{ID: "RequestType", FieldId: "RequestType", Type: utils.META_COMPOSED, + Value: NewRSRParsersMustCompile("~4", true), Mandatory: true}, + &FCTemplate{ID: "Tenant", FieldId: "Tenant", Type: utils.META_COMPOSED, + Value: NewRSRParsersMustCompile("~6", true), Mandatory: true}, + &FCTemplate{ID: "Category", FieldId: "Category", Type: utils.META_COMPOSED, + Value: NewRSRParsersMustCompile("~7", true), Mandatory: true}, + &FCTemplate{ID: "Account", FieldId: "Account", Type: utils.META_COMPOSED, + Value: NewRSRParsersMustCompile("~8", true), Mandatory: true}, + &FCTemplate{ID: "Subject", FieldId: "Subject", Type: utils.META_COMPOSED, + Value: NewRSRParsersMustCompile("~9", true), Mandatory: true}, + &FCTemplate{ID: "Destination", FieldId: "Destination", Type: utils.META_COMPOSED, + Value: NewRSRParsersMustCompile("~10", true), Mandatory: true}, + &FCTemplate{ID: "SetupTime", FieldId: "SetupTime", Type: utils.META_COMPOSED, + Value: NewRSRParsersMustCompile("~11", true), Mandatory: true}, + &FCTemplate{ID: "AnswerTime", FieldId: "AnswerTime", Type: utils.META_COMPOSED, + Value: NewRSRParsersMustCompile("~12", true), Mandatory: true}, + &FCTemplate{ID: "Usage", FieldId: "Usage", Type: utils.META_COMPOSED, + Value: NewRSRParsersMustCompile("~13", true), Mandatory: true}, + }, + TrailerFields: make([]*FCTemplate, 0), + CacheDumpFields: []*FCTemplate{ + &FCTemplate{ID: "CGRID", Type: utils.META_COMPOSED, + Value: NewRSRParsersMustCompile(utils.DynamicDataPrefix+utils.CGRID, true)}, + &FCTemplate{ID: "RunID", Type: utils.META_COMPOSED, + Value: NewRSRParsersMustCompile(utils.DynamicDataPrefix+utils.RunID, true)}, + &FCTemplate{ID: "TOR", Type: utils.META_COMPOSED, + Value: NewRSRParsersMustCompile(utils.DynamicDataPrefix+utils.ToR, true)}, + &FCTemplate{ID: "OriginID", Type: utils.META_COMPOSED, + Value: NewRSRParsersMustCompile(utils.DynamicDataPrefix+utils.OriginID, true)}, + &FCTemplate{ID: "RequestType", Type: utils.META_COMPOSED, + Value: NewRSRParsersMustCompile(utils.DynamicDataPrefix+utils.RequestType, true)}, + &FCTemplate{ID: "Tenant", Type: utils.META_COMPOSED, + Value: NewRSRParsersMustCompile(utils.DynamicDataPrefix+utils.Tenant, true)}, + &FCTemplate{ID: "Category", Type: utils.META_COMPOSED, + Value: NewRSRParsersMustCompile(utils.DynamicDataPrefix+utils.Category, true)}, + &FCTemplate{ID: "Account", Type: utils.META_COMPOSED, + Value: NewRSRParsersMustCompile(utils.DynamicDataPrefix+utils.Account, true)}, + &FCTemplate{ID: "Subject", Type: utils.META_COMPOSED, + Value: NewRSRParsersMustCompile(utils.DynamicDataPrefix+utils.Subject, true)}, + &FCTemplate{ID: "Destination", Type: utils.META_COMPOSED, + Value: NewRSRParsersMustCompile(utils.DynamicDataPrefix+utils.Destination, true)}, + &FCTemplate{ID: "SetupTime", Type: utils.META_COMPOSED, + Value: NewRSRParsersMustCompile(utils.DynamicDataPrefix+utils.SetupTime, true), + Layout: "2006-01-02T15:04:05Z07:00"}, + &FCTemplate{ID: "AnswerTime", Type: utils.META_COMPOSED, + Value: NewRSRParsersMustCompile(utils.DynamicDataPrefix+utils.AnswerTime, true), + Layout: "2006-01-02T15:04:05Z07:00"}, + &FCTemplate{ID: "Usage", Type: utils.META_COMPOSED, + Value: NewRSRParsersMustCompile(utils.DynamicDataPrefix+utils.Usage, true)}, + &FCTemplate{ID: "Cost", Type: utils.META_COMPOSED, + Value: NewRSRParsersMustCompile(utils.DynamicDataPrefix+utils.COST, true)}, + }, + }, + } + if !reflect.DeepEqual(eCgrCfg.CdrcProfiles, cgrCfg.CdrcProfiles) { + t.Errorf("Expected: %+v,\n received: %+v", + utils.ToJSON(eCgrCfg.CdrcProfiles["/var/spool/cgrates/cdrc/in"][0]), + utils.ToJSON(cgrCfg.CdrcProfiles["/var/spool/cgrates/cdrc/in"][0])) + } +} + func TestCgrMigratorCfg2(t *testing.T) { JSN_CFG := ` { diff --git a/general_tests/tutorial_it_test.go b/general_tests/tutorial_it_test.go index 9adc2e6e9..48d7e44df 100644 --- a/general_tests/tutorial_it_test.go +++ b/general_tests/tutorial_it_test.go @@ -121,7 +121,7 @@ func testTutorialGetCost(t *testing.T) { Category: "call", Subject: "1001", Destination: "1002", - AnswerTime: time.Now(), + AnswerTime: "*now", Usage: "2m10s", } var rply *engine.EventCost