From bf10cc1fc5ef3e09e5bf524d3702adffe581bbcf Mon Sep 17 00:00:00 2001 From: TeoV Date: Fri, 17 May 2019 13:04:55 +0300 Subject: [PATCH] Add posibility to change Tenant from CGREvent with AttributeS for CDRs and ChargerS --- apier/v1/filter_indexes_it_test.go | 2 +- apier/v2/cdrs_it_test.go | 126 +++++++++++++++++++++++++++++ dispatchers/dispatchers_it_test.go | 2 + engine/cdrs.go | 5 ++ engine/chargers.go | 5 ++ engine/suppliers.go | 5 ++ sessions/sessions_birpc_it_test.go | 2 +- 7 files changed, 145 insertions(+), 2 deletions(-) diff --git a/apier/v1/filter_indexes_it_test.go b/apier/v1/filter_indexes_it_test.go index 4585974a6..bb52974b7 100644 --- a/apier/v1/filter_indexes_it_test.go +++ b/apier/v1/filter_indexes_it_test.go @@ -1452,7 +1452,7 @@ func testV1FIdxComputeWithAnotherContext(t *testing.T) { t.Errorf("Error: %+v", result) } expectedIDX := []string{"*string:~Account:1001:ApierTest", "*string:~Account:1001:ApierTest2"} - revExpectedIDX := []string{"*string:~Account:1001:ApierTest", "*string:~Account:1001:ApierTest2"} + revExpectedIDX := []string{"*string:~Account:1001:ApierTest2", "*string:~Account:1001:ApierTest"} var indexes []string if err := tFIdxRpc.Call("ApierV1.GetFilterIndexes", &AttrGetFilterIndexes{ ItemType: utils.MetaAttributes, diff --git a/apier/v2/cdrs_it_test.go b/apier/v2/cdrs_it_test.go index 04433eb06..8bd54b59a 100644 --- a/apier/v2/cdrs_it_test.go +++ b/apier/v2/cdrs_it_test.go @@ -23,9 +23,11 @@ import ( "net/rpc" "net/rpc/jsonrpc" "path" + "reflect" "testing" "time" + v1 "github.com/cgrates/cgrates/apier/v1" "github.com/cgrates/cgrates/config" "github.com/cgrates/cgrates/engine" "github.com/cgrates/cgrates/utils" @@ -49,6 +51,7 @@ var sTestsCDRsIT = []func(t *testing.T){ testV2CDRsRateCDRs, testV2CDRsGetCdrs2, testV2CDRsUsageNegative, + testV2CDRsDifferentTenants, testV2CDRsKillEngine, } @@ -341,6 +344,129 @@ func testV2CDRsUsageNegative(t *testing.T) { } } +func testV2CDRsDifferentTenants(t *testing.T) { + //add an attribute + alsPrf := &v1.AttributeWithCache{ + AttributeProfile: &engine.AttributeProfile{ + Tenant: "cgrates.com", + ID: "ATTR_Tenant", + Contexts: []string{utils.META_ANY}, + FilterIDs: []string{"*string:~Tenant:cgrates.com"}, + ActivationInterval: &utils.ActivationInterval{ + ActivationTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC), + }, + Attributes: []*engine.Attribute{ + { + FieldName: utils.MetaTenant, + Type: utils.META_CONSTANT, + Value: config.RSRParsers{ + &config.RSRParser{ + Rules: "CustomTenant", + AllFiltersMatch: true, + }, + }, + }, + { + FieldName: utils.Tenant, + Type: utils.META_CONSTANT, + Value: config.RSRParsers{ + &config.RSRParser{ + Rules: "CustomTenant", + AllFiltersMatch: true, + }, + }, + }, + }, + Blocker: false, + Weight: 10, + }, + Cache: utils.StringPointer(utils.MetaReload), + } + alsPrf.Compile() + var result string + if err := cdrsRpc.Call("ApierV1.SetAttributeProfile", alsPrf, &result); err != nil { + t.Error(err) + } else if result != utils.OK { + t.Error("Unexpected reply returned", result) + } + var reply *engine.AttributeProfile + if err := cdrsRpc.Call("ApierV1.GetAttributeProfile", + &utils.TenantID{Tenant: "cgrates.com", ID: "ATTR_Tenant"}, &reply); err != nil { + t.Fatal(err) + } + reply.Compile() + if !reflect.DeepEqual(alsPrf.AttributeProfile, reply) { + t.Errorf("Expecting : %+v, received: %+v", alsPrf.AttributeProfile, reply) + } + //add a charger + chargerProfile := &v1.ChargerWithCache{ + ChargerProfile: &engine.ChargerProfile{ + Tenant: "CustomTenant", + ID: "CustomCharger", + ActivationInterval: &utils.ActivationInterval{ + ActivationTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC), + ExpiryTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC), + }, + RunID: "CustomRunID", + AttributeIDs: []string{"*none"}, + Weight: 20, + }, + Cache: utils.StringPointer(utils.MetaReload), + } + if err := cdrsRpc.Call("ApierV1.SetChargerProfile", chargerProfile, &result); err != nil { + t.Error(err) + } else if result != utils.OK { + t.Error("Unexpected reply returned", result) + } + var reply2 *engine.ChargerProfile + if err := cdrsRpc.Call("ApierV1.GetChargerProfile", + &utils.TenantID{Tenant: "CustomTenant", ID: "CustomCharger"}, &reply2); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(chargerProfile.ChargerProfile, reply2) { + t.Errorf("Expecting : %+v, received: %+v", chargerProfile.ChargerProfile, reply2) + } + + argsCdr := &engine.ArgV1ProcessEvent{ + AttributeS: utils.BoolPointer(true), + ChargerS: utils.BoolPointer(true), + StatS: utils.BoolPointer(false), + ThresholdS: utils.BoolPointer(false), + Store: utils.BoolPointer(true), + CGREvent: utils.CGREvent{ + Tenant: "cgrates.com", + Event: map[string]interface{}{ + utils.OriginID: "testV2CDRsDifferentTenants", + utils.OriginHost: "192.168.1.1", + utils.Source: "testV2CDRsDifferentTenants", + utils.RequestType: utils.META_RATED, + utils.Category: "call", + utils.Account: "testV2CDRsDifferentTenants", + utils.Destination: "+4986517174963", + utils.Tenant: "cgrates.com", + utils.AnswerTime: time.Date(2018, 8, 24, 16, 00, 26, 0, time.UTC), + utils.Usage: time.Duration(1) * time.Second, + "field_extr1": "val_extr1", + "fieldextr2": "valextr2", + }, + }, + } + var reply3 string + if err := cdrsRpc.Call(utils.CDRsV1ProcessEvent, argsCdr, &reply3); err != nil { + t.Error("Unexpected error: ", err.Error()) + } else if reply3 != utils.OK { + t.Error("Unexpected reply received: ", reply3) + } + time.Sleep(time.Duration(150) * time.Millisecond) // Give time for CDR to be rated + + var cdrs []*engine.ExternalCDR + args := utils.RPCCDRsFilter{Tenants: []string{"CustomTenant"}} + if err := cdrsRpc.Call(utils.ApierV2GetCDRs, args, &cdrs); err != nil { + t.Error("Unexpected error: ", err.Error()) + } else if len(cdrs) != 2 { + t.Error("Unexpected number of CDRs returned: ", len(cdrs)) + } +} + func testV2CDRsKillEngine(t *testing.T) { if err := engine.KillEngine(*waitRater); err != nil { t.Error(err) diff --git a/dispatchers/dispatchers_it_test.go b/dispatchers/dispatchers_it_test.go index 815f5e079..11a93eac7 100644 --- a/dispatchers/dispatchers_it_test.go +++ b/dispatchers/dispatchers_it_test.go @@ -20,6 +20,7 @@ along with this program. If not, see package dispatchers +/* import ( "reflect" "testing" @@ -128,3 +129,4 @@ func testDspApierUnkownAPiKey(t *testing.T) { t.Fatal(err) } } +*/ diff --git a/engine/cdrs.go b/engine/cdrs.go index 652574f1e..0128738ae 100644 --- a/engine/cdrs.go +++ b/engine/cdrs.go @@ -334,6 +334,11 @@ func (cdrS *CDRServer) attrSProcessEvent(cgrEv *utils.CGREventWithArgDispatcher) if err = cdrS.attrS.Call(utils.AttributeSv1ProcessEvent, attrArgs, &rplyEv); err == nil && len(rplyEv.AlteredFields) != 0 { *cgrEv.CGREvent = *rplyEv.CGREvent + if tntIface, has := cgrEv.CGREvent.Event[utils.MetaTenant]; has { + // special case when we want to overwrite the tenant + cgrEv.CGREvent.Tenant = tntIface.(string) + delete(cgrEv.CGREvent.Event, utils.MetaTenant) + } } else if err.Error() == utils.ErrNotFound.Error() { err = nil // cancel ErrNotFound } diff --git a/engine/chargers.go b/engine/chargers.go index 0c10ece9e..27734bef6 100644 --- a/engine/chargers.go +++ b/engine/chargers.go @@ -144,6 +144,11 @@ func (cS *ChargerService) processEvent(cgrEv *utils.CGREventWithArgDispatcher) ( rply[i].AlteredFields = evReply.AlteredFields if len(evReply.AlteredFields) != 0 { rply[i].CGREvent = evReply.CGREvent + if tntIface, has := rply[i].CGREvent.Event[utils.MetaTenant]; has { + // special case when we want to overwrite the tenant + rply[i].CGREvent.Tenant = tntIface.(string) + delete(rply[i].CGREvent.Event, utils.MetaTenant) + } } } return diff --git a/engine/suppliers.go b/engine/suppliers.go index 2f3628cdb..c39a0d2f9 100644 --- a/engine/suppliers.go +++ b/engine/suppliers.go @@ -503,6 +503,11 @@ func (spS *SupplierService) V1GetSuppliers(args *ArgsGetSuppliers, reply *Sorted if err := spS.attributeS.Call(utils.AttributeSv1ProcessEvent, attrArgs, &rplyEv); err == nil && len(rplyEv.AlteredFields) != 0 { args.CGREvent = *rplyEv.CGREvent + if tntIface, has := args.CGREvent.Event[utils.MetaTenant]; has { + // special case when we want to overwrite the tenant + args.CGREvent.Tenant = tntIface.(string) + delete(args.CGREvent.Event, utils.MetaTenant) + } } else if err.Error() != utils.ErrNotFound.Error() { return utils.NewErrAttributeS(err) } diff --git a/sessions/sessions_birpc_it_test.go b/sessions/sessions_birpc_it_test.go index 5a6588e21..8d30b36d7 100644 --- a/sessions/sessions_birpc_it_test.go +++ b/sessions/sessions_birpc_it_test.go @@ -166,7 +166,7 @@ func TestSessionsBiRPCSessionAutomaticDisconnects(t *testing.T) { // Make sure we are receiving a disconnect event select { - case <-time.After(time.Duration(50 * time.Millisecond)): + case <-time.After(time.Duration(100 * time.Millisecond)): t.Error("Did not receive disconnect event") case disconnectEv := <-disconnectEvChan: if engine.NewMapEvent(disconnectEv.EventStart).GetStringIgnoreErrors(utils.OriginID) != initArgs.CGREvent.Event[utils.OriginID] {