diff --git a/engine/cdr.go b/engine/cdr.go index 83870124a..b8447c31a 100644 --- a/engine/cdr.go +++ b/engine/cdr.go @@ -167,19 +167,6 @@ func (cdr *CDR) FieldsAsString(rsrFlds config.RSRParsers) string { return outVal } -// Used to retrieve fields as string, primary fields are const labeled -func (cdr *CDR) FieldAsStringWithRSRField(rsrFld *utils.RSRField) (parsed string, err error) { - if rsrFld.IsStatic() { // Static values do not care about headers - parsed, err = rsrFld.Parse("") - return - } - fldIface, err := utils.ReflectFieldInterface(cdr, rsrFld.Id, "ExtraFields") - if err != nil { - return "", err - } - return rsrFld.Parse(fldIface) -} - // Populates the field with id from value; strings are appended to original one func (cdr *CDR) ParseFieldValue(fieldId, fieldVal, timezone string) error { var err error @@ -274,147 +261,6 @@ func (cdr *CDR) AsMapStringIface() (mp map[string]interface{}) { return } -// Used in mediation, primaryMandatory marks whether missing field out of request represents error or can be ignored -func (cdr *CDR) ForkCdr(runId string, RequestTypeFld, tenantFld, - categFld, accountFld, subjectFld, destFld, setupTimeFld, - answerTimeFld, durationFld, ratedFld, costFld *utils.RSRField, - extraFlds []*utils.RSRField, primaryMandatory bool, timezone string) (*CDR, error) { - if RequestTypeFld == nil { - RequestTypeFld, _ = utils.NewRSRField(utils.META_DEFAULT) - } - if RequestTypeFld.Id == utils.META_DEFAULT { - RequestTypeFld.Id = utils.RequestType - } - if tenantFld == nil { - tenantFld, _ = utils.NewRSRField(utils.META_DEFAULT) - } - if tenantFld.Id == utils.META_DEFAULT { - tenantFld.Id = utils.Tenant - } - if categFld == nil { - categFld, _ = utils.NewRSRField(utils.META_DEFAULT) - } - if categFld.Id == utils.META_DEFAULT { - categFld.Id = utils.Category - } - if accountFld == nil { - accountFld, _ = utils.NewRSRField(utils.META_DEFAULT) - } - if accountFld.Id == utils.META_DEFAULT { - accountFld.Id = utils.Account - } - if subjectFld == nil { - subjectFld, _ = utils.NewRSRField(utils.META_DEFAULT) - } - if subjectFld.Id == utils.META_DEFAULT { - subjectFld.Id = utils.Subject - } - if destFld == nil { - destFld, _ = utils.NewRSRField(utils.META_DEFAULT) - } - if destFld.Id == utils.META_DEFAULT { - destFld.Id = utils.Destination - } - if setupTimeFld == nil { - setupTimeFld, _ = utils.NewRSRField(utils.META_DEFAULT) - } - if setupTimeFld.Id == utils.META_DEFAULT { - setupTimeFld.Id = utils.SetupTime - } - if answerTimeFld == nil { - answerTimeFld, _ = utils.NewRSRField(utils.META_DEFAULT) - } - if answerTimeFld.Id == utils.META_DEFAULT { - answerTimeFld.Id = utils.AnswerTime - } - if durationFld == nil { - durationFld, _ = utils.NewRSRField(utils.META_DEFAULT) - } - if durationFld.Id == utils.META_DEFAULT { - durationFld.Id = utils.Usage - } - if ratedFld == nil { - ratedFld, _ = utils.NewRSRField(utils.META_DEFAULT) - } - if ratedFld.Id == utils.META_DEFAULT { - ratedFld.Id = utils.PreRated - } - if costFld == nil { - costFld, _ = utils.NewRSRField(utils.META_DEFAULT) - } - if costFld.Id == utils.META_DEFAULT { - costFld.Id = utils.Cost - } - var err error - frkStorCdr := new(CDR) - frkStorCdr.CGRID = cdr.CGRID - frkStorCdr.ToR = cdr.ToR - frkStorCdr.RunID = runId - frkStorCdr.Cost = -1.0 // Default for non-rated CDR - frkStorCdr.OriginID = cdr.OriginID - frkStorCdr.OriginHost = cdr.OriginHost - frkStorCdr.Source = cdr.Source - frkStorCdr.RequestType, _ = cdr.FieldAsStringWithRSRField(RequestTypeFld) - if primaryMandatory && len(frkStorCdr.RequestType) == 0 { - return nil, utils.NewErrMandatoryIeMissing(utils.RequestType, RequestTypeFld.Id) - } - frkStorCdr.Tenant, _ = cdr.FieldAsStringWithRSRField(tenantFld) - if primaryMandatory && len(frkStorCdr.Tenant) == 0 { - return nil, utils.NewErrMandatoryIeMissing(utils.Tenant, tenantFld.Id) - } - frkStorCdr.Category, _ = cdr.FieldAsStringWithRSRField(categFld) - if primaryMandatory && len(frkStorCdr.Category) == 0 { - return nil, utils.NewErrMandatoryIeMissing(utils.Category, categFld.Id) - } - frkStorCdr.Account, _ = cdr.FieldAsStringWithRSRField(accountFld) - if primaryMandatory && len(frkStorCdr.Account) == 0 { - return nil, utils.NewErrMandatoryIeMissing(utils.Account, accountFld.Id) - } - frkStorCdr.Subject, _ = cdr.FieldAsStringWithRSRField(subjectFld) - if primaryMandatory && len(frkStorCdr.Subject) == 0 { - return nil, utils.NewErrMandatoryIeMissing(utils.Subject, subjectFld.Id) - } - frkStorCdr.Destination, _ = cdr.FieldAsStringWithRSRField(destFld) - if primaryMandatory && len(frkStorCdr.Destination) == 0 && frkStorCdr.ToR == utils.VOICE { - return nil, utils.NewErrMandatoryIeMissing(utils.Destination, destFld.Id) - } - sTimeStr, _ := cdr.FieldAsStringWithRSRField(setupTimeFld) - if primaryMandatory && len(sTimeStr) == 0 { - return nil, utils.NewErrMandatoryIeMissing(utils.SetupTime, setupTimeFld.Id) - } else if frkStorCdr.SetupTime, err = utils.ParseTimeDetectLayout(sTimeStr, timezone); err != nil { - return nil, err - } - aTimeStr, _ := cdr.FieldAsStringWithRSRField(answerTimeFld) - if primaryMandatory && len(aTimeStr) == 0 { - return nil, utils.NewErrMandatoryIeMissing(utils.AnswerTime, answerTimeFld.Id) - } else if frkStorCdr.AnswerTime, err = utils.ParseTimeDetectLayout(aTimeStr, timezone); err != nil { - return nil, err - } - durStr, _ := cdr.FieldAsStringWithRSRField(durationFld) - if primaryMandatory && len(durStr) == 0 { - return nil, utils.NewErrMandatoryIeMissing(utils.Usage, durationFld.Id) - } else if frkStorCdr.Usage, err = utils.ParseDurationWithNanosecs(durStr); err != nil { - return nil, err - } - ratedStr, _ := cdr.FieldAsStringWithRSRField(ratedFld) - if primaryMandatory && len(ratedStr) == 0 { - return nil, utils.NewErrMandatoryIeMissing(utils.PreRated, ratedFld.Id) - } else if frkStorCdr.PreRated, err = strconv.ParseBool(ratedStr); err != nil { - return nil, err - } - costStr, _ := cdr.FieldAsStringWithRSRField(costFld) - if primaryMandatory && len(costStr) == 0 { - return nil, utils.NewErrMandatoryIeMissing(utils.COST, costFld.Id) - } else if frkStorCdr.Cost, err = strconv.ParseFloat(costStr, 64); err != nil { - return nil, err - } - frkStorCdr.ExtraFields = make(map[string]string, len(extraFlds)) - for _, fld := range extraFlds { - frkStorCdr.ExtraFields[fld.Id], _ = cdr.FieldAsStringWithRSRField(fld) - } - return frkStorCdr, nil -} - func (cdr *CDR) AsExternalCDR() *ExternalCDR { var usageStr string switch cdr.ToR { diff --git a/engine/cdr_test.go b/engine/cdr_test.go index 268bd7850..d98d44ff9 100644 --- a/engine/cdr_test.go +++ b/engine/cdr_test.go @@ -370,123 +370,6 @@ func TestCDRAsHttpForm(t *testing.T) { } */ -func TestCDRForkCdr(t *testing.T) { - storCdr := CDR{CGRID: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC).String()), - OrderID: 123, ToR: utils.VOICE, OriginID: "dsafdsaf", OriginHost: "192.168.1.1", Source: utils.UNIT_TEST, - RequestType: utils.META_RATED, Tenant: "cgrates.org", Category: "call", Account: "1001", - Subject: "1001", Destination: "1002", RunID: utils.DEFAULT_RUNID, - SetupTime: time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC), - AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), - Usage: time.Duration(10) * time.Second, Cost: 1.01, - ExtraFields: map[string]string{"field_extr1": "val_extr1", "field_extr2": "valextr2"}} - rtSampleCdrOut, err := storCdr.ForkCdr("sample_run1", &utils.RSRField{Id: utils.RequestType}, &utils.RSRField{Id: utils.Tenant}, - &utils.RSRField{Id: utils.Category}, &utils.RSRField{Id: utils.Account}, &utils.RSRField{Id: utils.Subject}, &utils.RSRField{Id: utils.Destination}, - &utils.RSRField{Id: utils.SetupTime}, &utils.RSRField{Id: utils.AnswerTime}, &utils.RSRField{Id: utils.Usage}, - &utils.RSRField{Id: utils.PreRated}, &utils.RSRField{Id: utils.COST}, - []*utils.RSRField{&utils.RSRField{Id: "field_extr1"}, &utils.RSRField{Id: "field_extr2"}}, true, "") - if err != nil { - t.Error("Unexpected error received", err) - } - expctSplPreRatedCdr := &CDR{CGRID: storCdr.CGRID, ToR: utils.VOICE, OriginID: "dsafdsaf", - OriginHost: "192.168.1.1", Source: utils.UNIT_TEST, RequestType: utils.META_RATED, - Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", - SetupTime: time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC), - AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), - Usage: time.Duration(10) * time.Second, - ExtraFields: map[string]string{"field_extr1": "val_extr1", "field_extr2": "valextr2"}, - RunID: "sample_run1", PreRated: false, Cost: 1.01} - if !reflect.DeepEqual(expctSplPreRatedCdr, rtSampleCdrOut) { - t.Errorf("Expected: %v, received: %v", expctSplPreRatedCdr, rtSampleCdrOut) - } -} - -func TestCDRForkCdrStaticVals(t *testing.T) { - storCdr := CDR{ - CGRID: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC).String()), - OrderID: 123, ToR: utils.VOICE, OriginID: "dsafdsaf", - OriginHost: "192.168.1.1", Source: utils.UNIT_TEST, RequestType: utils.META_RATED, - Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", - SetupTime: time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC), - AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), RunID: utils.DEFAULT_RUNID, - Usage: time.Duration(10) * time.Second, Cost: 1.01, - ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, - } - rsrStPostpaid, _ := utils.NewRSRField("^" + utils.META_POSTPAID) - rsrStCgr, _ := utils.NewRSRField("^cgrates.com") - rsrStPC, _ := utils.NewRSRField("^premium_call") - rsrStFA, _ := utils.NewRSRField("^first_account") - rsrStFS, _ := utils.NewRSRField("^first_subject") - rsrStST, _ := utils.NewRSRField("^2013-12-07T08:42:24Z") - rsrStAT, _ := utils.NewRSRField("^2013-12-07T08:42:26Z") - rsrStDur, _ := utils.NewRSRField("^12s") - rsrStPreRated, _ := utils.NewRSRField("^true") - rsrStCost, _ := utils.NewRSRField("^1.2") - rtCdrOut2, err := storCdr.ForkCdr("wholesale_run", rsrStPostpaid, rsrStCgr, rsrStPC, rsrStFA, rsrStFS, &utils.RSRField{Id: utils.Destination}, - rsrStST, rsrStAT, rsrStDur, rsrStPreRated, rsrStCost, []*utils.RSRField{}, true, "") - if err != nil { - t.Error("Unexpected error received", err) - } - expctPreRatedCdr2 := &CDR{CGRID: storCdr.CGRID, ToR: utils.VOICE, OriginID: "dsafdsaf", - OriginHost: "192.168.1.1", Source: utils.UNIT_TEST, RequestType: utils.META_POSTPAID, - Tenant: "cgrates.com", Category: "premium_call", Account: "first_account", - Subject: "first_subject", Destination: "1002", - SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), - AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC), - Usage: time.Duration(12) * time.Second, PreRated: true, Cost: 1.2, - ExtraFields: map[string]string{}, RunID: "wholesale_run"} - if !reflect.DeepEqual(rtCdrOut2, expctPreRatedCdr2) { - t.Errorf("Received: %v, expected: %v", rtCdrOut2, expctPreRatedCdr2) - } - _, err = storCdr.ForkCdr("wholesale_run", &utils.RSRField{Id: "dummy_header"}, - &utils.RSRField{Id: utils.Tenant}, &utils.RSRField{Id: utils.ToR}, - &utils.RSRField{Id: utils.Account}, &utils.RSRField{Id: utils.Subject}, - &utils.RSRField{Id: utils.Destination}, &utils.RSRField{Id: utils.SetupTime}, - &utils.RSRField{Id: utils.AnswerTime}, &utils.RSRField{Id: utils.Usage}, - &utils.RSRField{Id: utils.PreRated}, &utils.RSRField{Id: utils.COST}, - []*utils.RSRField{}, true, "") - if err == nil { - t.Error("Failed to detect missing header") - } -} - -func TestCDRForkCdrFromMetaDefaults(t *testing.T) { - storCdr := CDR{CGRID: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC).String()), - OrderID: 123, ToR: utils.VOICE, OriginID: "dsafdsaf", OriginHost: "192.168.1.1", Source: utils.UNIT_TEST, - RequestType: utils.META_RATED, Tenant: "cgrates.org", Category: "call", - Account: "1001", Subject: "1001", Destination: "1002", RunID: utils.DEFAULT_RUNID, - SetupTime: time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC), - AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), - Usage: time.Duration(10) * time.Second, Cost: 1.01, - ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}, - } - expctCdr := &CDR{CGRID: storCdr.CGRID, ToR: utils.VOICE, OriginID: "dsafdsaf", - OriginHost: "192.168.1.1", Source: utils.UNIT_TEST, RequestType: utils.META_RATED, - Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002", - SetupTime: time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC), - AnswerTime: time.Date(2013, 11, 7, 8, 42, 26, 0, time.UTC), - Usage: time.Duration(10) * time.Second, Cost: 1.01, RunID: "wholesale_run", - ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"}} - cdrOut, err := storCdr.ForkCdr("wholesale_run", &utils.RSRField{Id: utils.META_DEFAULT}, &utils.RSRField{Id: utils.META_DEFAULT}, - &utils.RSRField{Id: utils.META_DEFAULT}, &utils.RSRField{Id: utils.META_DEFAULT}, &utils.RSRField{Id: utils.META_DEFAULT}, - &utils.RSRField{Id: utils.META_DEFAULT}, &utils.RSRField{Id: utils.META_DEFAULT}, &utils.RSRField{Id: utils.META_DEFAULT}, - &utils.RSRField{Id: utils.META_DEFAULT}, &utils.RSRField{Id: utils.META_DEFAULT}, &utils.RSRField{Id: utils.META_DEFAULT}, - []*utils.RSRField{&utils.RSRField{Id: "field_extr1"}, &utils.RSRField{Id: "fieldextr2"}}, true, "") - if err != nil { - t.Fatal("Unexpected error received", err) - } - - if !reflect.DeepEqual(expctCdr, cdrOut) { - t.Errorf("Expected: %v, received: %v", expctCdr, cdrOut) - } - // Should also accept nil as defaults - if cdrOut, err := storCdr.ForkCdr("wholesale_run", nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, - []*utils.RSRField{&utils.RSRField{Id: "field_extr1"}, &utils.RSRField{Id: "fieldextr2"}}, true, ""); err != nil { - t.Fatal("Unexpected error received", err) - } else if !reflect.DeepEqual(expctCdr, cdrOut) { - t.Errorf("Expected: %v, received: %v", expctCdr, cdrOut) - } -} - func TestCDRAsExternalCDR(t *testing.T) { storCdr := CDR{CGRID: utils.Sha1("dsafdsaf", time.Date(2013, 11, 7, 8, 42, 20, 0, time.UTC).String()), OrderID: 123, ToR: utils.VOICE, OriginID: "dsafdsaf", OriginHost: "192.168.1.1",