diff --git a/config/cdrecfg.go b/config/cdrecfg.go
index 9e92db639..f4b5a556f 100644
--- a/config/cdrecfg.go
+++ b/config/cdrecfg.go
@@ -18,7 +18,9 @@ along with this program. If not, see
package config
-import "github.com/cgrates/cgrates/utils"
+import (
+ "github.com/cgrates/cgrates/utils"
+)
// One instance of CdrExporter
type CdreCfg struct {
@@ -93,10 +95,10 @@ func (self *CdreCfg) Clone() *CdreCfg {
return clnCdre
}
-func (cdre *CdreCfg) AsMapInterface() map[string]interface{} {
+func (cdre *CdreCfg) AsMapInterface(separator string) map[string]interface{} {
fields := make([]map[string]interface{}, len(cdre.Fields))
for i, item := range cdre.Fields {
- fields[i] = item.AsMapInterface()
+ fields[i] = item.AsMapInterface(separator)
}
return map[string]interface{}{
@@ -107,7 +109,7 @@ func (cdre *CdreCfg) AsMapInterface() map[string]interface{} {
utils.AttributeSContextCfg: cdre.AttributeSContext,
utils.SynchronousCfg: cdre.Synchronous,
utils.AttemptsCfg: cdre.Attempts,
- utils.FieldSeparatorCfg: cdre.FieldSeparator,
+ utils.FieldSeparatorCfg: string(cdre.FieldSeparator),
utils.FieldsCfg: fields,
}
}
diff --git a/config/cdrecfg_test.go b/config/cdrecfg_test.go
index c6bf8884a..57ca650de 100644
--- a/config/cdrecfg_test.go
+++ b/config/cdrecfg_test.go
@@ -135,3 +135,53 @@ func TestCdreCfgloadFromJsonCfg(t *testing.T) {
t.Errorf("Expected: %+v , recived: %+v", utils.ToJSON(expected), utils.ToJSON(lstcfg))
}
}
+
+func TestCdreCfgAsMapInterface(t *testing.T) {
+ var cdre CdreCfg
+ cfgJSONStr := `{
+ "cdre": {
+ "*default": {
+ "export_format": "*file_csv",
+ "export_path": "/var/spool/cgrates/cdre",
+ "filters" :[],
+ "tenant": "",
+ "synchronous": false,
+ "attempts": 1,
+ "field_separator": ",",
+ "attributes_context": "",
+ "fields": [
+ {"path": "*exp.CGRID", "type": "*variable", "value": "~*req.CGRID"},
+ ],
+ },
+ },
+}`
+ eMap := map[string]interface{}{
+ "export_format": "*file_csv",
+ "export_path": "/var/spool/cgrates/cdre",
+ "filters": []string{},
+ "tenant": "",
+ "synchronous": false,
+ "attempts": 1,
+ "field_separator": ",",
+ "attributes_context": "",
+ "fields": []map[string]interface{}{
+ {
+ "path": "*exp.CGRID",
+ "tag": "*exp.CGRID",
+ "type": "*variable",
+ "value": "~*req.CGRID",
+ },
+ },
+ }
+
+ if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil {
+ t.Error(err)
+ } else if cdreCfg, err := jsnCfg.CdreJsonCfgs(); err != nil {
+ t.Error(err)
+ } else if err = cdre.loadFromJsonCfg(cdreCfg["*default"], utils.EmptyString); err != nil {
+ t.Error(err)
+ } else if rcv := cdre.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 d9c48eb6f..ce41b4b45 100755
--- a/config/config.go
+++ b/config/config.go
@@ -1466,7 +1466,7 @@ func (cfg *CGRConfig) reloadSections(sections ...string) (err error) {
return
}
-func (cfg *CGRConfig) AsMapInterface() map[string]interface{} {
+func (cfg *CGRConfig) AsMapInterface(separator string) map[string]interface{} {
rpcConns := make(map[string]map[string]interface{}, len(cfg.rpcConns))
for key, val := range cfg.rpcConns {
rpcConns[key] = val.AsMapInterface()
@@ -1474,17 +1474,17 @@ func (cfg *CGRConfig) AsMapInterface() map[string]interface{} {
cdreProfiles := make(map[string]map[string]interface{})
for key, val := range cfg.CdreProfiles {
- cdreProfiles[key] = val.AsMapInterface()
+ cdreProfiles[key] = val.AsMapInterface(separator)
}
loaderCfg := make([]map[string]interface{}, len(cfg.loaderCfg))
for i, item := range cfg.loaderCfg {
- loaderCfg[i] = item.AsMapInterface()
+ loaderCfg[i] = item.AsMapInterface(separator)
}
httpAgentCfg := make([]map[string]interface{}, len(cfg.httpAgentCfg))
for i, item := range cfg.httpAgentCfg {
- httpAgentCfg[i] = item.AsMapInterface()
+ httpAgentCfg[i] = item.AsMapInterface(separator)
}
return map[string]interface{}{
@@ -1508,9 +1508,9 @@ func (cfg *CGRConfig) AsMapInterface() map[string]interface{} {
utils.FsAgentCfg: cfg.fsAgentCfg.AsMapInterface(),
utils.KamAgentCfg: cfg.kamAgentCfg.AsMapInterface(),
utils.AsteriskAgentCfg: cfg.asteriskAgentCfg.AsMapInterface(),
- utils.DiameterAgentCfg: cfg.diameterAgentCfg.AsMapInterface(),
- utils.RadiusAgentCfg: cfg.radiusAgentCfg.AsMapInterface(),
- utils.DnsAgentCfg: cfg.dnsAgentCfg.AsMapInterface(),
+ utils.DiameterAgentCfg: cfg.diameterAgentCfg.AsMapInterface(separator),
+ utils.RadiusAgentCfg: cfg.radiusAgentCfg.AsMapInterface(separator),
+ utils.DnsAgentCfg: cfg.dnsAgentCfg.AsMapInterface(separator),
utils.AttributeSCfg: cfg.attributeSCfg.AsMapInterface(),
utils.ChargerSCfg: cfg.chargerSCfg.AsMapInterface(),
utils.ResourceSCfg: cfg.resourceSCfg.AsMapInterface(),
@@ -1524,6 +1524,6 @@ func (cfg *CGRConfig) AsMapInterface() map[string]interface{} {
utils.MailerCfg: cfg.mailerCfg.AsMapInterface(),
utils.AnalyzerSCfg: cfg.analyzerSCfg.AsMapInterface(),
utils.Apier: cfg.apier.AsMapInterface(),
- utils.ErsCfg: cfg.ersCfg.AsMapInterface(),
+ utils.ErsCfg: cfg.ersCfg.AsMapInterface(separator),
}
}
diff --git a/config/config_test.go b/config/config_test.go
index 936d7d96c..21d6f9659 100755
--- a/config/config_test.go
+++ b/config/config_test.go
@@ -1851,3 +1851,70 @@ func TestCheckConfigSanity(t *testing.T) {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
}
+
+func TestGeneralCfg(t *testing.T) {
+ var gencfg GeneralCfg
+ cfgJSONStr := `{
+ "general": {
+ "node_id": "",
+ "logger":"*syslog",
+ "log_level": 6,
+ "http_skip_tls_verify": false,
+ "rounding_decimals": 5,
+ "dbdata_encoding": "*msgpack",
+ "tpexport_dir": "/var/spool/cgrates/tpe",
+ "poster_attempts": 3,
+ "failed_posts_dir": "/var/spool/cgrates/failed_posts",
+ "failed_posts_ttl": "5s",
+ "default_request_type": "*rated",
+ "default_category": "call",
+ "default_tenant": "cgrates.org",
+ "default_timezone": "Local",
+ "default_caching":"*reload",
+ "connect_attempts": 5,
+ "reconnects": -1,
+ "connect_timeout": "1s",
+ "reply_timeout": "2s",
+ "locking_timeout": "0",
+ "digest_separator": ",",
+ "digest_equal": ":",
+ "rsr_separator": ";",
+ "max_parralel_conns": 100,
+ },
+}`
+ eMap := map[string]interface{}{
+ "node_id": "",
+ "logger": "*syslog",
+ "log_level": 6,
+ "http_skip_tls_verify": false,
+ "rounding_decimals": 5,
+ "dbdata_encoding": "*msgpack",
+ "tpexport_dir": "/var/spool/cgrates/tpe",
+ "poster_attempts": 3,
+ "failed_posts_dir": "/var/spool/cgrates/failed_posts",
+ "failed_posts_ttl": "5s",
+ "default_request_type": "*rated",
+ "default_category": "call",
+ "default_tenant": "cgrates.org",
+ "default_timezone": "Local",
+ "default_caching": "*reload",
+ "connect_attempts": 5,
+ "reconnects": -1,
+ "connect_timeout": "1s",
+ "reply_timeout": "2s",
+ "locking_timeout": "0",
+ "digest_separator": ",",
+ "digest_equal": ":",
+ "rsr_separator": ";",
+ "max_parralel_conns": 100,
+ }
+ if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil {
+ t.Error(err)
+ } else if jsnGenCfg, err := jsnCfg.GeneralJsonCfg(); err != nil {
+ t.Error(err)
+ } else if err = gencfg.loadFromJsonCfg(jsnGenCfg); err != nil {
+ t.Error(err)
+ } else if rcv := gencfg.AsMapInterface(); !reflect.DeepEqual(eMap, rcv) {
+ t.Errorf("Expected: %+v\nRecived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv))
+ }
+}
diff --git a/config/datadbcfg.go b/config/datadbcfg.go
index e945d8ddf..049c0577e 100644
--- a/config/datadbcfg.go
+++ b/config/datadbcfg.go
@@ -100,6 +100,7 @@ func (dbcfg *DataDbCfg) loadFromJsonCfg(jsnDbCfg *DbJsonCfg) (err error) {
}
}
if jsnDbCfg.Items != nil {
+ dbcfg.Items = make(map[string]*ItemOpt)
for kJsn, vJsn := range *jsnDbCfg.Items {
val, has := dbcfg.Items[kJsn]
if val == nil || !has {
@@ -134,16 +135,21 @@ func (dbcfg *DataDbCfg) AsMapInterface() map[string]interface{} {
for key, item := range dbcfg.Items {
items[key] = item.AsMapInterface()
}
+ var queryTimeout string = "0"
+ if dbcfg.QueryTimeout != 0 {
+ queryTimeout = dbcfg.QueryTimeout.String()
+ }
+ dbPort, _ := strconv.Atoi(dbcfg.DataDbPort)
return map[string]interface{}{
- utils.DataDbTypeCfg: dbcfg.DataDbType,
+ utils.DataDbTypeCfg: utils.Meta + dbcfg.DataDbType,
utils.DataDbHostCfg: dbcfg.DataDbHost,
- utils.DataDbPortCfg: dbcfg.DataDbPort,
+ utils.DataDbPortCfg: dbPort,
utils.DataDbNameCfg: dbcfg.DataDbName,
utils.DataDbUserCfg: dbcfg.DataDbUser,
utils.DataDbPassCfg: dbcfg.DataDbPass,
utils.DataDbSentinelNameCfg: dbcfg.DataDbSentinelName,
- utils.QueryTimeoutCfg: dbcfg.QueryTimeout,
+ utils.QueryTimeoutCfg: queryTimeout,
utils.RmtConnsCfg: dbcfg.RmtConns,
utils.RplConnsCfg: dbcfg.RplConns,
utils.ItemsCfg: items,
@@ -162,11 +168,16 @@ type ItemOpt struct {
}
func (itm *ItemOpt) AsMapInterface() map[string]interface{} {
+ var ttl string = ""
+ if itm.TTL != 0 {
+ ttl = itm.TTL.String()
+ }
+
return map[string]interface{}{
utils.RemoteCfg: itm.Remote,
utils.ReplicateCfg: itm.Replicate,
utils.LimitCfg: itm.Limit,
- utils.TTLCfg: itm.TTL,
+ utils.TTLCfg: ttl,
utils.StaticTTLCfg: itm.StaticTTL,
}
}
diff --git a/config/datadbcfg_test.go b/config/datadbcfg_test.go
index 516dfef28..3d9c4a638 100644
--- a/config/datadbcfg_test.go
+++ b/config/datadbcfg_test.go
@@ -218,3 +218,227 @@ func TestDataDBRemoteReplication(t *testing.T) {
t.Errorf("Expected: %+v ,\n recived: %+v", utils.ToJSON(expected), utils.ToJSON(dbcfg))
}
}
+
+func TestDataDbCfgloadFromJsonCfgItems(t *testing.T) {
+ var dbcfg, expected DataDbCfg
+ cfgJSONStr := `{
+"data_db": { // database used to store runtime data (eg: accounts, cdr stats)
+ "db_type": "*redis", // data_db type: <*redis|*mongo|*internal>
+ "db_host": "127.0.0.1", // data_db host address
+ "db_port": -1, // data_db port to reach the database
+ "db_name": "10", // data_db database name to connect to
+ "db_user": "cgrates", // username to use when connecting to data_db
+ "db_password": "password", // password to use when connecting to data_db
+ "redis_sentinel":"sentinel", // redis_sentinel is the name of sentinel
+ "remote_conns":["Conn1"],
+ "items":{
+ "*accounts":{"replicate":true, "limit": 5,"ttl": "6"},
+ "*reverse_destinations": {"replicate":false},
+ "*destinations": {"replicate":false},
+ }
+ }
+}`
+
+ expected = DataDbCfg{
+ DataDbType: "redis",
+ DataDbHost: "127.0.0.1",
+ DataDbPort: "6379",
+ DataDbName: "10",
+ DataDbUser: "cgrates",
+ DataDbPass: "password",
+ DataDbSentinelName: "sentinel",
+ RmtConns: []string{"Conn1"},
+ Items: map[string]*ItemOpt{
+ utils.MetaAccounts: &ItemOpt{
+ Replicate: true,
+ TTL: 6,
+ Limit: 5,
+ },
+ utils.MetaReverseDestinations: &ItemOpt{
+ Replicate: false,
+ },
+ utils.MetaDestinations: &ItemOpt{
+ Replicate: false,
+ },
+ },
+ }
+ dbcfg.Items = make(map[string]*ItemOpt)
+ if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil {
+ t.Error(err)
+ } else if jsnDataDbCfg, err := jsnCfg.DbJsonCfg(DATADB_JSN); err != nil {
+ t.Error(err)
+ } else if err = dbcfg.loadFromJsonCfg(jsnDataDbCfg); err != nil {
+ t.Error(err)
+ } else if !reflect.DeepEqual(expected, dbcfg) {
+ t.Errorf("Expected: %+v ,\n recived: %+v", utils.ToJSON(expected), utils.ToJSON(dbcfg))
+ }
+
+ cfgJSONStr = `{
+ "data_db": { // database used to store runtime data (eg: accounts, cdr stats)
+ "db_type": "*redis", // data_db type: <*redis|*mongo|*internal>
+ "db_host": "127.0.0.1", // data_db host address
+ "db_port": -1, // data_db port to reach the database
+ "db_name": "10", // data_db database name to connect to
+ "db_user": "cgrates", // username to use when connecting to data_db
+ "db_password": "password", // password to use when connecting to data_db
+ "redis_sentinel":"sentinel", // redis_sentinel is the name of sentinel
+ "remote_conns":["Conn1"],
+ "items":{
+ "*dispatcher_hosts":{"remote":true, "replicate":true, "limit": -1, "ttl": "", "static_ttl": true},
+ "*filter_indexes" :{"remote":true, "replicate":true, "limit": -1, "ttl": "", "static_ttl": true},
+ "*load_ids":{"remote":true, "replicate":true, "limit": -1, "ttl": "", "static_ttl": true},
+
+ }
+ }
+ }`
+
+ expected = DataDbCfg{
+ DataDbType: "redis",
+ DataDbHost: "127.0.0.1",
+ DataDbPort: "6379",
+ DataDbName: "10",
+ DataDbUser: "cgrates",
+ DataDbPass: "password",
+ DataDbSentinelName: "sentinel",
+ RmtConns: []string{"Conn1"},
+ Items: map[string]*ItemOpt{
+ utils.MetaDispatcherHosts: &ItemOpt{
+ Remote: true,
+ Replicate: true,
+ Limit: -1,
+ StaticTTL: true,
+ },
+ utils.MetaFilterIndexes: &ItemOpt{
+ Remote: true,
+ Replicate: true,
+ Limit: -1,
+ StaticTTL: true,
+ },
+ utils.MetaLoadIDs: &ItemOpt{
+ Remote: true,
+ Replicate: true,
+ Limit: -1,
+ StaticTTL: true,
+ },
+ },
+ }
+ dbcfg.Items = make(map[string]*ItemOpt)
+ if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil {
+ t.Error(err)
+ } else if jsnDataDbCfg, err := jsnCfg.DbJsonCfg(DATADB_JSN); err != nil {
+ t.Error(err)
+ } else if err = dbcfg.loadFromJsonCfg(jsnDataDbCfg); err != nil {
+ t.Error(err)
+ } else if !reflect.DeepEqual(expected, dbcfg) {
+ t.Errorf("Expected: %+v ,\n recived: %+v", utils.ToJSON(expected), utils.ToJSON(dbcfg))
+ }
+
+ cfgJSONStr = `{
+ "data_db": { // database used to store runtime data (eg: accounts, cdr stats)
+ "db_type": "*redis", // data_db type: <*redis|*mongo|*internal>
+ "db_host": "127.0.0.1", // data_db host address
+ "db_port": -1, // data_db port to reach the database
+ "db_name": "10", // data_db database name to connect to
+ "db_user": "cgrates", // username to use when connecting to data_db
+ "db_password": "password", // password to use when connecting to data_db
+ "redis_sentinel":"sentinel", // redis_sentinel is the name of sentinel
+ "remote_conns":["Conn1"],
+ "items":{
+ "*timings": {"remote":false, "replicate":false, "limit": 9, "ttl": "8", "static_ttl": true},
+ "*resource_profiles":{"remote":false, "replicate":false, "limit": 9, "ttl": "8", "static_ttl": true},
+ "*resources":{"remote":false, "replicate":false, "limit": 9, "ttl": "8", "static_ttl": true},
+ "*statqueue_profiles": {"remote":false, "replicate":false, "limit": 9, "ttl": "8", "static_ttl": true},
+ }
+ }
+ }`
+
+ expected = DataDbCfg{
+ DataDbType: "redis",
+ DataDbHost: "127.0.0.1",
+ DataDbPort: "6379",
+ DataDbName: "10",
+ DataDbUser: "cgrates",
+ DataDbPass: "password",
+ DataDbSentinelName: "sentinel",
+ RmtConns: []string{"Conn1"},
+ Items: map[string]*ItemOpt{
+ utils.MetaTimings: &ItemOpt{
+ Limit: 9,
+ TTL: 8,
+ StaticTTL: true,
+ },
+ utils.MetaResourceProfile: &ItemOpt{
+ Limit: 9,
+ TTL: 8,
+ StaticTTL: true,
+ },
+ utils.MetaResources: &ItemOpt{
+ Limit: 9,
+ TTL: 8,
+ StaticTTL: true,
+ },
+ utils.MetaStatQueueProfiles: &ItemOpt{
+ Limit: 9,
+ TTL: 8,
+ StaticTTL: true,
+ },
+ },
+ }
+ dbcfg.Items = make(map[string]*ItemOpt)
+ if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil {
+ t.Error(err)
+ } else if jsnDataDbCfg, err := jsnCfg.DbJsonCfg(DATADB_JSN); err != nil {
+ t.Error(err)
+ } else if err = dbcfg.loadFromJsonCfg(jsnDataDbCfg); err != nil {
+ t.Error(err)
+ } else if !reflect.DeepEqual(expected, dbcfg) {
+ t.Errorf("Expected: %+v ,\n recived: %+v", utils.ToJSON(expected), utils.ToJSON(dbcfg))
+ }
+}
+
+func TestDataDbCfgAsMapInterface(t *testing.T) {
+ var dbcfg DataDbCfg
+ cfgJSONStr := `{
+ "data_db": {
+ "db_type": "*redis",
+ "db_host": "127.0.0.1",
+ "db_port": 6379,
+ "db_name": "10",
+ "db_user": "cgrates",
+ "db_password": "",
+ "redis_sentinel":"",
+ "query_timeout":"10s",
+ "remote_conns":[],
+ "replication_conns":[],
+ "items":{
+ "*accounts":{"remote":true, "replicate":false, "limit": -1, "ttl": "", "static_ttl": false},
+ "*reverse_destinations": {"remote":false, "replicate":false, "limit": 7, "ttl": "", "static_ttl": true},
+ },
+ },
+}`
+ eMap := map[string]interface{}{
+ "db_type": "*redis",
+ "db_host": "127.0.0.1",
+ "db_port": 6379,
+ "db_name": "10",
+ "db_user": "cgrates",
+ "db_password": "",
+ "redis_sentinel": "",
+ "query_timeout": "10s",
+ "remote_conns": []string{},
+ "replication_conns": []string{},
+ "items": map[string]interface{}{
+ "*accounts": map[string]interface{}{"remote": true, "replicate": false, "limit": -1, "ttl": "", "static_ttl": false},
+ "*reverse_destinations": map[string]interface{}{"remote": false, "replicate": false, "limit": 7, "ttl": "", "static_ttl": true},
+ },
+ }
+ if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil {
+ t.Error(err)
+ } else if jsnDataDbCfg, err := jsnCfg.DbJsonCfg(DATADB_JSN); err != nil {
+ t.Error(err)
+ } else if err = dbcfg.loadFromJsonCfg(jsnDataDbCfg); err != nil {
+ t.Error(err)
+ } else if rcv := dbcfg.AsMapInterface(); !reflect.DeepEqual(eMap, rcv) {
+ t.Errorf("Expected: %+v ,\n recived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv))
+ }
+}
diff --git a/config/diametercfg.go b/config/diametercfg.go
index ef619f055..ac98fc441 100644
--- a/config/diametercfg.go
+++ b/config/diametercfg.go
@@ -117,12 +117,12 @@ func (da *DiameterAgentCfg) loadFromJsonCfg(jsnCfg *DiameterAgentJsonCfg, separa
return nil
}
-func (ds *DiameterAgentCfg) AsMapInterface() map[string]interface{} {
+func (ds *DiameterAgentCfg) AsMapInterface(separator string) map[string]interface{} {
templates := make(map[string][]map[string]interface{})
for key, value := range ds.Templates {
fcTemplate := make([]map[string]interface{}, len(value))
for i, val := range value {
- fcTemplate[i] = val.AsMapInterface()
+ fcTemplate[i] = val.AsMapInterface(separator)
}
templates[key] = fcTemplate
@@ -130,7 +130,7 @@ func (ds *DiameterAgentCfg) AsMapInterface() map[string]interface{} {
requestProcessors := make([]map[string]interface{}, len(ds.RequestProcessors))
for i, item := range ds.RequestProcessors {
- requestProcessors[i] = item.AsMapInterface()
+ requestProcessors[i] = item.AsMapInterface(separator)
}
return map[string]interface{}{
diff --git a/config/dnsagntcfg.go b/config/dnsagntcfg.go
index 912c15b6b..e1a61b94d 100644
--- a/config/dnsagntcfg.go
+++ b/config/dnsagntcfg.go
@@ -19,6 +19,8 @@ along with this program. If not, see
package config
import (
+ "strings"
+
"github.com/cgrates/cgrates/utils"
)
@@ -80,10 +82,10 @@ func (da *DNSAgentCfg) loadFromJsonCfg(jsnCfg *DNSAgentJsonCfg, sep string) (err
return nil
}
-func (da *DNSAgentCfg) AsMapInterface() map[string]interface{} {
+func (da *DNSAgentCfg) AsMapInterface(separator string) map[string]interface{} {
requestProcessors := make([]map[string]interface{}, len(da.RequestProcessors))
for i, item := range da.RequestProcessors {
- requestProcessors[i] = item.AsMapInterface()
+ requestProcessors[i] = item.AsMapInterface(separator)
}
return map[string]interface{}{
@@ -147,23 +149,36 @@ func (rp *RequestProcessor) loadFromJsonCfg(jsnCfg *ReqProcessorJsnCfg, sep stri
return nil
}
-func (rp *RequestProcessor) AsMapInterface() map[string]interface{} {
+func (rp *RequestProcessor) AsMapInterface(separator string) map[string]interface{} {
replyFields := make([]map[string]interface{}, len(rp.ReplyFields))
for i, item := range rp.ReplyFields {
- replyFields[i] = item.AsMapInterface()
+ replyFields[i] = item.AsMapInterface(separator)
}
requestFields := make([]map[string]interface{}, len(rp.RequestFields))
for i, item := range rp.RequestFields {
- requestFields[i] = item.AsMapInterface()
+ requestFields[i] = item.AsMapInterface(separator)
+ }
+ var tenant string
+ if rp.Tenant != nil {
+ values := make([]string, len(rp.Tenant))
+ for i, item := range rp.Tenant {
+ values[i] = item.Rules
+ }
+ tenant = strings.Join(values, utils.EmptyString)
+ }
+
+ flags := make(map[string][]string, len(rp.Flags))
+ for key, item := range rp.Flags {
+ flags[key] = item
}
return map[string]interface{}{
- utils.ID: rp.ID,
- utils.Tenant: rp.Tenant,
- utils.Filters: rp.Filters,
- utils.Flags: rp.Flags,
- utils.TimezoneCfg: rp.Timezone,
+ utils.IDCfg: rp.ID,
+ utils.TenantCfg: tenant,
+ utils.FiltersCfg: rp.Filters,
+ utils.FlagsCfg: flags,
+ utils.TimezoneCfgC: rp.Timezone,
utils.RequestFieldsCfg: requestFields,
utils.ReplyFieldsCfg: replyFields,
}
diff --git a/config/erscfg.go b/config/erscfg.go
index 2f4616f20..f55f7be34 100644
--- a/config/erscfg.go
+++ b/config/erscfg.go
@@ -98,11 +98,11 @@ func (erS *ERsCfg) Clone() (cln *ERsCfg) {
return
}
-func (erS *ERsCfg) AsMapInterface() map[string]interface{} {
+func (erS *ERsCfg) AsMapInterface(separator string) map[string]interface{} {
readers := make([]map[string]interface{}, len(erS.Readers))
for i, item := range erS.Readers {
- readers[i] = item.AsMapInterface()
+ readers[i] = item.AsMapInterface(separator)
}
return map[string]interface{}{
@@ -247,7 +247,7 @@ func (er *EventReaderCfg) Clone() (cln *EventReaderCfg) {
return
}
-func (er *EventReaderCfg) AsMapInterface() map[string]interface{} {
+func (er *EventReaderCfg) AsMapInterface(separator string) map[string]interface{} {
xmlRootPath := make([]string, len(er.XmlRootPath))
for i, item := range er.XmlRootPath {
xmlRootPath[i] = item
@@ -262,11 +262,11 @@ func (er *EventReaderCfg) AsMapInterface() map[string]interface{} {
}
fields := make([]map[string]interface{}, len(er.Fields))
for i, item := range er.Fields {
- fields[i] = item.AsMapInterface()
+ fields[i] = item.AsMapInterface(separator)
}
cacheDumpFields := make([]map[string]interface{}, len(er.CacheDumpFields))
for i, item := range er.CacheDumpFields {
- cacheDumpFields[i] = item.AsMapInterface()
+ cacheDumpFields[i] = item.AsMapInterface(separator)
}
return map[string]interface{}{
diff --git a/config/fctemplate.go b/config/fctemplate.go
index d09487f10..e999ccb8d 100755
--- a/config/fctemplate.go
+++ b/config/fctemplate.go
@@ -191,32 +191,74 @@ func (self *FCTemplate) Clone() *FCTemplate {
return cln
}
-func (fc *FCTemplate) AsMapInterface() map[string]interface{} {
- values := make([]string, len(fc.Value))
- for i, item := range fc.Value {
- values[i] = item.Rules
- }
-
- return map[string]interface{}{
- utils.TagCfg: fc.Tag,
- utils.TypeCf: fc.Type,
- utils.PathCfg: fc.Path,
- utils.FiltersCfg: fc.Filters,
- utils.ValueCfg: values,
- utils.WidthCfg: fc.Width,
- utils.StripCfg: fc.Strip,
- utils.PaddingCfg: fc.Padding,
- utils.MandatoryCfg: fc.Mandatory,
- utils.AttributeIDCfg: fc.AttributeID,
- utils.NewBranchCfg: fc.NewBranch,
- utils.TimezoneCfg: fc.Timezone,
- utils.BlockerCfg: fc.Blocker,
- utils.BreakOnSuccessCfg: fc.BreakOnSuccess,
- utils.LayoutCfg: fc.Layout,
- utils.CostShiftDigitsCfg: fc.CostShiftDigits,
- utils.RoundingDecimalsCfg: fc.RoundingDecimals,
- utils.MaskDestIDCfg: fc.MaskDestID,
- utils.MaskLenCfg: fc.MaskLen,
+func (fc *FCTemplate) AsMapInterface(separator string) (mp map[string]interface{}) {
+ mp = make(map[string]interface{})
+ if fc.Tag != utils.EmptyString {
+ mp[utils.TagCfg] = fc.Tag
+ }
+ if fc.Type != utils.EmptyString {
+ mp[utils.TypeCf] = fc.Type
+ }
+ if fc.Path != utils.EmptyString {
+ mp[utils.PathCfg] = fc.Path
+ }
+ if fc.Filters != nil {
+ mp[utils.FiltersCfg] = fc.Filters
+ }
+ if fc.Value != nil {
+ for i, item := range fc.Value {
+ if i != 0 {
+ mp[utils.ValueCfg] = mp[utils.ValueCfg].(string) + separator
+ }
+ if mp[utils.ValueCfg] == nil {
+ mp[utils.ValueCfg] = item.Rules
+ } else {
+ mp[utils.ValueCfg] = mp[utils.ValueCfg].(string) + item.Rules
+ }
+ }
+ }
+ if fc.Width != 0 {
+ mp[utils.WidthCfg] = fc.Width
+ }
+ if fc.Strip != utils.EmptyString {
+ mp[utils.StripCfg] = fc.Strip
+ }
+ if fc.Padding != utils.EmptyString {
+ mp[utils.PaddingCfg] = fc.Padding
+ }
+ if fc.Mandatory != false {
+ mp[utils.MandatoryCfg] = fc.Mandatory
+ }
+ if fc.AttributeID != utils.EmptyString {
+ mp[utils.AttributeIDCfg] = fc.AttributeID
+ }
+ if fc.NewBranch != false {
+ mp[utils.NewBranchCfg] = fc.NewBranch
+ }
+ if fc.Timezone != utils.EmptyString {
+ mp[utils.TimezoneCfg] = fc.Timezone
+ }
+ if fc.Blocker != false {
+ mp[utils.BlockerCfg] = fc.Blocker
+ }
+ if fc.BreakOnSuccess != false {
+ mp[utils.BreakOnSuccessCfg] = fc.BreakOnSuccess
+ }
+ if fc.Layout != time.RFC3339 {
+ 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.MaskDestID != utils.EmptyString {
+ mp[utils.MaskDestIDCfg] = fc.MaskDestID
+ }
+ if fc.MaskLen != 0 {
+ mp[utils.MaskLenCfg] = fc.MaskLen
}
+ return
}
diff --git a/config/filterscfg_test.go b/config/filterscfg_test.go
index 9c1e01b5a..fe259da49 100644
--- a/config/filterscfg_test.go
+++ b/config/filterscfg_test.go
@@ -54,3 +54,29 @@ func TestFilterSCfgloadFromJsonCfg(t *testing.T) {
t.Errorf("Expected: %+v , recived: %+v", utils.ToJSON(expected), utils.ToJSON(fscfg))
}
}
+
+func TestFilterSCfgAsMapInterface(t *testing.T) {
+ var fscfg FilterSCfg
+ cfgJSONStr := `{
+ "filters": {
+ "stats_conns": ["*localhost"],
+ "resources_conns": [],
+ "apiers_conns": [],
+ },
+}`
+ var emptySlice []string
+ eMap := map[string]interface{}{
+ "stats_conns": []string{"*localhost"},
+ "resources_conns": emptySlice,
+ "apiers_conns": emptySlice,
+ }
+ if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil {
+ t.Error(err)
+ } else if jsnFsCfg, err := jsnCfg.FilterSJsonCfg(); err != nil {
+ t.Error(err)
+ } else if err = fscfg.loadFromJsonCfg(jsnFsCfg); err != nil {
+ t.Error(err)
+ } else if rcv := fscfg.AsMapInterface(); reflect.DeepEqual(eMap, rcv) {
+ t.Errorf("Expected: %+v ,\n recived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv))
+ }
+}
diff --git a/config/generalcfg.go b/config/generalcfg.go
index 9a5ea9674..80b49a38d 100644
--- a/config/generalcfg.go
+++ b/config/generalcfg.go
@@ -144,17 +144,34 @@ func (gencfg *GeneralCfg) loadFromJsonCfg(jsnGeneralCfg *GeneralJsonCfg) (err er
}
func (gencfg *GeneralCfg) AsMapInterface() map[string]interface{} {
+ var lockingTimeout string = "0"
+ var failedPostsTTL string = "0"
+ var connectTimeout string = "0"
+ var replyTimeout string = "0"
+ if gencfg.LockingTimeout != 0 {
+ lockingTimeout = gencfg.LockingTimeout.String()
+ }
+ if gencfg.FailedPostsTTL != 0 {
+ failedPostsTTL = gencfg.FailedPostsTTL.String()
+ }
+ if gencfg.ConnectTimeout != 0 {
+ connectTimeout = gencfg.ConnectTimeout.String()
+ }
+ if gencfg.ReplyTimeout != 0 {
+ replyTimeout = gencfg.ReplyTimeout.String()
+ }
+
return map[string]interface{}{
utils.NodeIDCfg: gencfg.NodeID,
utils.LoggerCfg: gencfg.Logger,
utils.LogLevelCfg: gencfg.LogLevel,
utils.HttpSkipTlsVerifyCfg: gencfg.HttpSkipTlsVerify,
utils.RoundingDecimalsCfg: gencfg.RoundingDecimals,
- utils.DBDataEncodingCfg: gencfg.DBDataEncoding,
+ utils.DBDataEncodingCfg: utils.Meta + gencfg.DBDataEncoding,
utils.TpExportPathCfg: gencfg.TpExportPath,
utils.PosterAttemptsCfg: gencfg.PosterAttempts,
utils.FailedPostsDirCfg: gencfg.FailedPostsDir,
- utils.FailedPostsTTLCfg: gencfg.FailedPostsTTL,
+ utils.FailedPostsTTLCfg: failedPostsTTL,
utils.DefaultReqTypeCfg: gencfg.DefaultReqType,
utils.DefaultCategoryCfg: gencfg.DefaultCategory,
utils.DefaultTenantCfg: gencfg.DefaultTenant,
@@ -162,9 +179,9 @@ func (gencfg *GeneralCfg) AsMapInterface() map[string]interface{} {
utils.DefaultCachingCfg: gencfg.DefaultCaching,
utils.ConnectAttemptsCfg: gencfg.ConnectAttempts,
utils.ReconnectsCfg: gencfg.Reconnects,
- utils.ConnectTimeoutCfg: gencfg.ConnectTimeout,
- utils.ReplyTimeoutCfg: gencfg.ReplyTimeout,
- utils.LockingTimeoutCfg: gencfg.LockingTimeout,
+ utils.ConnectTimeoutCfg: connectTimeout,
+ utils.ReplyTimeoutCfg: replyTimeout,
+ utils.LockingTimeoutCfg: lockingTimeout,
utils.DigestSeparatorCfg: gencfg.DigestSeparator,
utils.DigestEqualCfg: gencfg.DigestEqual,
utils.RSRSepCfg: gencfg.RSRSep,
diff --git a/config/httpagntcfg.go b/config/httpagntcfg.go
index ce8caad0e..2a704827c 100644
--- a/config/httpagntcfg.go
+++ b/config/httpagntcfg.go
@@ -50,6 +50,14 @@ func (hcfgs *HttpAgentCfgs) loadFromJsonCfg(jsnHttpAgntCfg *[]*HttpAgentJsonCfg,
return nil
}
+func (hcfgs *HttpAgentCfgs) AsMapInterface(separator string) []map[string]interface{} {
+ mp := make([]map[string]interface{}, len(*hcfgs))
+ for i, item := range *hcfgs {
+ mp[i] = item.AsMapInterface(separator)
+ }
+ return mp
+}
+
type HttpAgentCfg struct {
ID string // identifier for the agent, so we can update it's processors
Url string
@@ -118,10 +126,10 @@ func (ca *HttpAgentCfg) loadFromJsonCfg(jsnCfg *HttpAgentJsonCfg, separator stri
return nil
}
-func (ca *HttpAgentCfg) AsMapInterface() map[string]interface{} {
+func (ca *HttpAgentCfg) AsMapInterface(separator string) map[string]interface{} {
requestProcessors := make([]map[string]interface{}, len(ca.RequestProcessors))
for i, item := range ca.RequestProcessors {
- requestProcessors[i] = item.AsMapInterface()
+ requestProcessors[i] = item.AsMapInterface(separator)
}
return map[string]interface{}{
@@ -130,6 +138,6 @@ func (ca *HttpAgentCfg) AsMapInterface() map[string]interface{} {
utils.SessionSConnsCfg: ca.SessionSConns,
utils.RequestPayloadCfg: ca.RequestPayload,
utils.ReplyPayloadCfg: ca.ReplyPayload,
- utils.RequestProcessorsCfg: ca.RequestProcessors,
+ utils.RequestProcessorsCfg: requestProcessors,
}
}
diff --git a/config/httpagntcfg_test.go b/config/httpagntcfg_test.go
index 45c721494..7388aa109 100644
--- a/config/httpagntcfg_test.go
+++ b/config/httpagntcfg_test.go
@@ -344,3 +344,76 @@ func TestHttpAgentCfgappendHttpAgntProcCfgs(t *testing.T) {
t.Errorf("Expected: %+v , recived: %+v", utils.ToJSON(expected), utils.ToJSON(initial))
}
}
+
+func TestHttpAgentCfgAsMapInterface(t *testing.T) {
+ var httpcfg HttpAgentCfgs
+ cfgJSONStr := `{
+
+"http_agent": [
+ {
+ "id": "conecto1",
+ "url": "/conecto",
+ "sessions_conns": ["*localhost"],
+ "request_payload": "*url",
+ "reply_payload": "*xml",
+ "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{}{
+ {
+ "id": "conecto1",
+ "url": "/conecto",
+ "sessions_conns": []string{"*localhost"},
+ "request_payload": "*url",
+ "reply_payload": "*xml",
+ "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 jsnhttpCfg, err := jsnCfg.HttpAgentJsonCfg(); err != nil {
+ t.Error(err)
+ } else if err = httpcfg.loadFromJsonCfg(jsnhttpCfg, utils.INFIELD_SEP); err != nil {
+ t.Error(err)
+ } else if rcv := httpcfg.AsMapInterface(";"); !reflect.DeepEqual(eMap, rcv) {
+ t.Errorf("Expected: %+v,\nRecived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv))
+ }
+}
diff --git a/config/httpcfg.go b/config/httpcfg.go
index d97db7061..258f0fe21 100644
--- a/config/httpcfg.go
+++ b/config/httpcfg.go
@@ -58,12 +58,17 @@ func (httpcfg *HTTPCfg) loadFromJsonCfg(jsnHttpCfg *HTTPJsonCfg) (err error) {
}
func (httpcfg *HTTPCfg) AsMapInterface() map[string]interface{} {
+ httpUsers := map[string]interface{}{}
+ for key, item := range httpcfg.HTTPAuthUsers {
+ httpUsers[key] = item
+ }
+
return map[string]interface{}{
utils.HTTPJsonRPCURLCfg: httpcfg.HTTPJsonRPCURL,
utils.HTTPWSURLCfg: httpcfg.HTTPWSURL,
utils.HTTPFreeswitchCDRsURLCfg: httpcfg.HTTPFreeswitchCDRsURL,
utils.HTTPCDRsURLCfg: httpcfg.HTTPCDRsURL,
utils.HTTPUseBasicAuthCfg: httpcfg.HTTPUseBasicAuth,
- utils.HTTPAuthUsersCfg: httpcfg.HTTPAuthUsers,
+ utils.HTTPAuthUsersCfg: httpUsers,
}
}
diff --git a/config/httpcfg_test.go b/config/httpcfg_test.go
index 5b3f856c2..071c38c3d 100644
--- a/config/httpcfg_test.go
+++ b/config/httpcfg_test.go
@@ -20,6 +20,8 @@ package config
import (
"reflect"
"testing"
+
+ "github.com/cgrates/cgrates/utils"
)
func TestHTTPCfgloadFromJsonCfg(t *testing.T) {
@@ -62,3 +64,36 @@ func TestHTTPCfgloadFromJsonCfg(t *testing.T) {
t.Errorf("Expected: %+v , recived: %+v", expected, httpcfg)
}
}
+
+func TestHTTPCfgAsMapInterface(t *testing.T) {
+ var httpcfg HTTPCfg
+ cfgJSONStr := `{
+ "http": {
+ "json_rpc_url": "/jsonrpc",
+ "ws_url": "/ws",
+ "freeswitch_cdrs_url": "/freeswitch_json",
+ "http_cdrs": "/cdr_http",
+ "use_basic_auth": false,
+ "auth_users": {},
+ },
+}`
+
+ eMap := map[string]interface{}{
+ "json_rpc_url": "/jsonrpc",
+ "ws_url": "/ws",
+ "freeswitch_cdrs_url": "/freeswitch_json",
+ "http_cdrs": "/cdr_http",
+ "use_basic_auth": false,
+ "auth_users": map[string]interface{}{},
+ }
+
+ if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil {
+ t.Error(err)
+ } else if jsnhttpCfg, err := jsnCfg.HttpJsonCfg(); err != nil {
+ t.Error(err)
+ } else if err = httpcfg.loadFromJsonCfg(jsnhttpCfg); err != nil {
+ t.Error(err)
+ } else if rcv := httpcfg.AsMapInterface(); !reflect.DeepEqual(eMap, rcv) {
+ t.Errorf("Expected: %+v ,\n recived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv))
+ }
+}
diff --git a/config/loaderscfg.go b/config/loaderscfg.go
index 412c01121..4ed55b9ad 100644
--- a/config/loaderscfg.go
+++ b/config/loaderscfg.go
@@ -19,6 +19,7 @@ along with this program. If not, see
package config
import (
+ "strings"
"time"
"github.com/cgrates/cgrates/utils"
@@ -182,10 +183,10 @@ func (self *LoaderSCfg) Clone() *LoaderSCfg {
return clnLoader
}
-func (lData *LoaderDataType) AsMapInterface() map[string]interface{} {
+func (lData *LoaderDataType) AsMapInterface(separator string) map[string]interface{} {
fields := make([]map[string]interface{}, len(lData.Fields))
for i, item := range lData.Fields {
- fields[i] = item.AsMapInterface()
+ fields[i] = item.AsMapInterface(separator)
}
return map[string]interface{}{
@@ -195,25 +196,39 @@ func (lData *LoaderDataType) AsMapInterface() map[string]interface{} {
}
}
-func (l *LoaderSCfg) AsMapInterface() map[string]interface{} {
+func (l *LoaderSCfg) AsMapInterface(separator string) map[string]interface{} {
tenant := make([]string, len(l.Tenant))
for i, item := range l.Tenant {
tenant[i] = item.Rules
}
+ strings.Join(tenant, utils.EmptyString)
data := make([]map[string]interface{}, len(l.Data))
for i, item := range l.Data {
- data[i] = item.AsMapInterface()
+ data[i] = item.AsMapInterface(separator)
+ }
+ var runDelay string = "0"
+ if l.RunDelay != 0 {
+ runDelay = l.RunDelay.String()
+ }
+ cacheSConns := make([]string, len(l.CacheSConns))
+ for i, item := range l.CacheSConns {
+ buf := utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCaches)
+ if item == buf {
+ cacheSConns[i] = strings.ReplaceAll(item, ":*caches", utils.EmptyString)
+ } else {
+ cacheSConns[i] = item
+ }
}
return map[string]interface{}{
utils.IdCfg: l.Id,
utils.EnabledCfg: l.Enabled,
- utils.TenantCfg: tenant,
+ utils.TenantCfg: strings.Join(tenant, utils.EmptyString),
utils.DryRunCfg: l.DryRun,
- utils.RunDelayCfg: l.RunDelay,
+ utils.RunDelayCfg: runDelay,
utils.LockFileNameCfg: l.LockFileName,
- utils.CacheSConnsCfg: l.CacheSConns,
+ utils.CacheSConnsCfg: cacheSConns,
utils.FieldSeparatorCfg: l.FieldSeparator,
utils.TpInDirCfg: l.TpInDir,
utils.TpOutDirCfg: l.TpOutDir,
diff --git a/config/loaderscfg_test.go b/config/loaderscfg_test.go
index 616a7e7ef..f3acf9869 100644
--- a/config/loaderscfg_test.go
+++ b/config/loaderscfg_test.go
@@ -102,3 +102,78 @@ func TestLoaderSCfgloadFromJsonCfg(t *testing.T) {
t.Errorf("Expected: %+v , recived: %+v", utils.ToJSON(expected), utils.ToJSON(loadscfg))
}
}
+
+func TestLoaderCfgAsMapInterface(t *testing.T) {
+ var loadscfg LoaderSCfg
+ cfgJSONStr := `{
+ "loaders": [
+ {
+ "id": "*default",
+ "enabled": false,
+ "tenant": "",
+ "dry_run": false,
+ "run_delay": 0,
+ "lock_filename": ".cgr.lck",
+ "caches_conns": ["*internal"],
+ "field_separator": ",",
+ "tp_in_dir": "/var/spool/cgrates/loader/in",
+ "tp_out_dir": "/var/spool/cgrates/loader/out",
+ "data":[
+ {
+ "type": "*attributes",
+ "file_name": "Attributes.csv",
+ "fields": [
+ {"tag": "TenantID", "path": "Tenant", "type": "*variable", "value": "~0", "mandatory": true},
+ {"tag": "ProfileID", "path": "ID", "type": "*variable", "value": "~1", "mandatory": true},
+ ],
+ },
+ ],
+ },
+ ],
+
+}`
+ eMap := map[string]interface{}{
+ "id": "*default",
+ "enabled": false,
+ "tenant": "",
+ "dry_run": false,
+ "run_delay": "0",
+ "lock_filename": ".cgr.lck",
+ "caches_conns": []string{"*internal"},
+ "field_separator": ",",
+ "tp_in_dir": "/var/spool/cgrates/loader/in",
+ "tp_out_dir": "/var/spool/cgrates/loader/out",
+ "data": []map[string]interface{}{
+ {
+ "type": "*attributes",
+ "file_name": "Attributes.csv",
+ "fields": []map[string]interface{}{
+ {
+ "tag": "TenantID",
+ "path": "Tenant",
+ "type": "*variable",
+ "value": "~0",
+ "mandatory": true,
+ }, {
+ "tag": "ProfileID",
+ "path": "ID",
+ "type": "*variable",
+ "value": "~1",
+ "mandatory": true,
+ },
+ },
+ },
+ },
+ }
+
+ if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil {
+ t.Error(err)
+ } else if jsnLoadersCfg, err := jsnCfg.LoaderJsonCfg(); err != nil {
+ t.Error(err)
+ } else if err = loadscfg.loadFromJsonCfg(jsnLoadersCfg[0], utils.INFIELD_SEP); err != nil {
+ t.Error(err)
+ } else if rcv := loadscfg.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 b2ce1aaa7..7c1ca7db7 100644
--- a/config/radiuscfg.go
+++ b/config/radiuscfg.go
@@ -96,7 +96,7 @@ func (self *RadiusAgentCfg) loadFromJsonCfg(jsnCfg *RadiusAgentJsonCfg, separato
return nil
}
-func (ra *RadiusAgentCfg) AsMapInterface() map[string]interface{} {
+func (ra *RadiusAgentCfg) AsMapInterface(separator string) map[string]interface{} {
clientSecrets := make(map[string]interface{}, len(ra.ClientSecrets))
for key, val := range ra.ClientSecrets {
clientSecrets[key] = val
@@ -109,7 +109,7 @@ func (ra *RadiusAgentCfg) AsMapInterface() map[string]interface{} {
requestProcessors := make([]map[string]interface{}, len(ra.RequestProcessors))
for i, item := range ra.RequestProcessors {
- requestProcessors[i] = item.AsMapInterface()
+ requestProcessors[i] = item.AsMapInterface(separator)
}
return map[string]interface{}{
diff --git a/config/ralscfg.go b/config/ralscfg.go
index 563d2a12b..7801cdc7d 100644
--- a/config/ralscfg.go
+++ b/config/ralscfg.go
@@ -19,6 +19,8 @@ along with this program. If not, see
package config
import (
+ "strconv"
+ "strings"
"time"
"github.com/cgrates/cgrates/utils"
@@ -85,6 +87,7 @@ func (ralsCfg *RalsCfg) loadFromJsonCfg(jsnRALsCfg *RalsJsonCfg) (err error) {
ralsCfg.RemoveExpired = *jsnRALsCfg.Remove_expired
}
if jsnRALsCfg.Max_computed_usage != nil {
+ ralsCfg.MaxComputedUsage = make(map[string]time.Duration, len(*jsnRALsCfg.Max_computed_usage))
for k, v := range *jsnRALsCfg.Max_computed_usage {
if ralsCfg.MaxComputedUsage[k], err = utils.ParseDurationWithNanosecs(v); err != nil {
return
@@ -95,6 +98,7 @@ func (ralsCfg *RalsCfg) loadFromJsonCfg(jsnRALsCfg *RalsJsonCfg) (err error) {
ralsCfg.MaxIncrements = *jsnRALsCfg.Max_increments
}
if jsnRALsCfg.Balance_rating_subject != nil {
+ ralsCfg.BalanceRatingSubject = make(map[string]string, len(*jsnRALsCfg.Balance_rating_subject))
for k, v := range *jsnRALsCfg.Balance_rating_subject {
ralsCfg.BalanceRatingSubject[k] = v
}
@@ -106,7 +110,21 @@ func (ralsCfg *RalsCfg) loadFromJsonCfg(jsnRALsCfg *RalsJsonCfg) (err error) {
func (ralsCfg *RalsCfg) AsMapInterface() map[string]interface{} {
maxComputed := make(map[string]interface{})
for key, item := range ralsCfg.MaxComputedUsage {
- maxComputed[key] = item
+ if key == utils.ANY || key == utils.VOICE {
+ maxComputed[key] = item.String()
+ } else {
+ maxComputed[key] = strconv.Itoa(int(item))
+ }
+ }
+
+ cacheSConns := make([]string, len(ralsCfg.CacheSConns))
+ for i, item := range ralsCfg.CacheSConns {
+ buf := utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCaches)
+ if item == buf {
+ cacheSConns[i] = strings.ReplaceAll(item, ":*caches", utils.EmptyString)
+ } else {
+ cacheSConns[i] = item
+ }
}
balanceRating := make(map[string]interface{})
@@ -118,11 +136,12 @@ func (ralsCfg *RalsCfg) AsMapInterface() map[string]interface{} {
utils.EnabledCfg: ralsCfg.Enabled,
utils.ThresholdSConnsCfg: ralsCfg.ThresholdSConns,
utils.StatSConnsCfg: ralsCfg.StatSConns,
- utils.CacheSConnsCfg: ralsCfg.CacheSConns,
+ utils.CacheSConnsCfg: cacheSConns,
utils.RpSubjectPrefixMatchingCfg: ralsCfg.RpSubjectPrefixMatching,
utils.RemoveExpiredCfg: ralsCfg.RemoveExpired,
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 6fb9e4541..835fbc2c1 100644
--- a/config/ralscfg_test.go
+++ b/config/ralscfg_test.go
@@ -75,3 +75,61 @@ func TestRalsCfgFromJsonCfg(t *testing.T) {
t.Errorf("Expected: %+v , recived: %+v", utils.ToJSON(expected), utils.ToJSON(ralscfg))
}
}
+
+func TestRalsCfgAsMapInterface(t *testing.T) {
+ var ralscfg RalsCfg
+ cfgJSONStr := `{
+ "rals": {
+ "enabled": false,
+ "thresholds_conns": [],
+ "stats_conns": [],
+ "caches_conns":["*internal"],
+ "rp_subject_prefix_matching": false,
+ "remove_expired":true,
+ "max_computed_usage": {
+ "*any": "189h",
+ "*voice": "72h",
+ "*data": "107374182400",
+ "*sms": "10000",
+ "*mms": "10000"
+ },
+ "max_increments": 1000000,
+ "balance_rating_subject":{
+ "*any": "*zero1ns",
+ "*voice": "*zero1s"
+ },
+ "dynaprepaid_actionplans": [],
+ },
+}`
+ eMap := map[string]interface{}{
+ "enabled": false,
+ "thresholds_conns": []string{},
+ "stats_conns": []string{},
+ "caches_conns": []string{"*internal"},
+ "rp_subject_prefix_matching": false,
+ "remove_expired": true,
+ "max_computed_usage": map[string]interface{}{
+ "*any": "189h0m0s",
+ "*voice": "72h0m0s",
+ "*data": "107374182400",
+ "*sms": "10000",
+ "*mms": "10000",
+ },
+ "max_increments": 1000000,
+ "balance_rating_subject": map[string]interface{}{
+ "*any": "*zero1ns",
+ "*voice": "*zero1s",
+ },
+ "dynaprepaid_actionplans": []string{},
+ }
+
+ if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil {
+ t.Error(err)
+ } else if jsnRalsCfg, err := jsnCfg.RalsJsonCfg(); err != nil {
+ t.Error(err)
+ } else if err = ralscfg.loadFromJsonCfg(jsnRalsCfg); err != nil {
+ t.Error(err)
+ } else if rcv := ralscfg.AsMapInterface(); !reflect.DeepEqual(eMap, rcv) {
+ t.Errorf("Expected: %+v ,\n recived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv))
+ }
+}
diff --git a/config/rpcconn.go b/config/rpcconn.go
index 1f13506e0..acf36d4e6 100644
--- a/config/rpcconn.go
+++ b/config/rpcconn.go
@@ -69,9 +69,9 @@ func (rC *RPCConn) AsMapInterface() map[string]interface{} {
}
return map[string]interface{}{
- utils.Strategy: rC.Strategy,
- utils.PoolSize: rC.PoolSize,
- utils.Conns: conns,
+ utils.StrategyCfg: rC.Strategy,
+ utils.PoolSize: rC.PoolSize,
+ utils.Conns: conns,
}
}
@@ -104,9 +104,9 @@ func (self *RemoteHost) loadFromJsonCfg(jsnCfg *RemoteHostJson) error {
func (rh *RemoteHost) AsMapInterface() map[string]interface{} {
return map[string]interface{}{
- utils.Address: rh.Address,
- utils.Transport: rh.Transport,
- utils.Synchronous: rh.Synchronous,
- utils.TLS: rh.TLS,
+ utils.AddressCfg: rh.Address,
+ utils.TransportCfg: rh.Transport,
+ utils.SynchronousCfg: rh.Synchronous,
+ utils.TLS: rh.TLS,
}
}
diff --git a/config/rpcconn_test.go b/config/rpcconn_test.go
index 6d55b49ee..f8ec2647f 100644
--- a/config/rpcconn_test.go
+++ b/config/rpcconn_test.go
@@ -17,3 +17,42 @@ along with this program. If not, see
*/
package config
+
+import (
+ "reflect"
+ "testing"
+
+ "github.com/cgrates/cgrates/utils"
+)
+
+func TestRPCConnsAsMapInterface(t *testing.T) {
+ var cfg RPCConn
+ cfgJSONStr := `{
+ "rpc_conns": {
+ "*localhost": {
+ "conns": [{"address": "127.0.0.1:2012", "transport":"*json"}],
+ },
+ },
+}`
+ eMap := map[string]interface{}{
+ "poolSize": 0,
+ "strategy": "",
+ "conns": []map[string]interface{}{
+ {
+ "address": "127.0.0.1:2012",
+ "transport": "*json",
+ "synchronous": false,
+ "TLS": false,
+ },
+ },
+ }
+ if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil {
+ t.Error(err)
+ } else if jsnRPCCfg, err := jsnCfg.RPCConnJsonCfg(); err != nil {
+ t.Error(err)
+ } else if err = cfg.loadFromJsonCfg(jsnRPCCfg["*localhost"]); err != nil {
+ t.Error(err)
+ } else if rcv := cfg.AsMapInterface(); !reflect.DeepEqual(eMap, rcv) {
+ t.Errorf("\nExpected: %+v\nRecived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv))
+ }
+}
diff --git a/config/stordbcfg.go b/config/stordbcfg.go
index fd7f3cd94..1295d5ebe 100644
--- a/config/stordbcfg.go
+++ b/config/stordbcfg.go
@@ -95,6 +95,7 @@ func (dbcfg *StorDbCfg) loadFromJsonCfg(jsnDbCfg *DbJsonCfg) (err error) {
dbcfg.SSLMode = *jsnDbCfg.Sslmode
}
if jsnDbCfg.Items != nil {
+ dbcfg.Items = make(map[string]*ItemOpt)
for kJsn, vJsn := range *jsnDbCfg.Items {
val := new(ItemOpt)
if err := val.loadFromJsonCfg(vJsn); err != nil {
@@ -131,11 +132,16 @@ func (dbcfg *StorDbCfg) AsMapInterface() map[string]interface{} {
for key, item := range dbcfg.Items {
items[key] = item.AsMapInterface()
}
+ var queryTimeout string = "0"
+ if dbcfg.QueryTimeout != 0 {
+ queryTimeout = dbcfg.QueryTimeout.String()
+ }
+ dbPort, _ := strconv.Atoi(dbcfg.Port)
return map[string]interface{}{
- utils.TypeCfg: dbcfg.Type,
+ utils.TypeCfg: utils.Meta + dbcfg.Type,
utils.HostCfg: dbcfg.Host,
- utils.PortCfg: dbcfg.Port,
+ utils.PortCfg: dbPort,
utils.NameCfg: dbcfg.Name,
utils.UserCfg: dbcfg.User,
utils.PasswordCfg: dbcfg.Password,
@@ -144,7 +150,7 @@ func (dbcfg *StorDbCfg) AsMapInterface() map[string]interface{} {
utils.ConnMaxLifetimeCfg: dbcfg.ConnMaxLifetime,
utils.StringIndexedFieldsCfg: dbcfg.StringIndexedFields,
utils.PrefixIndexedFieldsCfg: dbcfg.PrefixIndexedFields,
- utils.QueryTimeoutCfg: dbcfg.QueryTimeout,
+ utils.QueryTimeoutCfg: queryTimeout,
utils.SSLModeCfg: dbcfg.SSLMode,
utils.ItemsCfg: items,
}
diff --git a/config/stordbcfg_test.go b/config/stordbcfg_test.go
index b05344dc5..1ef7e654d 100644
--- a/config/stordbcfg_test.go
+++ b/config/stordbcfg_test.go
@@ -20,6 +20,8 @@ package config
import (
"reflect"
"testing"
+
+ "github.com/cgrates/cgrates/utils"
)
func TestStoreDbCfgloadFromJsonCfg(t *testing.T) {
@@ -130,3 +132,57 @@ func TestStoreDbCfgloadFromJsonCfgPort(t *testing.T) {
t.Errorf("Expected: %+v , recived: %+v", expected, dbcfg)
}
}
+
+func TestStorDbCfgAsMapInterface(t *testing.T) {
+ var dbcfg StorDbCfg
+ cfgJSONStr := `{
+ "stor_db": {
+ "db_type": "*mysql",
+ "db_host": "127.0.0.1",
+ "db_port": -1,
+ "db_name": "cgrates",
+ "db_user": "cgrates",
+ "db_password": "",
+ "max_open_conns": 100,
+ "max_idle_conns": 10,
+ "conn_max_lifetime": 0,
+ "string_indexed_fields": [],
+ "prefix_indexed_fields":[],
+ "query_timeout":"10s",
+ "sslmode":"disable",
+ "items":{
+ "session_costs": {"limit": -1, "ttl": "", "static_ttl": false},
+ "cdrs": {"limit": -1, "ttl": "", "static_ttl": false},
+ },
+ },
+}`
+
+ eMap := map[string]interface{}{
+ "db_type": "*mysql",
+ "db_host": "127.0.0.1",
+ "db_port": 3306,
+ "db_name": "cgrates",
+ "db_user": "cgrates",
+ "db_password": "",
+ "max_open_conns": 100,
+ "max_idle_conns": 10,
+ "conn_max_lifetime": 0,
+ "string_indexed_fields": []string{},
+ "prefix_indexed_fields": []string{},
+ "query_timeout": "10s",
+ "sslmode": "disable",
+ "items": map[string]interface{}{
+ "session_costs": map[string]interface{}{"limit": -1, "ttl": "", "static_ttl": false, "remote": false, "replicate": false},
+ "cdrs": map[string]interface{}{"limit": -1, "ttl": "", "static_ttl": false, "remote": false, "replicate": false},
+ },
+ }
+ if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil {
+ t.Error(err)
+ } else if jsnStoreDbCfg, err := jsnCfg.DbJsonCfg(STORDB_JSN); err != nil {
+ t.Error(err)
+ } else if err = dbcfg.loadFromJsonCfg(jsnStoreDbCfg); err != nil {
+ t.Error(err)
+ } else if rcv := dbcfg.AsMapInterface(); !reflect.DeepEqual(eMap, rcv) {
+ t.Errorf("Expected: %+v ,\n recived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv))
+ }
+}
diff --git a/config/tlscfg_test.go b/config/tlscfg_test.go
index c72dcdf13..ef12e5964 100644
--- a/config/tlscfg_test.go
+++ b/config/tlscfg_test.go
@@ -20,6 +20,8 @@ package config
import (
"reflect"
"testing"
+
+ "github.com/cgrates/cgrates/utils"
)
func TestTlsCfgloadFromJsonCfg(t *testing.T) {
@@ -65,3 +67,67 @@ func TestTlsCfgloadFromJsonCfg(t *testing.T) {
t.Errorf("Expected: %+v , recived: %+v", expected, tlscfg)
}
}
+func TestTlsCfgAsMapInterface(t *testing.T) {
+ var tlscfg TlsCfg
+ cfgJSONStr := ` {
+ "tls": {
+ "server_certificate" : "",
+ "server_key":"",
+ "client_certificate" : "",
+ "client_key":"",
+ "ca_certificate":"",
+ "server_policy":4,
+ "server_name":"",
+ },
+}`
+ eMap := map[string]interface{}{
+ "server_certificate": "",
+ "server_key": "",
+ "client_certificate": "",
+ "client_key": "",
+ "ca_certificate": "",
+ "server_policy": 4,
+ "server_name": "",
+ }
+
+ if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil {
+ t.Error(err)
+ } else if jsntlsCfg, err := jsnCfg.TlsCfgJson(); err != nil {
+ t.Error(err)
+ } else if err = tlscfg.loadFromJsonCfg(jsntlsCfg); err != nil {
+ t.Error(err)
+ } else if rcv := tlscfg.AsMapInterface(); !reflect.DeepEqual(eMap, rcv) {
+ t.Errorf("Expected: %+v,\nRecived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv))
+ }
+
+ cfgJSONStr = ` {
+ "tls":{
+ "server_certificate" : "path/To/Server/Cert",
+ "server_key":"path/To/Server/Key",
+ "client_certificate" : "path/To/Client/Cert",
+ "client_key":"path/To/Client/Key",
+ "ca_certificate":"path/To/CA/Cert",
+ "server_name":"TestServerName",
+ "server_policy":3,
+ },
+}`
+ eMap = map[string]interface{}{
+ "server_certificate": "path/To/Server/Cert",
+ "server_key": "path/To/Server/Key",
+ "client_certificate": "path/To/Client/Cert",
+ "client_key": "path/To/Client/Key",
+ "ca_certificate": "path/To/CA/Cert",
+ "server_name": "TestServerName",
+ "server_policy": 3,
+ }
+
+ if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil {
+ t.Error(err)
+ } else if jsntlsCfg, err := jsnCfg.TlsCfgJson(); err != nil {
+ t.Error(err)
+ } else if err = tlscfg.loadFromJsonCfg(jsntlsCfg); err != nil {
+ t.Error(err)
+ } else if rcv := tlscfg.AsMapInterface(); !reflect.DeepEqual(eMap, rcv) {
+ t.Errorf("Expected: %+v,\nRecived: %+v", utils.ToJSON(eMap), utils.ToJSON(rcv))
+ }
+}
diff --git a/utils/consts.go b/utils/consts.go
index 3bac5b500..dd5a57f39 100755
--- a/utils/consts.go
+++ b/utils/consts.go
@@ -1738,6 +1738,7 @@ const (
// KamAgentCfg
EvapiConnsCfg = "evapi_conns"
TimezoneCfg = "timezone"
+ TimezoneCfgC = "Timezone"
// AsteriskConnCfg
UserCf = "user"
@@ -1763,8 +1764,8 @@ const (
RequestProcessorsCfg = "request_processors"
// RequestProcessor
- RequestFieldsCfg = "Request_fields"
- ReplyFieldsCfg = "Reply_fields"
+ RequestFieldsCfg = "request_fields"
+ ReplyFieldsCfg = "reply_fields"
// RadiusAgentCfg
ListenAuthCfg = "listen_auth"
@@ -1803,13 +1804,16 @@ const (
TpOutDirCfg = "tp_out_dir"
DataCfg = "data"
- DefaultRatioCfg = "default_ratio"
- ReadersCfg = "readers"
- PoolSize = "PoolSize"
- Conns = "Conns"
- FilenameCfg = "file_name"
- RequestPayloadCfg = "Request_payload"
- ReplyPayloadCfg = "Reply_payload"
+ DefaultRatioCfg = "default_ratio"
+ ReadersCfg = "readers"
+ PoolSize = "poolSize"
+ Conns = "conns"
+ FilenameCfg = "file_name"
+ RequestPayloadCfg = "request_payload"
+ ReplyPayloadCfg = "reply_payload"
+ TransportCfg = "transport"
+ StrategyCfg = "strategy"
+ Dynaprepaid_actionplansCfg = "dynaprepaid_actionplans"
)
// FC Template