diff --git a/config/analyzerscfg_test.go b/config/analyzerscfg_test.go new file mode 100644 index 000000000..5168a1562 --- /dev/null +++ b/config/analyzerscfg_test.go @@ -0,0 +1,79 @@ +/* +Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments +Copyright (C) ITsysCOM GmbH + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ +package config + +import ( + "reflect" + "testing" + + "github.com/cgrates/cgrates/utils" +) + +func TestAnalyzerSCfgloadFromJsonCfg(t *testing.T) { + var alS, expected AnalyzerSCfg + if err := alS.loadFromJsonCfg(nil); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(alS, expected) { + t.Errorf("Expected: %+v ,recived: %+v", expected, alS) + } + if err := alS.loadFromJsonCfg(new(AnalyzerSJsonCfg)); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(alS, expected) { + t.Errorf("Expected: %+v ,recived: %+v", expected, alS) + } + cfgJSONStr := `{ + "analyzers":{ // AnalyzerS config + "enabled":false // starts AnalyzerS service: . + }, + +}` + expected = AnalyzerSCfg{ + Enabled: false, + } + if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil { + t.Error(err) + } else if jsnalS, err := jsnCfg.AnalyzerCfgJson(); err != nil { + t.Error(err) + } else if err = alS.loadFromJsonCfg(jsnalS); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(expected, alS) { + t.Errorf("Expected: %+v , recived: %+v", expected, alS) + } +} + +func TestAnalyzerSCfgAsMapInterface(t *testing.T) { + var alS AnalyzerSCfg + cfgJSONStr := `{ + "analyzers":{ + "enabled":false + }, + +}` + eMap := map[string]interface{}{ + "enabled": false, + } + if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil { + t.Error(err) + } else if jsnalS, err := jsnCfg.AnalyzerCfgJson(); err != nil { + t.Error(err) + } else if err = alS.loadFromJsonCfg(jsnalS); err != nil { + t.Error(err) + } else if rcv := alS.AsMapInterface(); !reflect.DeepEqual(eMap, rcv) { + t.Errorf("\nExpected: %+v\nRecived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv)) + } +} diff --git a/config/apiercfg.go b/config/apiercfg.go index 439929f04..1d36aee9e 100644 --- a/config/apiercfg.go +++ b/config/apiercfg.go @@ -18,7 +18,11 @@ along with this program. If not, see package config -import "github.com/cgrates/cgrates/utils" +import ( + "strings" + + "github.com/cgrates/cgrates/utils" +) // ApierCfg is the configuration of Apier service type ApierCfg struct { @@ -73,11 +77,39 @@ func (aCfg *ApierCfg) loadFromJsonCfg(jsnCfg *ApierJsonCfg) (err error) { } func (aCfg *ApierCfg) AsMapInterface() map[string]interface{} { + cachesConns := make([]string, len(aCfg.CachesConns)) + for i, item := range aCfg.CachesConns { + buf := utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCaches) + if item == buf { + cachesConns[i] = strings.ReplaceAll(item, utils.CONCATENATED_KEY_SEP+utils.MetaCaches, utils.EmptyString) + } else { + cachesConns[i] = item + } + } + schedulerConns := make([]string, len(aCfg.SchedulerConns)) + for i, item := range aCfg.SchedulerConns { + buf := utils.ConcatenatedKey(utils.MetaInternal, utils.MetaScheduler) + if item == buf { + schedulerConns[i] = strings.ReplaceAll(item, utils.CONCATENATED_KEY_SEP+utils.MetaScheduler, utils.EmptyString) + } else { + schedulerConns[i] = item + } + } + attributeSConns := make([]string, len(aCfg.AttributeSConns)) + for i, item := range aCfg.AttributeSConns { + buf := utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAttributes) + if item == buf { + attributeSConns[i] = strings.ReplaceAll(item, utils.CONCATENATED_KEY_SEP+utils.MetaAttributes, utils.EmptyString) + } else { + attributeSConns[i] = item + } + } + return map[string]interface{}{ utils.EnabledCfg: aCfg.Enabled, - utils.CachesConnsCfg: aCfg.CachesConns, - utils.SchedulerConnsCfg: aCfg.SchedulerConns, - utils.AttributeSConnsCfg: aCfg.AttributeSConns, + utils.CachesConnsCfg: cachesConns, + utils.SchedulerConnsCfg: schedulerConns, + utils.AttributeSConnsCfg: attributeSConns, } } diff --git a/config/apiercfg_test.go b/config/apiercfg_test.go new file mode 100644 index 000000000..db8869e98 --- /dev/null +++ b/config/apiercfg_test.go @@ -0,0 +1,113 @@ +/* +Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments +Copyright (C) ITsysCOM GmbH + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ +package config + +import ( + "reflect" + "testing" + + "github.com/cgrates/cgrates/utils" +) + +func TestApierCfgloadFromJsonCfg(t *testing.T) { + var aCfg, expected ApierCfg + if err := aCfg.loadFromJsonCfg(nil); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(aCfg, expected) { + t.Errorf("Expected: %+v ,recived: %+v", expected, aCfg) + } + if err := aCfg.loadFromJsonCfg(new(ApierJsonCfg)); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(aCfg, expected) { + t.Errorf("Expected: %+v ,recived: %+v", expected, aCfg) + } + cfgJSONStr := `{ + "apiers": { + "enabled": false, + "caches_conns":["*internal"], + "scheduler_conns": [], + "attributes_conns": [], + }, +}` + expected = ApierCfg{ + Enabled: false, + CachesConns: []string{"*internal:*caches"}, + SchedulerConns: []string{}, + AttributeSConns: []string{}, + } + if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil { + t.Error(err) + } else if jsnaCfg, err := jsnCfg.ApierCfgJson(); err != nil { + t.Error(err) + } else if err = aCfg.loadFromJsonCfg(jsnaCfg); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(expected, aCfg) { + t.Errorf("Expected: %+v , recived: %+v", expected, aCfg) + } +} + +func TestApierCfgAsMapInterface(t *testing.T) { + var aCfg ApierCfg + cfgJSONStr := `{ + "apiers": { + "enabled": false, + "caches_conns":[], + "scheduler_conns": [], + "attributes_conns": [], + }, +}` + eMap := map[string]interface{}{ + "enabled": false, + "caches_conns": []string{}, + "scheduler_conns": []string{}, + "attributes_conns": []string{}, + } + if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil { + t.Error(err) + } else if jsnaCfg, err := jsnCfg.ApierCfgJson(); err != nil { + t.Error(err) + } else if err = aCfg.loadFromJsonCfg(jsnaCfg); err != nil { + t.Error(err) + } else if rcv := aCfg.AsMapInterface(); !reflect.DeepEqual(eMap, rcv) { + t.Errorf("\nExpected: %+v\nRecived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv)) + } + + cfgJSONStr = `{ + "apiers": { + "enabled": false, + "caches_conns":["*internal"], + "scheduler_conns": ["*internal"], + "attributes_conns": ["*internal"], + }, + }` + eMap = map[string]interface{}{ + "enabled": false, + "caches_conns": []string{"*internal"}, + "scheduler_conns": []string{"*internal"}, + "attributes_conns": []string{"*internal"}, + } + if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil { + t.Error(err) + } else if jsnaCfg, err := jsnCfg.ApierCfgJson(); err != nil { + t.Error(err) + } else if err = aCfg.loadFromJsonCfg(jsnaCfg); err != nil { + t.Error(err) + } else if rcv := aCfg.AsMapInterface(); !reflect.DeepEqual(eMap, rcv) { + t.Errorf("\nExpected: %+v\nRecived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv)) + } +} diff --git a/config/attributescfg.go b/config/attributescfg.go index 019c02552..e06339a5f 100644 --- a/config/attributescfg.go +++ b/config/attributescfg.go @@ -64,12 +64,25 @@ func (alS *AttributeSCfg) loadFromJsonCfg(jsnCfg *AttributeSJsonCfg) (err error) } func (alS *AttributeSCfg) AsMapInterface() map[string]interface{} { - + stringIndexedFields := []string{} + if alS.StringIndexedFields != nil { + stringIndexedFields = make([]string, len(*alS.StringIndexedFields)) + for i, item := range *alS.StringIndexedFields { + stringIndexedFields[i] = item + } + } + prefixIndexedFields := []string{} + if alS.PrefixIndexedFields != nil { + prefixIndexedFields = make([]string, len(*alS.PrefixIndexedFields)) + for i, item := range *alS.PrefixIndexedFields { + prefixIndexedFields[i] = item + } + } return map[string]interface{}{ utils.EnabledCfg: alS.Enabled, utils.IndexedSelectsCfg: alS.IndexedSelects, - utils.StringIndexedFieldsCfg: alS.StringIndexedFields, - utils.PrefixIndexedFieldsCfg: alS.PrefixIndexedFields, + utils.StringIndexedFieldsCfg: stringIndexedFields, + utils.PrefixIndexedFieldsCfg: prefixIndexedFields, utils.ProcessRunsCfg: alS.ProcessRuns, utils.NestedFieldsCfg: alS.NestedFields, } diff --git a/config/attributescfg_test.go b/config/attributescfg_test.go index f4137d773..9ac471fd3 100644 --- a/config/attributescfg_test.go +++ b/config/attributescfg_test.go @@ -20,6 +20,8 @@ package config import ( "reflect" "testing" + + "github.com/cgrates/cgrates/utils" ) func TestAttributeSCfgloadFromJsonCfg(t *testing.T) { @@ -57,3 +59,31 @@ func TestAttributeSCfgloadFromJsonCfg(t *testing.T) { t.Errorf("Expected: %+v , recived: %+v", expected, attscfg) } } + +func TestAttributeSCfgAsMapInterface(t *testing.T) { + var attscfg AttributeSCfg + cfgJSONStr := `{ +"attributes": { + "enabled": true, + "prefix_indexed_fields": ["index1","index2"], + "process_runs": 3, + }, +}` + eMap := map[string]interface{}{ + "enabled": true, + "prefix_indexed_fields": []string{"index1", "index2"}, + "process_runs": 3, + "indexed_selects": false, + "nested_fields": false, + "string_indexed_fields": []string{}, + } + if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil { + t.Error(err) + } else if jsnAttSCfg, err := jsnCfg.AttributeServJsonCfg(); err != nil { + t.Error(err) + } else if err = attscfg.loadFromJsonCfg(jsnAttSCfg); err != nil { + t.Error(err) + } else if rcv := attscfg.AsMapInterface(); !reflect.DeepEqual(eMap, rcv) { + t.Errorf("\nExpected: %+v\nRecived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv)) + } +} diff --git a/config/cachecfg.go b/config/cachecfg.go index 158ca42e2..450c7443b 100755 --- a/config/cachecfg.go +++ b/config/cachecfg.go @@ -56,11 +56,16 @@ func (cParam *CacheParamCfg) loadFromJsonCfg(jsnCfg *CacheParamJsonCfg) error { } func (cParam *CacheParamCfg) AsMapInterface() map[string]interface{} { + var TTL string = "" + if cParam.TTL != 0 { + TTL = cParam.TTL.String() + } + return map[string]interface{}{ - utils.Limit: cParam.Limit, - utils.TTL: cParam.TTL, - utils.StaticTTL: cParam.StaticTTL, - utils.Precache: cParam.Precache, + utils.LimitCfg: cParam.Limit, + utils.TTLCfg: TTL, + utils.StaticTTLCfg: cParam.StaticTTL, + utils.PrecacheCfg: cParam.Precache, } } @@ -103,14 +108,10 @@ func (cCfg CacheCfg) AddTmpCaches() { } func (cCfg *CacheCfg) AsMapInterface() map[string]interface{} { - partitions := make(map[string]interface{}, len(cCfg.Partitions)) - for key, value := range cCfg.Partitions { - partitions[key] = value.AsMapInterface() - } - - return map[string]interface{}{ - utils.PartitionsCfg: partitions, - utils.RplConnsCfg: cCfg.ReplicationConns, + mp := make(map[string]interface{}, len(*cCfg)) + for key, value := range *cCfg { + mp[key] = value.AsMapInterface() } + return mp } diff --git a/config/cachecfg_test.go b/config/cachecfg_test.go index 4531dc5a0..041546317 100644 --- a/config/cachecfg_test.go +++ b/config/cachecfg_test.go @@ -114,3 +114,65 @@ func TestCacheParamCfgloadFromJsonCfg(t *testing.T) { t.Errorf("Expected: %+v , recived: %+v", utils.ToJSON(expected), utils.ToJSON(fscocfg)) } } + +/* +func TestCacheCfgAsMapInterface(t *testing.T) { + var cachecfg *CacheCfg + cfgJSONStr := `{ + "caches":{ + "partitions": { + "*destinations": {"limit": -1, "ttl": "", "static_ttl": false, "precache": false}, + "*reverse_destinations": {"limit": -1, "ttl": "", "static_ttl": false, "precache": false}, + "*rating_plans": {"limit": -1, "ttl": "", "static_ttl": false, "precache": false}, + }, + }, + }` + eMap := map[string]interface{}{ + "partitions": map[string]interface{}{ + "*destinations": map[string]interface{}{"limit": -1, "ttl": "", "static_ttl": false, "precache": false}, + "*reverse_destinations": map[string]interface{}{"limit": -1, "ttl": "", "static_ttl": false, "precache": false}, + "*rating_plans": map[string]interface{}{"limit": -1, "ttl": "", "static_ttl": false, "precache": false}, + }, + "replication_conns": []string{}, + } + cachecfg = new(CacheCfg) + cachecfg.Partitions = make(map[string]*CacheParamCfg) + if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil { + t.Error(err) + } else if jsnCacheCfg, err := jsnCfg.CacheJsonCfg(); err != nil { + t.Error(err) + } else if err = cachecfg.loadFromJsonCfg(jsnCacheCfg); err != nil { + t.Error(err) + } else if rcv := cachecfg.AsMapInterface(); !reflect.DeepEqual(eMap, rcv) { + t.Errorf("\nExpected: %+v\nRecived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv)) + } + cfgJSONStr = `{ +"caches":{ + "partitions": { + "*destinations": {"limit": -1, "ttl": "8m", "static_ttl": false, "precache": false}, + "*reverse_destinations": {"limit": -1, "ttl": "1m", "static_ttl": false, "precache": false}, + "*rating_plans": {"limit": 10, "ttl": "", "static_ttl": true, "precache": true}, + }, + }, +}` + eMap = map[string]interface{}{ + "partitions": map[string]interface{}{ + "*destinations": map[string]interface{}{"limit": -1, "ttl": "8m0s", "static_ttl": false, "precache": false}, + "*reverse_destinations": map[string]interface{}{"limit": -1, "ttl": "1m0s", "static_ttl": false, "precache": false}, + "*rating_plans": map[string]interface{}{"limit": 10, "ttl": "", "static_ttl": true, "precache": true}, + }, + "replication_conns": []string{}, + } + cachecfg = new(CacheCfg) + cachecfg.Partitions = make(map[string]*CacheParamCfg) + if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil { + t.Error(err) + } else if jsnCacheCfg, err := jsnCfg.CacheJsonCfg(); err != nil { + t.Error(err) + } else if err = cachecfg.loadFromJsonCfg(jsnCacheCfg); err != nil { + t.Error(err) + } else if rcv := cachecfg.AsMapInterface(); !reflect.DeepEqual(eMap, rcv) { + t.Errorf("\nExpected: %+v\nRecived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv)) + } +} +*/ diff --git a/config/cdrscfg.go b/config/cdrscfg.go index 589dc3bdd..90be25ad9 100644 --- a/config/cdrscfg.go +++ b/config/cdrscfg.go @@ -19,6 +19,8 @@ along with this program. If not, see package config import ( + "strings" + "github.com/cgrates/cgrates/utils" ) @@ -123,17 +125,70 @@ func (cdrscfg *CdrsCfg) AsMapInterface() map[string]interface{} { for i, item := range cdrscfg.ExtraFields { extraFields[i] = item.Rules } + onlineCDRExports := make([]string, len(cdrscfg.OnlineCDRExports)) + for i, item := range cdrscfg.OnlineCDRExports { + onlineCDRExports[i] = item + } + + chargerSConns := make([]string, len(cdrscfg.ChargerSConns)) + for i, item := range cdrscfg.ChargerSConns { + buf := utils.ConcatenatedKey(utils.MetaInternal, utils.MetaChargers) + if item == buf { + chargerSConns[i] = strings.ReplaceAll(item, utils.CONCATENATED_KEY_SEP+utils.MetaChargers, utils.EmptyString) + } else { + chargerSConns[i] = item + } + } + RALsConns := make([]string, len(cdrscfg.RaterConns)) + for i, item := range cdrscfg.RaterConns { + buf := utils.ConcatenatedKey(utils.MetaInternal, utils.MetaResponder) + + if item == buf { + RALsConns[i] = strings.ReplaceAll(item, utils.CONCATENATED_KEY_SEP+utils.MetaResponder, utils.EmptyString) + } else { + RALsConns[i] = item + } + } + + attributeSConns := make([]string, len(cdrscfg.AttributeSConns)) + for i, item := range cdrscfg.AttributeSConns { + buf := utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAttributes) + if item == buf { + attributeSConns[i] = strings.ReplaceAll(item, utils.CONCATENATED_KEY_SEP+utils.MetaAttributes, utils.EmptyString) + } else { + attributeSConns[i] = item + } + } + + thresholdSConns := make([]string, len(cdrscfg.ThresholdSConns)) + for i, item := range cdrscfg.ThresholdSConns { + buf := utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds) + if item == buf { + thresholdSConns[i] = strings.ReplaceAll(item, utils.CONCATENATED_KEY_SEP+utils.MetaThresholds, utils.EmptyString) + } else { + thresholdSConns[i] = item + } + } + statSConns := make([]string, len(cdrscfg.StatSConns)) + for i, item := range cdrscfg.StatSConns { + buf := utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStatS) + if item == buf { + statSConns[i] = strings.ReplaceAll(item, utils.CONCATENATED_KEY_SEP+utils.MetaStatS, utils.EmptyString) + } else { + statSConns[i] = item + } + } return map[string]interface{}{ utils.EnabledCfg: cdrscfg.Enabled, utils.ExtraFieldsCfg: extraFields, utils.StoreCdrsCfg: cdrscfg.StoreCdrs, utils.SMCostRetriesCfg: cdrscfg.SMCostRetries, - utils.ChargerSConnsCfg: cdrscfg.ChargerSConns, - utils.RALsConnsCfg: cdrscfg.RaterConns, - utils.AttributeSConnsCfg: cdrscfg.AttributeSConns, - utils.ThresholdSConnsCfg: cdrscfg.ThresholdSConns, - utils.StatSConnsCfg: cdrscfg.StatSConns, - utils.OnlineCDRExportsCfg: cdrscfg.OnlineCDRExports, + utils.ChargerSConnsCfg: chargerSConns, + utils.RALsConnsCfg: RALsConns, + utils.AttributeSConnsCfg: attributeSConns, + utils.ThresholdSConnsCfg: thresholdSConns, + utils.StatSConnsCfg: statSConns, + utils.OnlineCDRExportsCfg: onlineCDRExports, } } diff --git a/config/cdrscfg_test.go b/config/cdrscfg_test.go index 7bf3accb2..858238a48 100644 --- a/config/cdrscfg_test.go +++ b/config/cdrscfg_test.go @@ -69,3 +69,103 @@ func TestCdrsCfgloadFromJsonCfg(t *testing.T) { t.Errorf("Expected: %+v , recived: %+v", utils.ToJSON(expected), utils.ToJSON(cdrscfg)) } } + +func TestExtraFieldsinAsMapInterface(t *testing.T) { + var cdrscfg CdrsCfg + cfgJSONStr := `{ + "cdrs": { + "enabled": true, + "extra_fields": ["PayPalAccount", "LCRProfile", "ResourceID"], + "chargers_conns":["*localhost"], + "store_cdrs": true, + "online_cdr_exports": [] + }, + }` + expectedExtra := []string{"PayPalAccount", "LCRProfile", "ResourceID"} + if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil { + t.Error(err) + } else if jsnCdrsCfg, err := jsnCfg.CdrsJsonCfg(); err != nil { + t.Error(err) + } else if err = cdrscfg.loadFromJsonCfg(jsnCdrsCfg); err != nil { + t.Error(err) + } else if rcv := cdrscfg.AsMapInterface(); !reflect.DeepEqual(rcv[utils.ExtraFieldsCfg], expectedExtra) { + t.Errorf("Expecting: '%+v', received: '%+v' ", expectedExtra, rcv[utils.ExtraFieldsCfg]) + } +} + +func TestCdrsCfgAsMapInterface(t *testing.T) { + var cdrscfg CdrsCfg + cfgJSONStr := `{ + "cdrs": { + "enabled": false, + "extra_fields": [], + "store_cdrs": true, + "session_cost_retries": 5, + "chargers_conns":["*localhost"], + "rals_conns": ["*internal"], + "attributes_conns": [], + "thresholds_conns": [], + "stats_conns": [], + "online_cdr_exports":[], + "scheduler_conns": [], + }, +}` + eMap := map[string]interface{}{ + "enabled": false, + "extra_fields": []string{}, + "store_cdrs": true, + "session_cost_retries": 5, + "chargers_conns": []string{"*localhost"}, + "rals_conns": []string{"*internal"}, + "attributes_conns": []string{}, + "thresholds_conns": []string{}, + "stats_conns": []string{}, + "online_cdr_exports": []string{}, + } + if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil { + t.Error(err) + } else if jsnCdrsCfg, err := jsnCfg.CdrsJsonCfg(); err != nil { + t.Error(err) + } else if err = cdrscfg.loadFromJsonCfg(jsnCdrsCfg); err != nil { + t.Error(err) + } else if rcv := cdrscfg.AsMapInterface(); !reflect.DeepEqual(eMap, rcv) { + t.Errorf("\nExpected: %+v\nRecived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv)) + } + + cfgJSONStr = `{ + "cdrs": { + "enabled": true, + "extra_fields": ["PayPalAccount", "LCRProfile", "ResourceID"], + "store_cdrs": true, + "session_cost_retries": 9, + "chargers_conns":["*internal"], + "rals_conns": ["*internal"], + "attributes_conns": ["*internal"], + "thresholds_conns": ["*internal"], + "stats_conns": ["*internal"], + "online_cdr_exports":["http_localhost", "amqp_localhost", "http_test_file", "amqp_test_file","aws_test_file","sqs_test_file","kafka_localhost","s3_test_file"], + "scheduler_conns": ["*internal"], + }, + }` + eMap = map[string]interface{}{ + "enabled": true, + "extra_fields": []string{"PayPalAccount", "LCRProfile", "ResourceID"}, + "store_cdrs": true, + "session_cost_retries": 9, + "chargers_conns": []string{"*internal"}, + "rals_conns": []string{"*internal"}, + "attributes_conns": []string{"*internal"}, + "thresholds_conns": []string{"*internal"}, + "stats_conns": []string{"*internal"}, + "online_cdr_exports": []string{"http_localhost", "amqp_localhost", "http_test_file", "amqp_test_file", "aws_test_file", "sqs_test_file", "kafka_localhost", "s3_test_file"}, + } + if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil { + t.Error(err) + } else if jsnCdrsCfg, err := jsnCfg.CdrsJsonCfg(); err != nil { + t.Error(err) + } else if err = cdrscfg.loadFromJsonCfg(jsnCdrsCfg); err != nil { + t.Error(err) + } else if rcv := cdrscfg.AsMapInterface(); !reflect.DeepEqual(eMap, rcv) { + t.Errorf("\nExpected: %+v\nRecived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv)) + } +} diff --git a/config/chargerscfg.go b/config/chargerscfg.go index 41146671c..fe55749cd 100644 --- a/config/chargerscfg.go +++ b/config/chargerscfg.go @@ -18,7 +18,11 @@ along with this program. If not, see package config -import "github.com/cgrates/cgrates/utils" +import ( + "strings" + + "github.com/cgrates/cgrates/utils" +) // SupplierSCfg is the configuration of supplier service type ChargerSCfg struct { @@ -72,12 +76,35 @@ func (cS *ChargerSCfg) loadFromJsonCfg(jsnCfg *ChargerSJsonCfg) (err error) { } func (cS *ChargerSCfg) AsMapInterface() map[string]interface{} { + attributeSConns := make([]string, len(cS.AttributeSConns)) + for i, item := range cS.AttributeSConns { + buf := utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAttributes) + if item == buf { + attributeSConns[i] = strings.ReplaceAll(item, utils.CONCATENATED_KEY_SEP+utils.MetaAttributes, utils.EmptyString) + } else { + attributeSConns[i] = item + } + } + stringIndexedFields := []string{} + if cS.StringIndexedFields != nil { + stringIndexedFields = make([]string, len(*cS.StringIndexedFields)) + for i, item := range *cS.StringIndexedFields { + stringIndexedFields[i] = item + } + } + prefixIndexedFields := []string{} + if cS.PrefixIndexedFields != nil { + prefixIndexedFields = make([]string, len(*cS.PrefixIndexedFields)) + for i, item := range *cS.PrefixIndexedFields { + prefixIndexedFields[i] = item + } + } return map[string]interface{}{ utils.EnabledCfg: cS.Enabled, utils.IndexedSelectsCfg: cS.IndexedSelects, - utils.AttributeSConnsCfg: cS.AttributeSConns, - utils.StringIndexedFieldsCfg: cS.StringIndexedFields, - utils.PrefixIndexedFieldsCfg: cS.PrefixIndexedFields, + utils.AttributeSConnsCfg: attributeSConns, + utils.StringIndexedFieldsCfg: stringIndexedFields, + utils.PrefixIndexedFieldsCfg: prefixIndexedFields, utils.NestedFieldsCfg: cS.NestedFields, } } diff --git a/config/chargerscfg_test.go b/config/chargerscfg_test.go index 4d24d5936..ff9447e0e 100644 --- a/config/chargerscfg_test.go +++ b/config/chargerscfg_test.go @@ -20,6 +20,8 @@ package config import ( "reflect" "testing" + + "github.com/cgrates/cgrates/utils" ) func TestChargerSCfgloadFromJsonCfg(t *testing.T) { @@ -57,3 +59,60 @@ func TestChargerSCfgloadFromJsonCfg(t *testing.T) { t.Errorf("Expected: %+v , recived: %+v", expected, chgscfg) } } + +func TestChargerSCfgAsMapInterface(t *testing.T) { + var chgscfg ChargerSCfg + cfgJSONStr := `{ + "chargers": { + "enabled": false, + "attributes_conns": [], + "indexed_selects":true, + "prefix_indexed_fields": [], + "nested_fields": false, + }, +}` + eMap := map[string]interface{}{ + "enabled": false, + "attributes_conns": []string{}, + "indexed_selects": true, + "prefix_indexed_fields": []string{}, + "nested_fields": false, + "string_indexed_fields": []string{}, + } + if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil { + t.Error(err) + } else if jsnChgCfg, err := jsnCfg.ChargerServJsonCfg(); err != nil { + t.Error(err) + } else if err = chgscfg.loadFromJsonCfg(jsnChgCfg); err != nil { + t.Error(err) + } else if rcv := chgscfg.AsMapInterface(); !reflect.DeepEqual(eMap, rcv) { + t.Errorf("\nExpected: %+v\nRecived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv)) + } + + cfgJSONStr = `{ + "chargers": { + "enabled": false, + "attributes_conns": ["*internal"], + "indexed_selects":true, + "prefix_indexed_fields": [], + "nested_fields": false, + }, + }` + eMap = map[string]interface{}{ + "enabled": false, + "attributes_conns": []string{"*internal"}, + "indexed_selects": true, + "prefix_indexed_fields": []string{}, + "nested_fields": false, + "string_indexed_fields": []string{}, + } + if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil { + t.Error(err) + } else if jsnChgCfg, err := jsnCfg.ChargerServJsonCfg(); err != nil { + t.Error(err) + } else if err = chgscfg.loadFromJsonCfg(jsnChgCfg); err != nil { + t.Error(err) + } else if rcv := chgscfg.AsMapInterface(); !reflect.DeepEqual(eMap, rcv) { + t.Errorf("\nExpected: %+v\nRecived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv)) + } +} diff --git a/config/config.go b/config/config.go index ce41b4b45..f31e99868 100755 --- a/config/config.go +++ b/config/config.go @@ -1505,7 +1505,7 @@ func (cfg *CGRConfig) AsMapInterface(separator string) map[string]interface{} { utils.SchedulerCfg: cfg.schedulerCfg.AsMapInterface(), utils.CdrsCfg: cfg.cdrsCfg.AsMapInterface(), utils.SessionSCfg: cfg.sessionSCfg.AsMapInterface(), - utils.FsAgentCfg: cfg.fsAgentCfg.AsMapInterface(), + utils.FsAgentCfg: cfg.fsAgentCfg.AsMapInterface(separator), utils.KamAgentCfg: cfg.kamAgentCfg.AsMapInterface(), utils.AsteriskAgentCfg: cfg.asteriskAgentCfg.AsMapInterface(), utils.DiameterAgentCfg: cfg.diameterAgentCfg.AsMapInterface(separator), @@ -1517,7 +1517,7 @@ func (cfg *CGRConfig) AsMapInterface(separator string) map[string]interface{} { utils.StatsCfg: cfg.statsCfg.AsMapInterface(), utils.ThresholdSCfg: cfg.thresholdSCfg.AsMapInterface(), utils.SupplierSCfg: cfg.supplierSCfg.AsMapInterface(), - utils.SureTaxCfg: cfg.sureTaxCfg.AsMapInterface(), + utils.SureTaxCfg: cfg.sureTaxCfg.AsMapInterface(separator), utils.DispatcherSCfg: cfg.dispatcherSCfg.AsMapInterface(), utils.LoaderCgrCfg: cfg.loaderCgrCfg.AsMapInterface(), utils.MigratorCgrCfg: cfg.migratorCgrCfg.AsMapInterface(), diff --git a/config/diametercfg.go b/config/diametercfg.go index ac98fc441..37af7cbda 100644 --- a/config/diametercfg.go +++ b/config/diametercfg.go @@ -18,7 +18,11 @@ along with this program. If not, see package config -import "github.com/cgrates/cgrates/utils" +import ( + "strings" + + "github.com/cgrates/cgrates/utils" +) type DiameterAgentCfg struct { Enabled bool // enables the diameter agent: @@ -133,12 +137,22 @@ func (ds *DiameterAgentCfg) AsMapInterface(separator string) map[string]interfac requestProcessors[i] = item.AsMapInterface(separator) } + sessionSConns := make([]string, len(ds.SessionSConns)) + for i, item := range ds.SessionSConns { + buf := utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS) + if item == buf { + sessionSConns[i] = strings.ReplaceAll(item, utils.CONCATENATED_KEY_SEP+utils.MetaSessionS, utils.EmptyString) + } else { + sessionSConns[i] = item + } + } + return map[string]interface{}{ utils.EnabledCfg: ds.Enabled, utils.ListenNetCfg: ds.ListenNet, utils.ListenCfg: ds.Listen, utils.DictionariesPathCfg: ds.DictionariesPath, - utils.SessionSConnsCfg: ds.SessionSConns, + utils.SessionSConnsCfg: sessionSConns, utils.OriginHostCfg: ds.OriginHost, utils.OriginRealmCfg: ds.OriginRealm, utils.VendorIdCfg: ds.VendorId, @@ -146,8 +160,6 @@ func (ds *DiameterAgentCfg) AsMapInterface(separator string) map[string]interfac utils.ConcurrentReqsCfg: ds.ConcurrentReqs, utils.SyncedConnReqsCfg: ds.SyncedConnReqs, utils.ASRTemplateCfg: ds.ASRTemplate, - utils.RARTemplateCfg: ds.RARTemplate, - utils.ForcedDisconnectCfg: ds.ForcedDisconnect, utils.TemplatesCfg: templates, utils.RequestProcessorsCfg: requestProcessors, } diff --git a/config/diametercfg_test.go b/config/diametercfg_test.go index 3c99009fa..161d8811e 100644 --- a/config/diametercfg_test.go +++ b/config/diametercfg_test.go @@ -72,3 +72,47 @@ func TestDiameterAgentCfgloadFromJsonCfg(t *testing.T) { t.Errorf("Expected: %+v , recived: %+v", utils.ToJSON(expected), utils.ToJSON(dacfg)) } } + +func TestDiameterAgentCfgAsMapInterface(t *testing.T) { + var dacfg DiameterAgentCfg + cfgJSONStr := `{ + "diameter_agent": { + "enabled": false, + "listen": "127.0.0.1:3868", + "dictionaries_path": "/usr/share/cgrates/diameter/dict/", + "sessions_conns": ["*internal"], + "origin_host": "CGR-DA", + "origin_realm": "cgrates.org", + "vendor_id": 0, + "product_name": "CGRateS", + "synced_conn_requests": true, + "templates":{}, + "request_processors": [], + }, +}` + eMap := map[string]interface{}{ + "asr_template": "", + "concurrent_requests": 0, + "dictionaries_path": "/usr/share/cgrates/diameter/dict/", + "enabled": false, + "listen": "127.0.0.1:3868", + "listen_net": "", + "origin_host": "CGR-DA", + "origin_realm": "cgrates.org", + "product_name": "CGRateS", + "sessions_conns": []string{"*internal"}, + "synced_conn_requests": true, + "vendor_id": 0, + "templates": map[string][]map[string]interface{}{}, + "request_processors": []map[string]interface{}{}, + } + if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil { + t.Error(err) + } else if jsnDaCfg, err := jsnCfg.DiameterAgentJsonCfg(); err != nil { + t.Error(err) + } else if err = dacfg.loadFromJsonCfg(jsnDaCfg, utils.INFIELD_SEP); err != nil { + t.Error(err) + } else if rcv := dacfg.AsMapInterface(utils.EmptyString); !reflect.DeepEqual(eMap, rcv) { + t.Errorf("Expected: %+v,\nRecived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv)) + } +} diff --git a/config/dispatchercfg.go b/config/dispatchercfg.go index 797f328c9..30122123f 100755 --- a/config/dispatchercfg.go +++ b/config/dispatchercfg.go @@ -18,7 +18,11 @@ along with this program. If not, see package config -import "github.com/cgrates/cgrates/utils" +import ( + "strings" + + "github.com/cgrates/cgrates/utils" +) // DispatcherSCfg is the configuration of dispatcher service type DispatcherSCfg struct { @@ -72,12 +76,36 @@ func (dps *DispatcherSCfg) loadFromJsonCfg(jsnCfg *DispatcherSJsonCfg) (err erro } func (dps *DispatcherSCfg) AsMapInterface() map[string]interface{} { + stringIndexedFields := []string{} + if dps.StringIndexedFields != nil { + stringIndexedFields = make([]string, len(*dps.StringIndexedFields)) + for i, item := range *dps.StringIndexedFields { + stringIndexedFields[i] = item + } + } + prefixIndexedFields := []string{} + if dps.PrefixIndexedFields != nil { + prefixIndexedFields = make([]string, len(*dps.PrefixIndexedFields)) + for i, item := range *dps.PrefixIndexedFields { + prefixIndexedFields[i] = item + } + } + attributeSConns := make([]string, len(dps.AttributeSConns)) + for i, item := range dps.AttributeSConns { + buf := utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAttributes) + if item == buf { + attributeSConns[i] = strings.ReplaceAll(item, utils.CONCATENATED_KEY_SEP+utils.MetaAttributes, utils.EmptyString) + } else { + attributeSConns[i] = item + } + } + return map[string]interface{}{ utils.EnabledCfg: dps.Enabled, utils.IndexedSelectsCfg: dps.IndexedSelects, - utils.StringIndexedFieldsCfg: dps.StringIndexedFields, - utils.PrefixIndexedFieldsCfg: dps.PrefixIndexedFields, - utils.AttributeSConnsCfg: dps.AttributeSConns, + utils.StringIndexedFieldsCfg: stringIndexedFields, + utils.PrefixIndexedFieldsCfg: prefixIndexedFields, + utils.AttributeSConnsCfg: attributeSConns, utils.NestedFieldsCfg: dps.NestedFields, } diff --git a/config/dispatchercfg_test.go b/config/dispatchercfg_test.go new file mode 100644 index 000000000..da386593d --- /dev/null +++ b/config/dispatchercfg_test.go @@ -0,0 +1,138 @@ +/* +Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments +Copyright (C) ITsysCOM GmbH + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +package config + +import ( + "reflect" + "testing" + + "github.com/cgrates/cgrates/utils" +) + +func TestDispatcherSCfgloadFromJsonCfg(t *testing.T) { + var daCfg, expected DispatcherSCfg + if err := daCfg.loadFromJsonCfg(nil); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(daCfg, expected) { + t.Errorf("Expected: %+v ,recived: %+v", expected, daCfg) + } + if err := daCfg.loadFromJsonCfg(new(DispatcherSJsonCfg)); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(daCfg, expected) { + t.Errorf("Expected: %+v ,recived: %+v", expected, daCfg) + } + cfgJSONStr := `{ + "dispatchers":{ + "enabled": false, + "indexed_selects":true, + //"string_indexed_fields": [], + "prefix_indexed_fields": [], + "nested_fields": false, + "attributes_conns": [], + }, + +}` + expected = DispatcherSCfg{ + Enabled: false, + IndexedSelects: true, + PrefixIndexedFields: &[]string{}, + AttributeSConns: []string{}, + NestedFields: false, + } + if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil { + t.Error(err) + } else if jsnDaCfg, err := jsnCfg.DispatcherSJsonCfg(); err != nil { + t.Error(err) + } else if err = daCfg.loadFromJsonCfg(jsnDaCfg); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(expected, daCfg) { + t.Errorf("Expected: %+v,\nRecived: %+v", utils.ToJSON(expected), utils.ToJSON(daCfg)) + } +} + +func TestDispatcherSCfgAsMapInterface(t *testing.T) { + var daCfg, expected DispatcherSCfg + if err := daCfg.loadFromJsonCfg(nil); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(daCfg, expected) { + t.Errorf("Expected: %+v ,recived: %+v", expected, daCfg) + } + if err := daCfg.loadFromJsonCfg(new(DispatcherSJsonCfg)); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(daCfg, expected) { + t.Errorf("Expected: %+v ,recived: %+v", expected, daCfg) + } + cfgJSONStr := `{ + "dispatchers":{ + "enabled": false, + "indexed_selects":true, + //"string_indexed_fields": [], + "prefix_indexed_fields": [], + "nested_fields": false, + "attributes_conns": [], + }, + +}` + eMap := map[string]interface{}{ + "enabled": false, + "indexed_selects": true, + "prefix_indexed_fields": []string{}, + "nested_fields": false, + "attributes_conns": []string{}, + "string_indexed_fields": []string{}, + } + if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil { + t.Error(err) + } else if jsnDaCfg, err := jsnCfg.DispatcherSJsonCfg(); err != nil { + t.Error(err) + } else if err = daCfg.loadFromJsonCfg(jsnDaCfg); err != nil { + t.Error(err) + } else if rcv := daCfg.AsMapInterface(); !reflect.DeepEqual(eMap, rcv) { + t.Errorf("\nExpected: %+v\nRecived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv)) + } + + cfgJSONStr = `{ + "dispatchers":{ + "enabled": false, + "indexed_selects":true, + "string_indexed_fields": ["string","indexed","fields"], + "prefix_indexed_fields": ["prefix","indexed","fields"], + "nested_fields": false, + "attributes_conns": ["*internal"], + }, + +}` + eMap = map[string]interface{}{ + "enabled": false, + "indexed_selects": true, + "prefix_indexed_fields": []string{"prefix", "indexed", "fields"}, + "nested_fields": false, + "attributes_conns": []string{"*internal"}, + "string_indexed_fields": []string{"string", "indexed", "fields"}, + } + if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil { + t.Error(err) + } else if jsnDaCfg, err := jsnCfg.DispatcherSJsonCfg(); err != nil { + t.Error(err) + } else if err = daCfg.loadFromJsonCfg(jsnDaCfg); err != nil { + t.Error(err) + } else if rcv := daCfg.AsMapInterface(); !reflect.DeepEqual(eMap, rcv) { + t.Errorf("\nExpected: %+v\nRecived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv)) + } +} diff --git a/config/dnsagentcfg_test.go b/config/dnsagentcfg_test.go index fab5cf868..9a52d683d 100644 --- a/config/dnsagentcfg_test.go +++ b/config/dnsagentcfg_test.go @@ -94,3 +94,101 @@ func TestRequestProcessorloadFromJsonCfg(t *testing.T) { t.Errorf("Expected: %+v , recived: %+v", utils.ToJSON(expected), utils.ToJSON(dareq)) } } + +func TestDNSAgentCfgAsMapInterface(t *testing.T) { + var dnsCfg DNSAgentCfg + cfgJSONStr := `{ + "dns_agent": { + "enabled": false, + "listen": "127.0.0.1:2053", + "listen_net": "udp", + "sessions_conns": ["*internal"], + "timezone": "", + "request_processors": [ + ], + }, +}` + eMap := map[string]interface{}{ + "enabled": false, + "listen": "127.0.0.1:2053", + "listen_net": "udp", + "sessions_conns": []string{"*internal"}, + "timezone": "", + "request_processors": []map[string]interface{}{}, + } + if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil { + t.Error(err) + } else if jsnDaCfg, err := jsnCfg.DNSAgentJsonCfg(); err != nil { + t.Error(err) + } else if err = dnsCfg.loadFromJsonCfg(jsnDaCfg, utils.INFIELD_SEP); err != nil { + t.Error(err) + } else if rcv := dnsCfg.AsMapInterface(utils.EmptyString); !reflect.DeepEqual(eMap, rcv) { + t.Errorf("\nExpected: %+v\nRecived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv)) + } + + cfgJSONStr = `{ + "dns_agent": { + "enabled": false, + "listen": "127.0.0.1:2053", + "listen_net": "udp", + "sessions_conns": ["*internal"], + "timezone": "UTC", + "request_processors": [ + { + "id": "OutboundAUTHDryRun", + "filters": ["*string:~*req.request_type:OutboundAUTH","*string:~*req.Msisdn:497700056231"], + "tenant": "cgrates.org", + "flags": ["*dryrun"], + "request_fields":[ + ], + "reply_fields":[ + {"tag": "Allow", "path": "*rep.response.Allow", "type": "*constant", + "value": "1", "mandatory": true}, + {"tag": "Concatenated1", "path": "*rep.response.Concatenated", "type": "*composed", + "value": "~*req.MCC;/", "mandatory": true}, + {"tag": "Concatenated2", "path": "*rep.response.Concatenated", "type": "*composed", + "value": "Val1"}, + {"tag": "MaxDuration", "path": "*rep.response.MaxDuration", "type": "*constant", + "value": "1200", "blocker": true}, + {"tag": "Unused", "path": "*rep.response.Unused", "type": "*constant", + "value": "0"}, + ], + }, + ], + }, + }` + eMap = map[string]interface{}{ + "enabled": false, + "listen": "127.0.0.1:2053", + "listen_net": "udp", + "sessions_conns": []string{"*internal"}, + "timezone": "UTC", + "request_processors": []map[string]interface{}{ + { + "id": "OutboundAUTHDryRun", + "filters": []string{"*string:~*req.request_type:OutboundAUTH", "*string:~*req.Msisdn:497700056231"}, + "tenant": "cgrates.org", + "flags": map[string][]string{"*dryrun": {}}, + "Timezone": "", + "request_fields": []map[string]interface{}{}, + "reply_fields": []map[string]interface{}{ + {"tag": "Allow", "path": "*rep.response.Allow", "type": "*constant", "value": "1", "mandatory": true}, + {"tag": "Concatenated1", "path": "*rep.response.Concatenated", "type": "*composed", "value": "~*req.MCC;/", "mandatory": true}, + {"tag": "Concatenated2", "path": "*rep.response.Concatenated", "type": "*composed", "value": "Val1"}, + {"tag": "MaxDuration", "path": "*rep.response.MaxDuration", "type": "*constant", "value": "1200", "blocker": true}, + {"tag": "Unused", "path": "*rep.response.Unused", "type": "*constant", "value": "0"}, + }, + }, + }, + } + if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil { + t.Error(err) + } else if jsnDaCfg, err := jsnCfg.DNSAgentJsonCfg(); err != nil { + t.Error(err) + } else if err = dnsCfg.loadFromJsonCfg(jsnDaCfg, utils.INFIELD_SEP); err != nil { + t.Error(err) + } else if rcv := dnsCfg.AsMapInterface(";"); !reflect.DeepEqual(eMap, rcv) { + t.Errorf("\nExpected: %+v\nRecived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv)) + } + +} diff --git a/config/dnsagntcfg.go b/config/dnsagntcfg.go index e1a61b94d..52daffaf1 100644 --- a/config/dnsagntcfg.go +++ b/config/dnsagntcfg.go @@ -87,12 +87,21 @@ func (da *DNSAgentCfg) AsMapInterface(separator string) map[string]interface{} { for i, item := range da.RequestProcessors { requestProcessors[i] = item.AsMapInterface(separator) } + sessionSConns := make([]string, len(da.SessionSConns)) + for i, item := range da.SessionSConns { + buf := utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS) + if item == buf { + sessionSConns[i] = strings.ReplaceAll(item, utils.CONCATENATED_KEY_SEP+utils.MetaSessionS, utils.EmptyString) + } else { + sessionSConns[i] = item + } + } return map[string]interface{}{ utils.EnabledCfg: da.Enabled, utils.ListenCfg: da.Listen, utils.ListenNetCfg: da.ListenNet, - utils.SessionSConnsCfg: da.SessionSConns, + utils.SessionSConnsCfg: sessionSConns, utils.TimezoneCfg: da.Timezone, utils.RequestProcessorsCfg: requestProcessors, } @@ -165,7 +174,7 @@ func (rp *RequestProcessor) AsMapInterface(separator string) map[string]interfac for i, item := range rp.Tenant { values[i] = item.Rules } - tenant = strings.Join(values, utils.EmptyString) + tenant = strings.Join(values, separator) } flags := make(map[string][]string, len(rp.Flags)) diff --git a/config/erscfg.go b/config/erscfg.go index f55f7be34..faf3f1997 100644 --- a/config/erscfg.go +++ b/config/erscfg.go @@ -19,6 +19,7 @@ along with this program. If not, see package config import ( + "strings" "time" "github.com/cgrates/cgrates/utils" @@ -252,13 +253,22 @@ func (er *EventReaderCfg) AsMapInterface(separator string) map[string]interface{ for i, item := range er.XmlRootPath { xmlRootPath[i] = item } - tenant := make([]string, len(er.Tenant)) - for i, item := range er.Tenant { - tenant[i] = item.Rules + var tenant string + if er.Tenant != nil { + values := make([]string, len(er.Tenant)) + for i, item := range er.Tenant { + values[i] = item.Rules + } + tenant = strings.Join(values, separator) } - flags := make(map[string][]string, len(er.Flags)) + + flags := make(map[string][]interface{}, len(er.Flags)) for key, val := range er.Flags { - flags[key] = val + buf := make([]interface{}, len(val)) + for i, item := range val { + buf[i] = item + } + flags[key] = buf } fields := make([]map[string]interface{}, len(er.Fields)) for i, item := range er.Fields { @@ -268,13 +278,26 @@ func (er *EventReaderCfg) AsMapInterface(separator string) map[string]interface{ for i, item := range er.CacheDumpFields { cacheDumpFields[i] = item.AsMapInterface(separator) } + var runDelay string + if er.RunDelay > 0 { + runDelay = er.RunDelay.String() + } else if er.RunDelay == 0 { + runDelay = "0" + } else { + runDelay = "-1" + } + + var partialRecordCache string = "0" + if er.PartialRecordCache != 0 { + partialRecordCache = er.PartialRecordCache.String() + } return map[string]interface{}{ utils.IDCfg: er.ID, utils.TypeCfg: er.Type, utils.RowLengthCfg: er.RowLength, utils.FieldSepCfg: er.FieldSep, - utils.RunDelayCfg: er.RunDelay, + utils.RunDelayCfg: runDelay, utils.ConcurrentReqsCfg: er.ConcurrentReqs, utils.SourcePathCfg: er.SourcePath, utils.ProcessedPathCfg: er.ProcessedPath, @@ -284,7 +307,7 @@ func (er *EventReaderCfg) AsMapInterface(separator string) map[string]interface{ utils.FiltersCfg: er.Filters, utils.FlagsCfg: flags, utils.FailedCallsPrefixCfg: er.FailedCallsPrefix, - utils.PartialRecordCacheCfg: er.PartialRecordCache, + utils.PartialRecordCacheCfg: partialRecordCache, utils.PartialCacheExpiryActionCfg: er.PartialCacheExpiryAction, utils.FieldsCfg: fields, utils.CacheDumpFieldsCfg: cacheDumpFields, diff --git a/config/erscfg_test.go b/config/erscfg_test.go index 46c23cfd1..03c62d0fb 100644 --- a/config/erscfg_test.go +++ b/config/erscfg_test.go @@ -224,3 +224,98 @@ func TestEventReaderSanitisation(t *testing.T) { t.Error(err) } } + +func TestERsCfgAsMapInterface(t *testing.T) { + cfgJSONStr := `{ + "ers": { + "enabled": true, + "sessions_conns":["conn1","conn3"], + "readers": [ + { + "id": "file_reader1", + "run_delay": "-1", + "type": "*file_csv", + "source_path": "/tmp/ers/in", + "processed_path": "/tmp/ers/out", + "cache_dump_fields": [], + }, + ], + } +}` + var filters []string + eMap := map[string]interface{}{ + "enabled": true, + "sessions_conns": []string{"conn1", "conn3"}, + "readers": []map[string]interface{}{ + { + "filters": []string{}, + "flags": map[string][]interface{}{}, + "id": "*default", + "partial_record_cache": "0", + "processed_path": "/var/spool/cgrates/cdrc/out", + "row_length": 0, + "run_delay": "0", + "soome": "", + "source_path": "/var/spool/cgrates/cdrc/in", + "tenant": "", + "timezone": "", + "xml_root_path": []string{""}, + "cache_dump_fields": []map[string]interface{}{}, + "concurrent_requests": 1024, + "db_type": "*file_csv", + "failed_calls_prefix": "", + "field_separator": ",", + "fields": []map[string]interface{}{ + {"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"}, + }, + }, + { + "cache_dump_fields": []map[string]interface{}{}, + "concurrent_requests": 1024, + "db_type": "*file_csv", + "failed_calls_prefix": "", + "field_separator": ",", + "fields": []map[string]interface{}{ + {"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": filters, + "flags": map[string][]interface{}{}, + "id": "file_reader1", + "partial_record_cache": "0", + "processed_path": "/tmp/ers/out", + "row_length": 0, + "run_delay": "-1", + "soome": "", + "source_path": "/tmp/ers/in", + "tenant": "", + "timezone": "", + "xml_root_path": []string{""}, + }, + }, + } + if cfg, err := NewCGRConfigFromJsonStringWithDefaults(cfgJSONStr); err != nil { + t.Error(err) + } else if rcv := cfg.ersCfg.AsMapInterface(utils.EmptyString); !reflect.DeepEqual(eMap, rcv) { + t.Errorf("\nExpected: %+v\nRecived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv)) + } +} diff --git a/config/fctemplate.go b/config/fctemplate.go index e999ccb8d..8157f1911 100755 --- a/config/fctemplate.go +++ b/config/fctemplate.go @@ -244,14 +244,14 @@ func (fc *FCTemplate) AsMapInterface(separator string) (mp map[string]interface{ if fc.BreakOnSuccess != false { mp[utils.BreakOnSuccessCfg] = fc.BreakOnSuccess } - if fc.Layout != time.RFC3339 { + if fc.Layout != utils.EmptyString { mp[utils.LayoutCfg] = fc.Layout } if fc.CostShiftDigits != 0 { mp[utils.CostShiftDigitsCfg] = fc.CostShiftDigits } - if fc.RoundingDecimals != nil { - mp[utils.RoundingDecimalsCfg] = *fc.RoundingDecimals + if fc.RoundingDecimals != 0 { + mp[utils.RoundingDecimalsCfg] = fc.RoundingDecimals } if fc.MaskDestID != utils.EmptyString { mp[utils.MaskDestIDCfg] = fc.MaskDestID diff --git a/config/filterscfg.go b/config/filterscfg.go index 037426f8d..6ac24768c 100644 --- a/config/filterscfg.go +++ b/config/filterscfg.go @@ -58,6 +58,5 @@ func (fSCfg *FilterSCfg) AsMapInterface() map[string]interface{} { return map[string]interface{}{ utils.StatSConnsCfg: fSCfg.StatSConns, utils.ResourceSConnsCfg: fSCfg.ResourceSConns, - utils.ApierSConnsCfg: fSCfg.ApierSConns, } } diff --git a/config/httpcfg.go b/config/httpcfg.go index 258f0fe21..d1e1ff9d3 100644 --- a/config/httpcfg.go +++ b/config/httpcfg.go @@ -58,7 +58,7 @@ func (httpcfg *HTTPCfg) loadFromJsonCfg(jsnHttpCfg *HTTPJsonCfg) (err error) { } func (httpcfg *HTTPCfg) AsMapInterface() map[string]interface{} { - httpUsers := map[string]interface{}{} + httpUsers := make(map[string]interface{}, len(httpcfg.HTTPAuthUsers)) for key, item := range httpcfg.HTTPAuthUsers { httpUsers[key] = item } diff --git a/config/kamagentcfg.go b/config/kamagentcfg.go index 418995c0c..854d3c180 100644 --- a/config/kamagentcfg.go +++ b/config/kamagentcfg.go @@ -18,7 +18,11 @@ along with this program. If not, see package config -import "github.com/cgrates/cgrates/utils" +import ( + "strings" + + "github.com/cgrates/cgrates/utils" +) // Represents one connection instance towards Kamailio type KamConnCfg struct { @@ -97,9 +101,19 @@ func (ka *KamAgentCfg) AsMapInterface() map[string]interface{} { evapiConns[i] = item.AsMapInterface() } + sessionSConns := make([]string, len(ka.SessionSConns)) + for i, item := range ka.SessionSConns { + buf := utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS) + if item == buf { + sessionSConns[i] = strings.ReplaceAll(item, utils.CONCATENATED_KEY_SEP+utils.MetaSessionS, utils.EmptyString) + } else { + sessionSConns[i] = item + } + } + return map[string]interface{}{ utils.EnabledCfg: ka.Enabled, - utils.SessionSConnsCfg: ka.SessionSConns, + utils.SessionSConnsCfg: sessionSConns, utils.CreateCdrCfg: ka.CreateCdr, utils.EvapiConnsCfg: evapiConns, utils.TimezoneCfg: ka.Timezone, diff --git a/config/kamagentcfg_test.go b/config/kamagentcfg_test.go index fc29bd368..42262fc98 100644 --- a/config/kamagentcfg_test.go +++ b/config/kamagentcfg_test.go @@ -88,3 +88,66 @@ func TestKamConnCfgloadFromJsonCfg(t *testing.T) { t.Errorf("Expected: %+v , recived: %+v", utils.ToJSON(expected), utils.ToJSON(kamcocfg)) } } + +func TestKamAgentCfgAsMapInterface(t *testing.T) { + var kamagcfg KamAgentCfg + cfgJSONStr := `{ + "kamailio_agent": { + "enabled": false, + "sessions_conns": [""], + "create_cdr": false, + "timezone": "", + "evapi_conns":[ + {"address": "127.0.0.1:8448", "reconnects": 5} + ], + }, + }` + eMap := map[string]interface{}{ + "enabled": false, + "sessions_conns": []string{""}, + "create_cdr": false, + "timezone": "", + "evapi_conns": []map[string]interface{}{ + {"address": "127.0.0.1:8448", "reconnects": 5, "alias": ""}, + }, + } + if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil { + t.Error(err) + } else if jsnKamAgCfg, err := jsnCfg.KamAgentJsonCfg(); err != nil { + t.Error(err) + } else if err = kamagcfg.loadFromJsonCfg(jsnKamAgCfg); err != nil { + t.Error(err) + } else if rcv := kamagcfg.AsMapInterface(); !reflect.DeepEqual(eMap, rcv) { + t.Errorf("\nExpected: %+v\nRecived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv)) + } + + cfgJSONStr = `{ + "kamailio_agent": { + "enabled": false, + "sessions_conns": ["*internal"], + "create_cdr": false, + "timezone": "", + "evapi_conns":[ + {"address": "127.0.0.1:8448", "reconnects": 5} + ], + }, +}` + eMap = map[string]interface{}{ + "enabled": false, + "sessions_conns": []string{"*internal"}, + "create_cdr": false, + "timezone": "", + "evapi_conns": []map[string]interface{}{ + {"address": "127.0.0.1:8448", "reconnects": 5, "alias": ""}, + }, + } + if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil { + t.Error(err) + } else if jsnKamAgCfg, err := jsnCfg.KamAgentJsonCfg(); err != nil { + t.Error(err) + } else if err = kamagcfg.loadFromJsonCfg(jsnKamAgCfg); err != nil { + t.Error(err) + } else if rcv := kamagcfg.AsMapInterface(); !reflect.DeepEqual(eMap, rcv) { + t.Errorf("\nExpected: %+v\nRecived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv)) + } +} diff --git a/config/loadercgrcfg.go b/config/loadercgrcfg.go index 11a3537b6..4e116f9cc 100644 --- a/config/loadercgrcfg.go +++ b/config/loadercgrcfg.go @@ -72,24 +72,12 @@ func (ld *LoaderCgrCfg) loadFromJsonCfg(jsnCfg *LoaderCfgJson) (err error) { } func (ld *LoaderCgrCfg) AsMapInterface() map[string]interface{} { - gapiCredentials := make([]byte, len(ld.GapiCredentials)) - for i, item := range ld.GapiCredentials { - gapiCredentials[i] = item - } - - gapiToken := make([]byte, len(ld.GapiToken)) - for i, item := range ld.GapiToken { - gapiToken[i] = item - } - return map[string]interface{}{ - utils.TpIDCfg: ld.TpID, - utils.DataPathCfg: ld.DataPath, - utils.DisableReverseCfg: ld.DisableReverse, - utils.FieldSeparatorCfg: ld.FieldSeparator, - utils.CachesConnsCfg: ld.CachesConns, - utils.SchedulerConnsCfg: ld.SchedulerConns, - utils.GapiCredentialsCfg: gapiCredentials, - utils.GapiTokenCfg: gapiToken, + utils.TpIDCfg: ld.TpID, + utils.DataPathCfg: ld.DataPath, + utils.DisableReverseCfg: ld.DisableReverse, + utils.FieldSeparatorCfg: string(ld.FieldSeparator), + utils.CachesConnsCfg: ld.CachesConns, + utils.SchedulerConnsCfg: ld.SchedulerConns, } } diff --git a/config/loadercgrcfg_test.go b/config/loadercgrcfg_test.go index 2254aca45..baeac970e 100644 --- a/config/loadercgrcfg_test.go +++ b/config/loadercgrcfg_test.go @@ -61,3 +61,48 @@ func TestLoaderCgrCfgloadFromJsonCfg(t *testing.T) { t.Errorf("Expected: %+v , recived: %+v", utils.ToJSON(expected), utils.ToJSON(loadscfg)) } } + +func TestLoaderCgrCfgAsMapInterface(t *testing.T) { + var loadscfg LoaderCgrCfg + cfgJSONStr := `{ + "loader": { + "tpid": "", + "data_path": "./", + "disable_reverse": false, + "field_separator": ",", + "caches_conns":["*localhost"], + "scheduler_conns": ["*localhost"], + "gapi_credentials": ".gapi/credentials.json", + "gapi_token": ".gapi/token.json" + }, +}` + eMap := map[string]interface{}{ + "tpid": "", + "data_path": "./", + "disable_reverse": false, + "field_separator": ",", + "caches_conns": []string{"*localhost"}, + "scheduler_conns": []string{"*localhost"}, + "gapi_credentials": ".gapi/credentials.json", + "gapi_token": ".gapi/token.json", + } + if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil { + t.Error(err) + } else if jsnLoadersCfg, err := jsnCfg.LoaderCfgJson(); err != nil { + t.Error(err) + } else if err = loadscfg.loadFromJsonCfg(jsnLoadersCfg); err != nil { + t.Error(err) + } else if rcv := loadscfg.AsMapInterface(); !reflect.DeepEqual(eMap["tpid"], rcv["tpid"]) { + t.Errorf("Expected: %+v, Recived: %+v, at field: '%s'", utils.ToJSON(eMap["tpid"]), utils.ToJSON(rcv["tpid"]), "tpid") + } else if !reflect.DeepEqual(eMap["data_path"], rcv["data_path"]) { + t.Errorf("Expected: %+v, Recived: %+v, at field: %s", utils.ToJSON(eMap["data_path"]), utils.ToJSON(rcv["data_path"]), "data_path") + } else if !reflect.DeepEqual(eMap["disable_reverse"], rcv["disable_reverse"]) { + t.Errorf("Expected: %+v, Recived: %+v, at field: %s", utils.ToJSON(eMap["disable_reverse"]), utils.ToJSON(rcv["disable_reverse"]), "disable_reverse") + } else if !reflect.DeepEqual(eMap["field_separator"], rcv["field_separator"]) { + t.Errorf("Expected: %+v, Recived: %+v, at field: %s", utils.ToJSON(eMap["field_separator"]), utils.ToJSON(rcv["field_separator"]), "field_separator") + } else if !reflect.DeepEqual(eMap["caches_conns"], rcv["caches_conns"]) { + t.Errorf("Expected: %+v, Recived: %+v, at field: %s", utils.ToJSON(eMap["caches_conns"]), utils.ToJSON(rcv["caches_conns"]), "caches_conns") + } else if !reflect.DeepEqual(eMap["scheduler_conns"], rcv["scheduler_conns"]) { + t.Errorf("Expected: %+v, Recived: %+v, at field: %s", utils.ToJSON(eMap["scheduler_conns"]), utils.ToJSON(rcv["scheduler_conns"]), "scheduler_conns") + } +} diff --git a/config/mailercfg_test.go b/config/mailercfg_test.go index 5682457f2..bfeab40d9 100644 --- a/config/mailercfg_test.go +++ b/config/mailercfg_test.go @@ -20,6 +20,8 @@ package config import ( "reflect" "testing" + + "github.com/cgrates/cgrates/utils" ) func TestMailerCfgloadFromJsonCfg(t *testing.T) { @@ -58,3 +60,54 @@ func TestMailerCfgloadFromJsonCfg(t *testing.T) { t.Errorf("Expected: %+v , recived: %+v", expected, mailcfg) } } + +func TestMailerCfgAsMapInterface(t *testing.T) { + var mailcfg MailerCfg + cfgJSONStr := `{ + "mailer": { + "server": "", + "auth_user": "", + "auth_password": "", + "from_address": "", + }, +}` + eMap := map[string]interface{}{ + "server": "", + "auth_user": "", + "auth_password": "", + "from_address": "", + } + if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil { + t.Error(err) + } else if jsnMailCfg, err := jsnCfg.MailerJsonCfg(); err != nil { + t.Error(err) + } else if err = mailcfg.loadFromJsonCfg(jsnMailCfg); err != nil { + t.Error(err) + } else if rcv := mailcfg.AsMapInterface(); !reflect.DeepEqual(eMap, rcv) { + t.Errorf("\nExpected: %+v\nRecived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv)) + } + + cfgJSONStr = `{ + "mailer": { + "server": "localhost", + "auth_user": "cgrates", + "auth_password": "CGRateS.org", + "from_address": "cgr-mailer@localhost.localdomain", + }, + }` + eMap = map[string]interface{}{ + "server": "localhost", + "auth_user": "cgrates", + "auth_password": "CGRateS.org", + "from_address": "cgr-mailer@localhost.localdomain", + } + if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil { + t.Error(err) + } else if jsnMailCfg, err := jsnCfg.MailerJsonCfg(); err != nil { + t.Error(err) + } else if err = mailcfg.loadFromJsonCfg(jsnMailCfg); err != nil { + t.Error(err) + } else if rcv := mailcfg.AsMapInterface(); !reflect.DeepEqual(eMap, rcv) { + t.Errorf("\nExpected: %+v\nRecived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv)) + } +} diff --git a/config/migratorcfg_test.go b/config/migratorcfg_test.go index 97436a1bf..c464518ff 100644 --- a/config/migratorcfg_test.go +++ b/config/migratorcfg_test.go @@ -20,6 +20,8 @@ package config import ( "reflect" "testing" + + "github.com/cgrates/cgrates/utils" ) func TestMigratorCgrCfgloadFromJsonCfg(t *testing.T) { @@ -76,3 +78,99 @@ func TestMigratorCgrCfgloadFromJsonCfg(t *testing.T) { t.Errorf("Expected: %+v , recived: %+v", expected, migcfg) } } + +func TestMigratorCgrCfgAsMapInterface(t *testing.T) { + var migcfg MigratorCgrCfg + cfgJSONStr := `{ + "migrator": { + "out_datadb_type": "redis", + "out_datadb_host": "127.0.0.1", + "out_datadb_port": "6379", + "out_datadb_name": "10", + "out_datadb_user": "cgrates", + "out_datadb_password": "", + "out_datadb_encoding" : "msgpack", + "out_stordb_type": "mysql", + "out_stordb_host": "127.0.0.1", + "out_stordb_port": "3306", + "out_stordb_name": "cgrates", + "out_stordb_user": "cgrates", + "out_stordb_password": "", + "users_filters":[], + }, +}` + var users_filters []string + eMap := map[string]interface{}{ + "out_datadb_type": "redis", + "out_datadb_host": "127.0.0.1", + "out_datadb_port": "6379", + "out_datadb_name": "10", + "out_datadb_user": "cgrates", + "out_datadb_password": "", + "out_datadb_encoding": "msgpack", + "out_stordb_type": "mysql", + "out_stordb_host": "127.0.0.1", + "out_stordb_port": "3306", + "out_stordb_name": "cgrates", + "out_stordb_user": "cgrates", + "out_stordb_password": "", + "users_filters": users_filters, + "out_datadb_redis_sentinel": "", + } + if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil { + t.Error(err) + } else if jsnThSCfg, err := jsnCfg.MigratorCfgJson(); err != nil { + t.Error(err) + } else if err = migcfg.loadFromJsonCfg(jsnThSCfg); err != nil { + t.Error(err) + } else if rcv := migcfg.AsMapInterface(); !reflect.DeepEqual(eMap, rcv) { + t.Errorf("\nExpected: %+v\nRecived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv)) + } + cfgJSONStr = `{ + "migrator": { + "out_datadb_type": "redis", + "out_datadb_host": "127.0.0.1", + "out_datadb_port": "6379", + "out_datadb_name": "10", + "out_datadb_user": "cgrates", + "out_datadb_password": "out_datadb_password", + "out_datadb_encoding" : "msgpack", + "out_stordb_type": "mysql", + "out_stordb_host": "127.0.0.1", + "out_stordb_port": "3306", + "out_stordb_name": "cgrates", + "out_stordb_user": "cgrates", + "out_stordb_password": "out_stordb_password", + "users_filters":["users","filters","Account"], + "out_datadb_redis_sentinel": "out_datadb_redis_sentinel", + }, + }` + + eMap = map[string]interface{}{ + "out_datadb_type": "redis", + "out_datadb_host": "127.0.0.1", + "out_datadb_port": "6379", + "out_datadb_name": "10", + "out_datadb_user": "cgrates", + "out_datadb_password": "out_datadb_password", + "out_datadb_encoding": "msgpack", + "out_stordb_type": "mysql", + "out_stordb_host": "127.0.0.1", + "out_stordb_port": "3306", + "out_stordb_name": "cgrates", + "out_stordb_user": "cgrates", + "out_stordb_password": "out_stordb_password", + "users_filters": []string{"users", "filters", "Account"}, + "out_datadb_redis_sentinel": "out_datadb_redis_sentinel", + } + if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil { + t.Error(err) + } else if jsnThSCfg, err := jsnCfg.MigratorCfgJson(); err != nil { + t.Error(err) + } else if err = migcfg.loadFromJsonCfg(jsnThSCfg); err != nil { + t.Error(err) + } else if rcv := migcfg.AsMapInterface(); !reflect.DeepEqual(eMap, rcv) { + t.Errorf("\nExpected: %+v\nRecived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv)) + } + +} diff --git a/config/radiuscfg.go b/config/radiuscfg.go index 7c1ca7db7..de0f6a7fc 100644 --- a/config/radiuscfg.go +++ b/config/radiuscfg.go @@ -18,7 +18,11 @@ along with this program. If not, see package config -import "github.com/cgrates/cgrates/utils" +import ( + "strings" + + "github.com/cgrates/cgrates/utils" +) type RadiusAgentCfg struct { Enabled bool @@ -112,6 +116,16 @@ func (ra *RadiusAgentCfg) AsMapInterface(separator string) map[string]interface{ requestProcessors[i] = item.AsMapInterface(separator) } + sessionSConns := make([]string, len(ra.SessionSConns)) + for i, item := range ra.SessionSConns { + buf := utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS) + if item == buf { + sessionSConns[i] = strings.ReplaceAll(item, utils.CONCATENATED_KEY_SEP+utils.MetaSessionS, utils.EmptyString) + } else { + sessionSConns[i] = item + } + } + return map[string]interface{}{ utils.EnabledCfg: ra.Enabled, utils.ListenNetCfg: ra.ListenNet, @@ -119,7 +133,7 @@ func (ra *RadiusAgentCfg) AsMapInterface(separator string) map[string]interface{ utils.ListenAcctCfg: ra.ListenAcct, utils.ClientSecretsCfg: clientSecrets, utils.ClientDictionariesCfg: clientDictionaries, - utils.SessionSConnsCfg: ra.SessionSConns, + utils.SessionSConnsCfg: sessionSConns, utils.RequestProcessorsCfg: requestProcessors, } diff --git a/config/radiuscfg_test.go b/config/radiuscfg_test.go index a36ea4f90..07f45b1b0 100644 --- a/config/radiuscfg_test.go +++ b/config/radiuscfg_test.go @@ -70,3 +70,47 @@ func TestRadiusAgentCfgloadFromJsonCfg(t *testing.T) { t.Errorf("Expected: %+v , recived: %+v", utils.ToJSON(expected), utils.ToJSON(racfg)) } } + +func TestRadiusAgentCfgAsMapInterface(t *testing.T) { + var racfg RadiusAgentCfg + cfgJSONStr := `{ + "radius_agent": { + "enabled": false, + "listen_net": "udp", + "listen_auth": "127.0.0.1:1812", + "listen_acct": "127.0.0.1:1813", + "client_secrets": { + "*default": "CGRateS.org" + }, + "client_dictionaries": { + "*default": "/usr/share/cgrates/radius/dict/", + }, + "sessions_conns": ["*internal"], + "request_processors": [ + ], + }, +}` + eMap := map[string]interface{}{ + "enabled": false, + "listen_net": "udp", + "listen_auth": "127.0.0.1:1812", + "listen_acct": "127.0.0.1:1813", + "client_secrets": map[string]interface{}{ + "*default": "CGRateS.org", + }, + "client_dictionaries": map[string]interface{}{ + "*default": "/usr/share/cgrates/radius/dict/", + }, + "sessions_conns": []string{"*internal"}, + "request_processors": []map[string]interface{}{}, + } + if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil { + t.Error(err) + } else if jsnRaCfg, err := jsnCfg.RadiusAgentJsonCfg(); err != nil { + t.Error(err) + } else if err = racfg.loadFromJsonCfg(jsnRaCfg, utils.INFIELD_SEP); err != nil { + t.Error(err) + } else if rcv := racfg.AsMapInterface(utils.EmptyString); !reflect.DeepEqual(eMap, rcv) { + t.Errorf("\nExpected: %+v\nRecived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv)) + } +} diff --git a/config/ralscfg.go b/config/ralscfg.go index 7801cdc7d..70a12d6eb 100644 --- a/config/ralscfg.go +++ b/config/ralscfg.go @@ -142,6 +142,5 @@ func (ralsCfg *RalsCfg) AsMapInterface() map[string]interface{} { utils.MaxComputedUsageCfg: maxComputed, utils.BalanceRatingSubjectCfg: balanceRating, utils.MaxIncrementsCfg: ralsCfg.MaxIncrements, - utils.Dynaprepaid_actionplansCfg: ralsCfg.DynaprepaidActionPlans, } } diff --git a/config/ralscfg_test.go b/config/ralscfg_test.go index 835fbc2c1..d78c0bb6a 100644 --- a/config/ralscfg_test.go +++ b/config/ralscfg_test.go @@ -120,7 +120,6 @@ func TestRalsCfgAsMapInterface(t *testing.T) { "*any": "*zero1ns", "*voice": "*zero1s", }, - "dynaprepaid_actionplans": []string{}, } if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil { diff --git a/config/resourcescfg.go b/config/resourcescfg.go index 887ef9c91..070a94880 100644 --- a/config/resourcescfg.go +++ b/config/resourcescfg.go @@ -19,6 +19,7 @@ along with this program. If not, see package config import ( + "strings" "time" "github.com/cgrates/cgrates/utils" @@ -81,14 +82,40 @@ func (rlcfg *ResourceSConfig) loadFromJsonCfg(jsnCfg *ResourceSJsonCfg) (err err } func (rlcfg *ResourceSConfig) AsMapInterface() map[string]interface{} { - + thresholdSConns := make([]string, len(rlcfg.ThresholdSConns)) + for i, item := range rlcfg.ThresholdSConns { + buf := utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds) + if item == buf { + thresholdSConns[i] = strings.ReplaceAll(item, utils.CONCATENATED_KEY_SEP+utils.MetaThresholds, utils.EmptyString) + } else { + thresholdSConns[i] = item + } + } + stringIndexedFields := []string{} + if rlcfg.StringIndexedFields != nil { + stringIndexedFields = make([]string, len(*rlcfg.StringIndexedFields)) + for i, item := range *rlcfg.StringIndexedFields { + stringIndexedFields[i] = item + } + } + prefixIndexedFields := []string{} + if rlcfg.PrefixIndexedFields != nil { + prefixIndexedFields = make([]string, len(*rlcfg.PrefixIndexedFields)) + for i, item := range *rlcfg.PrefixIndexedFields { + prefixIndexedFields[i] = item + } + } + var storeInterval string = "" + if rlcfg.StoreInterval != 0 { + storeInterval = rlcfg.StoreInterval.String() + } return map[string]interface{}{ utils.EnabledCfg: rlcfg.Enabled, utils.IndexedSelectsCfg: rlcfg.IndexedSelects, - utils.ThresholdSConnsCfg: rlcfg.ThresholdSConns, - utils.StoreIntervalCfg: rlcfg.StoreInterval, - utils.StringIndexedFieldsCfg: rlcfg.StringIndexedFields, - utils.PrefixIndexedFieldsCfg: rlcfg.PrefixIndexedFields, + utils.ThresholdSConnsCfg: thresholdSConns, + utils.StoreIntervalCfg: storeInterval, + utils.StringIndexedFieldsCfg: stringIndexedFields, + utils.PrefixIndexedFieldsCfg: prefixIndexedFields, utils.NestedFieldsCfg: rlcfg.NestedFields, } diff --git a/config/resourcescfg_test.go b/config/resourcescfg_test.go index 0e6ba68ff..48f90654b 100644 --- a/config/resourcescfg_test.go +++ b/config/resourcescfg_test.go @@ -21,6 +21,8 @@ import ( "reflect" "testing" "time" + + "github.com/cgrates/cgrates/utils" ) func TestResourceSConfigloadFromJsonCfg(t *testing.T) { @@ -60,3 +62,65 @@ func TestResourceSConfigloadFromJsonCfg(t *testing.T) { t.Errorf("Expected: %+v , recived: %+v", expected, rlcfg) } } + +func TestResourceSConfigAsMapInterface(t *testing.T) { + var rlcfg ResourceSConfig + + cfgJSONStr := `{ + "resources": { + "enabled": false, + "store_interval": "", + "thresholds_conns": [], + "indexed_selects":true, + "prefix_indexed_fields": [], + "nested_fields": false, + }, +}` + eMap := map[string]interface{}{ + "enabled": false, + "store_interval": "", + "thresholds_conns": []string{}, + "indexed_selects": true, + "string_indexed_fields": []string{}, + "prefix_indexed_fields": []string{}, + "nested_fields": false, + } + if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil { + t.Error(err) + } else if jsnRlcCfg, err := jsnCfg.ResourceSJsonCfg(); err != nil { + t.Error(err) + } else if err = rlcfg.loadFromJsonCfg(jsnRlcCfg); err != nil { + t.Error(err) + } else if rcv := rlcfg.AsMapInterface(); !reflect.DeepEqual(eMap, rcv) { + t.Errorf("\nExpected: %+v\nRecived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv)) + } + + cfgJSONStr = `{ + "resources": { + "enabled": false, + "store_interval": "7m", + "thresholds_conns": ["*internal"], + "indexed_selects":true, + "prefix_indexed_fields": ["prefix_indexed_fields1","prefix_indexed_fields2"], + "nested_fields": false, + }, + }` + eMap = map[string]interface{}{ + "enabled": false, + "store_interval": "7m0s", + "thresholds_conns": []string{"*internal"}, + "indexed_selects": true, + "string_indexed_fields": []string{}, + "prefix_indexed_fields": []string{"prefix_indexed_fields1", "prefix_indexed_fields2"}, + "nested_fields": false, + } + if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil { + t.Error(err) + } else if jsnRlcCfg, err := jsnCfg.ResourceSJsonCfg(); err != nil { + t.Error(err) + } else if err = rlcfg.loadFromJsonCfg(jsnRlcCfg); err != nil { + t.Error(err) + } else if rcv := rlcfg.AsMapInterface(); !reflect.DeepEqual(eMap, rcv) { + t.Errorf("\nExpected: %+v\nRecived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv)) + } +} diff --git a/config/rpcconn.go b/config/rpcconn.go index acf36d4e6..f397ea1d1 100644 --- a/config/rpcconn.go +++ b/config/rpcconn.go @@ -107,6 +107,6 @@ func (rh *RemoteHost) AsMapInterface() map[string]interface{} { utils.AddressCfg: rh.Address, utils.TransportCfg: rh.Transport, utils.SynchronousCfg: rh.Synchronous, - utils.TLS: rh.TLS, + utils.TlsCfg: rh.TLS, } } diff --git a/config/rpcconn_test.go b/config/rpcconn_test.go index f8ec2647f..eea95aadb 100644 --- a/config/rpcconn_test.go +++ b/config/rpcconn_test.go @@ -42,7 +42,7 @@ func TestRPCConnsAsMapInterface(t *testing.T) { "address": "127.0.0.1:2012", "transport": "*json", "synchronous": false, - "TLS": false, + "tls": false, }, }, } diff --git a/config/schedulercfg_test.go b/config/schedulercfg_test.go index 28f6de995..3e650fcdc 100644 --- a/config/schedulercfg_test.go +++ b/config/schedulercfg_test.go @@ -20,6 +20,8 @@ package config import ( "reflect" "testing" + + "github.com/cgrates/cgrates/utils" ) func TestSchedulerCfgloadFromJsonCfg(t *testing.T) { @@ -54,3 +56,28 @@ func TestSchedulerCfgloadFromJsonCfg(t *testing.T) { t.Errorf("Expected: %+v , recived: %+v", expected, schdcfg) } } + +func TestSchedulerCfgAsMapInterface(t *testing.T) { + var schdcfg SchedulerCfg + cfgJSONStr := `{ + "schedulers": { + "enabled": true, + "cdrs_conns": [], + "filters": [], + }, +}` + eMap := map[string]interface{}{ + "enabled": true, + "cdrs_conns": []string{}, + "filters": []string{}, + } + if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil { + t.Error(err) + } else if jsnSchCfg, err := jsnCfg.SchedulerJsonCfg(); err != nil { + t.Error(err) + } else if err = schdcfg.loadFromJsonCfg(jsnSchCfg); err != nil { + t.Error(err) + } else if rcv := schdcfg.AsMapInterface(); !reflect.DeepEqual(eMap, rcv) { + t.Errorf("\nExpected: %+v\nRecived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv)) + } +} diff --git a/config/smconfig.go b/config/smconfig.go index c6ed12ba4..d790726db 100644 --- a/config/smconfig.go +++ b/config/smconfig.go @@ -20,6 +20,7 @@ package config import ( "fmt" + "strings" "time" "github.com/cgrates/cgrates/utils" @@ -273,33 +274,137 @@ func (scfg *SessionSCfg) loadFromJsonCfg(jsnCfg *SessionSJsonCfg) (err error) { } func (scfg *SessionSCfg) AsMapInterface() map[string]interface{} { + var debitInterval string = "0" + if scfg.DebitInterval != 0 { + debitInterval = scfg.DebitInterval.String() + } + var minCallDuration string = "0" + if scfg.MinCallDuration != 0 { + minCallDuration = scfg.MinCallDuration.String() + } + var maxCallDuration string = "0" + if scfg.MaxCallDuration != 0 { + maxCallDuration = scfg.MaxCallDuration.String() + } + var sessionTTL string = "0" + if scfg.SessionTTL != 0 { + sessionTTL = scfg.SessionTTL.String() + } + var sessionTTLMaxDelay string = "0" + if scfg.SessionTTLMaxDelay != nil { + sessionTTLMaxDelay = scfg.SessionTTLMaxDelay.String() + } + var sessionTTLLastUsed string = "0" + if scfg.SessionTTLLastUsed != nil { + sessionTTLLastUsed = scfg.SessionTTLLastUsed.String() + } + var sessionTTLUsage string = "0" + if scfg.SessionTTLUsage != nil { + sessionTTLUsage = scfg.SessionTTLUsage.String() + } + var channelSyncInterval string = "0" + if scfg.ChannelSyncInterval != 0 { + channelSyncInterval = scfg.ChannelSyncInterval.String() + } + chargerSConns := make([]string, len(scfg.ChargerSConns)) + for i, item := range scfg.ChargerSConns { + buf := utils.ConcatenatedKey(utils.MetaInternal, utils.MetaChargers) + if item == buf { + chargerSConns[i] = strings.ReplaceAll(item, utils.CONCATENATED_KEY_SEP+utils.MetaChargers, utils.EmptyString) + } else { + chargerSConns[i] = item + } + } + RALsConns := make([]string, len(scfg.RALsConns)) + for i, item := range scfg.RALsConns { + buf := utils.ConcatenatedKey(utils.MetaInternal, utils.MetaResponder) + + if item == buf { + RALsConns[i] = strings.ReplaceAll(item, utils.CONCATENATED_KEY_SEP+utils.MetaResponder, utils.EmptyString) + } else { + RALsConns[i] = item + } + } + resSConns := make([]string, len(scfg.ResSConns)) + for i, item := range scfg.ResSConns { + buf := utils.ConcatenatedKey(utils.MetaInternal, utils.MetaResources) + if item == buf { + resSConns[i] = strings.ReplaceAll(item, utils.CONCATENATED_KEY_SEP+utils.MetaResources, utils.EmptyString) + } else { + resSConns[i] = item + } + } + threshSConns := make([]string, len(scfg.ThreshSConns)) + for i, item := range scfg.ThreshSConns { + buf := utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds) + if item == buf { + threshSConns[i] = strings.ReplaceAll(item, utils.CONCATENATED_KEY_SEP+utils.MetaThresholds, utils.EmptyString) + } else { + threshSConns[i] = item + } + } + statSConns := make([]string, len(scfg.StatSConns)) + for i, item := range scfg.StatSConns { + buf := utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStatS) + if item == buf { + statSConns[i] = strings.ReplaceAll(item, utils.CONCATENATED_KEY_SEP+utils.MetaStatS, utils.EmptyString) + } else { + statSConns[i] = item + } + } + supplSConns := make([]string, len(scfg.SupplSConns)) + for i, item := range scfg.SupplSConns { + buf := utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSuppliers) + if item == buf { + supplSConns[i] = strings.ReplaceAll(item, utils.CONCATENATED_KEY_SEP+utils.MetaSuppliers, utils.EmptyString) + } else { + supplSConns[i] = item + } + } + attrSConns := make([]string, len(scfg.AttrSConns)) + for i, item := range scfg.AttrSConns { + buf := utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAttributes) + if item == buf { + attrSConns[i] = strings.ReplaceAll(item, utils.CONCATENATED_KEY_SEP+utils.MetaAttributes, utils.EmptyString) + } else { + attrSConns[i] = item + } + } + CDRsConns := make([]string, len(scfg.CDRsConns)) + for i, item := range scfg.CDRsConns { + buf := utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCDRs) + if item == buf { + CDRsConns[i] = strings.ReplaceAll(item, utils.CONCATENATED_KEY_SEP+utils.MetaCDRs, utils.EmptyString) + } else { + CDRsConns[i] = item + } + } return map[string]interface{}{ utils.EnabledCfg: scfg.Enabled, utils.ListenBijsonCfg: scfg.ListenBijson, - utils.ChargerSConnsCfg: scfg.ChargerSConns, - utils.RALsConnsCfg: scfg.RALsConns, - utils.ResSConnsCfg: scfg.ResSConns, - utils.ThreshSConnsCfg: scfg.ThreshSConns, - utils.StatSConnsCfg: scfg.StatSConns, - utils.SupplSConnsCfg: scfg.SupplSConns, - utils.AttrSConnsCfg: scfg.AttrSConns, - utils.CDRsConnsCfg: scfg.CDRsConns, + utils.ChargerSConnsCfg: chargerSConns, + utils.RALsConnsCfg: RALsConns, + utils.ResSConnsCfg: resSConns, + utils.ThreshSConnsCfg: threshSConns, + utils.StatSConnsCfg: statSConns, + utils.SupplSConnsCfg: supplSConns, + utils.AttrSConnsCfg: attrSConns, + utils.CDRsConnsCfg: CDRsConns, utils.ReplicationConnsCfg: scfg.ReplicationConns, - utils.DebitIntervalCfg: scfg.DebitInterval, + utils.DebitIntervalCfg: debitInterval, utils.StoreSCostsCfg: scfg.StoreSCosts, - utils.MinCallDurationCfg: scfg.MinCallDuration, - utils.MaxCallDurationCfg: scfg.MaxCallDuration, - utils.SessionTTLCfg: scfg.SessionTTL, - utils.SessionTTLMaxDelayCfg: scfg.SessionTTLMaxDelay, - utils.SessionTTLLastUsedCfg: scfg.SessionTTLLastUsed, - utils.SessionTTLUsageCfg: scfg.SessionTTLUsage, - utils.SessionIndexesCfg: scfg.SessionIndexes.GetSlice(), + utils.MinCallDurationCfg: minCallDuration, + utils.MaxCallDurationCfg: maxCallDuration, + utils.SessionTTLCfg: sessionTTL, + utils.SessionTTLMaxDelayCfg: sessionTTLMaxDelay, + utils.SessionTTLLastUsedCfg: sessionTTLLastUsed, + utils.SessionTTLUsageCfg: sessionTTLUsage, + utils.SessionIndexesCfg: scfg.SessionIndexes.Slice(), utils.ClientProtocolCfg: scfg.ClientProtocol, - utils.ChannelSyncIntervalCfg: scfg.ChannelSyncInterval, + utils.ChannelSyncIntervalCfg: channelSyncInterval, utils.TerminateAttemptsCfg: scfg.TerminateAttempts, utils.AlterableFieldsCfg: scfg.AlterableFields.AsSlice(), - utils.MinDurLowBalanceCfg: scfg.MinDurLowBalance, } } @@ -369,23 +474,45 @@ func (self *FsAgentCfg) loadFromJsonCfg(jsnCfg *FreeswitchAgentJsonCfg) error { return nil } -func (fscfg *FsAgentCfg) AsMapInterface() map[string]interface{} { - var eventSocketConns []map[string]interface{} - // eventSocketConns := make(map[string]interface{}, len(fscfg.EventSocketConns)) - for _, item := range fscfg.EventSocketConns { - eventSocketConns = append(eventSocketConns, item.AsMapInterface()) +func (fscfg *FsAgentCfg) AsMapInterface(separator string) map[string]interface{} { + sessionSConns := make([]string, len(fscfg.SessionSConns)) + for i, item := range fscfg.SessionSConns { + buf := utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS) + if item == buf { + sessionSConns[i] = strings.ReplaceAll(item, utils.CONCATENATED_KEY_SEP+utils.MetaSessionS, utils.EmptyString) + } else { + sessionSConns[i] = item + } + } + + var extraFields string + if fscfg.ExtraFields != nil { + values := make([]string, len(fscfg.ExtraFields)) + for i, item := range fscfg.ExtraFields { + values[i] = item.Rules + } + extraFields = strings.Join(values, separator) + } + + var maxWaitConnection string = "" + if fscfg.MaxWaitConnection != 0 { + maxWaitConnection = fscfg.MaxWaitConnection.String() + } + + eventSocketConns := make([]map[string]interface{}, len(fscfg.EventSocketConns)) + for key, item := range fscfg.EventSocketConns { + eventSocketConns[key] = item.AsMapInterface() } return map[string]interface{}{ utils.EnabledCfg: fscfg.Enabled, - utils.SessionSConnsCfg: fscfg.SessionSConns, + utils.SessionSConnsCfg: sessionSConns, utils.SubscribeParkCfg: fscfg.SubscribePark, utils.CreateCdrCfg: fscfg.CreateCdr, - utils.ExtraFieldsCfg: fscfg.ExtraFields, - utils.LowBalanceAnnFileCfg: fscfg.LowBalanceAnnFile, + utils.ExtraFieldsCfg: extraFields, utils.EmptyBalanceContextCfg: fscfg.EmptyBalanceContext, utils.EmptyBalanceAnnFileCfg: fscfg.EmptyBalanceAnnFile, - utils.MaxWaitConnectionCfg: fscfg.MaxWaitConnection, + utils.MaxWaitConnectionCfg: maxWaitConnection, utils.EventSocketConnsCfg: eventSocketConns, } } @@ -497,9 +624,19 @@ func (aCfg *AsteriskAgentCfg) AsMapInterface() map[string]interface{} { conns[i] = item.AsMapInterface() } + sessionSConns := make([]string, len(aCfg.SessionSConns)) + for i, item := range aCfg.SessionSConns { + buf := utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS) + if item == buf { + sessionSConns[i] = strings.ReplaceAll(item, utils.CONCATENATED_KEY_SEP+utils.MetaSessionS, utils.EmptyString) + } else { + sessionSConns[i] = item + } + } + return map[string]interface{}{ utils.EnabledCfg: aCfg.Enabled, - utils.SessionSConnsCfg: aCfg.SessionSConns, + utils.SessionSConnsCfg: sessionSConns, utils.CreateCDRCfg: aCfg.CreateCDR, utils.AsteriskConnsCfg: conns, } diff --git a/config/smconfig_test.go b/config/smconfig_test.go index 4e37faab0..6a9c6efad 100644 --- a/config/smconfig_test.go +++ b/config/smconfig_test.go @@ -123,6 +123,146 @@ func TestSessionSCfgloadFromJsonCfg(t *testing.T) { } } +func TestSessionSCfgAsMapInterface(t *testing.T) { + var sescfg SessionSCfg + cfgJSONStr := `{ + "sessions": { + "enabled": false, + "listen_bijson": "127.0.0.1:2014", + "chargers_conns": [], + "rals_conns": [], + "cdrs_conns": [], + "resources_conns": [], + "thresholds_conns": [], + "stats_conns": [], + "suppliers_conns": [], + "attributes_conns": [], + "replication_conns": [], + "debit_interval": "0s", + "store_session_costs": false, + "min_call_duration": "0s", + "max_call_duration": "3h", + "session_ttl": "0s", + "session_indexes": [], + "client_protocol": 1.0, + "channel_sync_interval": "0", + "terminate_attempts": 5, + "alterable_fields": [], + "stir": { + "allowed_attest": ["*any"], + "payload_maxduration": "-1", + "default_attest": "A", + "publickey_path": "", + "privatekey_path": "", + }, + "scheduler_conns": [], + }, +}` + eMap := map[string]interface{}{ + "enabled": false, + "listen_bijson": "127.0.0.1:2014", + "chargers_conns": []string{}, + "rals_conns": []string{}, + "cdrs_conns": []string{}, + "resources_conns": []string{}, + "thresholds_conns": []string{}, + "stats_conns": []string{}, + "suppliers_conns": []string{}, + "attributes_conns": []string{}, + "replication_conns": []string{}, + "debit_interval": "0", + "store_session_costs": false, + "min_call_duration": "0", + "max_call_duration": "3h0m0s", + "session_ttl": "0", + "session_indexes": []string{}, + "client_protocol": 1.0, + "channel_sync_interval": "0", + "terminate_attempts": 5, + "alterable_fields": []string{}, + "session_ttl_last_used": "0", + "session_ttl_max_delay": "0", + "session_ttl_usage": "0", + } + if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil { + t.Error(err) + } else if jsnSesCfg, err := jsnCfg.SessionSJsonCfg(); err != nil { + t.Error(err) + } else if err = sescfg.loadFromJsonCfg(jsnSesCfg); err != nil { + t.Error(err) + } else if rcv := sescfg.AsMapInterface(); !reflect.DeepEqual(eMap, rcv) { + t.Errorf("\nExpected: %+v\nRecived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv)) + } + cfgJSONStr = `{ + "sessions": { + "enabled": false, + "listen_bijson": "127.0.0.1:2014", + "chargers_conns": ["*internal"], + "rals_conns": ["*internal"], + "cdrs_conns": ["*internal"], + "resources_conns": ["*internal"], + "thresholds_conns": ["*internal"], + "stats_conns": ["*internal"], + "suppliers_conns": ["*internal"], + "attributes_conns": ["*internal"], + "replication_conns": ["*localhost"], + "debit_interval": "0s", + "store_session_costs": false, + "min_call_duration": "0s", + "max_call_duration": "3h", + "session_ttl": "0s", + "session_indexes": [], + "client_protocol": 1.0, + "channel_sync_interval": "0", + "terminate_attempts": 5, + "alterable_fields": [], + "stir": { + "allowed_attest": ["*any"], + "payload_maxduration": "-1", + "default_attest": "A", + "publickey_path": "", + "privatekey_path": "", + }, + "scheduler_conns": ["*internal"], + }, + }` + eMap = map[string]interface{}{ + "enabled": false, + "listen_bijson": "127.0.0.1:2014", + "chargers_conns": []string{"*internal"}, + "rals_conns": []string{"*internal"}, + "cdrs_conns": []string{"*internal"}, + "resources_conns": []string{"*internal"}, + "thresholds_conns": []string{"*internal"}, + "stats_conns": []string{"*internal"}, + "suppliers_conns": []string{"*internal"}, + "attributes_conns": []string{"*internal"}, + "replication_conns": []string{"*localhost"}, + "debit_interval": "0", + "store_session_costs": false, + "min_call_duration": "0", + "max_call_duration": "3h0m0s", + "session_ttl": "0", + "session_indexes": []string{}, + "client_protocol": 1.0, + "channel_sync_interval": "0", + "terminate_attempts": 5, + "alterable_fields": []string{}, + "session_ttl_last_used": "0", + "session_ttl_max_delay": "0", + "session_ttl_usage": "0", + } + if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil { + t.Error(err) + } else if jsnSesCfg, err := jsnCfg.SessionSJsonCfg(); err != nil { + t.Error(err) + } else if err = sescfg.loadFromJsonCfg(jsnSesCfg); err != nil { + t.Error(err) + } else if rcv := sescfg.AsMapInterface(); !reflect.DeepEqual(eMap, rcv) { + t.Errorf("\nExpected: %+v\nRecived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv)) + } +} + func TestFsAgentCfgloadFromJsonCfg2(t *testing.T) { var fsagcfg, expected FsAgentCfg if err := fsagcfg.loadFromJsonCfg(nil); err != nil { @@ -175,6 +315,49 @@ func TestFsAgentCfgloadFromJsonCfg2(t *testing.T) { } } +func TestFsAgentCfgAsMapInterface(t *testing.T) { + var fsagcfg FsAgentCfg + cfgJSONStr := `{ + "freeswitch_agent": { + "enabled": false, + "sessions_conns": ["*internal"], + "subscribe_park": true, + "create_cdr": false, + "extra_fields": [], + //"min_dur_low_balance": "5s", + //"low_balance_ann_file": "", + "empty_balance_context": "", + "empty_balance_ann_file": "", + "max_wait_connection": "2s", + "event_socket_conns":[ + {"address": "127.0.0.1:8021", "password": "ClueCon", "reconnects": 5,"alias":""} + ], + }, +}` + eMap := map[string]interface{}{ + "enabled": false, + "sessions_conns": []string{"*internal"}, + "subscribe_park": true, + "create_cdr": false, + "extra_fields": "", + "empty_balance_context": "", + "empty_balance_ann_file": "", + "max_wait_connection": "2s", + "event_socket_conns": []map[string]interface{}{ + {"address": "127.0.0.1:8021", "password": "ClueCon", "reconnects": 5, "alias": "127.0.0.1:8021"}, + }, + } + if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil { + t.Error(err) + } else if jsnFsAgCfg, err := jsnCfg.FreeswitchAgentJsonCfg(); err != nil { + t.Error(err) + } else if err = fsagcfg.loadFromJsonCfg(jsnFsAgCfg); err != nil { + t.Error(err) + } else if rcv := fsagcfg.AsMapInterface(""); !reflect.DeepEqual(eMap, rcv) { + t.Errorf("\nExpected: %+v\nRecived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv)) + } +} + func TestFsConnCfgloadFromJsonCfg(t *testing.T) { var fscocfg, expected FsConnCfg if err := fscocfg.loadFromJsonCfg(nil); err != nil { @@ -276,6 +459,37 @@ func TestAsteriskAgentCfgloadFromJsonCfg(t *testing.T) { } } +func TestAsteriskAgentCfgAsMapInterface(t *testing.T) { + var asagcfg AsteriskAgentCfg + cfgJSONStr := `{ + "asterisk_agent": { + "enabled": true, + "sessions_conns": ["*internal"], + "create_cdr": false, + "asterisk_conns":[ + {"address": "127.0.0.1:8088", "user": "cgrates", "password": "CGRateS.org", "connect_attempts": 3,"reconnects": 5} + ], + }, +}` + eMap := map[string]interface{}{ + "enabled": true, + "sessions_conns": []string{"*internal"}, + "create_cdr": false, + "asterisk_conns": []map[string]interface{}{ + {"alias": "", "address": "127.0.0.1:8088", "user": "cgrates", "password": "CGRateS.org", "connect_attempts": 3, "reconnects": 5}, + }, + } + if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil { + t.Error(err) + } else if jsnAsAgCfg, err := jsnCfg.AsteriskAgentJsonCfg(); err != nil { + t.Error(err) + } else if err = asagcfg.loadFromJsonCfg(jsnAsAgCfg); err != nil { + t.Error(err) + } else if rcv := asagcfg.AsMapInterface(); !reflect.DeepEqual(eMap, rcv) { + t.Errorf("\nExpected: %+v\nRecived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv)) + } +} + func TestAsteriskConnCfgloadFromJsonCfg(t *testing.T) { var asconcfg, expected AsteriskConnCfg if err := asconcfg.loadFromJsonCfg(nil); err != nil { diff --git a/config/statscfg.go b/config/statscfg.go index 8bc99fc8e..1cbe06513 100644 --- a/config/statscfg.go +++ b/config/statscfg.go @@ -19,6 +19,7 @@ along with this program. If not, see package config import ( + "strings" "time" "github.com/cgrates/cgrates/utils" @@ -85,15 +86,42 @@ func (st *StatSCfg) loadFromJsonCfg(jsnCfg *StatServJsonCfg) (err error) { } func (st *StatSCfg) AsMapInterface() map[string]interface{} { + var storeInterval string = "" + if st.StoreInterval != 0 { + storeInterval = st.StoreInterval.String() + } + stringIndexedFields := []string{} + if st.StringIndexedFields != nil { + stringIndexedFields = make([]string, len(*st.StringIndexedFields)) + for i, item := range *st.StringIndexedFields { + stringIndexedFields[i] = item + } + } + prefixIndexedFields := []string{} + if st.PrefixIndexedFields != nil { + prefixIndexedFields = make([]string, len(*st.PrefixIndexedFields)) + for i, item := range *st.PrefixIndexedFields { + prefixIndexedFields[i] = item + } + } + thresholdSConns := make([]string, len(st.ThresholdSConns)) + for i, item := range st.ThresholdSConns { + buf := utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds) + if item == buf { + thresholdSConns[i] = strings.ReplaceAll(item, utils.CONCATENATED_KEY_SEP+utils.MetaThresholds, utils.EmptyString) + } else { + thresholdSConns[i] = item + } + } return map[string]interface{}{ utils.EnabledCfg: st.Enabled, utils.IndexedSelectsCfg: st.IndexedSelects, - utils.StoreIntervalCfg: st.StoreInterval, + utils.StoreIntervalCfg: storeInterval, utils.StoreUncompressedLimitCfg: st.StoreUncompressedLimit, - utils.ThresholdSConnsCfg: st.ThresholdSConns, - utils.StringIndexedFieldsCfg: st.StringIndexedFields, - utils.PrefixIndexedFieldsCfg: st.PrefixIndexedFields, + utils.ThresholdSConnsCfg: thresholdSConns, + utils.StringIndexedFieldsCfg: stringIndexedFields, + utils.PrefixIndexedFieldsCfg: prefixIndexedFields, utils.NestedFieldsCfg: st.NestedFields, } diff --git a/config/statscfg_test.go b/config/statscfg_test.go index ca487c4d7..c2c56cb47 100644 --- a/config/statscfg_test.go +++ b/config/statscfg_test.go @@ -21,6 +21,8 @@ import ( "reflect" "testing" "time" + + "github.com/cgrates/cgrates/utils" ) func TestStatSCfgloadFromJsonCfg(t *testing.T) { @@ -59,3 +61,78 @@ func TestStatSCfgloadFromJsonCfg(t *testing.T) { t.Errorf("Expected: %+v , recived: %+v", expected, statscfg) } } + +func TestStatSCfgAsMapInterface(t *testing.T) { + var statscfg, expected StatSCfg + if err := statscfg.loadFromJsonCfg(nil); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(statscfg, expected) { + t.Errorf("Expected: %+v ,recived: %+v", expected, statscfg) + } + if err := statscfg.loadFromJsonCfg(new(StatServJsonCfg)); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(statscfg, expected) { + t.Errorf("Expected: %+v ,recived: %+v", expected, statscfg) + } + cfgJSONStr := `{ + "stats": { + "enabled": false, + "store_interval": "", + "store_uncompressed_limit": 0, + "thresholds_conns": [], + "indexed_selects":true, + "prefix_indexed_fields": [], + "nested_fields": false, + }, + }` + eMap := map[string]interface{}{ + "enabled": false, + "store_interval": "", + "store_uncompressed_limit": 0, + "thresholds_conns": []string{}, + "indexed_selects": true, + "prefix_indexed_fields": []string{}, + "nested_fields": false, + "string_indexed_fields": []string{}, + } + if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil { + t.Error(err) + } else if jsnStatSCfg, err := jsnCfg.StatSJsonCfg(); err != nil { + t.Error(err) + } else if err = statscfg.loadFromJsonCfg(jsnStatSCfg); err != nil { + t.Error(err) + } else if rcv := statscfg.AsMapInterface(); !reflect.DeepEqual(eMap, rcv) { + t.Errorf("\nExpected: %+v\nRecived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv)) + } + + cfgJSONStr = `{ + "stats": { + "enabled": false, + "store_interval": "72h", + "store_uncompressed_limit": 0, + "thresholds_conns": ["*internal"], + "indexed_selects":true, + "prefix_indexed_fields": ["prefix_indexed_fields1","prefix_indexed_fields2"], + "nested_fields": false, + }, + }` + eMap = map[string]interface{}{ + "enabled": false, + "store_interval": "72h0m0s", + "store_uncompressed_limit": 0, + "thresholds_conns": []string{"*internal"}, + "indexed_selects": true, + "prefix_indexed_fields": []string{"prefix_indexed_fields1", "prefix_indexed_fields2"}, + "nested_fields": false, + "string_indexed_fields": []string{}, + } + if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil { + t.Error(err) + } else if jsnStatSCfg, err := jsnCfg.StatSJsonCfg(); err != nil { + t.Error(err) + } else if err = statscfg.loadFromJsonCfg(jsnStatSCfg); err != nil { + t.Error(err) + } else if rcv := statscfg.AsMapInterface(); !reflect.DeepEqual(eMap, rcv) { + t.Errorf("\nExpected: %+v\nRecived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv)) + } +} diff --git a/config/supplierscfg.go b/config/supplierscfg.go index 930262c03..8cd74bea5 100644 --- a/config/supplierscfg.go +++ b/config/supplierscfg.go @@ -18,7 +18,11 @@ along with this program. If not, see package config -import "github.com/cgrates/cgrates/utils" +import ( + "strings" + + "github.com/cgrates/cgrates/utils" +) // SupplierSCfg is the configuration of supplier service type SupplierSCfg struct { @@ -100,16 +104,56 @@ func (spl *SupplierSCfg) loadFromJsonCfg(jsnCfg *SupplierSJsonCfg) (err error) { } func (spl *SupplierSCfg) AsMapInterface() map[string]interface{} { + stringIndexedFields := []string{} + if spl.StringIndexedFields != nil { + stringIndexedFields = make([]string, len(*spl.StringIndexedFields)) + for i, item := range *spl.StringIndexedFields { + stringIndexedFields[i] = item + } + } + prefixIndexedFields := []string{} + if spl.PrefixIndexedFields != nil { + prefixIndexedFields = make([]string, len(*spl.PrefixIndexedFields)) + for i, item := range *spl.PrefixIndexedFields { + prefixIndexedFields[i] = item + } + } + attributeSConns := make([]string, len(spl.AttributeSConns)) + for i, item := range spl.AttributeSConns { + buf := utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAttributes) + if item == buf { + attributeSConns[i] = strings.ReplaceAll(item, utils.CONCATENATED_KEY_SEP+utils.MetaAttributes, utils.EmptyString) + } else { + attributeSConns[i] = item + } + } + resourceSConns := make([]string, len(spl.ResourceSConns)) + for i, item := range spl.ResourceSConns { + buf := utils.ConcatenatedKey(utils.MetaInternal, utils.MetaResources) + if item == buf { + resourceSConns[i] = strings.ReplaceAll(item, utils.CONCATENATED_KEY_SEP+utils.MetaResources, utils.EmptyString) + } else { + resourceSConns[i] = item + } + } + statSConns := make([]string, len(spl.StatSConns)) + for i, item := range spl.StatSConns { + buf := utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStatS) + if item == buf { + statSConns[i] = strings.ReplaceAll(item, utils.CONCATENATED_KEY_SEP+utils.MetaStatS, utils.EmptyString) + } else { + statSConns[i] = item + } + } return map[string]interface{}{ utils.EnabledCfg: spl.Enabled, utils.IndexedSelectsCfg: spl.IndexedSelects, - utils.StringIndexedFieldsCfg: spl.StringIndexedFields, - utils.PrefixIndexedFieldsCfg: spl.PrefixIndexedFields, - utils.AttributeSConnsCfg: spl.AttributeSConns, - utils.ResourceSConnsCfg: spl.ResourceSConns, - utils.StatSConnsCfg: spl.StatSConns, - utils.RALsConnsCfg: spl.ResponderSConns, + utils.StringIndexedFieldsCfg: stringIndexedFields, + utils.PrefixIndexedFieldsCfg: prefixIndexedFields, + utils.AttributeSConnsCfg: attributeSConns, + utils.ResourceSConnsCfg: resourceSConns, + utils.StatSConnsCfg: statSConns, utils.DefaultRatioCfg: spl.DefaultRatio, utils.NestedFieldsCfg: spl.NestedFields, } diff --git a/config/supplierscfg_test.go b/config/supplierscfg_test.go index beebfd4da..534e64162 100644 --- a/config/supplierscfg_test.go +++ b/config/supplierscfg_test.go @@ -20,6 +20,8 @@ package config import ( "reflect" "testing" + + "github.com/cgrates/cgrates/utils" ) func TestSupplierSCfgloadFromJsonCfg(t *testing.T) { @@ -62,3 +64,74 @@ func TestSupplierSCfgloadFromJsonCfg(t *testing.T) { t.Errorf("Expected: %+v , recived: %+v", expected, supscfg) } } + +func TestSupplierSCfgAsMapInterface(t *testing.T) { + var supscfg SupplierSCfg + cfgJSONStr := `{ + "suppliers": { + "enabled": false, + "indexed_selects":true, + "prefix_indexed_fields": [], + "nested_fields": false, + "attributes_conns": [], + "resources_conns": [], + "stats_conns": [], + "rals_conns": [], + "default_ratio":1 + }, +}` + eMap := map[string]interface{}{ + "enabled": false, + "indexed_selects": true, + "prefix_indexed_fields": []string{}, + "string_indexed_fields": []string{}, + "nested_fields": false, + "attributes_conns": []string{}, + "resources_conns": []string{}, + "stats_conns": []string{}, + "default_ratio": 1, + } + if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil { + t.Error(err) + } else if jsnSupSCfg, err := jsnCfg.SupplierSJsonCfg(); err != nil { + t.Error(err) + } else if err = supscfg.loadFromJsonCfg(jsnSupSCfg); err != nil { + t.Error(err) + } else if rcv := supscfg.AsMapInterface(); !reflect.DeepEqual(eMap, rcv) { + t.Errorf("\nExpected: %+v\nRecived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv)) + } + + cfgJSONStr = `{ + "suppliers": { + "enabled": false, + "indexed_selects":true, + "prefix_indexed_fields": ["prefix","indexed","fields"], + "nested_fields": false, + "attributes_conns": ["*internal"], + "resources_conns": ["*internal"], + "stats_conns": ["*internal"], + "rals_conns": ["*internal"], + "default_ratio":1 + }, + }` + eMap = map[string]interface{}{ + "enabled": false, + "indexed_selects": true, + "prefix_indexed_fields": []string{"prefix", "indexed", "fields"}, + "string_indexed_fields": []string{}, + "nested_fields": false, + "attributes_conns": []string{"*internal"}, + "resources_conns": []string{"*internal"}, + "stats_conns": []string{"*internal"}, + "default_ratio": 1, + } + if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil { + t.Error(err) + } else if jsnSupSCfg, err := jsnCfg.SupplierSJsonCfg(); err != nil { + t.Error(err) + } else if err = supscfg.loadFromJsonCfg(jsnSupSCfg); err != nil { + t.Error(err) + } else if rcv := supscfg.AsMapInterface(); !reflect.DeepEqual(eMap, rcv) { + t.Errorf("\nExpected: %+v\nRecived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv)) + } +} diff --git a/config/suretaxcfg.go b/config/suretaxcfg.go index 04bf8ec87..ad8bc9393 100644 --- a/config/suretaxcfg.go +++ b/config/suretaxcfg.go @@ -19,6 +19,7 @@ along with this program. If not, see package config import ( + "strings" "time" "github.com/cgrates/cgrates/utils" @@ -174,86 +175,134 @@ func (self *SureTaxCfg) loadFromJsonCfg(jsnCfg *SureTaxJsonCfg) (err error) { return nil } -func (st *SureTaxCfg) AsMapInterface() map[string]interface{} { - - clientTracking := make([]string, len(st.ClientTracking)) - for i, item := range st.ClientTracking { - clientTracking[i] = item.Rules +func (st *SureTaxCfg) AsMapInterface(separator string) map[string]interface{} { + var clientTracking string + if st.ClientTracking != nil { + values := make([]string, len(st.ClientTracking)) + for i, item := range st.ClientTracking { + values[i] = item.Rules + } + clientTracking = strings.Join(values, separator) } - - customerNumber := make([]string, len(st.CustomerNumber)) - for i, item := range st.CustomerNumber { - customerNumber[i] = item.Rules + var customerNumber string + if st.CustomerNumber != nil { + values := make([]string, len(st.CustomerNumber)) + for i, item := range st.CustomerNumber { + values[i] = item.Rules + } + customerNumber = strings.Join(values, separator) } - - origNumber := make([]string, len(st.OrigNumber)) - for i, item := range st.OrigNumber { - origNumber[i] = item.Rules + var origNumber string + if st.OrigNumber != nil { + values := make([]string, len(st.OrigNumber)) + for i, item := range st.OrigNumber { + values[i] = item.Rules + } + origNumber = strings.Join(values, separator) } - - termNumber := make([]string, len(st.TermNumber)) - for i, item := range st.TermNumber { - termNumber[i] = item.Rules + var termNumber string + if st.TermNumber != nil { + values := make([]string, len(st.TermNumber)) + for i, item := range st.TermNumber { + values[i] = item.Rules + } + termNumber = strings.Join(values, separator) } - - billToNumber := make([]string, len(st.BillToNumber)) - for i, item := range st.BillToNumber { - billToNumber[i] = item.Rules + var billToNumber string + if st.BillToNumber != nil { + values := make([]string, len(st.BillToNumber)) + for i, item := range st.BillToNumber { + values[i] = item.Rules + } + billToNumber = strings.Join(values, separator) } - - zipcode := make([]string, len(st.Zipcode)) - for i, item := range st.Zipcode { - zipcode[i] = item.Rules + var zipcode string + if st.Zipcode != nil { + values := make([]string, len(st.Zipcode)) + for i, item := range st.Zipcode { + values[i] = item.Rules + } + zipcode = strings.Join(values, separator) } - - plus4 := make([]string, len(st.Plus4)) - for i, item := range st.Plus4 { - plus4[i] = item.Rules + var plus4 string + if st.Plus4 != nil { + values := make([]string, len(st.Plus4)) + for i, item := range st.Plus4 { + values[i] = item.Rules + } + plus4 = strings.Join(values, separator) } - - p2PZipcode := make([]string, len(st.P2PZipcode)) - for i, item := range st.P2PZipcode { - p2PZipcode[i] = item.Rules + var p2PZipcode string + if st.P2PZipcode != nil { + values := make([]string, len(st.P2PZipcode)) + for i, item := range st.P2PZipcode { + values[i] = item.Rules + } + p2PZipcode = strings.Join(values, separator) } - - p2PPlus4 := make([]string, len(st.P2PPlus4)) - for i, item := range st.P2PPlus4 { - p2PPlus4[i] = item.Rules + var p2PPlus4 string + if st.P2PPlus4 != nil { + values := make([]string, len(st.P2PPlus4)) + for i, item := range st.P2PPlus4 { + values[i] = item.Rules + } + p2PPlus4 = strings.Join(values, separator) } - - units := make([]string, len(st.Units)) - for i, item := range st.Units { - units[i] = item.Rules + var units string + if st.Units != nil { + values := make([]string, len(st.Units)) + for i, item := range st.Units { + values[i] = item.Rules + } + units = strings.Join(values, separator) } - - unitType := make([]string, len(st.UnitType)) - for i, item := range st.UnitType { - unitType[i] = item.Rules + var unitType string + if st.UnitType != nil { + values := make([]string, len(st.UnitType)) + for i, item := range st.UnitType { + values[i] = item.Rules + } + unitType = strings.Join(values, separator) } - - taxIncluded := make([]string, len(st.TaxIncluded)) - for i, item := range st.TaxIncluded { - taxIncluded[i] = item.Rules + var taxIncluded string + if st.TaxIncluded != nil { + values := make([]string, len(st.TaxIncluded)) + for i, item := range st.TaxIncluded { + values[i] = item.Rules + } + taxIncluded = strings.Join(values, separator) } - - taxSitusRule := make([]string, len(st.TaxSitusRule)) - for i, item := range st.TaxSitusRule { - taxSitusRule[i] = item.Rules + var taxSitusRule string + if st.TaxSitusRule != nil { + values := make([]string, len(st.TaxSitusRule)) + for i, item := range st.TaxSitusRule { + values[i] = item.Rules + } + taxSitusRule = strings.Join(values, separator) } - - transTypeCode := make([]string, len(st.TransTypeCode)) - for i, item := range st.TransTypeCode { - transTypeCode[i] = item.Rules + var transTypeCode string + if st.TransTypeCode != nil { + values := make([]string, len(st.TransTypeCode)) + for i, item := range st.TransTypeCode { + values[i] = item.Rules + } + transTypeCode = strings.Join(values, separator) } - - salesTypeCode := make([]string, len(st.SalesTypeCode)) - for i, item := range st.SalesTypeCode { - salesTypeCode[i] = item.Rules + var salesTypeCode string + if st.SalesTypeCode != nil { + values := make([]string, len(st.SalesTypeCode)) + for i, item := range st.SalesTypeCode { + values[i] = item.Rules + } + salesTypeCode = strings.Join(values, separator) } - - taxExemptionCodeList := make([]string, len(st.TaxExemptionCodeList)) - for i, item := range st.TaxExemptionCodeList { - taxExemptionCodeList[i] = item.Rules + var taxExemptionCodeList string + if st.TaxExemptionCodeList != nil { + values := make([]string, len(st.TaxExemptionCodeList)) + for i, item := range st.TaxExemptionCodeList { + values[i] = item.Rules + } + taxExemptionCodeList = strings.Join(values, separator) } return map[string]interface{}{ @@ -267,22 +316,22 @@ func (st *SureTaxCfg) AsMapInterface() map[string]interface{} { utils.ResponseGroupCfg: st.ResponseGroup, utils.ResponseTypeCfg: st.ResponseType, utils.RegulatoryCodeCfg: st.RegulatoryCode, - utils.ClientTrackingCfg: st.ClientTracking, - utils.CustomerNumberCfg: st.CustomerNumber, - utils.OrigNumberCfg: st.OrigNumber, - utils.TermNumberCfg: st.TermNumber, - utils.BillToNumberCfg: st.BillToNumber, - utils.ZipcodeCfg: st.Zipcode, - utils.Plus4Cfg: st.Plus4, - utils.P2PZipcodeCfg: st.P2PZipcode, - utils.P2PPlus4Cfg: st.P2PPlus4, - utils.UnitsCfg: st.Units, - utils.UnitTypeCfg: st.UnitType, - utils.TaxIncludedCfg: st.TaxIncluded, - utils.TaxSitusRuleCfg: st.TaxSitusRule, - utils.TransTypeCodeCfg: st.TransTypeCode, - utils.SalesTypeCodeCfg: st.SalesTypeCode, - utils.TaxExemptionCodeListCfg: st.TaxExemptionCodeList, + utils.ClientTrackingCfg: clientTracking, + utils.CustomerNumberCfg: customerNumber, + utils.OrigNumberCfg: origNumber, + utils.TermNumberCfg: termNumber, + utils.BillToNumberCfg: billToNumber, + utils.ZipcodeCfg: zipcode, + utils.Plus4Cfg: plus4, + utils.P2PZipcodeCfg: p2PZipcode, + utils.P2PPlus4Cfg: p2PPlus4, + utils.UnitsCfg: units, + utils.UnitTypeCfg: unitType, + utils.TaxIncludedCfg: taxIncluded, + utils.TaxSitusRuleCfg: taxSitusRule, + utils.TransTypeCodeCfg: transTypeCode, + utils.SalesTypeCodeCfg: salesTypeCode, + utils.TaxExemptionCodeListCfg: taxExemptionCodeList, } } diff --git a/config/suretaxcfg_test.go b/config/suretaxcfg_test.go new file mode 100644 index 000000000..673a3b50f --- /dev/null +++ b/config/suretaxcfg_test.go @@ -0,0 +1,179 @@ +/* +Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments +Copyright (C) ITsysCOM GmbH + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +package config + +import ( + "reflect" + "testing" + "time" + + "github.com/cgrates/cgrates/utils" +) + +func TestSureTaxCfgloadFromJsonCfg(t *testing.T) { + var sureTaxCfg, expected SureTaxCfg + if err := sureTaxCfg.loadFromJsonCfg(nil); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(sureTaxCfg, expected) { + t.Errorf("Expected: %+v ,recived: %+v", expected, sureTaxCfg) + } + if err := sureTaxCfg.loadFromJsonCfg(new(SureTaxJsonCfg)); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(sureTaxCfg, expected) { + t.Errorf("Expected: %+v ,recived: %+v", expected, sureTaxCfg) + } + cfgJSONStr := `{ + "suretax": { + "url": "", + "client_number": "", + "validation_key": "", + "business_unit": "", + "timezone": "Local", + "include_local_cost": false, + "return_file_code": "0", + "response_group": "03", + "response_type": "D4", + "regulatory_code": "03", + "client_tracking": "~*req.CGRID", + "customer_number": "~*req.Subject", + "orig_number": "~*req.Subject", + "term_number": "~*req.Destination", + "bill_to_number": "", + "zipcode": "", + "plus4": "", + "p2pzipcode": "", + "p2pplus4": "", + "units": "1", + "unit_type": "00", + "tax_included": "0", + "tax_situs_rule": "04", + "trans_type_code": "010101", + "sales_type_code": "R", + "tax_exemption_code_list": "", + }, +}` + expected = SureTaxCfg{ + Url: utils.EmptyString, + ClientNumber: utils.EmptyString, + ValidationKey: utils.EmptyString, + BusinessUnit: utils.EmptyString, + Timezone: &time.Location{}, + IncludeLocalCost: false, + ReturnFileCode: "0", + ResponseGroup: "03", + ResponseType: "D4", + RegulatoryCode: "03", + ClientTracking: NewRSRParsersMustCompile("~*req.CGRID", true, utils.INFIELD_SEP), + CustomerNumber: NewRSRParsersMustCompile("~*req.Subject", true, utils.INFIELD_SEP), + OrigNumber: NewRSRParsersMustCompile("~*req.Subject", true, utils.INFIELD_SEP), + TermNumber: NewRSRParsersMustCompile("~*req.Destination", true, utils.INFIELD_SEP), + BillToNumber: NewRSRParsersMustCompile(utils.EmptyString, true, utils.INFIELD_SEP), + Zipcode: NewRSRParsersMustCompile(utils.EmptyString, true, utils.INFIELD_SEP), + Plus4: NewRSRParsersMustCompile(utils.EmptyString, true, utils.INFIELD_SEP), + P2PZipcode: NewRSRParsersMustCompile(utils.EmptyString, true, utils.INFIELD_SEP), + P2PPlus4: NewRSRParsersMustCompile(utils.EmptyString, true, utils.INFIELD_SEP), + Units: NewRSRParsersMustCompile("1", true, utils.INFIELD_SEP), + UnitType: NewRSRParsersMustCompile("00", true, utils.INFIELD_SEP), + TaxIncluded: NewRSRParsersMustCompile("0", true, utils.INFIELD_SEP), + TaxSitusRule: NewRSRParsersMustCompile("04", true, utils.INFIELD_SEP), + TransTypeCode: NewRSRParsersMustCompile("010101", true, utils.INFIELD_SEP), + SalesTypeCode: NewRSRParsersMustCompile("R", true, utils.INFIELD_SEP), + TaxExemptionCodeList: NewRSRParsersMustCompile(utils.EmptyString, true, utils.INFIELD_SEP), + } + if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil { + t.Error(err) + } else if sureTax, err := jsnCfg.SureTaxJsonCfg(); err != nil { + t.Error(err) + } else if err = sureTaxCfg.loadFromJsonCfg(sureTax); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(expected, sureTaxCfg) { + t.Errorf("Expected: %+v,\nRecived: %+v", utils.ToJSON(expected), utils.ToJSON(sureTaxCfg)) + } +} + +func TestSureTaxCfgAsMapInterface(t *testing.T) { + var sureTaxCfg SureTaxCfg + cfgJSONStr := `{ + "suretax": { + "url": "", + "client_number": "", + "validation_key": "", + "business_unit": "", + "timezone": "UTC", + "include_local_cost": false, + "return_file_code": "0", + "response_group": "03", + "response_type": "D4", + "regulatory_code": "03", + "client_tracking": "~*req.CGRID", + "customer_number": "~*req.Subject", + "orig_number": "~*req.Subject", + "term_number": "~*req.Destination", + "bill_to_number": "", + "zipcode": "", + "plus4": "", + "p2pzipcode": "", + "p2pplus4": "", + "units": "1", + "unit_type": "00", + "tax_included": "0", + "tax_situs_rule": "04", + "trans_type_code": "010101", + "sales_type_code": "R", + "tax_exemption_code_list": "", + }, +}` + eMap := map[string]interface{}{ + "url": "", + "client_number": "", + "validation_key": "", + "business_unit": "", + "timezone": "UTC", + "include_local_cost": false, + "return_file_code": "0", + "response_group": "03", + "response_type": "D4", + "regulatory_code": "03", + "client_tracking": "~*req.CGRID", + "customer_number": "~*req.Subject", + "orig_number": "~*req.Subject", + "term_number": "~*req.Destination", + "bill_to_number": "", + "zipcode": "", + "plus4": "", + "p2pzipcode": "", + "p2pplus4": "", + "units": "1", + "unit_type": "00", + "tax_included": "0", + "tax_situs_rule": "04", + "trans_type_code": "010101", + "sales_type_code": "R", + "tax_exemption_code_list": "", + } + if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil { + t.Error(err) + } else if sureTax, err := jsnCfg.SureTaxJsonCfg(); err != nil { + t.Error(err) + } else if err = sureTaxCfg.loadFromJsonCfg(sureTax); err != nil { + t.Error(err) + } else if rcv := sureTaxCfg.AsMapInterface(utils.EmptyString); !reflect.DeepEqual(eMap, rcv) { + t.Errorf("\nExpected: %+v\nRecived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv)) + } +} diff --git a/config/thresholdscfg.go b/config/thresholdscfg.go index eb75360da..39fb52c54 100644 --- a/config/thresholdscfg.go +++ b/config/thresholdscfg.go @@ -69,12 +69,30 @@ func (t *ThresholdSCfg) loadFromJsonCfg(jsnCfg *ThresholdSJsonCfg) (err error) { } func (t *ThresholdSCfg) AsMapInterface() map[string]interface{} { + var storeInterval string = "" + if t.StoreInterval != 0 { + storeInterval = t.StoreInterval.String() + } + stringIndexedFields := []string{} + if t.StringIndexedFields != nil { + stringIndexedFields = make([]string, len(*t.StringIndexedFields)) + for i, item := range *t.StringIndexedFields { + stringIndexedFields[i] = item + } + } + prefixIndexedFields := []string{} + if t.PrefixIndexedFields != nil { + prefixIndexedFields = make([]string, len(*t.PrefixIndexedFields)) + for i, item := range *t.PrefixIndexedFields { + prefixIndexedFields[i] = item + } + } return map[string]interface{}{ utils.EnabledCfg: t.Enabled, utils.IndexedSelectsCfg: t.IndexedSelects, - utils.StoreIntervalCfg: t.StoreInterval, - utils.StringIndexedFieldsCfg: t.StringIndexedFields, - utils.PrefixIndexedFieldsCfg: t.PrefixIndexedFields, + utils.StoreIntervalCfg: storeInterval, + utils.StringIndexedFieldsCfg: stringIndexedFields, + utils.PrefixIndexedFieldsCfg: prefixIndexedFields, utils.NestedFieldsCfg: t.NestedFields, } } diff --git a/config/thresholdscfg_test.go b/config/thresholdscfg_test.go index 9ae339c1f..b42984d4f 100644 --- a/config/thresholdscfg_test.go +++ b/config/thresholdscfg_test.go @@ -21,6 +21,8 @@ import ( "reflect" "testing" "time" + + "github.com/cgrates/cgrates/utils" ) func TestThresholdSCfgloadFromJsonCfg(t *testing.T) { @@ -57,3 +59,62 @@ func TestThresholdSCfgloadFromJsonCfg(t *testing.T) { t.Errorf("Expected: %+v , recived: %+v", expected, thscfg) } } + +func TestThresholdSCfgAsMapInterface(t *testing.T) { + var thscfg ThresholdSCfg + + cfgJSONStr := `{ + "thresholds": { + "enabled": false, + "store_interval": "", + "indexed_selects":true, + "prefix_indexed_fields": [], + "nested_fields": false, + }, +}` + eMap := map[string]interface{}{ + "enabled": false, + "store_interval": "", + "indexed_selects": true, + "string_indexed_fields": []string{}, + "prefix_indexed_fields": []string{}, + "nested_fields": false, + } + if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil { + t.Error(err) + } else if jsnThSCfg, err := jsnCfg.ThresholdSJsonCfg(); err != nil { + t.Error(err) + } else if err = thscfg.loadFromJsonCfg(jsnThSCfg); err != nil { + t.Error(err) + } else if rcv := thscfg.AsMapInterface(); !reflect.DeepEqual(eMap, rcv) { + t.Errorf("\nExpected: %+v\nRecived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv)) + } + + cfgJSONStr = `{ + "thresholds": { + "enabled": true, + "store_interval": "96h", + "indexed_selects":true, + "string_indexed_fields": ["string","indexed","fields"], + "prefix_indexed_fields": ["prefix_indexed_fields1","prefix_indexed_fields2"], + "nested_fields": true, + }, +}` + eMap = map[string]interface{}{ + "enabled": true, + "store_interval": "96h0m0s", + "indexed_selects": true, + "string_indexed_fields": []string{"string", "indexed", "fields"}, + "prefix_indexed_fields": []string{"prefix_indexed_fields1", "prefix_indexed_fields2"}, + "nested_fields": true, + } + if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil { + t.Error(err) + } else if jsnThSCfg, err := jsnCfg.ThresholdSJsonCfg(); err != nil { + t.Error(err) + } else if err = thscfg.loadFromJsonCfg(jsnThSCfg); err != nil { + t.Error(err) + } else if rcv := thscfg.AsMapInterface(); !reflect.DeepEqual(eMap, rcv) { + t.Errorf("\nExpected: %+v\nRecived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv)) + } +} diff --git a/utils/consts.go b/utils/consts.go index dd5a57f39..c54b5f8f9 100755 --- a/utils/consts.go +++ b/utils/consts.go @@ -1786,8 +1786,7 @@ const ( // Cache PartitionsCfg = "partitions" - StaticTTL = "StaticTTL" - Precache = "Precache" + PrecacheCfg = "precache" // CdreCfg ExportFormatCfg = "export_format" @@ -1855,8 +1854,8 @@ const ( BillToNumberCfg = "bill_to_number" ZipcodeCfg = "zipcode" Plus4Cfg = "plus4" - P2PZipcodeCfg = "p2PZipcode" - P2PPlus4Cfg = "p2PPlus4" + P2PZipcodeCfg = "p2pzipcode" + P2PPlus4Cfg = "p2pplus4" UnitsCfg = "units" UnitTypeCfg = "unit_type" TaxIncludedCfg = "tax_included" @@ -1880,29 +1879,29 @@ const ( // MigratorCgrCfg const ( - OutDataDBTypeCfg = "Out_dataDB_type" - OutDataDBHostCfg = "Out_dataDB_host" - OutDataDBPortCfg = "Out_dataDB_port" - OutDataDBNameCfg = "Out_dataDB_name" - OutDataDBUserCfg = "Out_dataDB_user" - OutDataDBPasswordCfg = "Out_dataDB_password" - OutDataDBEncodingCfg = "Out_dataDB_encoding" - OutDataDBRedisSentinelCfg = "Out_dataDB_redis_sentinel" - OutStorDBTypeCfg = "Out_storDB_type" - OutStorDBHostCfg = "Out_storDB_host" - OutStorDBPortCfg = "Out_storDB_port" - OutStorDBNameCfg = "Out_storDB_name" - OutStorDBUserCfg = "Out_storDB_user" - OutStorDBPasswordCfg = "Out_storDB_password" - UsersFiltersCfg = "Users_filters" + OutDataDBTypeCfg = "out_datadb_type" + OutDataDBHostCfg = "out_datadb_host" + OutDataDBPortCfg = "out_datadb_port" + OutDataDBNameCfg = "out_datadb_name" + OutDataDBUserCfg = "out_datadb_user" + OutDataDBPasswordCfg = "out_datadb_password" + OutDataDBEncodingCfg = "out_datadb_encoding" + OutDataDBRedisSentinelCfg = "out_datadb_redis_sentinel" + OutStorDBTypeCfg = "out_stordb_type" + OutStorDBHostCfg = "out_stordb_host" + OutStorDBPortCfg = "out_stordb_port" + OutStorDBNameCfg = "out_stordb_name" + OutStorDBUserCfg = "out_stordb_user" + OutStorDBPasswordCfg = "out_stordb_password" + UsersFiltersCfg = "users_filters" ) // MailerCfg const ( - MailerServerCfg = "Server" - MailerAuthUserCfg = "Auth_user" - MailerAuthPassCfg = "Auth_password" - MailerFromAddrCfg = "From_address" + MailerServerCfg = "server" + MailerAuthUserCfg = "auth_user" + MailerAuthPassCfg = "auth_password" + MailerFromAddrCfg = "from_address" ) // EventReaderCfg