diff --git a/apier/v1/routes_it_test.go b/apier/v1/routes_it_test.go index 48c7f5f18..9d73fce93 100644 --- a/apier/v1/routes_it_test.go +++ b/apier/v1/routes_it_test.go @@ -1110,15 +1110,22 @@ func testV1RouteGetRouteForEvent(t *testing.T) { t.Errorf("Expected: %s ,received: %s", utils.ToJSON(expected), utils.ToJSON(supProf)) } + supProf = nil ev.CGREvent.Tenant = utils.EmptyString if err := routeSv1Rpc.Call(utils.RouteSv1GetRouteProfilesForEvent, ev, &supProf); err != nil { t.Fatal(err) } sort.Slice(expected.Routes, func(i, j int) bool { + if expected.Routes[i].ID != expected.Routes[j].ID { + return expected.Routes[i].ID < expected.Routes[j].ID + } return expected.Routes[i].Weight < expected.Routes[j].Weight }) sort.Slice(supProf[0].Routes, func(i, j int) bool { + if supProf[0].Routes[i].ID != supProf[0].Routes[j].ID { + return supProf[0].Routes[i].ID < supProf[0].Routes[j].ID + } return supProf[0].Routes[i].Weight < supProf[0].Routes[j].Weight }) if !reflect.DeepEqual(&expected, supProf[0]) { @@ -1410,7 +1417,7 @@ func testV1RouteAccountWithRatingPlan(t *testing.T) { RouteID: "RouteWithAccAndRP", SortingData: map[string]interface{}{ utils.Account: "AccWithVoice", - "Cost": 0.0, + utils.Cost: 0.0, "MaxUsage": 30000000000.0, utils.Weight: 20.0, }, @@ -1425,6 +1432,27 @@ func testV1RouteAccountWithRatingPlan(t *testing.T) { }, }, } + if *encoding == utils.MetaGOB { + eSpls.SortedRoutes = []*engine.SortedRoute{ + { + RouteID: "RouteWithAccAndRP", + SortingData: map[string]interface{}{ + utils.Account: "AccWithVoice", + utils.Cost: 0., + "MaxUsage": 30 * time.Second, + utils.Weight: 20., + }, + }, + { + RouteID: "RouteWithRP", + SortingData: map[string]interface{}{ + utils.Cost: 0.3, + "RatingPlanID": "RP_ANY1CNT_SEC", + utils.Weight: 10., + }, + }, + } + } var suplsReply *engine.SortedRoutes if err := routeSv1Rpc.Call(utils.RouteSv1GetRoutes, ev, &suplsReply); err != nil { @@ -1461,7 +1489,7 @@ func testV1RouteAccountWithRatingPlan(t *testing.T) { RouteID: "RouteWithAccAndRP", SortingData: map[string]interface{}{ utils.Account: "AccWithVoice", - "Cost": 0.6, + utils.Cost: 0.6, "MaxUsage": 30000000000.0, "RatingPlanID": "RP_ANY2CNT_SEC", utils.Weight: 20.0, @@ -1470,13 +1498,35 @@ func testV1RouteAccountWithRatingPlan(t *testing.T) { { RouteID: "RouteWithRP", SortingData: map[string]interface{}{ - "Cost": 0.6, + utils.Cost: 0.6, "RatingPlanID": "RP_ANY1CNT_SEC", utils.Weight: 10.0, }, }, }, } + if *encoding == utils.MetaGOB { + eSpls.SortedRoutes = []*engine.SortedRoute{ + { + RouteID: "RouteWithAccAndRP", + SortingData: map[string]interface{}{ + utils.Account: "AccWithVoice", + utils.Cost: 0.6, + "MaxUsage": 30 * time.Second, + "RatingPlanID": "RP_ANY2CNT_SEC", + utils.Weight: 20., + }, + }, + { + RouteID: "RouteWithRP", + SortingData: map[string]interface{}{ + utils.Cost: 0.6, + "RatingPlanID": "RP_ANY1CNT_SEC", + utils.Weight: 10., + }, + }, + } + } var routeRply *engine.SortedRoutes if err := routeSv1Rpc.Call(utils.RouteSv1GetRoutes, ev, &routeRply); err != nil { @@ -1512,7 +1562,7 @@ func testV1RouteAccountWithRatingPlan(t *testing.T) { { RouteID: "RouteWithRP", SortingData: map[string]interface{}{ - "Cost": 0.61, + utils.Cost: 0.61, "RatingPlanID": "RP_ANY1CNT_SEC", utils.Weight: 10.0, }, @@ -1521,7 +1571,7 @@ func testV1RouteAccountWithRatingPlan(t *testing.T) { RouteID: "RouteWithAccAndRP", SortingData: map[string]interface{}{ utils.Account: "AccWithVoice", - "Cost": 0.62, + utils.Cost: 0.62, "MaxUsage": 30000000000.0, "RatingPlanID": "RP_ANY2CNT_SEC", utils.Weight: 20.0, @@ -1529,6 +1579,28 @@ func testV1RouteAccountWithRatingPlan(t *testing.T) { }, }, } + if *encoding == utils.MetaGOB { + eSpls.SortedRoutes = []*engine.SortedRoute{ + { + RouteID: "RouteWithRP", + SortingData: map[string]interface{}{ + utils.Cost: 0.61, + "RatingPlanID": "RP_ANY1CNT_SEC", + utils.Weight: 10., + }, + }, + { + RouteID: "RouteWithAccAndRP", + SortingData: map[string]interface{}{ + utils.Account: "AccWithVoice", + utils.Cost: 0.62, + "MaxUsage": 30 * time.Second, + "RatingPlanID": "RP_ANY2CNT_SEC", + utils.Weight: 20., + }, + }, + } + } var routeRply2 *engine.SortedRoutes if err := routeSv1Rpc.Call(utils.RouteSv1GetRoutes, ev, &routeRply2); err != nil { diff --git a/apier/v1/routes_with_rates_it_test.go b/apier/v1/routes_with_rates_it_test.go index 590c7607b..05d1b19c3 100644 --- a/apier/v1/routes_with_rates_it_test.go +++ b/apier/v1/routes_with_rates_it_test.go @@ -266,6 +266,9 @@ func testV1RouteSWithRateSAccountWithRateProfile(t *testing.T) { }, }, } + if *encoding == utils.MetaGOB { + eSpls.SortedRoutes[0].SortingData[utils.CapMaxUsage] = 30 * time.Second + } var suplsReply *engine.SortedRoutes if err := routeSv1Rpc.Call(utils.RouteSv1GetRoutes, ev, &suplsReply); err != nil { @@ -318,6 +321,9 @@ func testV1RouteSWithRateSAccountWithRateProfile(t *testing.T) { }, }, } + if *encoding == utils.MetaGOB { + eSpls.SortedRoutes[0].SortingData[utils.CapMaxUsage] = 30 * time.Second + } var routeRply *engine.SortedRoutes if err := routeSv1Rpc.Call(utils.RouteSv1GetRoutes, ev, &routeRply); err != nil { @@ -370,6 +376,9 @@ func testV1RouteSWithRateSAccountWithRateProfile(t *testing.T) { }, }, } + if *encoding == utils.MetaGOB { + eSpls.SortedRoutes[1].SortingData[utils.CapMaxUsage] = 30 * time.Second + } var routeRply2 *engine.SortedRoutes if err := routeSv1Rpc.Call(utils.RouteSv1GetRoutes, ev, &routeRply2); err != nil { diff --git a/apier/v1/thresholds_it_test.go b/apier/v1/thresholds_it_test.go index d637783dd..464df6a30 100644 --- a/apier/v1/thresholds_it_test.go +++ b/apier/v1/thresholds_it_test.go @@ -971,6 +971,7 @@ func testV1TSResetThresholdsWithoutTenant(t *testing.T) { t.Errorf("Expected %+v \n, received %+v", utils.OK, result) } expectedThreshold.Hits = 0 + reply = nil if err := tSv1Rpc.Call(utils.ThresholdSv1GetThreshold, &utils.TenantIDWithOpts{TenantID: &utils.TenantID{ID: "THD_ACNT_BALANCE_1"}}, &reply); err != nil { diff --git a/data/conf/samples/cdrsv2internal_gob/cgrates.json b/data/conf/samples/cdrsv2internal_gob/cgrates.json new file mode 100644 index 000000000..e95d792a0 --- /dev/null +++ b/data/conf/samples/cdrsv2internal_gob/cgrates.json @@ -0,0 +1,69 @@ +{ +// CGRateS Configuration file +// +// Used in apier_local_tests +// Starts rater, cdrs and mediator connecting over internal channel + +"general": { + "log_level": 7, +}, + +"stor_db": { + "db_type": "*internal", + "string_indexed_fields": ["RunID"] +}, + +"rpc_conns": { + "conn1": { + "strategy": "*first", + "conns": [{"address": "127.0.0.1:2013", "transport":"*gob"}], + }, +}, + +"rals": { + "enabled": true, + "thresholds_conns": ["conn1"], + "dynaprepaid_actionplans": ["PACKAGE_1001"], +}, + +"schedulers": { + "enabled": true, + "thresholds_conns": ["conn1"], +}, + +"cdrs": { + "enabled": true, + "attributes_conns":["*internal"], + "chargers_conns":["conn1"], + "rals_conns": ["conn1"], + "stats_conns": ["conn1"], + "thresholds_conns": ["conn1"], + "scheduler_conns": ["conn1"], +}, + +"attributes": { + "enabled": true, +}, + +"stats": { + "enabled": true, + "store_interval": "1s", + "thresholds_conns": ["*internal"], +}, + +"thresholds": { + "enabled": true, + "store_interval": "1s", +}, + +"chargers": { + "enabled": true, + "attributes_conns": ["*internal"], +}, + +"apiers": { + "enabled": true, + "scheduler_conns": ["*internal"], +}, + +} diff --git a/engine/caches.go b/engine/caches.go index 1f09e427e..5c6255d9b 100644 --- a/engine/caches.go +++ b/engine/caches.go @@ -92,6 +92,7 @@ func init() { gob.Register(time.Time{}) gob.Register(url.Values{}) gob.Register(json.RawMessage{}) + gob.Register(BalanceSummaries{}) } //SetCache shared the cache from other subsystems @@ -440,6 +441,11 @@ func (chS *CacheS) ReplicateSet(chID, itmID string, value interface{}) (err erro // V1ReplicateSet replicate an item func (chS *CacheS) V1ReplicateSet(args *utils.ArgCacheReplicateSet, reply *string) (err error) { + if cmp, canCast := args.Value.(utils.Compiler); canCast { + if err = cmp.Compile(); err != nil { + return + } + } chS.tCache.Set(args.CacheID, args.ItemID, args.Value, nil, true, utils.EmptyString) *reply = utils.OK return diff --git a/engine/eventcost.go b/engine/eventcost.go index 64c4704f0..e6d83a7ed 100644 --- a/engine/eventcost.go +++ b/engine/eventcost.go @@ -901,6 +901,9 @@ func (ec *EventCost) FieldAsInterface(fldPath []string) (val interface{}, err er if len(fldPath) == 0 { return nil, utils.ErrNotFound } + if ec.cache == nil { + ec.cache = utils.MapStorage{} // fix gob deserialization + } if val, err = ec.cache.FieldAsInterface(fldPath); err != nil { if err != utils.ErrNotFound { // item found in cache return @@ -958,12 +961,18 @@ func (ec *EventCost) fieldAsInterface(fldPath []string) (val interface{}, err er if len(fldPath) != 1 { return nil, utils.ErrNotFound } - return ec.Usage, nil + if ec.Usage == nil { + return nil, nil + } + return *ec.Usage, nil case utils.Cost: if len(fldPath) != 1 { return nil, utils.ErrNotFound } - return ec.Cost, nil + if ec.Cost == nil { + return nil, nil + } + return *ec.Cost, nil case utils.AccountSummary: if len(fldPath) == 1 { return ec.AccountSummary, nil diff --git a/engine/eventcost_test.go b/engine/eventcost_test.go index 08cf876d6..e0e3c8f98 100644 --- a/engine/eventcost_test.go +++ b/engine/eventcost_test.go @@ -2714,8 +2714,8 @@ func TestEventCostfieldAsInterface(t *testing.T) { } if rcv, err := eventCost.fieldAsInterface([]string{utils.Usage}); err != nil { t.Error(err) - } else if !reflect.DeepEqual(utils.DurationPointer(5*time.Minute), rcv) { - t.Errorf("Expecting: %+v, received: %+v", utils.DurationPointer(5*time.Minute), rcv) + } else if !reflect.DeepEqual(5*time.Minute, rcv) { + t.Errorf("Expecting: %+v, received: %+v", 5*time.Minute, rcv) } // case utils.Cost: if rcv, err := eventCost.fieldAsInterface([]string{utils.Cost, utils.Cost}); err == nil || err != utils.ErrNotFound { @@ -2728,8 +2728,8 @@ func TestEventCostfieldAsInterface(t *testing.T) { } if rcv, err := eventCost.fieldAsInterface([]string{utils.Cost}); err != nil { t.Error(err) - } else if !reflect.DeepEqual(utils.Float64Pointer(0.7), rcv) { - t.Errorf("Expecting: %+v, received: %+v", utils.Float64Pointer(0.7), rcv) + } else if !reflect.DeepEqual(0.7, rcv) { + t.Errorf("Expecting: %+v, received: %+v", 0.7, rcv) } // case utils.AccountSummary: eventCost = &EventCost{ diff --git a/engine/storage_internal_stordb.go b/engine/storage_internal_stordb.go index bb2365af4..e5340a35c 100644 --- a/engine/storage_internal_stordb.go +++ b/engine/storage_internal_stordb.go @@ -592,11 +592,11 @@ func (iDB *InternalDB) RemTpData(table, tpid string, args map[string]string) (er } key := tpid if args != nil { - if tpid == utils.TBLTPAccountActions { + if table == utils.TBLTPAccountActions { key += utils.CONCATENATED_KEY_SEP + args["loadid"] + utils.CONCATENATED_KEY_SEP + args["tenant"] + utils.CONCATENATED_KEY_SEP + args["account"] - } else if tpid == utils.TBLTPRatingProfiles { + } else if table == utils.TBLTPRatingProfiles { key += utils.CONCATENATED_KEY_SEP + args["loadid"] + utils.CONCATENATED_KEY_SEP + args["tenant"] + utils.CONCATENATED_KEY_SEP + args["category"] + diff --git a/general_tests/cdrs_exp_it_test.go b/general_tests/cdrs_exp_it_test.go index fc065233d..d58075810 100644 --- a/general_tests/cdrs_exp_it_test.go +++ b/general_tests/cdrs_exp_it_test.go @@ -37,6 +37,7 @@ import ( "testing" "time" + v1 "github.com/cgrates/cgrates/apier/v1" "github.com/cgrates/cgrates/config" "github.com/cgrates/cgrates/engine" "github.com/cgrates/cgrates/utils" @@ -222,12 +223,14 @@ func testCDRsExpInitRPC(t *testing.T) { func testCDRsExpLoadAddCharger(t *testing.T) { // //add a default charger - chargerProfile := &engine.ChargerProfile{ - Tenant: "cgrates.org", - ID: "*raw", - RunID: utils.MetaRaw, - AttributeIDs: []string{"*constant:*opts.AddOrderID:true"}, - Weight: 20, + chargerProfile := &v1.ChargerWithCache{ + ChargerProfile: &engine.ChargerProfile{ + Tenant: "cgrates.org", + ID: "*raw", + RunID: utils.MetaRaw, + AttributeIDs: []string{"*constant:*opts.AddOrderID:true"}, + Weight: 20, + }, } var result string if err := cdrsExpRPC.Call(utils.APIerSv1SetChargerProfile, chargerProfile, &result); err != nil { diff --git a/general_tests/rpccaching_it_test.go b/general_tests/rpccaching_it_test.go index 6d1ee5d87..b2786cbd1 100644 --- a/general_tests/rpccaching_it_test.go +++ b/general_tests/rpccaching_it_test.go @@ -547,23 +547,21 @@ func testRPCMethodsTerminateSession(t *testing.T) { } func testRPCMethodsProcessCDR(t *testing.T) { - args := &engine.ThresholdsArgsProcessEvent{ - CGREventWithOpts: &utils.CGREventWithOpts{ - CGREvent: &utils.CGREvent{ - Tenant: "cgrates.org", - ID: "testRPCMethodsProcessCDR", - Event: map[string]interface{}{ - utils.Tenant: "cgrates.org", - utils.ToR: utils.VOICE, - utils.OriginID: "testRPCMethodsProcessCDR", - utils.RequestType: utils.META_PREPAID, - utils.Account: "1001", - utils.Subject: "ANY2CNT", - utils.Destination: "1002", - utils.SetupTime: time.Date(2018, time.January, 7, 16, 60, 0, 0, time.UTC), - utils.AnswerTime: time.Date(2018, time.January, 7, 16, 60, 10, 0, time.UTC), - utils.Usage: 10 * time.Minute, - }, + args := &utils.CGREventWithOpts{ + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "testRPCMethodsProcessCDR", + Event: map[string]interface{}{ + utils.Tenant: "cgrates.org", + utils.ToR: utils.VOICE, + utils.OriginID: "testRPCMethodsProcessCDR", + utils.RequestType: utils.META_PREPAID, + utils.Account: "1001", + utils.Subject: "ANY2CNT", + utils.Destination: "1002", + utils.SetupTime: time.Date(2018, time.January, 7, 16, 60, 0, 0, time.UTC), + utils.AnswerTime: time.Date(2018, time.January, 7, 16, 60, 10, 0, time.UTC), + utils.Usage: 10 * time.Minute, }, }, } @@ -720,21 +718,25 @@ func testRPCMethodsProcessEvent(t *testing.T) { } func testRPCMethodsCdrsProcessCDR(t *testing.T) { - args := utils.CGREvent{ - Tenant: "cgrates.org", - ID: "testRPCMethodsCdrsProcessCDR", - Event: map[string]interface{}{ - utils.Tenant: "cgrates.org", - utils.ToR: utils.VOICE, - utils.OriginHost: "host", - utils.OriginID: "testRPCMethodsCdrsProcessCDR", - utils.RequestType: utils.META_PREPAID, - utils.Account: "1001", - utils.Subject: "ANY2CNT", - utils.Destination: "1002", - utils.SetupTime: time.Date(2018, time.January, 7, 16, 60, 0, 0, time.UTC), - utils.AnswerTime: time.Date(2018, time.January, 7, 16, 60, 10, 0, time.UTC), - utils.Usage: 10 * time.Minute, + args := &engine.ArgV1ProcessEvent{ + CGREventWithOpts: utils.CGREventWithOpts{ + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "testRPCMethodsCdrsProcessCDR", + Event: map[string]interface{}{ + utils.Tenant: "cgrates.org", + utils.ToR: utils.VOICE, + utils.OriginHost: "host", + utils.OriginID: "testRPCMethodsCdrsProcessCDR", + utils.RequestType: utils.META_PREPAID, + utils.Account: "1001", + utils.Subject: "ANY2CNT", + utils.Destination: "1002", + utils.SetupTime: time.Date(2018, time.January, 7, 16, 60, 0, 0, time.UTC), + utils.AnswerTime: time.Date(2018, time.January, 7, 16, 60, 10, 0, time.UTC), + utils.Usage: 10 * time.Minute, + }, + }, }, } diff --git a/general_tests/session3_it_test.go b/general_tests/session3_it_test.go index 64fd237fc..139a31716 100644 --- a/general_tests/session3_it_test.go +++ b/general_tests/session3_it_test.go @@ -391,24 +391,22 @@ func testSes3ItBalance(t *testing.T) { func testSes3ItCDRs(t *testing.T) { var reply string - if err := ses3RPC.Call(utils.SessionSv1ProcessCDR, &engine.ThresholdsArgsProcessEvent{ - CGREventWithOpts: &utils.CGREventWithOpts{ - CGREvent: &utils.CGREvent{ - Tenant: "cgrates.org", - ID: "TestSesItProccesCDR", - Event: map[string]interface{}{ - utils.Tenant: "cgrates.org", - utils.Category: "call", - utils.ToR: utils.VOICE, - utils.OriginID: "TestTerminate", - utils.RequestType: utils.META_PREPAID, - utils.Account: "1002", - utils.Subject: "1001", - utils.Destination: "1001", - utils.SetupTime: time.Date(2018, time.January, 7, 16, 60, 0, 0, time.UTC), - utils.AnswerTime: time.Date(2018, time.January, 7, 16, 60, 10, 0, time.UTC), - utils.Usage: 2 * time.Second, - }, + if err := ses3RPC.Call(utils.SessionSv1ProcessCDR, &utils.CGREventWithOpts{ + CGREvent: &utils.CGREvent{ + Tenant: "cgrates.org", + ID: "TestSesItProccesCDR", + Event: map[string]interface{}{ + utils.Tenant: "cgrates.org", + utils.Category: "call", + utils.ToR: utils.VOICE, + utils.OriginID: "TestTerminate", + utils.RequestType: utils.META_PREPAID, + utils.Account: "1002", + utils.Subject: "1001", + utils.Destination: "1001", + utils.SetupTime: time.Date(2018, time.January, 7, 16, 60, 0, 0, time.UTC), + utils.AnswerTime: time.Date(2018, time.January, 7, 16, 60, 10, 0, time.UTC), + utils.Usage: 2 * time.Second, }, }, }, &reply); err != nil { diff --git a/utils/apitpdata.go b/utils/apitpdata.go index 56b68ee6d..8d9c7eb2d 100755 --- a/utils/apitpdata.go +++ b/utils/apitpdata.go @@ -1427,6 +1427,11 @@ type ArgCacheReplicateSet struct { Tenant string } +// Compiler are objects that need post compiling +type Compiler interface { + Compile() error +} + type ArgCacheReplicateRemove struct { CacheID string ItemID string