From 6d091ea30eaca349c91460da6fe3b59aec4e99cf Mon Sep 17 00:00:00 2001 From: ionutboangiu Date: Thu, 26 Aug 2021 10:28:13 +0300 Subject: [PATCH] Add default_opts for attributes --- accounts/libaccounts.go | 7 -- apis/attributes_it_test.go | 4 - apis/config_test.go | 16 ++- changelog | 223 ++++++++++++++++++++++++++++++++++- config/attributescfg.go | 18 ++- config/attributescfg_test.go | 40 +++++-- config/config_defaults.go | 5 +- config/config_it_test.go | 2 - config/config_json_test.go | 6 +- config/config_test.go | 78 ++++++------ config/configsanity.go | 6 +- config/configsanity_test.go | 6 +- ees/ees.go | 7 -- engine/attributes.go | 20 ++-- engine/attributes_test.go | 40 +++++-- engine/cdrs.go | 9 +- engine/chargers.go | 7 -- engine/routes.go | 13 +- engine/z_attributes_test.go | 77 +++++------- sessions/sessions.go | 7 -- 20 files changed, 392 insertions(+), 199 deletions(-) mode change 120000 => 100644 changelog diff --git a/accounts/libaccounts.go b/accounts/libaccounts.go index 7fa3ac2bb..9c492614b 100644 --- a/accounts/libaccounts.go +++ b/accounts/libaccounts.go @@ -97,19 +97,12 @@ func processAttributeS(ctx *context.Context, connMgr *engine.ConnManager, cgrEv if len(attrSConns) == 0 { return nil, utils.NewErrNotConnected(utils.AttributeS) } - var procRuns *int - if val, has := cgrEv.APIOpts[utils.OptsAttributesProcessRuns]; has { - if v, err := utils.IfaceAsTInt64(val); err == nil { - procRuns = utils.IntPointer(int(v)) - } - } cgrEv.APIOpts[utils.OptsContext] = utils.FirstNonEmpty( utils.IfaceAsString(cgrEv.APIOpts[utils.OptsContext]), utils.MetaAccounts) attrArgs := &engine.AttrArgsProcessEvent{ CGREvent: cgrEv, AttributeIDs: attrIDs, - ProcessRuns: procRuns, } var tmpReply engine.AttrSProcessEventReply if err = connMgr.Call(ctx, attrSConns, utils.AttributeSv1ProcessEvent, diff --git a/apis/attributes_it_test.go b/apis/attributes_it_test.go index 3f2830736..bd8d0f1bf 100644 --- a/apis/attributes_it_test.go +++ b/apis/attributes_it_test.go @@ -616,7 +616,6 @@ func testAttributeProcessEvent(t *testing.T) { t.Fatal(err) } args := &engine.AttrArgsProcessEvent{ - ProcessRuns: utils.IntPointer(1), CGREvent: &utils.CGREvent{ Event: map[string]interface{}{ utils.ToR: utils.MetaVoice, @@ -678,7 +677,6 @@ func testAttributeProcessEventWithSearchAndReplace(t *testing.T) { t.Error("Unexpected reply returned", result) } attrArgs := &engine.AttrArgsProcessEvent{ - ProcessRuns: utils.IntPointer(1), CGREvent: &utils.CGREvent{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: "HeaderEventForAttribute", @@ -778,7 +776,6 @@ func testAttributeSProcessWithMultipleRuns(t *testing.T) { t.Error("Unexpected reply returned", result) } attrArgs := &engine.AttrArgsProcessEvent{ - ProcessRuns: utils.IntPointer(4), CGREvent: &utils.CGREvent{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: utils.GenUUID(), @@ -883,7 +880,6 @@ func testAttributeSProcessWithMultipleRuns2(t *testing.T) { t.Error("Unexpected reply returned", result) } attrArgs := &engine.AttrArgsProcessEvent{ - ProcessRuns: utils.IntPointer(4), CGREvent: &utils.CGREvent{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: utils.GenUUID(), diff --git a/apis/config_test.go b/apis/config_test.go index 82d8eea44..1e303c8cf 100644 --- a/apis/config_test.go +++ b/apis/config_test.go @@ -71,10 +71,12 @@ func TestConfigSetGetConfig(t *testing.T) { "indexed_selects": true, "nested_fields": false, "prefix_indexed_fields": []string{}, - "process_runs": 1, "resources_conns": []string{"*localhost"}, "stats_conns": []string{"*localhost"}, "suffix_indexed_fields": []string{}, + utils.DefaultOptsCfg: map[string]interface{}{ + utils.OptsAttributesProcessRuns: float64(1), + }, }, } if errGet != nil { @@ -133,10 +135,12 @@ func TestConfigSetGetReloadConfig(t *testing.T) { "indexed_selects": true, "nested_fields": false, "prefix_indexed_fields": []string{}, - "process_runs": 1, "resources_conns": []string{"*localhost"}, "stats_conns": []string{"*localhost"}, "suffix_indexed_fields": []string{}, + utils.DefaultOptsCfg: map[string]interface{}{ + utils.OptsAttributesProcessRuns: float64(1), + }, }, } if errGet != nil { @@ -171,10 +175,12 @@ func TestConfigSetGetReloadConfig(t *testing.T) { "indexed_selects": true, "nested_fields": false, "prefix_indexed_fields": []string{}, - "process_runs": 1, "resources_conns": []string{"*localhost"}, "stats_conns": []string{"*localhost"}, "suffix_indexed_fields": []string{}, + utils.DefaultOptsCfg: map[string]interface{}{ + utils.OptsAttributesProcessRuns: float64(1), + }, }, } if errGetRld != nil { @@ -197,7 +203,7 @@ func TestConfigGetSetConfigFromJSONErr(t *testing.T) { args := &config.SetConfigFromJSONArgs{ APIOpts: nil, Tenant: utils.CGRateSorg, - Config: "{\"attributes\":{\"admins_conns\":[\"*internal\"],\"enabled\":true,\"indexed_selects\":false,\"nested_fields\":false,\"prefix_indexed_fields\":[],\"process_runs\":2,\"resources_conns\":[\"*internal\"],\"stats_conns\":[\"*localhost\"],\"suffix_indexed_fields\":[]}}", + Config: "{\"attributes\":{\"admins_conns\":[\"*localhost\"],\"default_opts\":{\"*processRuns\":2},\"enabled\":true,\"indexed_selects\":true,\"nested_fields\":false,\"prefix_indexed_fields\":[],\"resources_conns\":[\"*localhost\"],\"stats_conns\":[\"*localhost\"],\"suffix_indexed_fields\":[]}}", DryRun: true, } var reply string @@ -217,7 +223,7 @@ func TestConfigGetSetConfigFromJSONErr(t *testing.T) { } var replyGet string errGet := rlcCfg.GetConfigAsJSON(context.Background(), argsGet, &replyGet) - expectedGet := "{\"attributes\":{\"admins_conns\":[\"*localhost\"],\"enabled\":true,\"indexed_selects\":true,\"nested_fields\":false,\"prefix_indexed_fields\":[],\"process_runs\":1,\"resources_conns\":[\"*localhost\"],\"stats_conns\":[\"*localhost\"],\"suffix_indexed_fields\":[]}}" + expectedGet := "{\"attributes\":{\"admins_conns\":[\"*localhost\"],\"default_opts\":{\"*processRuns\":1},\"enabled\":true,\"indexed_selects\":true,\"nested_fields\":false,\"prefix_indexed_fields\":[],\"resources_conns\":[\"*localhost\"],\"stats_conns\":[\"*localhost\"],\"suffix_indexed_fields\":[]}}" if err != nil { t.Errorf("\nExpected <%+v>, \nReceived <%+v>", nil, errGet) } diff --git a/changelog b/changelog deleted file mode 120000 index 984f9b2f5..000000000 --- a/changelog +++ /dev/null @@ -1 +0,0 @@ -./packages/debian/changelog \ No newline at end of file diff --git a/changelog b/changelog new file mode 100644 index 000000000..b01937138 --- /dev/null +++ b/changelog @@ -0,0 +1,222 @@ +cgrates (1.0) UNRELEASED; urgency=medium + [DanB] + * [EEs] Refactored the exporter options + * [ERs] Refactored the reader options + * [ERs] Removed *flatstore and *partialcsv + * [ERs] Added *opts.*partial to control if the event is partial or not + * [AttributeS] Added any_context config to control the matching attributes + * [DispatcherS] Added any_subsyste config to control the matching dispatchers + * [StatS] AverageCallCost and TotalCallCost now returns error for negative Cost field + * [SessionS] The sessions are no longer terminated on shutdown if the replication_conns are set + * [FilterS] Added *regex filter + * [DispatcherS] Removed Subsystems field in favor of filters + * [RSRParsers] Added *len dataconverter + * [ERs] Added *natsJSONMap + * [EEs] Added *natsJSONMap + * [RSRParsers] Added *slice dataconverter + * [CacheS] Updated LoadCache and ReloadCache APIs + + -- DanB Thu, 4 May 2021 12:05:00 +0200 + +cgrates (0.11.0) UNRELEASED; urgency=medium + [ DanB ] + * [FilterS] Renamed rals_conns to apiers_conns + * [FilterS] Updated *destination filter to get ReverseDestination form + API + * [SessionS] Added check for missing CGRevent + * [SessionS] Added *cost flag for SessionSv1.ProcessEvent to calculate + the rater cost + * [ConnManager] Added ApierSv2 as internal connection channel instead + of ApierSv1 + * [DiameterAgent] Using String function from diam.Message instead of + ToJSON for request String method + * [DiameterAgent] Updated 3gp_vendor dictionary + * [Templates] Added new dataconverter: *ip2hex + * [AgentS] Added support for *group type and correctly overwrite + the values in case of *variable + * [ERs] Correctly populate ConcurrentRequest from config + * [FilterS] Updated *exists to dynamically compute the path if the + path + * [AgentS] Added support for *tmp path + * [SessionS] Added new API SessionSv1.GetCost + * [SessionS] Updateed MaxUsage field from API replies + * [SessionS] Added support for *cdrs flag in SessionSv1.ProcessEvent + * [StatS] Update metric definition to include path for example: + *sum:~*req.Field1 + * [SupplierS] SupplierS require a connection to rals when give + AccountIDs and RatingPlanIDs to calculate + * [SupplierS] In case of missing usage from Event use 1 minute as + default value + * [DataDB] Mongo support different marshaler than msgpack + * [ConnManager] Fixed rpc_conns handling id with two connections and one of + it *internal + * [Replicator] Added Limit and StaticTTL otions for Items from + DataDB/StorDB + * [Migrator] Auto discover tenant from key instead of taking it from config + * [Templates] Fixed missing "*" for strip and pading strategy + * [DiameterAgent] Added RAR support + * [Loader] Added support to load CSV files from URL + * [Loader] Added configurable gapi_credentials + * [Loader] Added configurable gapi_token + * [AgentS] Add authentication mechanism for Radius (PAP, CHAP, + MSCHAPV2) + * [SessionS] Update subflags for *rals ( *authorize and *initiate ) + * [AgentS] Uniformize flags (*auth -> *authorize) + * [SessionS] Move *cost as subflag in *rals for + SessionSv1.ProcessEvent + * [DiameterAgent] Added DPR support + * [SupplierS] Add verification for event filters before populating + data + * [ERs] Add support for *json type + * [AgentS] Add ability to inject data in cache from agents + * [Config] Config cache format change to include partitions + * [ERs] Add *none EventReader type + * [SessionS] Added support for *stir_authenticate + * [SessionS] Added support for *stir_initiate + * [RouteS] Renaming from SupplierS to RouteS + * [AgentS] Improved NavigableMap + * [General] Default timingIDs start from time.Now() (i.e. *monthly time.Now() + 1 month ) + * [AgentS] FieldAsInterface return data instead of NMItem + * [RouteS] Add posibility to load routes with the sameID and different filters + * [RouteS] Correctly populate Sorting out of models + * [AgentS] Added SIPAgent for SIP redirection + * [AgentS] Added *constant: prefix to do not proccess the value + with RSRParsers + * [AgentS] Added DynamicDataProvider to AgentRequest + * [Server] Corectly log the server listen error + * [ERs] Added support to reference CSV fields by the column name + * [ERs] Renamed *default reader folders + * [FilterS] Updated Filter indexes + * [General] Added *mo+extraDuration time support (e.g. *mo+1h will be time.Now() + 1 month + 1 hour) + * [SessionS] Use correctly SessionTTLUsage when calculate end usage in case of terminate session from ttl mechanism + * [SessionS] Add SessionTLLLastUsage as option for an extra debit in case of ttl mechanism + * [LoaderS] Add *req as mandatory prefix + * [AgentS] Rename prefix from *cache to *uch + * [InternalDB] Updated InternalDB to use the global cache + * [RSRParsers] Removed *constant: prefix + * [RSRParsers] Removed attribute sistem from RSRParser + * [RSRParsers] Added grave accent(`) char as a delimiter to not split tge RSR value + * [RSRParsers] Moved RSRFilter from RSRParsers to the *rsr FilterS + * [SessionS] Rename from ResourceMessage to ResourceAllocation + * [LoaderS] Updated file selector from *req to *file(FileName) + * [SessionS] Added *chargers flag to ProcessEvent to proccess the events from ChargerS with other subsystems + * [SessionS] Updated the ids handling in flags by adding *ids as a new flag + * [SessionS] Added *derived_reply sub flag to ProcessEvent to specify if a subsystem needs to process the events from ChargerS + * [Templates] Added new dataconverter: *string2hex + * [AttributeS] Updated AttributeProfile matching to match the second AttributeProfile with the same weight + * [AttributeS] Updated inline AttributeProfiles to unite all consecutive inline attributes in a single profile + * [SessionS] Added *processRuns option to control the process runs for AttributeS + * [DispatcherS] Removed ArgDispatcher in favor of Opts + * [ERs] Add support for *template type + * [EEs] Add support for *template type + * [LoaderS] In case of empty output directory path don't move the processed file + * [FilterS] Added *ipnet filter to check if the network contains the IP + * [CacheS] Updated ReloadCache and LoadCache APIs to use a map instead of a structure to be compatible with gob encoding + * [CGR-CONSOLE] Uniformize the commands between profile and subsystem + * [StatS] Add rounding operation for duration metric (e.g. acd, tcd, etc...) + * [DispatcherH] Added DispatcherH subsystem + * [ERs] Added support for *amqpJSONMap type + * [DataDB] Moved all specific DB options in opts + * [Config] Add new section "template" + * [LoaderS] Add support for *template type + * [ActionS] Replaced the poster action with *export that will send the event to EEs + * [AgentS] DiameterAgent return NOT_FOUND instead of "filter not passing" error and let other subsystem to handle this (e.g. FilterS) + * [StatS] Change format of metricID when specifying fields ( e.g. *sum#~*req.FieldName ) + * [FilterS] Added *apiban filter + * [EEs] Add support for *elastic exporter + * [AttributeS] Add support for adding fields from other places that event (e.g. Resource.TotalUsage, Stat.MetricName, Account.Balance) + * [EEs] Empty fields in exporter config will export the full event for the exporters that use json format + * [DynamicDP] Add support for *libphonenumber prefix + * [Templates] Added new data converter: *unixtime + * [ActionsS] Add prefix *acnt and *act to cdrLog action + * [AttributeS] Add support for *prefix and *suffix type + * [ConfigS] Add "redis_" prefix to "dataDB" option for redis + * [DataDB] Add support for redis with TLS connection ( + integration test ) + * [ERs] Added support for *s3JSONMap type + * [ERs] Added support for *sqsJSONMap type + * [ERs] Added support for *amqpv1JSONMap type + * [RALs] Send balance update event from rals to threshold ( in case of negative) only once + * [SessionS] Use rals_conns when sending refund rounding + * [General] Made tenant optional for all API calls + * [ConfigS] Moved MinCallDuration,MaxCallDuration from sessions config to general config + * [StatS] Added support for nested fields in custom metrics + * [AccountS] Add Initial in AccountSummary as initail value before debit operation + * [General] For only *asap actions don't save AccountIDs withing ActionPlans + * [AnalyzerS] Added AnalyzerSv1.StringQuery API to search over the recorded RPC calls + * [CoreS] Moved the server implementation in the new cores package + * [RouteS] In case of same weight sort random + * [ConfigS] Renamed ReloadConfigFromPath API to ReloadConfig + * [ConfigS] Renamed ReloadConfig API to SetConfig + * [ConfigS] Renamed ReloadConfigFromJSON API to SetConfigFromJSON + * [CDRs] Replaced RSRField with RSRParser + * [RouteS] Add new field RouteRateProfileIDs in RateProfiles.csv + * [DispatcherS] Removed connection pool from DispatcherHost structure + * [DispatcherS] Updated *broadcast, *broadcast_sync and *broadcast_async to behave similar to RPCPool + * [ActionsS] Added *remote_set_account action + * [SessionS] Properly charge terminate without initiate event + * [ServiceS] Added service dependency map to control the shutdown order + * [EEs] Add support for *sql exporter + * [ApierS] Correct handle error in case of APIerSv1.GetActionTriggers + * [SessionS] Added extra condition to determine if the increment is considered the roundIncrement + * [SessionS] Cloned the charging interval added on EventCost merge + * [FilterS] Optimized the automated index fields matching + * [AgentS] Added *cfg as DataProvider for AgentRequest + * [AgentS] Added *routes_maxcost flag + * [SessionS] Added *sessionChargeable session option to control session charging + * [SessionS] Replaced max_call_duration config with default_usage for each ToR + * [SessionS] Added JSON and GOB BiRPC support + * [ActionS] Added *add_balance, *set_balance and *rem_balance + * [RegistrarC] Renamed DispatcherH to RegistrarC + * [DataDB] Added replication filtering + * [ApierS] Moved Cache field as options + * [RouteS] Updated RouteSv1.GetRoutes API to return multiple profiles + * [Templates] Added support for Length Field in case of NMSlice + * [Templates] Added support for multiple indexes + * [AgentS] Added ~*req prefix for freeswitch extra_fields + * [AgentS] Changed NavigableMap with DataNode for speed improvements + * [SessionS] RequestType *none returns back the requested usage + * [DataDB] Updated config options + * [StorDB] Updated config options + +cgrates (0.10.0) UNRELEASED; urgency=medium + + * Creating first stable branch. + + -- DanB Thu, 6 Feb 2020 12:05:00 +0200 + +cgrates (0.9.1~rc8) UNRELEASED; urgency=medium + + * RC8. + + -- DanB Mon, 22 Sep 2015 12:05:00 +0200 + +cgrates (0.9.1~rc7) UNRELEASED; urgency=low + + * RC7. + + -- DanB Wed, 3 Aug 2015 14:04:00 -0600 + +cgrates (0.9.1~rc6) UNRELEASED; urgency=low + + * RC6. + + -- DanB Wed, 10 Sep 2014 13:30:00 +0100 + +cgrates (0.9.1~rc5) UNRELEASED; urgency=low + + * RC5. + + -- DanB Mon, 18 Aug 2014 13:30:00 +0100 + + +cgrates (0.9.1~rc4) UNRELEASED; urgency=low + + * RC4. + + -- DanB Thu, 25 Mar 2014 17:30:00 +0100 + +cgrates (0.9.1~rc3) UNRELEASED; urgency=low + + * RC3. + + -- DanB Fri, 03 Jan 2014 17:37:31 +0100 diff --git a/config/attributescfg.go b/config/attributescfg.go index c36a47df5..a0bccadd7 100644 --- a/config/attributescfg.go +++ b/config/attributescfg.go @@ -30,8 +30,8 @@ type AttributeSCfg struct { StringIndexedFields *[]string PrefixIndexedFields *[]string SuffixIndexedFields *[]string - ProcessRuns int NestedFields bool + DefaultOpts map[string]interface{} } func (alS *AttributeSCfg) loadFromJSONCfg(jsnCfg *AttributeSJsonCfg) (err error) { @@ -62,12 +62,12 @@ func (alS *AttributeSCfg) loadFromJSONCfg(jsnCfg *AttributeSJsonCfg) (err error) if jsnCfg.Suffix_indexed_fields != nil { alS.SuffixIndexedFields = utils.SliceStringPointer(utils.CloneStringSlice(*jsnCfg.Suffix_indexed_fields)) } - if jsnCfg.Process_runs != nil { - alS.ProcessRuns = *jsnCfg.Process_runs - } if jsnCfg.Nested_fields != nil { alS.NestedFields = *jsnCfg.Nested_fields } + if jsnCfg.Default_opts != nil { + alS.DefaultOpts = jsnCfg.Default_opts + } return } @@ -76,8 +76,8 @@ func (alS *AttributeSCfg) AsMapInterface() (initialMP map[string]interface{}) { initialMP = map[string]interface{}{ utils.EnabledCfg: alS.Enabled, utils.IndexedSelectsCfg: alS.IndexedSelects, - utils.ProcessRunsCfg: alS.ProcessRuns, utils.NestedFieldsCfg: alS.NestedFields, + utils.DefaultOptsCfg: alS.DefaultOpts, } if alS.StringIndexedFields != nil { initialMP[utils.StringIndexedFieldsCfg] = utils.CloneStringSlice(*alS.StringIndexedFields) @@ -107,7 +107,7 @@ func (alS AttributeSCfg) Clone() (cln *AttributeSCfg) { Enabled: alS.Enabled, IndexedSelects: alS.IndexedSelects, NestedFields: alS.NestedFields, - ProcessRuns: alS.ProcessRuns, + DefaultOpts: alS.DefaultOpts, } if alS.ResourceSConns != nil { cln.ResourceSConns = utils.CloneStringSlice(alS.ResourceSConns) @@ -142,7 +142,7 @@ type AttributeSJsonCfg struct { Prefix_indexed_fields *[]string Suffix_indexed_fields *[]string Nested_fields *bool // applies when indexed fields is not defined - Process_runs *int + Default_opts map[string]interface{} } func diffAttributeSJsonCfg(d *AttributeSJsonCfg, v1, v2 *AttributeSCfg) *AttributeSJsonCfg { @@ -167,12 +167,10 @@ func diffAttributeSJsonCfg(d *AttributeSJsonCfg, v1, v2 *AttributeSCfg) *Attribu d.String_indexed_fields = diffIndexSlice(d.String_indexed_fields, v1.StringIndexedFields, v2.StringIndexedFields) d.Prefix_indexed_fields = diffIndexSlice(d.Prefix_indexed_fields, v1.PrefixIndexedFields, v2.PrefixIndexedFields) d.Suffix_indexed_fields = diffIndexSlice(d.Suffix_indexed_fields, v1.SuffixIndexedFields, v2.SuffixIndexedFields) - if v1.ProcessRuns != v2.ProcessRuns { - d.Process_runs = utils.IntPointer(v2.ProcessRuns) - } if v1.NestedFields != v2.NestedFields { d.Nested_fields = utils.BoolPointer(v2.NestedFields) } + d.Default_opts = diffMap(d.Default_opts, v1.DefaultOpts, v2.DefaultOpts) return d } diff --git a/config/attributescfg_test.go b/config/attributescfg_test.go index 33e4811ac..1b586bc03 100644 --- a/config/attributescfg_test.go +++ b/config/attributescfg_test.go @@ -34,7 +34,6 @@ func TestAttributeSCfgloadFromJsonCfg(t *testing.T) { String_indexed_fields: &[]string{"*req.index1"}, Prefix_indexed_fields: &[]string{"*req.index1", "*req.index2"}, Suffix_indexed_fields: &[]string{"*req.index1"}, - Process_runs: utils.IntPointer(1), Nested_fields: utils.BoolPointer(true), } expected := &AttributeSCfg{ @@ -46,8 +45,10 @@ func TestAttributeSCfgloadFromJsonCfg(t *testing.T) { StringIndexedFields: &[]string{"*req.index1"}, PrefixIndexedFields: &[]string{"*req.index1", "*req.index2"}, SuffixIndexedFields: &[]string{"*req.index1"}, - ProcessRuns: 1, NestedFields: true, + DefaultOpts: map[string]interface{}{ + utils.OptsAttributesProcessRuns: float64(1), + }, } jsnCfg := NewDefaultCGRConfig() if err = jsnCfg.attributeSCfg.loadFromJSONCfg(jsonCfg); err != nil { @@ -66,7 +67,9 @@ func TestAttributeSCfgAsMapInterface(t *testing.T) { "admins_conns": ["*internal"], "prefix_indexed_fields": ["*req.index1","*req.index2"], "string_indexed_fields": ["*req.index1"], - "process_runs": 3, + "default_opts": { + "*processRuns": 3, + }, }, }` eMap := map[string]interface{}{ @@ -76,10 +79,12 @@ func TestAttributeSCfgAsMapInterface(t *testing.T) { utils.AdminSConnsCfg: []string{utils.MetaInternal}, utils.StringIndexedFieldsCfg: []string{"*req.index1"}, utils.PrefixIndexedFieldsCfg: []string{"*req.index1", "*req.index2"}, - utils.ProcessRunsCfg: 3, utils.IndexedSelectsCfg: true, utils.NestedFieldsCfg: false, utils.SuffixIndexedFieldsCfg: []string{}, + utils.DefaultOptsCfg: map[string]interface{}{ + utils.OptsAttributesProcessRuns: float64(3), + }, } if cgrCfg, err := NewCGRConfigFromJSONStringWithDefaults(cfgJSONStr); err != nil { t.Error(err) @@ -94,7 +99,9 @@ func TestAttributeSCfgAsMapInterface2(t *testing.T) { "suffix_indexed_fields": ["*req.index1","*req.index2"], "nested_fields": true, "enabled": true, - "process_runs": 7, + "default_opts": { + "*processRuns": 7, + }, }, }` expectedMap := map[string]interface{}{ @@ -106,7 +113,9 @@ func TestAttributeSCfgAsMapInterface2(t *testing.T) { utils.PrefixIndexedFieldsCfg: []string{}, utils.SuffixIndexedFieldsCfg: []string{"*req.index1", "*req.index2"}, utils.NestedFieldsCfg: true, - utils.ProcessRunsCfg: 7, + utils.DefaultOptsCfg: map[string]interface{}{ + utils.OptsAttributesProcessRuns: float64(7), + }, } if cgrCfg, err := NewCGRConfigFromJSONStringWithDefaults(cfgJSONStr); err != nil { t.Error(err) @@ -130,7 +139,9 @@ func TestAttributeSCfgAsMapInterface3(t *testing.T) { utils.PrefixIndexedFieldsCfg: []string{}, utils.SuffixIndexedFieldsCfg: []string{}, utils.NestedFieldsCfg: false, - utils.ProcessRunsCfg: 1, + utils.DefaultOptsCfg: map[string]interface{}{ + utils.OptsAttributesProcessRuns: float64(1), + }, } if conv, err := NewCGRConfigFromJSONStringWithDefaults(myJSONStr); err != nil { t.Error(err) @@ -149,7 +160,6 @@ func TestAttributeSCfgClone(t *testing.T) { StringIndexedFields: &[]string{"*req.index1"}, PrefixIndexedFields: &[]string{"*req.index1", "*req.index2"}, SuffixIndexedFields: &[]string{"*req.index1"}, - ProcessRuns: 1, NestedFields: true, } rcv := ban.Clone() @@ -188,8 +198,10 @@ func TestDiffAttributeSJsonCfg(t *testing.T) { StringIndexedFields: &[]string{}, PrefixIndexedFields: &[]string{}, SuffixIndexedFields: &[]string{}, - ProcessRuns: 2, NestedFields: true, + DefaultOpts: map[string]interface{}{ + utils.OptsAttributesProcessRuns: float64(1), + }, } v2 := &AttributeSCfg{ @@ -201,8 +213,10 @@ func TestDiffAttributeSJsonCfg(t *testing.T) { StringIndexedFields: &[]string{"*req.Field1"}, PrefixIndexedFields: nil, SuffixIndexedFields: nil, - ProcessRuns: 3, NestedFields: false, + DefaultOpts: map[string]interface{}{ + utils.OptsAttributesProcessRuns: float64(1), + }, } expected := &AttributeSJsonCfg{ @@ -214,8 +228,8 @@ func TestDiffAttributeSJsonCfg(t *testing.T) { String_indexed_fields: &[]string{"*req.Field1"}, Prefix_indexed_fields: nil, Suffix_indexed_fields: nil, - Process_runs: utils.IntPointer(3), Nested_fields: utils.BoolPointer(false), + Default_opts: map[string]interface{}{}, } rcv := diffAttributeSJsonCfg(d, v1, v2) @@ -224,7 +238,9 @@ func TestDiffAttributeSJsonCfg(t *testing.T) { } v2_2 := v1 - expected2 := &AttributeSJsonCfg{} + expected2 := &AttributeSJsonCfg{ + Default_opts: map[string]interface{}{}, + } rcv = diffAttributeSJsonCfg(d, v1, v2_2) if !reflect.DeepEqual(rcv, expected2) { t.Errorf("Expected %v \n but received \n %v", utils.ToJSON(expected2), utils.ToJSON(rcv)) diff --git a/config/config_defaults.go b/config/config_defaults.go index 3a1e60737..303c74a58 100644 --- a/config/config_defaults.go +++ b/config/config_defaults.go @@ -667,7 +667,9 @@ const CGRATES_CFG_JSON = ` "prefix_indexed_fields": [], // query indexes based on these fields for faster processing "suffix_indexed_fields": [], // query indexes based on these fields for faster processing "nested_fields": false, // determines which field is checked when matching indexed filters(true: all; false: only the one on the first level) - "process_runs": 1, // number of run loops when processing event + "default_opts":{ // + "*processRuns": 1, // number of run loops when processing event + }, }, @@ -734,7 +736,6 @@ const CGRATES_CFG_JSON = ` "default_ratio":1, // default ratio used in case of *load strategy "default_opts":{ "*context": "*routes", - // "*processRuns": 1, "*routesProfilesCount": 1, }, }, diff --git a/config/config_it_test.go b/config/config_it_test.go index f67af096c..3fd940793 100644 --- a/config/config_it_test.go +++ b/config/config_it_test.go @@ -155,7 +155,6 @@ func testCGRConfigReloadAttributeS(t *testing.T) { PrefixIndexedFields: &[]string{}, SuffixIndexedFields: &[]string{}, IndexedSelects: true, - ProcessRuns: 1, } if !reflect.DeepEqual(expAttr, cfg.AttributeSCfg()) { t.Errorf("Expected %s , received: %s ", utils.ToJSON(expAttr), utils.ToJSON(cfg.AttributeSCfg())) @@ -191,7 +190,6 @@ func testCGRConfigReloadAttributeSWithDB(t *testing.T) { PrefixIndexedFields: &[]string{}, SuffixIndexedFields: &[]string{}, IndexedSelects: true, - ProcessRuns: 1, } if !reflect.DeepEqual(expAttr, cfg.AttributeSCfg()) { t.Errorf("Expected %s , received: %s ", utils.ToJSON(expAttr), utils.ToJSON(cfg.AttributeSCfg())) diff --git a/config/config_json_test.go b/config/config_json_test.go index 24df0d5c3..84b4c6d3f 100644 --- a/config/config_json_test.go +++ b/config/config_json_test.go @@ -753,7 +753,9 @@ func TestDfAttributeServJsonCfg(t *testing.T) { Prefix_indexed_fields: &[]string{}, Suffix_indexed_fields: &[]string{}, Nested_fields: utils.BoolPointer(false), - Process_runs: utils.IntPointer(1), + Default_opts: map[string]interface{}{ + utils.OptsAttributesProcessRuns: float64(1), + }, } dfCgrJSONCfg, err := NewCgrJsonCfgFromBytes([]byte(CGRATES_CFG_JSON)) if err != nil { @@ -762,7 +764,7 @@ func TestDfAttributeServJsonCfg(t *testing.T) { if cfg, err := dfCgrJSONCfg.AttributeServJsonCfg(); err != nil { t.Error(err) } else if !reflect.DeepEqual(eCfg, cfg) { - t.Error("Received: ", utils.ToJSON(cfg)) + t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ToJSON(eCfg), utils.ToJSON(cfg)) } } diff --git a/config/config_test.go b/config/config_test.go index 31b6c4f62..c905d2602 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -1301,24 +1301,6 @@ func TestLoadHttpAgentCfgError(t *testing.T) { } } -func TestLoadAttributeSCfgError(t *testing.T) { - cfgJSONStr := `{ -"attributes": { - "process_runs": "3", - }, -}` - expected := "json: cannot unmarshal string into Go struct field AttributeSJsonCfg.Process_runs of type int" - cgrConfig := NewDefaultCGRConfig() - if err != nil { - t.Error(err) - } - if cgrCfgJSON, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil { - t.Error(err) - } else if err := cgrConfig.loadAttributeSCfg(cgrCfgJSON); err == nil || err.Error() != expected { - t.Errorf("Expected %+v, received %+v", expected, err) - } -} - func TestLoadChargerSCfgError(t *testing.T) { cfgJSONStr := `{ "chargers": { @@ -1864,8 +1846,10 @@ func TestAttributeSConfig(t *testing.T) { IndexedSelects: true, PrefixIndexedFields: &[]string{}, SuffixIndexedFields: &[]string{}, - ProcessRuns: 1, NestedFields: false, + DefaultOpts: map[string]interface{}{ + utils.OptsAttributesProcessRuns: float64(1), + }, } cgrConfig := NewDefaultCGRConfig() if err != nil { @@ -4168,7 +4152,9 @@ func TestV1GetConfigAttribute(t *testing.T) { utils.PrefixIndexedFieldsCfg: []string{}, utils.SuffixIndexedFieldsCfg: []string{}, utils.NestedFieldsCfg: false, - utils.ProcessRunsCfg: 1, + utils.DefaultOptsCfg: map[string]interface{}{ + utils.OptsAttributesProcessRuns: float64(1), + }, }, } cfgCgr := NewDefaultCGRConfig() @@ -5031,7 +5017,7 @@ func TestV1GetConfigAsJSONDNSAgent(t *testing.T) { func TestV1GetConfigAsJSONAttributes(t *testing.T) { var reply string - expected := `{"attributes":{"admins_conns":[],"enabled":false,"indexed_selects":true,"nested_fields":false,"prefix_indexed_fields":[],"process_runs":1,"resources_conns":[],"stats_conns":[],"suffix_indexed_fields":[]}}` + expected := `{"attributes":{"admins_conns":[],"default_opts":{"*processRuns":1},"enabled":false,"indexed_selects":true,"nested_fields":false,"prefix_indexed_fields":[],"resources_conns":[],"stats_conns":[],"suffix_indexed_fields":[]}}` cgrCfg := NewDefaultCGRConfig() if err := cgrCfg.V1GetConfigAsJSON(context.Background(), &SectionWithAPIOpts{Sections: []string{AttributeSJSON}}, &reply); err != nil { t.Error(err) @@ -5355,7 +5341,7 @@ func TestV1GetConfigAsJSONAllConfig(t *testing.T) { } }` var reply string - expected := `{"accounts":{"attributes_conns":[],"enabled":false,"indexed_selects":true,"max_iterations":1000,"max_usage":"259200000000000","nested_fields":false,"prefix_indexed_fields":[],"rates_conns":[],"suffix_indexed_fields":[],"thresholds_conns":[]},"actions":{"accounts_conns":[],"cdrs_conns":[],"dynaprepaid_actionprofile":[],"ees_conns":[],"enabled":false,"indexed_selects":true,"nested_fields":false,"prefix_indexed_fields":[],"stats_conns":[],"suffix_indexed_fields":[],"tenants":[],"thresholds_conns":[]},"admins":{"actions_conns":[],"attributes_conns":[],"caches_conns":["*internal"],"ees_conns":[],"enabled":false},"analyzers":{"cleanup_interval":"1h0m0s","db_path":"/var/spool/cgrates/analyzers","enabled":false,"index_type":"*scorch","ttl":"24h0m0s"},"apiban":{"enabled":false,"keys":[]},"asterisk_agent":{"asterisk_conns":[{"address":"127.0.0.1:8088","alias":"","connect_attempts":3,"password":"CGRateS.org","reconnects":5,"user":"cgrates"}],"create_cdr":false,"enabled":false,"sessions_conns":["*birpc_internal"]},"attributes":{"admins_conns":[],"enabled":false,"indexed_selects":true,"nested_fields":false,"prefix_indexed_fields":[],"process_runs":1,"resources_conns":[],"stats_conns":[],"suffix_indexed_fields":[]},"caches":{"partitions":{"*account_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*accounts":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*action_profile_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*action_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*apiban":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":"2m0s"},"*attribute_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*attribute_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*caps_events":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*cdr_ids":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":"10m0s"},"*cdrs":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*charger_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*charger_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*closed_sessions":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":"10s"},"*diameter_messages":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":"3h0m0s"},"*dispatcher_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*dispatcher_hosts":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*dispatcher_loads":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*dispatcher_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*dispatcher_routes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*dispatchers":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*event_charges":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":"10s"},"*event_resources":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*filters":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*load_ids":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*rate_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*rate_profile_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*rate_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*replication_hosts":{"limit":0,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*resource_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*resource_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*resources":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*reverse_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*route_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*route_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*rpc_connections":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*rpc_responses":{"limit":0,"precache":false,"replicate":false,"static_ttl":false,"ttl":"2s"},"*session_costs":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*stat_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*statqueue_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*statqueues":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*stir":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":"3h0m0s"},"*threshold_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*threshold_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*thresholds":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_accounts":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_action_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_attributes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_chargers":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_dispatcher_hosts":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_dispatcher_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_filters":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_rate_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_resources":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_routes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_stats":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_thresholds":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*uch":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":"3h0m0s"},"*versions":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""}},"replication_conns":[]},"cdrs":{"accounts_conns":[],"actions_conns":[],"attributes_conns":[],"chargers_conns":[],"ees_conns":[],"enabled":false,"extra_fields":[],"online_cdr_exports":[],"rates_conns":[],"session_cost_retries":5,"stats_conns":[],"store_cdrs":true,"thresholds_conns":[]},"chargers":{"attributes_conns":[],"enabled":false,"indexed_selects":true,"nested_fields":false,"prefix_indexed_fields":[],"suffix_indexed_fields":[]},"config_db":{"db_host":"","db_name":"","db_password":"","db_port":0,"db_type":"*internal","db_user":"","items":{},"opts":{"mongoQueryTimeout":"10s","redisCACertificate":"","redisClientCertificate":"","redisClientKey":"","redisCluster":false,"redisClusterOndownDelay":"0","redisClusterSync":"5s","redisSentinel":"","redisTLS":false},"remote_conn_id":"","remote_conns":null,"replication_cache":"","replication_conns":null,"replication_filtered":false},"configs":{"enabled":false,"root_dir":"/var/spool/cgrates/configs","url":"/configs/"},"cores":{"caps":0,"caps_stats_interval":"0","caps_strategy":"*busy","shutdown_timeout":"1s"},"data_db":{"db_host":"127.0.0.1","db_name":"10","db_password":"","db_port":6379,"db_type":"*redis","db_user":"cgrates","items":{"*accounts":{"remote":false,"replicate":false},"*action_profiles":{"remote":false,"replicate":false},"*actions":{"remote":false,"replicate":false},"*attribute_profiles":{"remote":false,"replicate":false},"*charger_profiles":{"remote":false,"replicate":false},"*dispatcher_hosts":{"remote":false,"replicate":false},"*dispatcher_profiles":{"remote":false,"replicate":false},"*filters":{"remote":false,"replicate":false},"*indexes":{"remote":false,"replicate":false},"*load_ids":{"remote":false,"replicate":false},"*rate_profiles":{"remote":false,"replicate":false},"*resource_profiles":{"remote":false,"replicate":false},"*resources":{"remote":false,"replicate":false},"*route_profiles":{"remote":false,"replicate":false},"*statqueue_profiles":{"remote":false,"replicate":false},"*statqueues":{"remote":false,"replicate":false},"*threshold_profiles":{"remote":false,"replicate":false},"*thresholds":{"remote":false,"replicate":false}},"opts":{"mongoQueryTimeout":"10s","redisCACertificate":"","redisClientCertificate":"","redisClientKey":"","redisCluster":false,"redisClusterOndownDelay":"0","redisClusterSync":"5s","redisSentinel":"","redisTLS":false},"remote_conn_id":"","remote_conns":[],"replication_cache":"","replication_conns":[],"replication_filtered":false},"diameter_agent":{"asr_template":"","concurrent_requests":-1,"dictionaries_path":"/usr/share/cgrates/diameter/dict/","enabled":false,"forced_disconnect":"*none","listen":"127.0.0.1:3868","listen_net":"tcp","origin_host":"CGR-DA","origin_realm":"cgrates.org","product_name":"CGRateS","rar_template":"","request_processors":[],"sessions_conns":["*birpc_internal"],"synced_conn_requests":false,"vendor_id":0},"dispatchers":{"attributes_conns":[],"enabled":false,"indexed_selects":true,"nested_fields":false,"prefix_indexed_fields":[],"suffix_indexed_fields":[]},"dns_agent":{"enabled":false,"listen":"127.0.0.1:2053","listen_net":"udp","request_processors":[],"sessions_conns":["*internal"],"timezone":""},"ees":{"attributes_conns":[],"cache":{"*fileCSV":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":"5s"}},"enabled":false,"exporters":[{"attempts":1,"attribute_context":"","attribute_ids":[],"concurrent_requests":0,"export_path":"/var/spool/cgrates/ees","failed_posts_dir":"/var/spool/cgrates/failed_posts","fields":[],"filters":[],"flags":[],"id":"*default","opts":{},"synchronous":false,"timezone":"","type":"*none"}]},"ers":{"enabled":false,"partial_cache_ttl":"1s","readers":[{"cache_dump_fields":[],"concurrent_requests":1024,"fields":[{"mandatory":true,"path":"*cgreq.ToR","tag":"ToR","type":"*variable","value":"~*req.2"},{"mandatory":true,"path":"*cgreq.OriginID","tag":"OriginID","type":"*variable","value":"~*req.3"},{"mandatory":true,"path":"*cgreq.RequestType","tag":"RequestType","type":"*variable","value":"~*req.4"},{"mandatory":true,"path":"*cgreq.Tenant","tag":"Tenant","type":"*variable","value":"~*req.6"},{"mandatory":true,"path":"*cgreq.Category","tag":"Category","type":"*variable","value":"~*req.7"},{"mandatory":true,"path":"*cgreq.Account","tag":"Account","type":"*variable","value":"~*req.8"},{"mandatory":true,"path":"*cgreq.Subject","tag":"Subject","type":"*variable","value":"~*req.9"},{"mandatory":true,"path":"*cgreq.Destination","tag":"Destination","type":"*variable","value":"~*req.10"},{"mandatory":true,"path":"*cgreq.SetupTime","tag":"SetupTime","type":"*variable","value":"~*req.11"},{"mandatory":true,"path":"*cgreq.AnswerTime","tag":"AnswerTime","type":"*variable","value":"~*req.12"},{"mandatory":true,"path":"*cgreq.Usage","tag":"Usage","type":"*variable","value":"~*req.13"}],"filters":[],"flags":[],"id":"*default","opts":{"csvFieldSeparator":",","csvHeaderDefineChar":":","csvRowLength":0,"natsSubject":"cgrates_cdrs","partialCacheAction":"*none","partialOrderField":"~*req.AnswerTime","xmlRootPath":""},"partial_commit_fields":[],"processed_path":"/var/spool/cgrates/ers/out","run_delay":"0","source_path":"/var/spool/cgrates/ers/in","tenant":"","timezone":"","type":"*none"}],"sessions_conns":["*internal"]},"filters":{"admins_conns":[],"resources_conns":[],"stats_conns":[]},"freeswitch_agent":{"create_cdr":false,"empty_balance_ann_file":"","empty_balance_context":"","enabled":false,"event_socket_conns":[{"address":"127.0.0.1:8021","alias":"127.0.0.1:8021","password":"ClueCon","reconnects":5}],"extra_fields":[],"low_balance_ann_file":"","max_wait_connection":"2s","sessions_conns":["*birpc_internal"],"subscribe_park":true},"general":{"connect_attempts":5,"connect_timeout":"1s","dbdata_encoding":"*msgpack","default_caching":"*reload","default_category":"call","default_request_type":"*rated","default_tenant":"cgrates.org","default_timezone":"Local","digest_equal":":","digest_separator":",","failed_posts_dir":"/var/spool/cgrates/failed_posts","failed_posts_ttl":"5s","locking_timeout":"0","log_level":6,"logger":"*syslog","max_parallel_conns":100,"node_id":"ENGINE1","poster_attempts":3,"reconnects":-1,"reply_timeout":"2s","rounding_decimals":5,"rsr_separator":";","tpexport_dir":"/var/spool/cgrates/tpe"},"http":{"auth_users":{},"client_opts":{"dialFallbackDelay":"300ms","dialKeepAlive":"30s","dialTimeout":"30s","disableCompression":false,"disableKeepAlives":false,"expectContinueTimeout":"0","forceAttemptHttp2":true,"idleConnTimeout":"90s","maxConnsPerHost":0,"maxIdleConns":100,"maxIdleConnsPerHost":2,"responseHeaderTimeout":"0","skipTlsVerify":false,"tlsHandshakeTimeout":"10s"},"freeswitch_cdrs_url":"/freeswitch_json","http_cdrs":"/cdr_http","json_rpc_url":"/jsonrpc","registrars_url":"/registrar","use_basic_auth":false,"ws_url":"/ws"},"http_agent":[],"kamailio_agent":{"create_cdr":false,"enabled":false,"evapi_conns":[{"address":"127.0.0.1:8448","alias":"","reconnects":5}],"sessions_conns":["*birpc_internal"],"timezone":""},"listen":{"http":"127.0.0.1:2080","http_tls":"127.0.0.1:2280","rpc_gob":"127.0.0.1:2013","rpc_gob_tls":"127.0.0.1:2023","rpc_json":"127.0.0.1:2012","rpc_json_tls":"127.0.0.1:2022"},"loader":{"actions_conns":["*localhost"],"caches_conns":["*localhost"],"data_path":"./","disable_reverse":false,"field_separator":",","gapi_credentials":".gapi/credentials.json","gapi_token":".gapi/token.json","tpid":""},"loaders":[{"caches_conns":["*internal"],"data":[{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"Type","tag":"Type","type":"*variable","value":"~*req.2"},{"path":"Element","tag":"Element","type":"*variable","value":"~*req.3"},{"path":"Values","tag":"Values","type":"*variable","value":"~*req.4"}],"file_name":"Filters.csv","flags":null,"type":"*filters"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"TenantID","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ProfileID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.3"},{"path":"AttributeFilterIDs","tag":"AttributeFilterIDs","type":"*variable","value":"~*req.4"},{"path":"Path","tag":"Path","type":"*variable","value":"~*req.5"},{"path":"Type","tag":"Type","type":"*variable","value":"~*req.6"},{"path":"Value","tag":"Value","type":"*variable","value":"~*req.7"},{"path":"Blocker","tag":"Blocker","type":"*variable","value":"~*req.8"}],"file_name":"Attributes.csv","flags":null,"type":"*attributes"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.3"},{"path":"UsageTTL","tag":"TTL","type":"*variable","value":"~*req.4"},{"path":"Limit","tag":"Limit","type":"*variable","value":"~*req.5"},{"path":"AllocationMessage","tag":"AllocationMessage","type":"*variable","value":"~*req.6"},{"path":"Blocker","tag":"Blocker","type":"*variable","value":"~*req.7"},{"path":"Stored","tag":"Stored","type":"*variable","value":"~*req.8"},{"path":"ThresholdIDs","tag":"ThresholdIDs","type":"*variable","value":"~*req.9"}],"file_name":"Resources.csv","flags":null,"type":"*resources"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.3"},{"path":"QueueLength","tag":"QueueLength","type":"*variable","value":"~*req.4"},{"path":"TTL","tag":"TTL","type":"*variable","value":"~*req.5"},{"path":"MinItems","tag":"MinItems","type":"*variable","value":"~*req.6"},{"path":"MetricIDs","tag":"MetricIDs","type":"*variable","value":"~*req.7"},{"path":"MetricFilterIDs","tag":"MetricFilterIDs","type":"*variable","value":"~*req.8"},{"path":"Blocker","tag":"Blocker","type":"*variable","value":"~*req.9"},{"path":"Stored","tag":"Stored","type":"*variable","value":"~*req.10"},{"path":"ThresholdIDs","tag":"ThresholdIDs","type":"*variable","value":"~*req.11"}],"file_name":"Stats.csv","flags":null,"type":"*stats"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.3"},{"path":"MaxHits","tag":"MaxHits","type":"*variable","value":"~*req.4"},{"path":"MinHits","tag":"MinHits","type":"*variable","value":"~*req.5"},{"path":"MinSleep","tag":"MinSleep","type":"*variable","value":"~*req.6"},{"path":"Blocker","tag":"Blocker","type":"*variable","value":"~*req.7"},{"path":"ActionProfileIDs","tag":"ActionProfileIDs","type":"*variable","value":"~*req.8"},{"path":"Async","tag":"Async","type":"*variable","value":"~*req.9"}],"file_name":"Thresholds.csv","flags":null,"type":"*thresholds"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.3"},{"path":"Sorting","tag":"Sorting","type":"*variable","value":"~*req.4"},{"path":"SortingParameters","tag":"SortingParameters","type":"*variable","value":"~*req.5"},{"path":"RouteID","tag":"RouteID","type":"*variable","value":"~*req.6"},{"path":"RouteFilterIDs","tag":"RouteFilterIDs","type":"*variable","value":"~*req.7"},{"path":"RouteAccountIDs","tag":"RouteAccountIDs","type":"*variable","value":"~*req.8"},{"path":"RouteRatingPlanIDs","tag":"RouteRatingPlanIDs","type":"*variable","value":"~*req.9"},{"path":"RouteResourceIDs","tag":"RouteResourceIDs","type":"*variable","value":"~*req.10"},{"path":"RouteStatIDs","tag":"RouteStatIDs","type":"*variable","value":"~*req.11"},{"path":"RouteWeight","tag":"RouteWeight","type":"*variable","value":"~*req.12"},{"path":"RouteBlocker","tag":"RouteBlocker","type":"*variable","value":"~*req.13"},{"path":"RouteParameters","tag":"RouteParameters","type":"*variable","value":"~*req.14"}],"file_name":"Routes.csv","flags":null,"type":"*routes"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.3"},{"path":"RunID","tag":"RunID","type":"*variable","value":"~*req.4"},{"path":"AttributeIDs","tag":"AttributeIDs","type":"*variable","value":"~*req.5"}],"file_name":"Chargers.csv","flags":null,"type":"*chargers"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.3"},{"path":"Strategy","tag":"Strategy","type":"*variable","value":"~*req.4"},{"path":"StrategyParameters","tag":"StrategyParameters","type":"*variable","value":"~*req.5"},{"path":"ConnID","tag":"ConnID","type":"*variable","value":"~*req.6"},{"path":"ConnFilterIDs","tag":"ConnFilterIDs","type":"*variable","value":"~*req.7"},{"path":"ConnWeight","tag":"ConnWeight","type":"*variable","value":"~*req.8"},{"path":"ConnBlocker","tag":"ConnBlocker","type":"*variable","value":"~*req.9"},{"path":"ConnParameters","tag":"ConnParameters","type":"*variable","value":"~*req.10"}],"file_name":"DispatcherProfiles.csv","flags":null,"type":"*dispatchers"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"Address","tag":"Address","type":"*variable","value":"~*req.2"},{"path":"Transport","tag":"Transport","type":"*variable","value":"~*req.3"},{"path":"ConnectAttempts","tag":"ConnectAttempts","type":"*variable","value":"~*req.4"},{"path":"Reconnects","tag":"Reconnects","type":"*variable","value":"~*req.5"},{"path":"ConnectTimeout","tag":"ConnectTimeout","type":"*variable","value":"~*req.6"},{"path":"ReplyTimeout","tag":"ReplyTimeout","type":"*variable","value":"~*req.7"},{"path":"TLS","tag":"TLS","type":"*variable","value":"~*req.8"},{"path":"ClientKey","tag":"ClientKey","type":"*variable","value":"~*req.9"},{"path":"ClientCertificate","tag":"ClientCertificate","type":"*variable","value":"~*req.10"},{"path":"CaCertificate","tag":"CaCertificate","type":"*variable","value":"~*req.11"}],"file_name":"DispatcherHosts.csv","flags":null,"type":"*dispatcher_hosts"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.3"},{"path":"MinCost","tag":"MinCost","type":"*variable","value":"~*req.4"},{"path":"MaxCost","tag":"MaxCost","type":"*variable","value":"~*req.5"},{"path":"MaxCostStrategy","tag":"MaxCostStrategy","type":"*variable","value":"~*req.6"},{"path":"RateID","tag":"RateID","type":"*variable","value":"~*req.7"},{"path":"RateFilterIDs","tag":"RateFilterIDs","type":"*variable","value":"~*req.8"},{"path":"RateActivationTimes","tag":"RateActivationTimes","type":"*variable","value":"~*req.9"},{"path":"RateWeight","tag":"RateWeight","type":"*variable","value":"~*req.10"},{"path":"RateBlocker","tag":"RateBlocker","type":"*variable","value":"~*req.11"},{"path":"RateIntervalStart","tag":"RateIntervalStart","type":"*variable","value":"~*req.12"},{"path":"RateFixedFee","tag":"RateFixedFee","type":"*variable","value":"~*req.13"},{"path":"RateRecurrentFee","tag":"RateRecurrentFee","type":"*variable","value":"~*req.14"},{"path":"RateUnit","tag":"RateUnit","type":"*variable","value":"~*req.15"},{"path":"RateIncrement","tag":"RateIncrement","type":"*variable","value":"~*req.16"}],"file_name":"RateProfiles.csv","flags":null,"type":"*rate_profiles"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.3"},{"path":"Schedule","tag":"Schedule","type":"*variable","value":"~*req.4"},{"path":"TargetType","tag":"TargetType","type":"*variable","value":"~*req.5"},{"path":"TargetIDs","tag":"TargetIDs","type":"*variable","value":"~*req.6"},{"path":"ActionID","tag":"ActionID","type":"*variable","value":"~*req.7"},{"path":"ActionFilterIDs","tag":"ActionFilterIDs","type":"*variable","value":"~*req.8"},{"path":"ActionBlocker","tag":"ActionBlocker","type":"*variable","value":"~*req.9"},{"path":"ActionTTL","tag":"ActionTTL","type":"*variable","value":"~*req.10"},{"path":"ActionType","tag":"ActionType","type":"*variable","value":"~*req.11"},{"path":"ActionOpts","tag":"ActionOpts","type":"*variable","value":"~*req.12"},{"path":"ActionPath","tag":"ActionPath","type":"*variable","value":"~*req.13"},{"path":"ActionValue","tag":"ActionValue","type":"*variable","value":"~*req.14"}],"file_name":"ActionProfiles.csv","flags":null,"type":"*action_profiles"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.3"},{"path":"BalanceID","tag":"BalanceID","type":"*variable","value":"~*req.4"},{"path":"BalanceFilterIDs","tag":"BalanceFilterIDs","type":"*variable","value":"~*req.5"},{"path":"BalanceWeight","tag":"BalanceWeight","type":"*variable","value":"~*req.6"},{"path":"BalanceBlocker","tag":"BalanceBlocker","type":"*variable","value":"~*req.7"},{"path":"BalanceType","tag":"BalanceType","type":"*variable","value":"~*req.8"},{"path":"BalanceOpts","tag":"BalanceOpts","type":"*variable","value":"~*req.9"},{"path":"BalanceCostIncrements","tag":"BalanceCostIncrements","type":"*variable","value":"~*req.10"},{"path":"BalanceAttributeIDs","tag":"BalanceAttributeIDs","type":"*variable","value":"~*req.11"},{"path":"BalanceRateProfileIDs","tag":"BalanceRateProfileIDs","type":"*variable","value":"~*req.12"},{"path":"BalanceUnitFactors","tag":"BalanceUnitFactors","type":"*variable","value":"~*req.13"},{"path":"BalanceUnits","tag":"BalanceUnits","type":"*variable","value":"~*req.14"},{"path":"ThresholdIDs","tag":"ThresholdIDs","type":"*variable","value":"~*req.15"}],"file_name":"Accounts.csv","flags":null,"type":"*accounts"}],"dry_run":false,"enabled":false,"field_separator":",","id":"*default","lock_filename":".cgr.lck","run_delay":"0","tenant":"","tp_in_dir":"/var/spool/cgrates/loader/in","tp_out_dir":"/var/spool/cgrates/loader/out"}],"migrator":{"out_datadb_encoding":"msgpack","out_datadb_host":"127.0.0.1","out_datadb_name":"10","out_datadb_opts":{"redisCACertificate":"","redisClientCertificate":"","redisClientKey":"","redisCluster":false,"redisClusterOndownDelay":"0","redisClusterSync":"5s","redisSentinel":"","redisTLS":false},"out_datadb_password":"","out_datadb_port":"6379","out_datadb_type":"redis","out_datadb_user":"cgrates","out_stordb_host":"127.0.0.1","out_stordb_name":"cgrates","out_stordb_opts":{},"out_stordb_password":"","out_stordb_port":"3306","out_stordb_type":"mysql","out_stordb_user":"cgrates","users_filters":[]},"radius_agent":{"client_dictionaries":{"*default":"/usr/share/cgrates/radius/dict/"},"client_secrets":{"*default":"CGRateS.org"},"enabled":false,"listen_acct":"127.0.0.1:1813","listen_auth":"127.0.0.1:1812","listen_net":"udp","request_processors":[],"sessions_conns":["*internal"]},"rates":{"enabled":false,"indexed_selects":true,"nested_fields":false,"prefix_indexed_fields":[],"rate_indexed_selects":true,"rate_nested_fields":false,"rate_prefix_indexed_fields":[],"rate_suffix_indexed_fields":[],"suffix_indexed_fields":[],"verbosity":1000},"registrarc":{"dispatchers":{"hosts":[],"refresh_interval":"5m0s","registrars_conns":[]},"rpc":{"hosts":[],"refresh_interval":"5m0s","registrars_conns":[]}},"resources":{"enabled":false,"indexed_selects":true,"nested_fields":false,"prefix_indexed_fields":[],"store_interval":"","suffix_indexed_fields":[],"thresholds_conns":[]},"routes":{"accounts_conns":[],"attributes_conns":[],"default_opts":{"*context":"*routes","*routesProfilesCount":1},"default_ratio":1,"enabled":false,"indexed_selects":true,"nested_fields":false,"prefix_indexed_fields":[],"rates_conns":[],"resources_conns":[],"stats_conns":[],"suffix_indexed_fields":[]},"rpc_conns":{"*bijson_localhost":{"conns":[{"address":"127.0.0.1:2014","transport":"*birpc_json"}],"poolSize":0,"strategy":"*first"},"*birpc_internal":{"conns":[{"address":"*birpc_internal","transport":""}],"poolSize":0,"strategy":"*first"},"*internal":{"conns":[{"address":"*internal","transport":""}],"poolSize":0,"strategy":"*first"},"*localhost":{"conns":[{"address":"127.0.0.1:2012","transport":"*json"}],"poolSize":0,"strategy":"*first"}},"sessions":{"actions_conns":[],"alterable_fields":[],"attributes_conns":[],"cdrs_conns":[],"channel_sync_interval":"0","chargers_conns":[],"client_protocol":1,"debit_interval":"0","default_usage":{"*any":"3h0m0s","*data":"1048576","*sms":"1","*voice":"3h0m0s"},"enabled":false,"listen_bigob":"","listen_bijson":"127.0.0.1:2014","min_dur_low_balance":"0","replication_conns":[],"resources_conns":[],"routes_conns":[],"session_indexes":[],"session_ttl":"0","stats_conns":[],"stir":{"allowed_attest":["*any"],"default_attest":"A","payload_maxduration":"-1","privatekey_path":"","publickey_path":""},"store_session_costs":false,"terminate_attempts":5,"thresholds_conns":[]},"sip_agent":{"enabled":false,"listen":"127.0.0.1:5060","listen_net":"udp","request_processors":[],"retransmission_timer":"1s","sessions_conns":["*internal"],"timezone":""},"stats":{"enabled":false,"indexed_selects":true,"nested_fields":false,"prefix_indexed_fields":[],"store_interval":"","store_uncompressed_limit":0,"suffix_indexed_fields":[],"thresholds_conns":[]},"stor_db":{"db_host":"127.0.0.1","db_name":"cgrates","db_password":"","db_port":3306,"db_type":"*mysql","db_user":"cgrates","items":{"*cdrs":{"remote":false,"replicate":false},"*session_costs":{"remote":false,"replicate":false},"*tp_accounts":{"remote":false,"replicate":false},"*tp_action_profiles":{"remote":false,"replicate":false},"*tp_attributes":{"remote":false,"replicate":false},"*tp_chargers":{"remote":false,"replicate":false},"*tp_dispatcher_hosts":{"remote":false,"replicate":false},"*tp_dispatcher_profiles":{"remote":false,"replicate":false},"*tp_filters":{"remote":false,"replicate":false},"*tp_rate_profiles":{"remote":false,"replicate":false},"*tp_resources":{"remote":false,"replicate":false},"*tp_routes":{"remote":false,"replicate":false},"*tp_stats":{"remote":false,"replicate":false},"*tp_thresholds":{"remote":false,"replicate":false},"*versions":{"remote":false,"replicate":false}},"opts":{"mongoQueryTimeout":"10s","mysqlLocation":"Local","sqlConnMaxLifetime":0,"sqlMaxIdleConns":10,"sqlMaxOpenConns":100,"sslMode":"disable"},"prefix_indexed_fields":[],"remote_conns":null,"replication_conns":null,"string_indexed_fields":[]},"suretax":{"bill_to_number":"","business_unit":"","client_number":"","client_tracking":"~*req.CGRID","customer_number":"~*req.Subject","include_local_cost":false,"orig_number":"~*req.Subject","p2pplus4":"","p2pzipcode":"","plus4":"","regulatory_code":"03","response_group":"03","response_type":"D4","return_file_code":"0","sales_type_code":"R","tax_exemption_code_list":"","tax_included":"0","tax_situs_rule":"04","term_number":"~*req.Destination","timezone":"UTC","trans_type_code":"010101","unit_type":"00","units":"1","url":"","validation_key":"","zipcode":""},"templates":{"*asr":[{"mandatory":true,"path":"*diamreq.Session-Id","tag":"SessionId","type":"*variable","value":"~*req.Session-Id"},{"mandatory":true,"path":"*diamreq.Origin-Host","tag":"OriginHost","type":"*variable","value":"~*req.Destination-Host"},{"mandatory":true,"path":"*diamreq.Origin-Realm","tag":"OriginRealm","type":"*variable","value":"~*req.Destination-Realm"},{"mandatory":true,"path":"*diamreq.Destination-Realm","tag":"DestinationRealm","type":"*variable","value":"~*req.Origin-Realm"},{"mandatory":true,"path":"*diamreq.Destination-Host","tag":"DestinationHost","type":"*variable","value":"~*req.Origin-Host"},{"mandatory":true,"path":"*diamreq.Auth-Application-Id","tag":"AuthApplicationId","type":"*variable","value":"~*vars.*appid"}],"*cca":[{"mandatory":true,"path":"*rep.Session-Id","tag":"SessionId","type":"*variable","value":"~*req.Session-Id"},{"path":"*rep.Result-Code","tag":"ResultCode","type":"*constant","value":"2001"},{"mandatory":true,"path":"*rep.Origin-Host","tag":"OriginHost","type":"*variable","value":"~*vars.OriginHost"},{"mandatory":true,"path":"*rep.Origin-Realm","tag":"OriginRealm","type":"*variable","value":"~*vars.OriginRealm"},{"mandatory":true,"path":"*rep.Auth-Application-Id","tag":"AuthApplicationId","type":"*variable","value":"~*vars.*appid"},{"mandatory":true,"path":"*rep.CC-Request-Type","tag":"CCRequestType","type":"*variable","value":"~*req.CC-Request-Type"},{"mandatory":true,"path":"*rep.CC-Request-Number","tag":"CCRequestNumber","type":"*variable","value":"~*req.CC-Request-Number"}],"*cdrLog":[{"mandatory":true,"path":"*cdr.ToR","tag":"ToR","type":"*variable","value":"~*req.BalanceType"},{"mandatory":true,"path":"*cdr.OriginHost","tag":"OriginHost","type":"*constant","value":"127.0.0.1"},{"mandatory":true,"path":"*cdr.RequestType","tag":"RequestType","type":"*constant","value":"*none"},{"mandatory":true,"path":"*cdr.Tenant","tag":"Tenant","type":"*variable","value":"~*req.Tenant"},{"mandatory":true,"path":"*cdr.Account","tag":"Account","type":"*variable","value":"~*req.Account"},{"mandatory":true,"path":"*cdr.Subject","tag":"Subject","type":"*variable","value":"~*req.Account"},{"mandatory":true,"path":"*cdr.Cost","tag":"Cost","type":"*variable","value":"~*req.Cost"},{"mandatory":true,"path":"*cdr.Source","tag":"Source","type":"*constant","value":"*cdrLog"},{"mandatory":true,"path":"*cdr.Usage","tag":"Usage","type":"*constant","value":"1"},{"mandatory":true,"path":"*cdr.RunID","tag":"RunID","type":"*variable","value":"~*req.ActionType"},{"mandatory":true,"path":"*cdr.SetupTime","tag":"SetupTime","type":"*constant","value":"*now"},{"mandatory":true,"path":"*cdr.AnswerTime","tag":"AnswerTime","type":"*constant","value":"*now"},{"mandatory":true,"path":"*cdr.PreRated","tag":"PreRated","type":"*constant","value":"true"}],"*err":[{"mandatory":true,"path":"*rep.Session-Id","tag":"SessionId","type":"*variable","value":"~*req.Session-Id"},{"mandatory":true,"path":"*rep.Origin-Host","tag":"OriginHost","type":"*variable","value":"~*vars.OriginHost"},{"mandatory":true,"path":"*rep.Origin-Realm","tag":"OriginRealm","type":"*variable","value":"~*vars.OriginRealm"}],"*errSip":[{"mandatory":true,"path":"*rep.Request","tag":"Request","type":"*constant","value":"SIP/2.0 500 Internal Server Error"}],"*rar":[{"mandatory":true,"path":"*diamreq.Session-Id","tag":"SessionId","type":"*variable","value":"~*req.Session-Id"},{"mandatory":true,"path":"*diamreq.Origin-Host","tag":"OriginHost","type":"*variable","value":"~*req.Destination-Host"},{"mandatory":true,"path":"*diamreq.Origin-Realm","tag":"OriginRealm","type":"*variable","value":"~*req.Destination-Realm"},{"mandatory":true,"path":"*diamreq.Destination-Realm","tag":"DestinationRealm","type":"*variable","value":"~*req.Origin-Realm"},{"mandatory":true,"path":"*diamreq.Destination-Host","tag":"DestinationHost","type":"*variable","value":"~*req.Origin-Host"},{"mandatory":true,"path":"*diamreq.Auth-Application-Id","tag":"AuthApplicationId","type":"*variable","value":"~*vars.*appid"},{"path":"*diamreq.Re-Auth-Request-Type","tag":"ReAuthRequestType","type":"*constant","value":"0"}]},"thresholds":{"actions_conns":[],"enabled":false,"indexed_selects":true,"nested_fields":false,"prefix_indexed_fields":[],"store_interval":"","suffix_indexed_fields":[]},"tls":{"ca_certificate":"","client_certificate":"","client_key":"","server_certificate":"","server_key":"","server_name":"","server_policy":4}}` + expected := `{"accounts":{"attributes_conns":[],"enabled":false,"indexed_selects":true,"max_iterations":1000,"max_usage":"259200000000000","nested_fields":false,"prefix_indexed_fields":[],"rates_conns":[],"suffix_indexed_fields":[],"thresholds_conns":[]},"actions":{"accounts_conns":[],"cdrs_conns":[],"dynaprepaid_actionprofile":[],"ees_conns":[],"enabled":false,"indexed_selects":true,"nested_fields":false,"prefix_indexed_fields":[],"stats_conns":[],"suffix_indexed_fields":[],"tenants":[],"thresholds_conns":[]},"admins":{"actions_conns":[],"attributes_conns":[],"caches_conns":["*internal"],"ees_conns":[],"enabled":false},"analyzers":{"cleanup_interval":"1h0m0s","db_path":"/var/spool/cgrates/analyzers","enabled":false,"index_type":"*scorch","ttl":"24h0m0s"},"apiban":{"enabled":false,"keys":[]},"asterisk_agent":{"asterisk_conns":[{"address":"127.0.0.1:8088","alias":"","connect_attempts":3,"password":"CGRateS.org","reconnects":5,"user":"cgrates"}],"create_cdr":false,"enabled":false,"sessions_conns":["*birpc_internal"]},"attributes":{"admins_conns":[],"default_opts":{"*processRuns":1},"enabled":false,"indexed_selects":true,"nested_fields":false,"prefix_indexed_fields":[],"resources_conns":[],"stats_conns":[],"suffix_indexed_fields":[]},"caches":{"partitions":{"*account_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*accounts":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*action_profile_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*action_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*apiban":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":"2m0s"},"*attribute_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*attribute_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*caps_events":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*cdr_ids":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":"10m0s"},"*cdrs":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*charger_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*charger_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*closed_sessions":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":"10s"},"*diameter_messages":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":"3h0m0s"},"*dispatcher_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*dispatcher_hosts":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*dispatcher_loads":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*dispatcher_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*dispatcher_routes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*dispatchers":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*event_charges":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":"10s"},"*event_resources":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*filters":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*load_ids":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*rate_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*rate_profile_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*rate_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*replication_hosts":{"limit":0,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*resource_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*resource_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*resources":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*reverse_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*route_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*route_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*rpc_connections":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*rpc_responses":{"limit":0,"precache":false,"replicate":false,"static_ttl":false,"ttl":"2s"},"*session_costs":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*stat_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*statqueue_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*statqueues":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*stir":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":"3h0m0s"},"*threshold_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*threshold_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*thresholds":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_accounts":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_action_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_attributes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_chargers":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_dispatcher_hosts":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_dispatcher_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_filters":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_rate_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_resources":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_routes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_stats":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_thresholds":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*uch":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":"3h0m0s"},"*versions":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""}},"replication_conns":[]},"cdrs":{"accounts_conns":[],"actions_conns":[],"attributes_conns":[],"chargers_conns":[],"ees_conns":[],"enabled":false,"extra_fields":[],"online_cdr_exports":[],"rates_conns":[],"session_cost_retries":5,"stats_conns":[],"store_cdrs":true,"thresholds_conns":[]},"chargers":{"attributes_conns":[],"enabled":false,"indexed_selects":true,"nested_fields":false,"prefix_indexed_fields":[],"suffix_indexed_fields":[]},"config_db":{"db_host":"","db_name":"","db_password":"","db_port":0,"db_type":"*internal","db_user":"","items":{},"opts":{"mongoQueryTimeout":"10s","redisCACertificate":"","redisClientCertificate":"","redisClientKey":"","redisCluster":false,"redisClusterOndownDelay":"0","redisClusterSync":"5s","redisSentinel":"","redisTLS":false},"remote_conn_id":"","remote_conns":null,"replication_cache":"","replication_conns":null,"replication_filtered":false},"configs":{"enabled":false,"root_dir":"/var/spool/cgrates/configs","url":"/configs/"},"cores":{"caps":0,"caps_stats_interval":"0","caps_strategy":"*busy","shutdown_timeout":"1s"},"data_db":{"db_host":"127.0.0.1","db_name":"10","db_password":"","db_port":6379,"db_type":"*redis","db_user":"cgrates","items":{"*accounts":{"remote":false,"replicate":false},"*action_profiles":{"remote":false,"replicate":false},"*actions":{"remote":false,"replicate":false},"*attribute_profiles":{"remote":false,"replicate":false},"*charger_profiles":{"remote":false,"replicate":false},"*dispatcher_hosts":{"remote":false,"replicate":false},"*dispatcher_profiles":{"remote":false,"replicate":false},"*filters":{"remote":false,"replicate":false},"*indexes":{"remote":false,"replicate":false},"*load_ids":{"remote":false,"replicate":false},"*rate_profiles":{"remote":false,"replicate":false},"*resource_profiles":{"remote":false,"replicate":false},"*resources":{"remote":false,"replicate":false},"*route_profiles":{"remote":false,"replicate":false},"*statqueue_profiles":{"remote":false,"replicate":false},"*statqueues":{"remote":false,"replicate":false},"*threshold_profiles":{"remote":false,"replicate":false},"*thresholds":{"remote":false,"replicate":false}},"opts":{"mongoQueryTimeout":"10s","redisCACertificate":"","redisClientCertificate":"","redisClientKey":"","redisCluster":false,"redisClusterOndownDelay":"0","redisClusterSync":"5s","redisSentinel":"","redisTLS":false},"remote_conn_id":"","remote_conns":[],"replication_cache":"","replication_conns":[],"replication_filtered":false},"diameter_agent":{"asr_template":"","concurrent_requests":-1,"dictionaries_path":"/usr/share/cgrates/diameter/dict/","enabled":false,"forced_disconnect":"*none","listen":"127.0.0.1:3868","listen_net":"tcp","origin_host":"CGR-DA","origin_realm":"cgrates.org","product_name":"CGRateS","rar_template":"","request_processors":[],"sessions_conns":["*birpc_internal"],"synced_conn_requests":false,"vendor_id":0},"dispatchers":{"attributes_conns":[],"enabled":false,"indexed_selects":true,"nested_fields":false,"prefix_indexed_fields":[],"suffix_indexed_fields":[]},"dns_agent":{"enabled":false,"listen":"127.0.0.1:2053","listen_net":"udp","request_processors":[],"sessions_conns":["*internal"],"timezone":""},"ees":{"attributes_conns":[],"cache":{"*fileCSV":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":"5s"}},"enabled":false,"exporters":[{"attempts":1,"attribute_context":"","attribute_ids":[],"concurrent_requests":0,"export_path":"/var/spool/cgrates/ees","failed_posts_dir":"/var/spool/cgrates/failed_posts","fields":[],"filters":[],"flags":[],"id":"*default","opts":{},"synchronous":false,"timezone":"","type":"*none"}]},"ers":{"enabled":false,"partial_cache_ttl":"1s","readers":[{"cache_dump_fields":[],"concurrent_requests":1024,"fields":[{"mandatory":true,"path":"*cgreq.ToR","tag":"ToR","type":"*variable","value":"~*req.2"},{"mandatory":true,"path":"*cgreq.OriginID","tag":"OriginID","type":"*variable","value":"~*req.3"},{"mandatory":true,"path":"*cgreq.RequestType","tag":"RequestType","type":"*variable","value":"~*req.4"},{"mandatory":true,"path":"*cgreq.Tenant","tag":"Tenant","type":"*variable","value":"~*req.6"},{"mandatory":true,"path":"*cgreq.Category","tag":"Category","type":"*variable","value":"~*req.7"},{"mandatory":true,"path":"*cgreq.Account","tag":"Account","type":"*variable","value":"~*req.8"},{"mandatory":true,"path":"*cgreq.Subject","tag":"Subject","type":"*variable","value":"~*req.9"},{"mandatory":true,"path":"*cgreq.Destination","tag":"Destination","type":"*variable","value":"~*req.10"},{"mandatory":true,"path":"*cgreq.SetupTime","tag":"SetupTime","type":"*variable","value":"~*req.11"},{"mandatory":true,"path":"*cgreq.AnswerTime","tag":"AnswerTime","type":"*variable","value":"~*req.12"},{"mandatory":true,"path":"*cgreq.Usage","tag":"Usage","type":"*variable","value":"~*req.13"}],"filters":[],"flags":[],"id":"*default","opts":{"csvFieldSeparator":",","csvHeaderDefineChar":":","csvRowLength":0,"natsSubject":"cgrates_cdrs","partialCacheAction":"*none","partialOrderField":"~*req.AnswerTime","xmlRootPath":""},"partial_commit_fields":[],"processed_path":"/var/spool/cgrates/ers/out","run_delay":"0","source_path":"/var/spool/cgrates/ers/in","tenant":"","timezone":"","type":"*none"}],"sessions_conns":["*internal"]},"filters":{"admins_conns":[],"resources_conns":[],"stats_conns":[]},"freeswitch_agent":{"create_cdr":false,"empty_balance_ann_file":"","empty_balance_context":"","enabled":false,"event_socket_conns":[{"address":"127.0.0.1:8021","alias":"127.0.0.1:8021","password":"ClueCon","reconnects":5}],"extra_fields":[],"low_balance_ann_file":"","max_wait_connection":"2s","sessions_conns":["*birpc_internal"],"subscribe_park":true},"general":{"connect_attempts":5,"connect_timeout":"1s","dbdata_encoding":"*msgpack","default_caching":"*reload","default_category":"call","default_request_type":"*rated","default_tenant":"cgrates.org","default_timezone":"Local","digest_equal":":","digest_separator":",","failed_posts_dir":"/var/spool/cgrates/failed_posts","failed_posts_ttl":"5s","locking_timeout":"0","log_level":6,"logger":"*syslog","max_parallel_conns":100,"node_id":"ENGINE1","poster_attempts":3,"reconnects":-1,"reply_timeout":"2s","rounding_decimals":5,"rsr_separator":";","tpexport_dir":"/var/spool/cgrates/tpe"},"http":{"auth_users":{},"client_opts":{"dialFallbackDelay":"300ms","dialKeepAlive":"30s","dialTimeout":"30s","disableCompression":false,"disableKeepAlives":false,"expectContinueTimeout":"0","forceAttemptHttp2":true,"idleConnTimeout":"90s","maxConnsPerHost":0,"maxIdleConns":100,"maxIdleConnsPerHost":2,"responseHeaderTimeout":"0","skipTlsVerify":false,"tlsHandshakeTimeout":"10s"},"freeswitch_cdrs_url":"/freeswitch_json","http_cdrs":"/cdr_http","json_rpc_url":"/jsonrpc","registrars_url":"/registrar","use_basic_auth":false,"ws_url":"/ws"},"http_agent":[],"kamailio_agent":{"create_cdr":false,"enabled":false,"evapi_conns":[{"address":"127.0.0.1:8448","alias":"","reconnects":5}],"sessions_conns":["*birpc_internal"],"timezone":""},"listen":{"http":"127.0.0.1:2080","http_tls":"127.0.0.1:2280","rpc_gob":"127.0.0.1:2013","rpc_gob_tls":"127.0.0.1:2023","rpc_json":"127.0.0.1:2012","rpc_json_tls":"127.0.0.1:2022"},"loader":{"actions_conns":["*localhost"],"caches_conns":["*localhost"],"data_path":"./","disable_reverse":false,"field_separator":",","gapi_credentials":".gapi/credentials.json","gapi_token":".gapi/token.json","tpid":""},"loaders":[{"caches_conns":["*internal"],"data":[{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"Type","tag":"Type","type":"*variable","value":"~*req.2"},{"path":"Element","tag":"Element","type":"*variable","value":"~*req.3"},{"path":"Values","tag":"Values","type":"*variable","value":"~*req.4"}],"file_name":"Filters.csv","flags":null,"type":"*filters"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"TenantID","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ProfileID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.3"},{"path":"AttributeFilterIDs","tag":"AttributeFilterIDs","type":"*variable","value":"~*req.4"},{"path":"Path","tag":"Path","type":"*variable","value":"~*req.5"},{"path":"Type","tag":"Type","type":"*variable","value":"~*req.6"},{"path":"Value","tag":"Value","type":"*variable","value":"~*req.7"},{"path":"Blocker","tag":"Blocker","type":"*variable","value":"~*req.8"}],"file_name":"Attributes.csv","flags":null,"type":"*attributes"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.3"},{"path":"UsageTTL","tag":"TTL","type":"*variable","value":"~*req.4"},{"path":"Limit","tag":"Limit","type":"*variable","value":"~*req.5"},{"path":"AllocationMessage","tag":"AllocationMessage","type":"*variable","value":"~*req.6"},{"path":"Blocker","tag":"Blocker","type":"*variable","value":"~*req.7"},{"path":"Stored","tag":"Stored","type":"*variable","value":"~*req.8"},{"path":"ThresholdIDs","tag":"ThresholdIDs","type":"*variable","value":"~*req.9"}],"file_name":"Resources.csv","flags":null,"type":"*resources"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.3"},{"path":"QueueLength","tag":"QueueLength","type":"*variable","value":"~*req.4"},{"path":"TTL","tag":"TTL","type":"*variable","value":"~*req.5"},{"path":"MinItems","tag":"MinItems","type":"*variable","value":"~*req.6"},{"path":"MetricIDs","tag":"MetricIDs","type":"*variable","value":"~*req.7"},{"path":"MetricFilterIDs","tag":"MetricFilterIDs","type":"*variable","value":"~*req.8"},{"path":"Blocker","tag":"Blocker","type":"*variable","value":"~*req.9"},{"path":"Stored","tag":"Stored","type":"*variable","value":"~*req.10"},{"path":"ThresholdIDs","tag":"ThresholdIDs","type":"*variable","value":"~*req.11"}],"file_name":"Stats.csv","flags":null,"type":"*stats"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.3"},{"path":"MaxHits","tag":"MaxHits","type":"*variable","value":"~*req.4"},{"path":"MinHits","tag":"MinHits","type":"*variable","value":"~*req.5"},{"path":"MinSleep","tag":"MinSleep","type":"*variable","value":"~*req.6"},{"path":"Blocker","tag":"Blocker","type":"*variable","value":"~*req.7"},{"path":"ActionProfileIDs","tag":"ActionProfileIDs","type":"*variable","value":"~*req.8"},{"path":"Async","tag":"Async","type":"*variable","value":"~*req.9"}],"file_name":"Thresholds.csv","flags":null,"type":"*thresholds"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.3"},{"path":"Sorting","tag":"Sorting","type":"*variable","value":"~*req.4"},{"path":"SortingParameters","tag":"SortingParameters","type":"*variable","value":"~*req.5"},{"path":"RouteID","tag":"RouteID","type":"*variable","value":"~*req.6"},{"path":"RouteFilterIDs","tag":"RouteFilterIDs","type":"*variable","value":"~*req.7"},{"path":"RouteAccountIDs","tag":"RouteAccountIDs","type":"*variable","value":"~*req.8"},{"path":"RouteRatingPlanIDs","tag":"RouteRatingPlanIDs","type":"*variable","value":"~*req.9"},{"path":"RouteResourceIDs","tag":"RouteResourceIDs","type":"*variable","value":"~*req.10"},{"path":"RouteStatIDs","tag":"RouteStatIDs","type":"*variable","value":"~*req.11"},{"path":"RouteWeight","tag":"RouteWeight","type":"*variable","value":"~*req.12"},{"path":"RouteBlocker","tag":"RouteBlocker","type":"*variable","value":"~*req.13"},{"path":"RouteParameters","tag":"RouteParameters","type":"*variable","value":"~*req.14"}],"file_name":"Routes.csv","flags":null,"type":"*routes"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.3"},{"path":"RunID","tag":"RunID","type":"*variable","value":"~*req.4"},{"path":"AttributeIDs","tag":"AttributeIDs","type":"*variable","value":"~*req.5"}],"file_name":"Chargers.csv","flags":null,"type":"*chargers"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.3"},{"path":"Strategy","tag":"Strategy","type":"*variable","value":"~*req.4"},{"path":"StrategyParameters","tag":"StrategyParameters","type":"*variable","value":"~*req.5"},{"path":"ConnID","tag":"ConnID","type":"*variable","value":"~*req.6"},{"path":"ConnFilterIDs","tag":"ConnFilterIDs","type":"*variable","value":"~*req.7"},{"path":"ConnWeight","tag":"ConnWeight","type":"*variable","value":"~*req.8"},{"path":"ConnBlocker","tag":"ConnBlocker","type":"*variable","value":"~*req.9"},{"path":"ConnParameters","tag":"ConnParameters","type":"*variable","value":"~*req.10"}],"file_name":"DispatcherProfiles.csv","flags":null,"type":"*dispatchers"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"Address","tag":"Address","type":"*variable","value":"~*req.2"},{"path":"Transport","tag":"Transport","type":"*variable","value":"~*req.3"},{"path":"ConnectAttempts","tag":"ConnectAttempts","type":"*variable","value":"~*req.4"},{"path":"Reconnects","tag":"Reconnects","type":"*variable","value":"~*req.5"},{"path":"ConnectTimeout","tag":"ConnectTimeout","type":"*variable","value":"~*req.6"},{"path":"ReplyTimeout","tag":"ReplyTimeout","type":"*variable","value":"~*req.7"},{"path":"TLS","tag":"TLS","type":"*variable","value":"~*req.8"},{"path":"ClientKey","tag":"ClientKey","type":"*variable","value":"~*req.9"},{"path":"ClientCertificate","tag":"ClientCertificate","type":"*variable","value":"~*req.10"},{"path":"CaCertificate","tag":"CaCertificate","type":"*variable","value":"~*req.11"}],"file_name":"DispatcherHosts.csv","flags":null,"type":"*dispatcher_hosts"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.3"},{"path":"MinCost","tag":"MinCost","type":"*variable","value":"~*req.4"},{"path":"MaxCost","tag":"MaxCost","type":"*variable","value":"~*req.5"},{"path":"MaxCostStrategy","tag":"MaxCostStrategy","type":"*variable","value":"~*req.6"},{"path":"RateID","tag":"RateID","type":"*variable","value":"~*req.7"},{"path":"RateFilterIDs","tag":"RateFilterIDs","type":"*variable","value":"~*req.8"},{"path":"RateActivationTimes","tag":"RateActivationTimes","type":"*variable","value":"~*req.9"},{"path":"RateWeight","tag":"RateWeight","type":"*variable","value":"~*req.10"},{"path":"RateBlocker","tag":"RateBlocker","type":"*variable","value":"~*req.11"},{"path":"RateIntervalStart","tag":"RateIntervalStart","type":"*variable","value":"~*req.12"},{"path":"RateFixedFee","tag":"RateFixedFee","type":"*variable","value":"~*req.13"},{"path":"RateRecurrentFee","tag":"RateRecurrentFee","type":"*variable","value":"~*req.14"},{"path":"RateUnit","tag":"RateUnit","type":"*variable","value":"~*req.15"},{"path":"RateIncrement","tag":"RateIncrement","type":"*variable","value":"~*req.16"}],"file_name":"RateProfiles.csv","flags":null,"type":"*rate_profiles"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.3"},{"path":"Schedule","tag":"Schedule","type":"*variable","value":"~*req.4"},{"path":"TargetType","tag":"TargetType","type":"*variable","value":"~*req.5"},{"path":"TargetIDs","tag":"TargetIDs","type":"*variable","value":"~*req.6"},{"path":"ActionID","tag":"ActionID","type":"*variable","value":"~*req.7"},{"path":"ActionFilterIDs","tag":"ActionFilterIDs","type":"*variable","value":"~*req.8"},{"path":"ActionBlocker","tag":"ActionBlocker","type":"*variable","value":"~*req.9"},{"path":"ActionTTL","tag":"ActionTTL","type":"*variable","value":"~*req.10"},{"path":"ActionType","tag":"ActionType","type":"*variable","value":"~*req.11"},{"path":"ActionOpts","tag":"ActionOpts","type":"*variable","value":"~*req.12"},{"path":"ActionPath","tag":"ActionPath","type":"*variable","value":"~*req.13"},{"path":"ActionValue","tag":"ActionValue","type":"*variable","value":"~*req.14"}],"file_name":"ActionProfiles.csv","flags":null,"type":"*action_profiles"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.3"},{"path":"BalanceID","tag":"BalanceID","type":"*variable","value":"~*req.4"},{"path":"BalanceFilterIDs","tag":"BalanceFilterIDs","type":"*variable","value":"~*req.5"},{"path":"BalanceWeight","tag":"BalanceWeight","type":"*variable","value":"~*req.6"},{"path":"BalanceBlocker","tag":"BalanceBlocker","type":"*variable","value":"~*req.7"},{"path":"BalanceType","tag":"BalanceType","type":"*variable","value":"~*req.8"},{"path":"BalanceOpts","tag":"BalanceOpts","type":"*variable","value":"~*req.9"},{"path":"BalanceCostIncrements","tag":"BalanceCostIncrements","type":"*variable","value":"~*req.10"},{"path":"BalanceAttributeIDs","tag":"BalanceAttributeIDs","type":"*variable","value":"~*req.11"},{"path":"BalanceRateProfileIDs","tag":"BalanceRateProfileIDs","type":"*variable","value":"~*req.12"},{"path":"BalanceUnitFactors","tag":"BalanceUnitFactors","type":"*variable","value":"~*req.13"},{"path":"BalanceUnits","tag":"BalanceUnits","type":"*variable","value":"~*req.14"},{"path":"ThresholdIDs","tag":"ThresholdIDs","type":"*variable","value":"~*req.15"}],"file_name":"Accounts.csv","flags":null,"type":"*accounts"}],"dry_run":false,"enabled":false,"field_separator":",","id":"*default","lock_filename":".cgr.lck","run_delay":"0","tenant":"","tp_in_dir":"/var/spool/cgrates/loader/in","tp_out_dir":"/var/spool/cgrates/loader/out"}],"migrator":{"out_datadb_encoding":"msgpack","out_datadb_host":"127.0.0.1","out_datadb_name":"10","out_datadb_opts":{"redisCACertificate":"","redisClientCertificate":"","redisClientKey":"","redisCluster":false,"redisClusterOndownDelay":"0","redisClusterSync":"5s","redisSentinel":"","redisTLS":false},"out_datadb_password":"","out_datadb_port":"6379","out_datadb_type":"redis","out_datadb_user":"cgrates","out_stordb_host":"127.0.0.1","out_stordb_name":"cgrates","out_stordb_opts":{},"out_stordb_password":"","out_stordb_port":"3306","out_stordb_type":"mysql","out_stordb_user":"cgrates","users_filters":[]},"radius_agent":{"client_dictionaries":{"*default":"/usr/share/cgrates/radius/dict/"},"client_secrets":{"*default":"CGRateS.org"},"enabled":false,"listen_acct":"127.0.0.1:1813","listen_auth":"127.0.0.1:1812","listen_net":"udp","request_processors":[],"sessions_conns":["*internal"]},"rates":{"enabled":false,"indexed_selects":true,"nested_fields":false,"prefix_indexed_fields":[],"rate_indexed_selects":true,"rate_nested_fields":false,"rate_prefix_indexed_fields":[],"rate_suffix_indexed_fields":[],"suffix_indexed_fields":[],"verbosity":1000},"registrarc":{"dispatchers":{"hosts":[],"refresh_interval":"5m0s","registrars_conns":[]},"rpc":{"hosts":[],"refresh_interval":"5m0s","registrars_conns":[]}},"resources":{"enabled":false,"indexed_selects":true,"nested_fields":false,"prefix_indexed_fields":[],"store_interval":"","suffix_indexed_fields":[],"thresholds_conns":[]},"routes":{"accounts_conns":[],"attributes_conns":[],"default_opts":{"*context":"*routes","*routesProfilesCount":1},"default_ratio":1,"enabled":false,"indexed_selects":true,"nested_fields":false,"prefix_indexed_fields":[],"rates_conns":[],"resources_conns":[],"stats_conns":[],"suffix_indexed_fields":[]},"rpc_conns":{"*bijson_localhost":{"conns":[{"address":"127.0.0.1:2014","transport":"*birpc_json"}],"poolSize":0,"strategy":"*first"},"*birpc_internal":{"conns":[{"address":"*birpc_internal","transport":""}],"poolSize":0,"strategy":"*first"},"*internal":{"conns":[{"address":"*internal","transport":""}],"poolSize":0,"strategy":"*first"},"*localhost":{"conns":[{"address":"127.0.0.1:2012","transport":"*json"}],"poolSize":0,"strategy":"*first"}},"sessions":{"actions_conns":[],"alterable_fields":[],"attributes_conns":[],"cdrs_conns":[],"channel_sync_interval":"0","chargers_conns":[],"client_protocol":1,"debit_interval":"0","default_usage":{"*any":"3h0m0s","*data":"1048576","*sms":"1","*voice":"3h0m0s"},"enabled":false,"listen_bigob":"","listen_bijson":"127.0.0.1:2014","min_dur_low_balance":"0","replication_conns":[],"resources_conns":[],"routes_conns":[],"session_indexes":[],"session_ttl":"0","stats_conns":[],"stir":{"allowed_attest":["*any"],"default_attest":"A","payload_maxduration":"-1","privatekey_path":"","publickey_path":""},"store_session_costs":false,"terminate_attempts":5,"thresholds_conns":[]},"sip_agent":{"enabled":false,"listen":"127.0.0.1:5060","listen_net":"udp","request_processors":[],"retransmission_timer":"1s","sessions_conns":["*internal"],"timezone":""},"stats":{"enabled":false,"indexed_selects":true,"nested_fields":false,"prefix_indexed_fields":[],"store_interval":"","store_uncompressed_limit":0,"suffix_indexed_fields":[],"thresholds_conns":[]},"stor_db":{"db_host":"127.0.0.1","db_name":"cgrates","db_password":"","db_port":3306,"db_type":"*mysql","db_user":"cgrates","items":{"*cdrs":{"remote":false,"replicate":false},"*session_costs":{"remote":false,"replicate":false},"*tp_accounts":{"remote":false,"replicate":false},"*tp_action_profiles":{"remote":false,"replicate":false},"*tp_attributes":{"remote":false,"replicate":false},"*tp_chargers":{"remote":false,"replicate":false},"*tp_dispatcher_hosts":{"remote":false,"replicate":false},"*tp_dispatcher_profiles":{"remote":false,"replicate":false},"*tp_filters":{"remote":false,"replicate":false},"*tp_rate_profiles":{"remote":false,"replicate":false},"*tp_resources":{"remote":false,"replicate":false},"*tp_routes":{"remote":false,"replicate":false},"*tp_stats":{"remote":false,"replicate":false},"*tp_thresholds":{"remote":false,"replicate":false},"*versions":{"remote":false,"replicate":false}},"opts":{"mongoQueryTimeout":"10s","mysqlLocation":"Local","sqlConnMaxLifetime":0,"sqlMaxIdleConns":10,"sqlMaxOpenConns":100,"sslMode":"disable"},"prefix_indexed_fields":[],"remote_conns":null,"replication_conns":null,"string_indexed_fields":[]},"suretax":{"bill_to_number":"","business_unit":"","client_number":"","client_tracking":"~*req.CGRID","customer_number":"~*req.Subject","include_local_cost":false,"orig_number":"~*req.Subject","p2pplus4":"","p2pzipcode":"","plus4":"","regulatory_code":"03","response_group":"03","response_type":"D4","return_file_code":"0","sales_type_code":"R","tax_exemption_code_list":"","tax_included":"0","tax_situs_rule":"04","term_number":"~*req.Destination","timezone":"UTC","trans_type_code":"010101","unit_type":"00","units":"1","url":"","validation_key":"","zipcode":""},"templates":{"*asr":[{"mandatory":true,"path":"*diamreq.Session-Id","tag":"SessionId","type":"*variable","value":"~*req.Session-Id"},{"mandatory":true,"path":"*diamreq.Origin-Host","tag":"OriginHost","type":"*variable","value":"~*req.Destination-Host"},{"mandatory":true,"path":"*diamreq.Origin-Realm","tag":"OriginRealm","type":"*variable","value":"~*req.Destination-Realm"},{"mandatory":true,"path":"*diamreq.Destination-Realm","tag":"DestinationRealm","type":"*variable","value":"~*req.Origin-Realm"},{"mandatory":true,"path":"*diamreq.Destination-Host","tag":"DestinationHost","type":"*variable","value":"~*req.Origin-Host"},{"mandatory":true,"path":"*diamreq.Auth-Application-Id","tag":"AuthApplicationId","type":"*variable","value":"~*vars.*appid"}],"*cca":[{"mandatory":true,"path":"*rep.Session-Id","tag":"SessionId","type":"*variable","value":"~*req.Session-Id"},{"path":"*rep.Result-Code","tag":"ResultCode","type":"*constant","value":"2001"},{"mandatory":true,"path":"*rep.Origin-Host","tag":"OriginHost","type":"*variable","value":"~*vars.OriginHost"},{"mandatory":true,"path":"*rep.Origin-Realm","tag":"OriginRealm","type":"*variable","value":"~*vars.OriginRealm"},{"mandatory":true,"path":"*rep.Auth-Application-Id","tag":"AuthApplicationId","type":"*variable","value":"~*vars.*appid"},{"mandatory":true,"path":"*rep.CC-Request-Type","tag":"CCRequestType","type":"*variable","value":"~*req.CC-Request-Type"},{"mandatory":true,"path":"*rep.CC-Request-Number","tag":"CCRequestNumber","type":"*variable","value":"~*req.CC-Request-Number"}],"*cdrLog":[{"mandatory":true,"path":"*cdr.ToR","tag":"ToR","type":"*variable","value":"~*req.BalanceType"},{"mandatory":true,"path":"*cdr.OriginHost","tag":"OriginHost","type":"*constant","value":"127.0.0.1"},{"mandatory":true,"path":"*cdr.RequestType","tag":"RequestType","type":"*constant","value":"*none"},{"mandatory":true,"path":"*cdr.Tenant","tag":"Tenant","type":"*variable","value":"~*req.Tenant"},{"mandatory":true,"path":"*cdr.Account","tag":"Account","type":"*variable","value":"~*req.Account"},{"mandatory":true,"path":"*cdr.Subject","tag":"Subject","type":"*variable","value":"~*req.Account"},{"mandatory":true,"path":"*cdr.Cost","tag":"Cost","type":"*variable","value":"~*req.Cost"},{"mandatory":true,"path":"*cdr.Source","tag":"Source","type":"*constant","value":"*cdrLog"},{"mandatory":true,"path":"*cdr.Usage","tag":"Usage","type":"*constant","value":"1"},{"mandatory":true,"path":"*cdr.RunID","tag":"RunID","type":"*variable","value":"~*req.ActionType"},{"mandatory":true,"path":"*cdr.SetupTime","tag":"SetupTime","type":"*constant","value":"*now"},{"mandatory":true,"path":"*cdr.AnswerTime","tag":"AnswerTime","type":"*constant","value":"*now"},{"mandatory":true,"path":"*cdr.PreRated","tag":"PreRated","type":"*constant","value":"true"}],"*err":[{"mandatory":true,"path":"*rep.Session-Id","tag":"SessionId","type":"*variable","value":"~*req.Session-Id"},{"mandatory":true,"path":"*rep.Origin-Host","tag":"OriginHost","type":"*variable","value":"~*vars.OriginHost"},{"mandatory":true,"path":"*rep.Origin-Realm","tag":"OriginRealm","type":"*variable","value":"~*vars.OriginRealm"}],"*errSip":[{"mandatory":true,"path":"*rep.Request","tag":"Request","type":"*constant","value":"SIP/2.0 500 Internal Server Error"}],"*rar":[{"mandatory":true,"path":"*diamreq.Session-Id","tag":"SessionId","type":"*variable","value":"~*req.Session-Id"},{"mandatory":true,"path":"*diamreq.Origin-Host","tag":"OriginHost","type":"*variable","value":"~*req.Destination-Host"},{"mandatory":true,"path":"*diamreq.Origin-Realm","tag":"OriginRealm","type":"*variable","value":"~*req.Destination-Realm"},{"mandatory":true,"path":"*diamreq.Destination-Realm","tag":"DestinationRealm","type":"*variable","value":"~*req.Origin-Realm"},{"mandatory":true,"path":"*diamreq.Destination-Host","tag":"DestinationHost","type":"*variable","value":"~*req.Origin-Host"},{"mandatory":true,"path":"*diamreq.Auth-Application-Id","tag":"AuthApplicationId","type":"*variable","value":"~*vars.*appid"},{"path":"*diamreq.Re-Auth-Request-Type","tag":"ReAuthRequestType","type":"*constant","value":"0"}]},"thresholds":{"actions_conns":[],"enabled":false,"indexed_selects":true,"nested_fields":false,"prefix_indexed_fields":[],"store_interval":"","suffix_indexed_fields":[]},"tls":{"ca_certificate":"","client_certificate":"","client_key":"","server_certificate":"","server_key":"","server_name":"","server_policy":4}}` cgrCfg, err := NewCGRConfigFromJSONStringWithDefaults(cfgJSON) if err != nil { t.Fatal(err) @@ -5946,8 +5932,10 @@ func TestSetCfgInDb(t *testing.T) { StringIndexedFields: &[]string{"field1"}, SuffixIndexedFields: &[]string{"field1"}, PrefixIndexedFields: &[]string{"field1"}, - ProcessRuns: 2, - NestedFields: true, + DefaultOpts: map[string]interface{}{ + utils.OptsAttributesProcessRuns: float64(2), + }, + NestedFields: true, } cfg.rldChans[DataDBJSON] = make(chan struct{}, 1) cfg.rldChans[AttributeSJSON] = make(chan struct{}, 1) @@ -5962,8 +5950,10 @@ func TestSetCfgInDb(t *testing.T) { String_indexed_fields: &[]string{"field2"}, Suffix_indexed_fields: &[]string{"field2"}, Prefix_indexed_fields: &[]string{"field2"}, - Process_runs: utils.IntPointer(3), - Nested_fields: utils.BoolPointer(false), + Default_opts: map[string]interface{}{ + utils.OptsAttributesProcessRuns: float64(3), + }, + Nested_fields: utils.BoolPointer(false), }, }, } @@ -5976,8 +5966,10 @@ func TestSetCfgInDb(t *testing.T) { String_indexed_fields: &[]string{"field2"}, Suffix_indexed_fields: &[]string{"field2"}, Prefix_indexed_fields: &[]string{"field2"}, - Process_runs: utils.IntPointer(3), - Nested_fields: utils.BoolPointer(false), + Default_opts: map[string]interface{}{ + utils.OptsAttributesProcessRuns: float64(3), + }, + Nested_fields: utils.BoolPointer(false), } var reply string if err := cfg.V1SetConfig(context.Background(), args, &reply); err != nil { @@ -6006,8 +5998,10 @@ func TestSetNilCfgInDb(t *testing.T) { StringIndexedFields: &[]string{"field1"}, SuffixIndexedFields: &[]string{"field1"}, PrefixIndexedFields: &[]string{"field1"}, - ProcessRuns: 2, - NestedFields: true, + DefaultOpts: map[string]interface{}{ + utils.OptsAttributesProcessRuns: float64(2), + }, + NestedFields: true, } cfg.rldChans[DataDBJSON] = make(chan struct{}, 1) cfg.rldChans[AttributeSJSON] = make(chan struct{}, 1) @@ -6017,7 +6011,9 @@ func TestSetNilCfgInDb(t *testing.T) { "attributes": attributes, }, } - expected := &AttributeSJsonCfg{} + expected := &AttributeSJsonCfg{ + Default_opts: make(map[string]interface{}), + } var reply string if err := cfg.V1SetConfig(context.Background(), args, &reply); err != nil { t.Error(err) @@ -6028,7 +6024,7 @@ func TestSetNilCfgInDb(t *testing.T) { t.Error(err) } if !reflect.DeepEqual(expected, rcv) { - t.Errorf("Expected %v \n but received \n %v", expected, rcv) + t.Errorf("Expected %v \n but received \n %v", utils.ToJSON(expected), utils.ToJSON(rcv)) } } @@ -6045,8 +6041,10 @@ func TestReloadCfgInDb(t *testing.T) { StringIndexedFields: &[]string{"field1"}, SuffixIndexedFields: &[]string{"field1"}, PrefixIndexedFields: &[]string{"field1"}, - ProcessRuns: 2, - NestedFields: true, + DefaultOpts: map[string]interface{}{ + utils.OptsAttributesProcessRuns: float64(2), + }, + NestedFields: true, } var reply string cfg.rldChans[AttributeSJSON] = make(chan struct{}, 1) @@ -6061,8 +6059,10 @@ func TestReloadCfgInDb(t *testing.T) { String_indexed_fields: &[]string{"field2"}, Suffix_indexed_fields: &[]string{"field2"}, Prefix_indexed_fields: &[]string{"field2"}, - Process_runs: utils.IntPointer(3), - Nested_fields: utils.BoolPointer(false), + Default_opts: map[string]interface{}{ + utils.OptsAttributesProcessRuns: float64(3), + }, + Nested_fields: utils.BoolPointer(false), } db.SetSection(context.Background(), AttributeSJSON, jsn) expected := &AttributeSCfg{ @@ -6074,8 +6074,10 @@ func TestReloadCfgInDb(t *testing.T) { StringIndexedFields: &[]string{"field2"}, SuffixIndexedFields: &[]string{"field2"}, PrefixIndexedFields: &[]string{"field2"}, - ProcessRuns: 3, - NestedFields: false, + DefaultOpts: map[string]interface{}{ + utils.OptsAttributesProcessRuns: float64(3), + }, + NestedFields: false, } args2 := &ReloadArgs{ Section: AttributeSJSON, diff --git a/config/configsanity.go b/config/configsanity.go index 30b47fe0a..55f3508b5 100644 --- a/config/configsanity.go +++ b/config/configsanity.go @@ -544,7 +544,11 @@ func (cfg *CGRConfig) checkConfigSanity() error { } if cfg.attributeSCfg.Enabled { - if cfg.attributeSCfg.ProcessRuns < 1 { + processRuns, err := utils.IfaceAsTInt64(cfg.attributeSCfg.DefaultOpts[utils.OptsAttributesProcessRuns]) + if err != nil { + return fmt.Errorf("<%s> invalid type", utils.AttributeS) + } + if processRuns < 1 { return fmt.Errorf("<%s> process_runs needs to be bigger than 0", utils.AttributeS) } } diff --git a/config/configsanity_test.go b/config/configsanity_test.go index 5bcec3e75..20c11a771 100644 --- a/config/configsanity_test.go +++ b/config/configsanity_test.go @@ -986,8 +986,10 @@ func TestConfigSanityAttributesCfg(t *testing.T) { cfg := NewDefaultCGRConfig() cfg.attributeSCfg = &AttributeSCfg{ - Enabled: true, - ProcessRuns: -1, + Enabled: true, + DefaultOpts: map[string]interface{}{ + utils.OptsAttributesProcessRuns: float64(0), + }, } expected := " process_runs needs to be bigger than 0" if err := cfg.checkConfigSanity(); err == nil || err.Error() != expected { diff --git a/ees/ees.go b/ees/ees.go index a17f3ca9a..7bbdf21ed 100644 --- a/ees/ees.go +++ b/ees/ees.go @@ -104,17 +104,10 @@ func (eeS *EventExporterS) attrSProcessEvent(cgrEv *utils.CGREvent, attrIDs []st cgrEv.APIOpts = make(map[string]interface{}) } cgrEv.APIOpts[utils.Subsys] = utils.MetaEEs - var processRuns *int - if val, has := cgrEv.APIOpts[utils.OptsAttributesProcessRuns]; has { - if v, err := utils.IfaceAsTInt64(val); err == nil { - processRuns = utils.IntPointer(int(v)) - } - } cgrEv.APIOpts[utils.OptsContext] = ctx attrArgs := &engine.AttrArgsProcessEvent{ AttributeIDs: attrIDs, CGREvent: cgrEv, - ProcessRuns: processRuns, } if err = eeS.connMgr.Call(context.TODO(), eeS.cfg.EEsNoLksCfg().AttributeSConns, diff --git a/engine/attributes.go b/engine/attributes.go index 31e894829..6dacb29cb 100644 --- a/engine/attributes.go +++ b/engine/attributes.go @@ -130,7 +130,6 @@ func (attrReply *AttrSProcessEventReply) Digest() (rplyDigest string) { // AttrArgsProcessEvent arguments used for proccess event type AttrArgsProcessEvent struct { AttributeIDs []string - ProcessRuns *int // number of loops for ProcessEvent *utils.CGREvent clnb bool //rpcclonable } @@ -157,14 +156,8 @@ func (attr *AttrArgsProcessEvent) Clone() *AttrArgsProcessEvent { attrIDs[i] = id } } - var procRuns *int - if attr.ProcessRuns != nil { - procRuns = new(int) - *procRuns = *attr.ProcessRuns - } return &AttrArgsProcessEvent{ AttributeIDs: attrIDs, - ProcessRuns: procRuns, CGREvent: attr.CGREvent.Clone(), } } @@ -270,10 +263,15 @@ func (alS *AttributeService) V1ProcessEvent(ctx *context.Context, args *AttrArgs tnt = alS.cgrcfg.GeneralCfg().DefaultTenant } - processRuns := alS.cgrcfg.AttributeSCfg().ProcessRuns - if args.ProcessRuns != nil && *args.ProcessRuns != 0 { - processRuns = *args.ProcessRuns + var processRuns int64 + if v, has := args.APIOpts[utils.OptsAttributesProcessRuns]; has { + if processRuns, err = utils.IfaceAsTInt64(v); err != nil { + return + } + } else if processRuns, err = utils.IfaceAsTInt64(alS.cgrcfg.AttributeSCfg().DefaultOpts[utils.OptsAttributesProcessRuns]); err != nil { + return } + args.CGREvent = args.CGREvent.Clone() processedPrf := make(utils.StringSet) eNV := utils.MapStorage{ @@ -295,7 +293,7 @@ func (alS *AttributeService) V1ProcessEvent(ctx *context.Context, args *AttrArgs alteredFields := make(utils.StringSet) dynDP := newDynamicDP(ctx, alS.cgrcfg.AttributeSCfg().ResourceSConns, alS.cgrcfg.AttributeSCfg().StatSConns, alS.cgrcfg.AttributeSCfg().AdminSConns, args.Tenant, eNV) - for i := 0; i < processRuns; i++ { + for i := int64(0); i < processRuns; i++ { (eNV[utils.MetaVars].(utils.MapStorage))[utils.OptsAttributesProcessRuns] = i + 1 var evRply *AttrSProcessEventReply evRply, err = alS.processEvent(ctx, tnt, args, eNV, dynDP, lastID) diff --git a/engine/attributes_test.go b/engine/attributes_test.go index a5e7abaeb..6915d9ceb 100644 --- a/engine/attributes_test.go +++ b/engine/attributes_test.go @@ -96,8 +96,10 @@ func TestAttributesV1ProcessEvent(t *testing.T) { Event: map[string]interface{}{ utils.AccountField: "adrian@itsyscom.com", }, + APIOpts: map[string]interface{}{ + utils.OptsAttributesProcessRuns: 2, + }, }, - ProcessRuns: utils.IntPointer(2), } rply := &AttrSProcessEventReply{} expected := &AttrSProcessEventReply{ @@ -110,7 +112,9 @@ func TestAttributesV1ProcessEvent(t *testing.T) { utils.AccountField: "andrei.itsyscom.com", "Password": "CGRATES.ORG", }, - APIOpts: map[string]interface{}{}, + APIOpts: map[string]interface{}{ + utils.OptsAttributesProcessRuns: 2, + }, }, blocker: false, } @@ -191,15 +195,17 @@ func TestAttributesV1ProcessEventErrorMetaSum(t *testing.T) { Event: map[string]interface{}{ utils.AccountField: "adrian@itsyscom.com", }, + APIOpts: map[string]interface{}{ + utils.OptsAttributesProcessRuns: 2, + }, }, - ProcessRuns: utils.IntPointer(2), } rply := &AttrSProcessEventReply{} err = alS.V1ProcessEvent(context.Background(), args, rply) sort.Strings(rply.AlteredFields) expErr := "SERVER_ERROR: NotEnoughParameters" if err == nil || err.Error() != expErr { - t.Errorf("\nExpected <%+v>, \nReceived <%+v>", nil, err) + t.Errorf("\nExpected <%+v>, \nReceived <%+v>", expErr, err) } } @@ -271,15 +277,17 @@ func TestAttributesV1ProcessEventErrorMetaDifference(t *testing.T) { Event: map[string]interface{}{ utils.AccountField: "adrian@itsyscom.com", }, + APIOpts: map[string]interface{}{ + utils.OptsAttributesProcessRuns: 2, + }, }, - ProcessRuns: utils.IntPointer(2), } rply := &AttrSProcessEventReply{} err = alS.V1ProcessEvent(context.Background(), args, rply) sort.Strings(rply.AlteredFields) expErr := "SERVER_ERROR: NotEnoughParameters" if err == nil || err.Error() != expErr { - t.Errorf("\nExpected <%+v>, \nReceived <%+v>", nil, err) + t.Errorf("\nExpected <%+v>, \nReceived <%+v>", expErr, err) } } @@ -351,8 +359,10 @@ func TestAttributesV1ProcessEventErrorMetaValueExponent(t *testing.T) { Event: map[string]interface{}{ utils.AccountField: "adrian@itsyscom.com", }, + APIOpts: map[string]interface{}{ + utils.OptsAttributesProcessRuns: 2, + }, }, - ProcessRuns: utils.IntPointer(2), } rply := &AttrSProcessEventReply{} err = alS.V1ProcessEvent(context.Background(), args, rply) @@ -708,13 +718,15 @@ func TestAttributesV1ProcessEventMultipleRuns1(t *testing.T) { args := &AttrArgsProcessEvent{ AttributeIDs: []string{"ATTR1", "ATTR2"}, - ProcessRuns: utils.IntPointer(4), CGREvent: &utils.CGREvent{ Tenant: "cgrates.org", ID: "AttrProcessEventMultipleRuns", Event: map[string]interface{}{ "Password": "passwd", }, + APIOpts: map[string]interface{}{ + utils.OptsAttributesProcessRuns: 4, + }, }, } reply := &AttrSProcessEventReply{} @@ -728,7 +740,9 @@ func TestAttributesV1ProcessEventMultipleRuns1(t *testing.T) { "Password": "CGRateS.org", utils.RequestType: utils.MetaPostpaid, }, - APIOpts: make(map[string]interface{}), + APIOpts: map[string]interface{}{ + utils.OptsAttributesProcessRuns: 4, + }, }, } @@ -814,11 +828,13 @@ func TestAttributesV1ProcessEventMultipleRuns2(t *testing.T) { } args := &AttrArgsProcessEvent{ - ProcessRuns: utils.IntPointer(3), CGREvent: &utils.CGREvent{ Tenant: "cgrates.org", ID: "AttrProcessEventMultipleRuns", Event: map[string]interface{}{}, + APIOpts: map[string]interface{}{ + utils.OptsAttributesProcessRuns: 3, + }, }, } @@ -834,7 +850,9 @@ func TestAttributesV1ProcessEventMultipleRuns2(t *testing.T) { "PaypalAccount": "cgrates@paypal.com", utils.RequestType: utils.MetaPostpaid, }, - APIOpts: make(map[string]interface{}), + APIOpts: map[string]interface{}{ + utils.OptsAttributesProcessRuns: 3, + }, }, } if err := alS.V1ProcessEvent(context.Background(), args, reply); err != nil { diff --git a/engine/cdrs.go b/engine/cdrs.go index 4910a768f..046b289eb 100644 --- a/engine/cdrs.go +++ b/engine/cdrs.go @@ -155,18 +155,11 @@ func (cdrS *CDRServer) attrSProcessEvent(cgrEv *utils.CGREvent) (err error) { cgrEv.APIOpts = make(map[string]interface{}) } cgrEv.APIOpts[utils.Subsys] = utils.MetaCDRs - var processRuns *int - if val, has := cgrEv.APIOpts[utils.OptsAttributesProcessRuns]; has { - if v, err := utils.IfaceAsTInt64(val); err == nil { - processRuns = utils.IntPointer(int(v)) - } - } cgrEv.APIOpts[utils.OptsContext] = utils.FirstNonEmpty( utils.IfaceAsString(cgrEv.APIOpts[utils.OptsContext]), utils.MetaCDRs) attrArgs := &AttrArgsProcessEvent{ - CGREvent: cgrEv, - ProcessRuns: processRuns, + CGREvent: cgrEv, } if err = cdrS.connMgr.Call(context.TODO(), cdrS.cgrCfg.CdrsCfg().AttributeSConns, utils.AttributeSv1ProcessEvent, diff --git a/engine/chargers.go b/engine/chargers.go index 7f410c344..73a2129c9 100644 --- a/engine/chargers.go +++ b/engine/chargers.go @@ -103,12 +103,6 @@ type ChrgSProcessEventReply struct { func (cS *ChargerService) processEvent(ctx *context.Context, tnt string, cgrEv *utils.CGREvent) (rply []*ChrgSProcessEventReply, err error) { var cPs ChargerProfiles - var processRuns *int - if val, has := cgrEv.APIOpts[utils.OptsAttributesProcessRuns]; has { - if v, err := utils.IfaceAsTInt64(val); err == nil { - processRuns = utils.IntPointer(int(v)) - } - } if cPs, err = cS.matchingChargerProfilesForEvent(ctx, tnt, cgrEv); err != nil { return nil, err } @@ -131,7 +125,6 @@ func (cS *ChargerService) processEvent(ctx *context.Context, tnt string, cgrEv * utils.MetaChargers) args := &AttrArgsProcessEvent{ AttributeIDs: cP.AttributeIDs, - ProcessRuns: processRuns, CGREvent: clonedEv, } var evReply AttrSProcessEventReply diff --git a/engine/routes.go b/engine/routes.go index b610ec715..1751f4e93 100644 --- a/engine/routes.go +++ b/engine/routes.go @@ -577,23 +577,12 @@ func (rpS *RouteService) V1GetRoutes(ctx *context.Context, args *ArgsGetRoutes, args.APIOpts = make(map[string]interface{}) } args.APIOpts[utils.Subsys] = utils.MetaRoutes - var processRuns *int - if val, has := args.APIOpts[utils.OptsAttributesProcessRuns]; has { - if v, err := utils.IfaceAsTInt64(val); err == nil { - processRuns = utils.IntPointer(int(v)) - } - } else if val, has = rpS.cgrcfg.RouteSCfg().DefaultOpts[utils.OptsAttributesProcessRuns]; has { - if v, err := utils.IfaceAsTInt64(val); err == nil { - processRuns = utils.IntPointer(int(v)) - } - } args.CGREvent.APIOpts[utils.OptsContext] = utils.FirstNonEmpty( utils.IfaceAsString(args.CGREvent.APIOpts[utils.OptsContext]), utils.IfaceAsString(rpS.cgrcfg.RouteSCfg().DefaultOpts[utils.OptsContext]), utils.MetaRoutes) attrArgs := &AttrArgsProcessEvent{ - CGREvent: args.CGREvent, - ProcessRuns: processRuns, + CGREvent: args.CGREvent, } var rplyEv AttrSProcessEventReply if err := rpS.connMgr.Call(ctx, rpS.cgrcfg.RouteSCfg().AttributeSConns, diff --git a/engine/z_attributes_test.go b/engine/z_attributes_test.go index 01f195a21..ee8e8e666 100644 --- a/engine/z_attributes_test.go +++ b/engine/z_attributes_test.go @@ -80,7 +80,8 @@ var ( "DistinctMatch": 20, }, APIOpts: map[string]interface{}{ - utils.OptsContext: utils.MetaSessionS, + utils.OptsContext: utils.MetaSessionS, + utils.OptsAttributesProcessRuns: 0, }, }, }, @@ -139,7 +140,6 @@ var ( func TestAttributePopulateAttrService(t *testing.T) { defaultCfg := config.NewDefaultCGRConfig() - defaultCfg.AttributeSCfg().ProcessRuns = 1 defaultCfg.AttributeSCfg().StringIndexedFields = nil defaultCfg.AttributeSCfg().PrefixIndexedFields = nil data := NewInternalDB(nil, nil, true) @@ -305,7 +305,7 @@ func TestAttributeProcessEventWithNotFound(t *testing.T) { } if _, err := attrS.processEvent(context.TODO(), attrEvs[0].Tenant, attrEvs[3], eNM, newDynamicDP(context.TODO(), nil, nil, nil, "cgrates.org", eNM), utils.EmptyString); err == nil || err != utils.ErrNotFound { - t.Errorf("Error: %+v", err) + t.Errorf("expected: <%+v>, \nreceived: <%+v>", utils.ErrNotFound, err) } } @@ -541,7 +541,6 @@ func TestAttributeProcessWithMultipleRuns1(t *testing.T) { t.Errorf("Error: %+v", err) } attrArgs := &AttrArgsProcessEvent{ - ProcessRuns: utils.IntPointer(4), CGREvent: &utils.CGREvent{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: utils.GenUUID(), @@ -549,7 +548,8 @@ func TestAttributeProcessWithMultipleRuns1(t *testing.T) { "InitialField": "InitialValue", }, APIOpts: map[string]interface{}{ - utils.OptsContext: utils.MetaSessionS, + utils.OptsContext: utils.MetaSessionS, + utils.OptsAttributesProcessRuns: 4, }, }, } @@ -644,7 +644,6 @@ func TestAttributeProcessWithMultipleRuns2(t *testing.T) { t.Errorf("Error: %+v", err) } attrArgs := &AttrArgsProcessEvent{ - ProcessRuns: utils.IntPointer(4), CGREvent: &utils.CGREvent{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: utils.GenUUID(), @@ -652,7 +651,8 @@ func TestAttributeProcessWithMultipleRuns2(t *testing.T) { "InitialField": "InitialValue", }, APIOpts: map[string]interface{}{ - utils.OptsContext: utils.MetaSessionS, + utils.OptsContext: utils.MetaSessionS, + utils.OptsAttributesProcessRuns: 4, }, }, } @@ -743,7 +743,6 @@ func TestAttributeProcessWithMultipleRuns3(t *testing.T) { t.Errorf("Error: %+v", err) } attrArgs := &AttrArgsProcessEvent{ - ProcessRuns: utils.IntPointer(2), CGREvent: &utils.CGREvent{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: utils.GenUUID(), @@ -751,7 +750,8 @@ func TestAttributeProcessWithMultipleRuns3(t *testing.T) { "InitialField": "InitialValue", }, APIOpts: map[string]interface{}{ - utils.OptsContext: utils.MetaSessionS, + utils.OptsContext: utils.MetaSessionS, + utils.OptsAttributesProcessRuns: 2, }, }, } @@ -827,7 +827,6 @@ func TestAttributeProcessWithMultipleRuns4(t *testing.T) { t.Errorf("Error: %+v", err) } attrArgs := &AttrArgsProcessEvent{ - ProcessRuns: utils.IntPointer(4), CGREvent: &utils.CGREvent{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: utils.GenUUID(), @@ -835,7 +834,8 @@ func TestAttributeProcessWithMultipleRuns4(t *testing.T) { "InitialField": "InitialValue", }, APIOpts: map[string]interface{}{ - utils.OptsContext: utils.MetaSessionS, + utils.OptsContext: utils.MetaSessionS, + utils.OptsAttributesProcessRuns: 4, }, }, } @@ -929,7 +929,6 @@ func TestAttributeMultipleProcessWithBlocker(t *testing.T) { t.Errorf("Error: %+v", err) } attrArgs := &AttrArgsProcessEvent{ - ProcessRuns: utils.IntPointer(4), CGREvent: &utils.CGREvent{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: utils.GenUUID(), @@ -937,7 +936,8 @@ func TestAttributeMultipleProcessWithBlocker(t *testing.T) { "InitialField": "InitialValue", }, APIOpts: map[string]interface{}{ - utils.OptsContext: utils.MetaSessionS, + utils.OptsContext: utils.MetaSessionS, + utils.OptsAttributesProcessRuns: 4, }, }, } @@ -1030,7 +1030,6 @@ func TestAttributeMultipleProcessWithBlocker2(t *testing.T) { t.Errorf("Error: %+v", err) } attrArgs := &AttrArgsProcessEvent{ - ProcessRuns: utils.IntPointer(4), CGREvent: &utils.CGREvent{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: utils.GenUUID(), @@ -1038,7 +1037,8 @@ func TestAttributeMultipleProcessWithBlocker2(t *testing.T) { "InitialField": "InitialValue", }, APIOpts: map[string]interface{}{ - utils.OptsContext: utils.MetaSessionS, + utils.OptsContext: utils.MetaSessionS, + utils.OptsAttributesProcessRuns: 4, }, }, } @@ -1098,7 +1098,6 @@ func TestAttributeProcessValue(t *testing.T) { t.Error(err) } attrArgs := &AttrArgsProcessEvent{ - ProcessRuns: utils.IntPointer(1), CGREvent: &utils.CGREvent{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: utils.GenUUID(), @@ -1175,7 +1174,6 @@ func TestAttributeAttributeFilterIDs(t *testing.T) { t.Error(err) } attrArgs := &AttrArgsProcessEvent{ - ProcessRuns: utils.IntPointer(1), CGREvent: &utils.CGREvent{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: utils.GenUUID(), @@ -1246,7 +1244,6 @@ func TestAttributeProcessEventConstant(t *testing.T) { t.Error(err) } attrArgs := &AttrArgsProcessEvent{ - ProcessRuns: utils.IntPointer(1), CGREvent: &utils.CGREvent{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: utils.GenUUID(), @@ -1320,7 +1317,6 @@ func TestAttributeProcessEventVariable(t *testing.T) { t.Error(err) } attrArgs := &AttrArgsProcessEvent{ - ProcessRuns: utils.IntPointer(1), CGREvent: &utils.CGREvent{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: utils.GenUUID(), @@ -1401,7 +1397,6 @@ func TestAttributeProcessEventComposed(t *testing.T) { t.Error(err) } attrArgs := &AttrArgsProcessEvent{ - ProcessRuns: utils.IntPointer(1), CGREvent: &utils.CGREvent{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: utils.GenUUID(), @@ -1472,7 +1467,6 @@ func TestAttributeProcessEventSum(t *testing.T) { t.Error(err) } attrArgs := &AttrArgsProcessEvent{ - ProcessRuns: utils.IntPointer(1), CGREvent: &utils.CGREvent{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: utils.GenUUID(), @@ -1545,7 +1539,6 @@ func TestAttributeProcessEventUsageDifference(t *testing.T) { t.Error(err) } attrArgs := &AttrArgsProcessEvent{ - ProcessRuns: utils.IntPointer(1), CGREvent: &utils.CGREvent{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: utils.GenUUID(), @@ -1620,7 +1613,6 @@ func TestAttributeProcessEventValueExponent(t *testing.T) { t.Error(err) } attrArgs := &AttrArgsProcessEvent{ - ProcessRuns: utils.IntPointer(1), CGREvent: &utils.CGREvent{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: utils.GenUUID(), @@ -1667,7 +1659,6 @@ func TestAttributeProcessEventValueExponent(t *testing.T) { func BenchmarkAttributeProcessEventConstant(b *testing.B) { defaultCfg := config.NewDefaultCGRConfig() - defaultCfg.AttributeSCfg().ProcessRuns = 1 data := NewInternalDB(nil, nil, true) dmAtr = NewDataManager(data, config.CgrConfig().CacheCfg(), nil) attrS = NewAttributeService(dmAtr, &FilterS{dm: dmAtr, cfg: defaultCfg}, defaultCfg) @@ -1700,7 +1691,6 @@ func BenchmarkAttributeProcessEventConstant(b *testing.B) { b.Error(err) } attrArgs := &AttrArgsProcessEvent{ - ProcessRuns: utils.IntPointer(1), CGREvent: &utils.CGREvent{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: utils.GenUUID(), @@ -1723,7 +1713,6 @@ func BenchmarkAttributeProcessEventConstant(b *testing.B) { func BenchmarkAttributeProcessEventVariable(b *testing.B) { defaultCfg := config.NewDefaultCGRConfig() - defaultCfg.AttributeSCfg().ProcessRuns = 1 data := NewInternalDB(nil, nil, true) dmAtr = NewDataManager(data, config.CgrConfig().CacheCfg(), nil) attrS = NewAttributeService(dmAtr, &FilterS{dm: dmAtr, cfg: defaultCfg}, defaultCfg) @@ -1757,7 +1746,6 @@ func BenchmarkAttributeProcessEventVariable(b *testing.B) { b.Error(err) } attrArgs := &AttrArgsProcessEvent{ - ProcessRuns: utils.IntPointer(1), CGREvent: &utils.CGREvent{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: utils.GenUUID(), @@ -1809,7 +1797,6 @@ func TestGetAttributeProfileFromInline(t *testing.T) { func TestProcessAttributeConstant(t *testing.T) { defaultCfg := config.NewDefaultCGRConfig() - defaultCfg.AttributeSCfg().ProcessRuns = 1 data := NewInternalDB(nil, nil, true) dmAtr = NewDataManager(data, config.CgrConfig().CacheCfg(), nil) attrS = NewAttributeService(dmAtr, &FilterS{dm: dmAtr, cfg: defaultCfg}, defaultCfg) @@ -1867,7 +1854,6 @@ func TestProcessAttributeConstant(t *testing.T) { func TestProcessAttributeVariable(t *testing.T) { defaultCfg := config.NewDefaultCGRConfig() - defaultCfg.AttributeSCfg().ProcessRuns = 1 data := NewInternalDB(nil, nil, true) dmAtr = NewDataManager(data, config.CgrConfig().CacheCfg(), nil) Cache.Clear(nil) @@ -1928,7 +1914,6 @@ func TestProcessAttributeVariable(t *testing.T) { func TestProcessAttributeComposed(t *testing.T) { defaultCfg := config.NewDefaultCGRConfig() - defaultCfg.AttributeSCfg().ProcessRuns = 1 data := NewInternalDB(nil, nil, true) dmAtr = NewDataManager(data, config.CgrConfig().CacheCfg(), nil) Cache.Clear(nil) @@ -1995,7 +1980,6 @@ func TestProcessAttributeComposed(t *testing.T) { func TestProcessAttributeUsageDifference(t *testing.T) { defaultCfg := config.NewDefaultCGRConfig() - defaultCfg.AttributeSCfg().ProcessRuns = 1 data := NewInternalDB(nil, nil, true) dmAtr = NewDataManager(data, config.CgrConfig().CacheCfg(), nil) Cache.Clear(nil) @@ -2057,7 +2041,6 @@ func TestProcessAttributeUsageDifference(t *testing.T) { func TestProcessAttributeSum(t *testing.T) { defaultCfg := config.NewDefaultCGRConfig() - defaultCfg.AttributeSCfg().ProcessRuns = 1 data := NewInternalDB(nil, nil, true) dmAtr = NewDataManager(data, config.CgrConfig().CacheCfg(), nil) Cache.Clear(nil) @@ -2119,7 +2102,6 @@ func TestProcessAttributeSum(t *testing.T) { func TestProcessAttributeDiff(t *testing.T) { defaultCfg := config.NewDefaultCGRConfig() - defaultCfg.AttributeSCfg().ProcessRuns = 1 data := NewInternalDB(nil, nil, true) dmAtr = NewDataManager(data, config.CgrConfig().CacheCfg(), nil) Cache.Clear(nil) @@ -2181,7 +2163,6 @@ func TestProcessAttributeDiff(t *testing.T) { func TestProcessAttributeMultiply(t *testing.T) { defaultCfg := config.NewDefaultCGRConfig() - defaultCfg.AttributeSCfg().ProcessRuns = 1 data := NewInternalDB(nil, nil, true) dmAtr = NewDataManager(data, config.CgrConfig().CacheCfg(), nil) Cache.Clear(nil) @@ -2243,7 +2224,6 @@ func TestProcessAttributeMultiply(t *testing.T) { func TestProcessAttributeDivide(t *testing.T) { defaultCfg := config.NewDefaultCGRConfig() - defaultCfg.AttributeSCfg().ProcessRuns = 1 data := NewInternalDB(nil, nil, true) dmAtr = NewDataManager(data, config.CgrConfig().CacheCfg(), nil) Cache.Clear(nil) @@ -2305,7 +2285,6 @@ func TestProcessAttributeDivide(t *testing.T) { func TestProcessAttributeValueExponent(t *testing.T) { defaultCfg := config.NewDefaultCGRConfig() - defaultCfg.AttributeSCfg().ProcessRuns = 1 data := NewInternalDB(nil, nil, true) dmAtr = NewDataManager(data, config.CgrConfig().CacheCfg(), nil) Cache.Clear(nil) @@ -2367,7 +2346,6 @@ func TestProcessAttributeValueExponent(t *testing.T) { func TestProcessAttributeUnixTimeStamp(t *testing.T) { defaultCfg := config.NewDefaultCGRConfig() - defaultCfg.AttributeSCfg().ProcessRuns = 1 data := NewInternalDB(nil, nil, true) dmAtr = NewDataManager(data, config.CgrConfig().CacheCfg(), nil) Cache.Clear(nil) @@ -2429,7 +2407,6 @@ func TestProcessAttributeUnixTimeStamp(t *testing.T) { func TestProcessAttributePrefix(t *testing.T) { defaultCfg := config.NewDefaultCGRConfig() - defaultCfg.AttributeSCfg().ProcessRuns = 1 data := NewInternalDB(nil, nil, true) dmAtr = NewDataManager(data, config.CgrConfig().CacheCfg(), nil) Cache.Clear(nil) @@ -2490,7 +2467,6 @@ func TestProcessAttributePrefix(t *testing.T) { func TestProcessAttributeSuffix(t *testing.T) { defaultCfg := config.NewDefaultCGRConfig() - defaultCfg.AttributeSCfg().ProcessRuns = 1 data := NewInternalDB(nil, nil, true) dmAtr = NewDataManager(data, config.CgrConfig().CacheCfg(), nil) Cache.Clear(nil) @@ -2552,7 +2528,6 @@ func TestProcessAttributeSuffix(t *testing.T) { func TestAttributeIndexSelectsFalse(t *testing.T) { // change the IndexedSelects to false defaultCfg := config.NewDefaultCGRConfig() - defaultCfg.AttributeSCfg().ProcessRuns = 1 defaultCfg.AttributeSCfg().StringIndexedFields = nil defaultCfg.AttributeSCfg().PrefixIndexedFields = nil defaultCfg.AttributeSCfg().IndexedSelects = false @@ -2587,7 +2562,6 @@ func TestAttributeIndexSelectsFalse(t *testing.T) { } attrArgs := &AttrArgsProcessEvent{ - ProcessRuns: utils.IntPointer(1), CGREvent: &utils.CGREvent{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: utils.GenUUID(), @@ -2609,7 +2583,6 @@ func TestAttributeIndexSelectsFalse(t *testing.T) { func TestProcessAttributeWithSameWeight(t *testing.T) { defaultCfg := config.NewDefaultCGRConfig() - defaultCfg.AttributeSCfg().ProcessRuns = 1 data := NewInternalDB(nil, nil, true) dmAtr = NewDataManager(data, config.CgrConfig().CacheCfg(), nil) Cache.Clear(nil) @@ -2648,7 +2621,6 @@ func TestProcessAttributeWithSameWeight(t *testing.T) { t.Error(err) } ev := &AttrArgsProcessEvent{ - ProcessRuns: utils.IntPointer(2), CGREvent: &utils.CGREvent{ //matching ATTR_UNIX_TIMESTAMP Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: "TestProcessAttributeUnixTimeStamp", @@ -2658,7 +2630,8 @@ func TestProcessAttributeWithSameWeight(t *testing.T) { utils.Weight: "20.0", }, APIOpts: map[string]interface{}{ - utils.OptsContext: utils.MetaSessionS, + utils.OptsContext: utils.MetaSessionS, + utils.OptsAttributesProcessRuns: 2, }, }, } @@ -2727,7 +2700,6 @@ func TestAttributeMultipleProcessWithFiltersExists(t *testing.T) { t.Error(err) } attrArgs := &AttrArgsProcessEvent{ - ProcessRuns: utils.IntPointer(4), CGREvent: &utils.CGREvent{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: utils.GenUUID(), @@ -2735,7 +2707,8 @@ func TestAttributeMultipleProcessWithFiltersExists(t *testing.T) { "InitialField": "InitialValue", }, APIOpts: map[string]interface{}{ - utils.OptsContext: utils.MetaSessionS, + utils.OptsContext: utils.MetaSessionS, + utils.OptsAttributesProcessRuns: 4, }, }, } @@ -2815,7 +2788,6 @@ func TestAttributeMultipleProcessWithFiltersNotEmpty(t *testing.T) { t.Error(err) } attrArgs := &AttrArgsProcessEvent{ - ProcessRuns: utils.IntPointer(4), CGREvent: &utils.CGREvent{ Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, ID: utils.GenUUID(), @@ -2823,7 +2795,8 @@ func TestAttributeMultipleProcessWithFiltersNotEmpty(t *testing.T) { "InitialField": "InitialValue", }, APIOpts: map[string]interface{}{ - utils.OptsContext: utils.MetaSessionS, + utils.OptsContext: utils.MetaSessionS, + utils.OptsAttributesProcessRuns: 4, }, }, } @@ -2974,12 +2947,14 @@ func TestAttributesPorcessEventMatchingProcessRuns(t *testing.T) { attr := NewAttributeService(dm, fltrS, cfg) args := &AttrArgsProcessEvent{ - ProcessRuns: utils.IntPointer(2), CGREvent: &utils.CGREvent{ Event: map[string]interface{}{ "Account": "pc_test", "CompanyName": "MY_company_will_be_changed", }, + APIOpts: map[string]interface{}{ + utils.OptsAttributesProcessRuns: 2, + }, }, } reply := &AttrSProcessEventReply{} @@ -2993,7 +2968,9 @@ func TestAttributesPorcessEventMatchingProcessRuns(t *testing.T) { "CompanyName": "ITSYS COMMUNICATIONS SRL", "Password": "CGRateS.org", }, - APIOpts: map[string]interface{}{}, + APIOpts: map[string]interface{}{ + utils.OptsAttributesProcessRuns: 2, + }, }, } if err := attr.V1ProcessEvent(context.Background(), args, reply); err != nil { diff --git a/sessions/sessions.go b/sessions/sessions.go index 0bcc2bf67..63a72f52e 100644 --- a/sessions/sessions.go +++ b/sessions/sessions.go @@ -2902,19 +2902,12 @@ func (sS *SessionS) processAttributes(ctx *context.Context, cgrEv *utils.CGREven cgrEv.APIOpts = make(engine.MapEvent) } cgrEv.APIOpts[utils.Subsys] = utils.MetaSessionS - var processRuns *int - if val, has := cgrEv.APIOpts[utils.OptsAttributesProcessRuns]; has { - if v, err := utils.IfaceAsTInt64(val); err == nil { - processRuns = utils.IntPointer(int(v)) - } - } cgrEv.APIOpts[utils.OptsContext] = utils.FirstNonEmpty( utils.IfaceAsString(cgrEv.APIOpts[utils.OptsContext]), utils.MetaSessionS) attrArgs := &engine.AttrArgsProcessEvent{ CGREvent: cgrEv, AttributeIDs: attrIDs, - ProcessRuns: processRuns, } attrArgs.SetCloneable(clnb) err = sS.connMgr.Call(ctx, sS.cgrCfg.SessionSCfg().AttrSConns, utils.AttributeSv1ProcessEvent,