diff --git a/agents/diam_it_test.go b/agents/diam_it_test.go
index 24fc208fa..5f0f8c6c8 100644
--- a/agents/diam_it_test.go
+++ b/agents/diam_it_test.go
@@ -224,7 +224,7 @@ func testDiamItStartEngine(t *testing.T) {
func testDiamItConnectDiameterClient(t *testing.T) {
diamClnt, err = NewDiameterClient(daCfg.DiameterAgentCfg().Listen, "INTEGRATION_TESTS",
- daCfg.DiameterAgentCfg().OriginRealm, daCfg.DiameterAgentCfg().VendorId,
+ daCfg.DiameterAgentCfg().OriginRealm, daCfg.DiameterAgentCfg().VendorID,
daCfg.DiameterAgentCfg().ProductName, utils.DIAMETER_FIRMWARE_REVISION,
daCfg.DiameterAgentCfg().DictionariesPath, daCfg.DiameterAgentCfg().ListenNet)
if err != nil {
diff --git a/agents/diamagent.go b/agents/diamagent.go
index 129062bc1..d6f72053e 100644
--- a/agents/diamagent.go
+++ b/agents/diamagent.go
@@ -126,7 +126,7 @@ func (da *DiameterAgent) handlers() diam.Handler {
settings := &sm.Settings{
OriginHost: datatype.DiameterIdentity(da.cgrCfg.DiameterAgentCfg().OriginHost),
OriginRealm: datatype.DiameterIdentity(da.cgrCfg.DiameterAgentCfg().OriginRealm),
- VendorID: datatype.Unsigned32(da.cgrCfg.DiameterAgentCfg().VendorId),
+ VendorID: datatype.Unsigned32(da.cgrCfg.DiameterAgentCfg().VendorID),
ProductName: datatype.UTF8String(da.cgrCfg.DiameterAgentCfg().ProductName),
FirmwareRevision: datatype.Unsigned32(utils.DIAMETER_FIRMWARE_REVISION),
}
diff --git a/agents/httpagent_it_test.go b/agents/httpagent_it_test.go
index ec75184b9..15461379e 100644
--- a/agents/httpagent_it_test.go
+++ b/agents/httpagent_it_test.go
@@ -195,7 +195,7 @@ func testHAitAuthDryRun(t *testing.T) {
httpConst = "https"
}
reqUrl := fmt.Sprintf("%s://%s%s?request_type=OutboundAUTH&CallID=123456&Msisdn=497700056231&Imsi=2343000000000123&Destination=491239440004&MSRN=0102220233444488999&ProfileID=1&AgentID=176&GlobalMSISDN=497700056129&GlobalIMSI=214180000175129&ICCID=8923418450000089629&MCC=234&MNC=10&calltype=callback",
- httpConst, addr, haCfg.HTTPAgentCfg()[0].Url)
+ httpConst, addr, haCfg.HTTPAgentCfg()[0].URL)
rply, err := httpC.Get(reqUrl)
if err != nil {
t.Fatal(err)
@@ -245,7 +245,7 @@ func testHAitAuth1001(t *testing.T) {
}
reqUrl := fmt.Sprintf("%s://%s%s?request_type=OutboundAUTH&CallID=123456&Msisdn=%s&Imsi=2343000000000123&Destination=1002&MSRN=0102220233444488999&ProfileID=1&AgentID=176&GlobalMSISDN=497700056129&GlobalIMSI=214180000175129&ICCID=8923418450000089629&MCC=234&MNC=10&calltype=callback",
- httpConst, addr, haCfg.HTTPAgentCfg()[0].Url, acnt)
+ httpConst, addr, haCfg.HTTPAgentCfg()[0].URL, acnt)
rply, err := httpC.Get(reqUrl)
if err != nil {
t.Fatal(err)
@@ -272,7 +272,7 @@ func testHAitCDRmtcall(t *testing.T) {
httpConst = "https"
}
reqUrl := fmt.Sprintf("%s://%s%s?request_type=MTCALL_CDR×tamp=2018-08-14%%2012:03:22&call_date=2018-0814%%2012:00:49&transactionid=10000&CDR_ID=123456&carrierid=1&mcc=0&mnc=0&imsi=434180000000000&msisdn=1001&destination=1002&leg=C&leg_duration=185&reseller_charge=11.1605&client_charge=0.0000&user_charge=22.0000&IOT=0&user_balance=10.00&cli=%%2B498702190000&polo=0.0100&ddi_map=N",
- httpConst, addr, haCfg.HTTPAgentCfg()[0].Url)
+ httpConst, addr, haCfg.HTTPAgentCfg()[0].URL)
rply, err := httpC.Get(reqUrl)
if err != nil {
t.Fatal(err)
@@ -316,7 +316,7 @@ func testHAitCDRmtcall2(t *testing.T) {
addr = haCfg.ListenCfg().HTTPTLSListen
httpConst = "https"
}
- url := fmt.Sprintf("%s://%s%s", httpConst, addr, haCfg.HTTPAgentCfg()[1].Url)
+ url := fmt.Sprintf("%s://%s%s", httpConst, addr, haCfg.HTTPAgentCfg()[1].URL)
req, err := http.NewRequest("POST", url, bytes.NewBuffer([]byte(xmlBody)))
if err != nil {
@@ -351,7 +351,7 @@ func testHAitTextPlain(t *testing.T) {
httpConst = "https"
}
reqUrl := fmt.Sprintf("%s://%s%s?request_type=TextPlainDryRun&CallID=123456&Msisdn=497700056231&Imsi=2343000000000123&Destination=491239440004",
- httpConst, addr, haCfg.HTTPAgentCfg()[2].Url)
+ httpConst, addr, haCfg.HTTPAgentCfg()[2].URL)
rply, err := httpC.Get(reqUrl)
if err != nil {
t.Fatal(err)
diff --git a/cmd/cgr-loader/cgr-loader_it_test.go b/cmd/cgr-loader/cgr-loader_it_test.go
index a4482eb38..24ff570be 100644
--- a/cmd/cgr-loader/cgr-loader_it_test.go
+++ b/cmd/cgr-loader/cgr-loader_it_test.go
@@ -156,7 +156,7 @@ func TestLoadConfig(t *testing.T) {
if !reflect.DeepEqual(ldrCfg.LoaderCgrCfg().SchedulerConns, expAddrs) {
t.Errorf("Expected %v received %v", expAddrs, ldrCfg.LoaderCgrCfg().SchedulerConns)
}
- expaddr := config.RpcConns{
+ expaddr := config.RPCConns{
utils.MetaInternal: {
Strategy: rpcclient.PoolFirst,
PoolSize: 0,
diff --git a/config/cachecfg.go b/config/cachecfg.go
index 7ce15cacd..b141a4717 100644
--- a/config/cachecfg.go
+++ b/config/cachecfg.go
@@ -141,31 +141,24 @@ func (cCfg *CacheCfg) AddTmpCaches() {
// AsMapInterface returns the config as a map[string]interface{}
func (cCfg *CacheCfg) AsMapInterface() (initialMP map[string]interface{}) {
initialMP = make(map[string]interface{})
- if cCfg.Partitions != nil {
- partitions := make(map[string]interface{}, len(cCfg.Partitions))
- for key, value := range cCfg.Partitions {
- partitions[key] = value.AsMapInterface()
- }
- initialMP[utils.PartitionsCfg] = partitions
+ partitions := make(map[string]interface{}, len(cCfg.Partitions))
+ for key, value := range cCfg.Partitions {
+ partitions[key] = value.AsMapInterface()
}
+ initialMP[utils.PartitionsCfg] = partitions
if cCfg.ReplicationConns != nil {
- replicationConns := make([]string, len(cCfg.ReplicationConns))
- for i, item := range cCfg.ReplicationConns {
- replicationConns[i] = item
- }
- initialMP[utils.RplConnsCfg] = replicationConns
+ initialMP[utils.RplConnsCfg] = cCfg.ReplicationConns
}
return
}
// Clone returns a deep copy of CacheCfg
func (cCfg CacheCfg) Clone() (cln *CacheCfg) {
- cln = new(CacheCfg)
- if cCfg.Partitions != nil {
- cln.Partitions = make(map[string]*CacheParamCfg)
- for key, par := range cCfg.Partitions {
- cln.Partitions[key] = par.Clone()
- }
+ cln = &CacheCfg{
+ Partitions: make(map[string]*CacheParamCfg),
+ }
+ for key, par := range cCfg.Partitions {
+ cln.Partitions[key] = par.Clone()
}
if cCfg.ReplicationConns != nil {
cln.ReplicationConns = make([]string, len(cCfg.ReplicationConns))
diff --git a/config/cdrscfg.go b/config/cdrscfg.go
index b4f9ed284..98087b22e 100644
--- a/config/cdrscfg.go
+++ b/config/cdrscfg.go
@@ -19,11 +19,10 @@ along with this program. If not, see
package config
import (
- "strings"
-
"github.com/cgrates/cgrates/utils"
)
+// CdrsCfg is the CDR server
type CdrsCfg struct {
Enabled bool // Enable CDR Server service
ExtraFields RSRParsers // Extra fields to store in CDRs
@@ -39,8 +38,8 @@ type CdrsCfg struct {
EEsConns []string
}
-//loadFromJsonCfg loads Cdrs config from JsonCfg
-func (cdrscfg *CdrsCfg) loadFromJsonCfg(jsnCdrsCfg *CdrsJsonCfg) (err error) {
+// loadFromJSONCfg loads Cdrs config from JsonCfg
+func (cdrscfg *CdrsCfg) loadFromJSONCfg(jsnCdrsCfg *CdrsJsonCfg) (err error) {
if jsnCdrsCfg == nil {
return nil
}
@@ -62,10 +61,9 @@ func (cdrscfg *CdrsCfg) loadFromJsonCfg(jsnCdrsCfg *CdrsJsonCfg) (err error) {
cdrscfg.ChargerSConns = make([]string, len(*jsnCdrsCfg.Chargers_conns))
for idx, connID := range *jsnCdrsCfg.Chargers_conns {
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
+ cdrscfg.ChargerSConns[idx] = connID
if connID == utils.MetaInternal {
cdrscfg.ChargerSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaChargers)
- } else {
- cdrscfg.ChargerSConns[idx] = connID
}
}
}
@@ -73,10 +71,9 @@ func (cdrscfg *CdrsCfg) loadFromJsonCfg(jsnCdrsCfg *CdrsJsonCfg) (err error) {
cdrscfg.RaterConns = make([]string, len(*jsnCdrsCfg.Rals_conns))
for idx, connID := range *jsnCdrsCfg.Rals_conns {
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
+ cdrscfg.RaterConns[idx] = connID
if connID == utils.MetaInternal {
cdrscfg.RaterConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaResponder)
- } else {
- cdrscfg.RaterConns[idx] = connID
}
}
}
@@ -84,10 +81,9 @@ func (cdrscfg *CdrsCfg) loadFromJsonCfg(jsnCdrsCfg *CdrsJsonCfg) (err error) {
cdrscfg.AttributeSConns = make([]string, len(*jsnCdrsCfg.Attributes_conns))
for idx, connID := range *jsnCdrsCfg.Attributes_conns {
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
+ cdrscfg.AttributeSConns[idx] = connID
if connID == utils.MetaInternal {
cdrscfg.AttributeSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAttributes)
- } else {
- cdrscfg.AttributeSConns[idx] = connID
}
}
}
@@ -95,10 +91,9 @@ func (cdrscfg *CdrsCfg) loadFromJsonCfg(jsnCdrsCfg *CdrsJsonCfg) (err error) {
cdrscfg.ThresholdSConns = make([]string, len(*jsnCdrsCfg.Thresholds_conns))
for idx, connID := range *jsnCdrsCfg.Thresholds_conns {
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
+ cdrscfg.ThresholdSConns[idx] = connID
if connID == utils.MetaInternal {
cdrscfg.ThresholdSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds)
- } else {
- cdrscfg.ThresholdSConns[idx] = connID
}
}
}
@@ -106,10 +101,9 @@ func (cdrscfg *CdrsCfg) loadFromJsonCfg(jsnCdrsCfg *CdrsJsonCfg) (err error) {
cdrscfg.StatSConns = make([]string, len(*jsnCdrsCfg.Stats_conns))
for idx, connID := range *jsnCdrsCfg.Stats_conns {
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
+ cdrscfg.StatSConns[idx] = connID
if connID == utils.MetaInternal {
cdrscfg.StatSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStatS)
- } else {
- cdrscfg.StatSConns[idx] = connID
}
}
}
@@ -122,10 +116,9 @@ func (cdrscfg *CdrsCfg) loadFromJsonCfg(jsnCdrsCfg *CdrsJsonCfg) (err error) {
cdrscfg.SchedulerConns = make([]string, len(*jsnCdrsCfg.Scheduler_conns))
for idx, connID := range *jsnCdrsCfg.Scheduler_conns {
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
+ cdrscfg.SchedulerConns[idx] = connID
if connID == utils.MetaInternal {
cdrscfg.SchedulerConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaScheduler)
- } else {
- cdrscfg.SchedulerConns[idx] = connID
}
}
}
@@ -134,16 +127,16 @@ func (cdrscfg *CdrsCfg) loadFromJsonCfg(jsnCdrsCfg *CdrsJsonCfg) (err error) {
cdrscfg.EEsConns = make([]string, len(*jsnCdrsCfg.Ees_conns))
for idx, connID := range *jsnCdrsCfg.Ees_conns {
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
+ cdrscfg.EEsConns[idx] = connID
if connID == utils.MetaInternal {
cdrscfg.EEsConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaEEs)
- } else {
- cdrscfg.EEsConns[idx] = connID
}
}
}
return nil
}
+// AsMapInterface returns the config as a map[string]interface{}
func (cdrscfg *CdrsCfg) AsMapInterface() (initialMP map[string]interface{}) {
initialMP = map[string]interface{}{
utils.EnabledCfg: cdrscfg.Enabled,
@@ -166,10 +159,9 @@ func (cdrscfg *CdrsCfg) AsMapInterface() (initialMP map[string]interface{}) {
if cdrscfg.ChargerSConns != nil {
chargerSConns := make([]string, len(cdrscfg.ChargerSConns))
for i, item := range cdrscfg.ChargerSConns {
+ chargerSConns[i] = item
if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaChargers) {
- chargerSConns[i] = strings.TrimSuffix(item, utils.CONCATENATED_KEY_SEP+utils.MetaChargers)
- } else {
- chargerSConns[i] = item
+ chargerSConns[i] = utils.MetaInternal
}
}
initialMP[utils.ChargerSConnsCfg] = chargerSConns
@@ -177,10 +169,9 @@ func (cdrscfg *CdrsCfg) AsMapInterface() (initialMP map[string]interface{}) {
if cdrscfg.RaterConns != nil {
raterConns := make([]string, len(cdrscfg.RaterConns))
for i, item := range cdrscfg.RaterConns {
+ raterConns[i] = item
if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaResponder) {
- raterConns[i] = strings.TrimSuffix(item, utils.CONCATENATED_KEY_SEP+utils.MetaResponder)
- } else {
- raterConns[i] = item
+ raterConns[i] = utils.MetaInternal
}
}
initialMP[utils.RALsConnsCfg] = raterConns
@@ -188,10 +179,9 @@ func (cdrscfg *CdrsCfg) AsMapInterface() (initialMP map[string]interface{}) {
if cdrscfg.AttributeSConns != nil {
attributeSConns := make([]string, len(cdrscfg.AttributeSConns))
for i, item := range cdrscfg.AttributeSConns {
+ attributeSConns[i] = item
if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAttributes) {
- attributeSConns[i] = strings.TrimSuffix(item, utils.CONCATENATED_KEY_SEP+utils.MetaAttributes)
- } else {
- attributeSConns[i] = item
+ attributeSConns[i] = utils.MetaInternal
}
}
initialMP[utils.AttributeSConnsCfg] = attributeSConns
@@ -199,10 +189,9 @@ func (cdrscfg *CdrsCfg) AsMapInterface() (initialMP map[string]interface{}) {
if cdrscfg.ThresholdSConns != nil {
thresholdSConns := make([]string, len(cdrscfg.ThresholdSConns))
for i, item := range cdrscfg.ThresholdSConns {
+ thresholdSConns[i] = item
if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds) {
- thresholdSConns[i] = strings.TrimSuffix(item, utils.CONCATENATED_KEY_SEP+utils.MetaThresholds)
- } else {
- thresholdSConns[i] = item
+ thresholdSConns[i] = utils.MetaInternal
}
}
initialMP[utils.ThresholdSConnsCfg] = thresholdSConns
@@ -210,10 +199,9 @@ func (cdrscfg *CdrsCfg) AsMapInterface() (initialMP map[string]interface{}) {
if cdrscfg.StatSConns != nil {
statSConns := make([]string, len(cdrscfg.StatSConns))
for i, item := range cdrscfg.StatSConns {
+ statSConns[i] = item
if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStatS) {
- statSConns[i] = strings.TrimSuffix(item, utils.CONCATENATED_KEY_SEP+utils.MetaStatS)
- } else {
- statSConns[i] = item
+ statSConns[i] = utils.MetaInternal
}
}
initialMP[utils.StatSConnsCfg] = statSConns
@@ -221,10 +209,9 @@ func (cdrscfg *CdrsCfg) AsMapInterface() (initialMP map[string]interface{}) {
if cdrscfg.SchedulerConns != nil {
schedulerConns := make([]string, len(cdrscfg.SchedulerConns))
for i, item := range cdrscfg.SchedulerConns {
+ schedulerConns[i] = item
if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaScheduler) {
- schedulerConns[i] = strings.TrimSuffix(item, utils.CONCATENATED_KEY_SEP+utils.MetaScheduler)
- } else {
- schedulerConns[i] = item
+ schedulerConns[i] = utils.MetaInternal
}
}
initialMP[utils.SchedulerConnsCfg] = schedulerConns
@@ -232,13 +219,72 @@ func (cdrscfg *CdrsCfg) AsMapInterface() (initialMP map[string]interface{}) {
if cdrscfg.EEsConns != nil {
eesConns := make([]string, len(cdrscfg.EEsConns))
for i, item := range cdrscfg.EEsConns {
+ eesConns[i] = item
if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaEEs) {
- eesConns[i] = strings.TrimSuffix(item, utils.CONCATENATED_KEY_SEP+utils.MetaEEs)
- } else {
- eesConns[i] = item
+ eesConns[i] = utils.MetaInternal
}
}
initialMP[utils.EEsConnsCfg] = eesConns
}
return
}
+
+// Clone returns a deep copy of CdrsCfg
+func (cdrscfg CdrsCfg) Clone() (cln *CdrsCfg) {
+ cln = &CdrsCfg{
+ Enabled: cdrscfg.Enabled,
+ ExtraFields: cdrscfg.ExtraFields.Clone(),
+ StoreCdrs: cdrscfg.StoreCdrs,
+ SMCostRetries: cdrscfg.SMCostRetries,
+ }
+ if cdrscfg.ChargerSConns != nil {
+ cln.ChargerSConns = make([]string, len(cdrscfg.ChargerSConns))
+ for i, con := range cdrscfg.ChargerSConns {
+ cln.ChargerSConns[i] = con
+ }
+ }
+ if cdrscfg.RaterConns != nil {
+ cln.RaterConns = make([]string, len(cdrscfg.RaterConns))
+ for i, con := range cdrscfg.RaterConns {
+ cln.RaterConns[i] = con
+ }
+ }
+ if cdrscfg.AttributeSConns != nil {
+ cln.AttributeSConns = make([]string, len(cdrscfg.AttributeSConns))
+ for i, con := range cdrscfg.AttributeSConns {
+ cln.AttributeSConns[i] = con
+ }
+ }
+ if cdrscfg.ThresholdSConns != nil {
+ cln.ThresholdSConns = make([]string, len(cdrscfg.ThresholdSConns))
+ for i, con := range cdrscfg.ThresholdSConns {
+ cln.ThresholdSConns[i] = con
+ }
+ }
+ if cdrscfg.StatSConns != nil {
+ cln.StatSConns = make([]string, len(cdrscfg.StatSConns))
+ for i, con := range cdrscfg.StatSConns {
+ cln.StatSConns[i] = con
+ }
+ }
+ if cdrscfg.OnlineCDRExports != nil {
+ cln.OnlineCDRExports = make([]string, len(cdrscfg.OnlineCDRExports))
+ for i, con := range cdrscfg.OnlineCDRExports {
+ cln.OnlineCDRExports[i] = con
+ }
+ }
+ if cdrscfg.SchedulerConns != nil {
+ cln.SchedulerConns = make([]string, len(cdrscfg.SchedulerConns))
+ for i, con := range cdrscfg.SchedulerConns {
+ cln.SchedulerConns[i] = con
+ }
+ }
+ if cdrscfg.EEsConns != nil {
+ cln.EEsConns = make([]string, len(cdrscfg.EEsConns))
+ for i, con := range cdrscfg.EEsConns {
+ cln.EEsConns[i] = con
+ }
+ }
+
+ return
+}
diff --git a/config/cdrscfg_test.go b/config/cdrscfg_test.go
index 7d73e02f6..7ebab2caf 100644
--- a/config/cdrscfg_test.go
+++ b/config/cdrscfg_test.go
@@ -54,7 +54,7 @@ func TestCdrsCfgloadFromJsonCfg(t *testing.T) {
}
if jsnCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = jsnCfg.cdrsCfg.loadFromJsonCfg(jsonCfg); err != nil {
+ } else if err = jsnCfg.cdrsCfg.loadFromJSONCfg(jsonCfg); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(expected, jsnCfg.cdrsCfg) {
t.Errorf("Expected %+v \n, received %+v", utils.ToJSON(expected), utils.ToJSON(jsnCfg.cdrsCfg))
@@ -68,7 +68,7 @@ func TestExtraFieldsinloadFromJsonCfg(t *testing.T) {
expectedErrMessage := "emtpy RSRParser in rule: <>"
if jsonCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = jsonCfg.cdrsCfg.loadFromJsonCfg(cfgJSON); err == nil || err.Error() != expectedErrMessage {
+ } else if err = jsonCfg.cdrsCfg.loadFromJSONCfg(cfgJSON); err == nil || err.Error() != expectedErrMessage {
t.Errorf("Expected %+v, received %+v", expectedErrMessage, err)
}
}
@@ -140,3 +140,49 @@ func TestCdrsCfgAsMapInterface2(t *testing.T) {
t.Errorf("Expected %+v \n, recieved %+v", eMap, rcv)
}
}
+
+func TestCdrsCfgClone(t *testing.T) {
+ ban := &CdrsCfg{
+ Enabled: true,
+ StoreCdrs: true,
+ SMCostRetries: 1,
+ ChargerSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaChargers), "*conn1"},
+ RaterConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaResponder), "*conn1"},
+ AttributeSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAttributes), "*conn1"},
+ ThresholdSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds), "*conn1"},
+ StatSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStats), "*conn1"},
+ SchedulerConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaScheduler), "*conn1"},
+ EEsConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaEEs), "*conn1"},
+ OnlineCDRExports: []string{"randomVal"},
+ ExtraFields: RSRParsers{},
+ }
+ rcv := ban.Clone()
+ if !reflect.DeepEqual(ban, rcv) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(ban), utils.ToJSON(rcv))
+ }
+ if rcv.ChargerSConns[1] = ""; ban.ChargerSConns[1] != "*conn1" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+ if rcv.RaterConns[1] = ""; ban.RaterConns[1] != "*conn1" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+ if rcv.AttributeSConns[1] = ""; ban.AttributeSConns[1] != "*conn1" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+ if rcv.ThresholdSConns[1] = ""; ban.ThresholdSConns[1] != "*conn1" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+ if rcv.StatSConns[1] = ""; ban.StatSConns[1] != "*conn1" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+ if rcv.SchedulerConns[1] = ""; ban.SchedulerConns[1] != "*conn1" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+ if rcv.EEsConns[1] = ""; ban.EEsConns[1] != "*conn1" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+
+ if rcv.OnlineCDRExports[0] = ""; ban.OnlineCDRExports[0] != "randomVal" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+}
diff --git a/config/config.go b/config/config.go
index 7b7595a63..764214439 100644
--- a/config/config.go
+++ b/config/config.go
@@ -147,7 +147,7 @@ func NewDefaultCGRConfig() (cfg *CGRConfig, err error) {
cfg.storDbCfg = new(StorDbCfg)
cfg.storDbCfg.Items = make(map[string]*ItemOpt)
cfg.storDbCfg.Opts = make(map[string]interface{})
- cfg.tlsCfg = new(TlsCfg)
+ cfg.tlsCfg = new(TLSCfg)
cfg.cacheCfg = new(CacheCfg)
cfg.cacheCfg.Partitions = make(map[string]*CacheParamCfg)
cfg.listenCfg = new(ListenCfg)
@@ -282,18 +282,18 @@ type CGRConfig struct {
dfltEvExp *EventExporterCfg // default event exporter
loaderCfg LoaderSCfgs // LoaderS configs
- httpAgentCfg HttpAgentCfgs // HttpAgent configs
+ httpAgentCfg HTTPAgentCfgs // HttpAgent configs
rldChans map[string]chan struct{} // index here the channels used for reloads
- rpcConns RpcConns
+ rpcConns RPCConns
templates FcTemplates
generalCfg *GeneralCfg // General config
dataDbCfg *DataDbCfg // Database config
storDbCfg *StorDbCfg // StroreDb config
- tlsCfg *TlsCfg // TLS config
+ tlsCfg *TLSCfg // TLS config
cacheCfg *CacheCfg // Cache config
listenCfg *ListenCfg // Listen config
httpCfg *HTTPCfg // HTTP config
@@ -420,7 +420,7 @@ func (cfg *CGRConfig) loadRPCConns(jsnCfg *CgrJsonCfg) (err error) {
}
for key, val := range jsnRPCConns {
cfg.rpcConns[key] = NewDfltRPCConn()
- cfg.rpcConns[key].loadFromJsonCfg(val)
+ cfg.rpcConns[key].loadFromJSONCfg(val)
}
return
}
@@ -431,7 +431,7 @@ func (cfg *CGRConfig) loadGeneralCfg(jsnCfg *CgrJsonCfg) (err error) {
if jsnGeneralCfg, err = jsnCfg.GeneralJsonCfg(); err != nil {
return
}
- return cfg.generalCfg.loadFromJsonCfg(jsnGeneralCfg)
+ return cfg.generalCfg.loadFromJSONCfg(jsnGeneralCfg)
}
// loadCacheCfg loads the Cache section of the configuration
@@ -449,7 +449,7 @@ func (cfg *CGRConfig) loadListenCfg(jsnCfg *CgrJsonCfg) (err error) {
if jsnListenCfg, err = jsnCfg.ListenJsonCfg(); err != nil {
return
}
- return cfg.listenCfg.loadFromJsonCfg(jsnListenCfg)
+ return cfg.listenCfg.loadFromJSONCfg(jsnListenCfg)
}
// loadHTTPCfg loads the Http section of the configuration
@@ -458,7 +458,7 @@ func (cfg *CGRConfig) loadHTTPCfg(jsnCfg *CgrJsonCfg) (err error) {
if jsnHTTPCfg, err = jsnCfg.HttpJsonCfg(); err != nil {
return
}
- return cfg.httpCfg.loadFromJsonCfg(jsnHTTPCfg)
+ return cfg.httpCfg.loadFromJSONCfg(jsnHTTPCfg)
}
// loadDataDBCfg loads the DataDB section of the configuration
@@ -467,7 +467,7 @@ func (cfg *CGRConfig) loadDataDBCfg(jsnCfg *CgrJsonCfg) (err error) {
if jsnDataDbCfg, err = jsnCfg.DbJsonCfg(DATADB_JSN); err != nil {
return
}
- if err = cfg.dataDbCfg.loadFromJsonCfg(jsnDataDbCfg); err != nil {
+ if err = cfg.dataDbCfg.loadFromJSONCfg(jsnDataDbCfg); err != nil {
return
}
return
@@ -480,7 +480,7 @@ func (cfg *CGRConfig) loadStorDBCfg(jsnCfg *CgrJsonCfg) (err error) {
if jsnDataDbCfg, err = jsnCfg.DbJsonCfg(STORDB_JSN); err != nil {
return
}
- return cfg.storDbCfg.loadFromJsonCfg(jsnDataDbCfg)
+ return cfg.storDbCfg.loadFromJSONCfg(jsnDataDbCfg)
}
// loadFilterSCfg loads the FilterS section of the configuration
@@ -489,7 +489,7 @@ func (cfg *CGRConfig) loadFilterSCfg(jsnCfg *CgrJsonCfg) (err error) {
if jsnFilterSCfg, err = jsnCfg.FilterSJsonCfg(); err != nil {
return
}
- return cfg.filterSCfg.loadFromJsonCfg(jsnFilterSCfg)
+ return cfg.filterSCfg.loadFromJSONCfg(jsnFilterSCfg)
}
// loadRalSCfg loads the RalS section of the configuration
@@ -498,7 +498,7 @@ func (cfg *CGRConfig) loadRalSCfg(jsnCfg *CgrJsonCfg) (err error) {
if jsnRALsCfg, err = jsnCfg.RalsJsonCfg(); err != nil {
return
}
- return cfg.ralsCfg.loadFromJsonCfg(jsnRALsCfg)
+ return cfg.ralsCfg.loadFromJSONCfg(jsnRALsCfg)
}
// loadSchedulerCfg loads the Scheduler section of the configuration
@@ -516,7 +516,7 @@ func (cfg *CGRConfig) loadCdrsCfg(jsnCfg *CgrJsonCfg) (err error) {
if jsnCdrsCfg, err = jsnCfg.CdrsJsonCfg(); err != nil {
return
}
- return cfg.cdrsCfg.loadFromJsonCfg(jsnCdrsCfg)
+ return cfg.cdrsCfg.loadFromJSONCfg(jsnCdrsCfg)
}
// loadSessionSCfg loads the SessionS section of the configuration
@@ -525,7 +525,7 @@ func (cfg *CGRConfig) loadSessionSCfg(jsnCfg *CgrJsonCfg) (err error) {
if jsnSessionSCfg, err = jsnCfg.SessionSJsonCfg(); err != nil {
return
}
- return cfg.sessionSCfg.loadFromJsonCfg(jsnSessionSCfg)
+ return cfg.sessionSCfg.loadFromJSONCfg(jsnSessionSCfg)
}
// loadFreeswitchAgentCfg loads the FreeswitchAgent section of the configuration
@@ -534,7 +534,7 @@ func (cfg *CGRConfig) loadFreeswitchAgentCfg(jsnCfg *CgrJsonCfg) (err error) {
if jsnSmFsCfg, err = jsnCfg.FreeswitchAgentJsonCfg(); err != nil {
return
}
- return cfg.fsAgentCfg.loadFromJsonCfg(jsnSmFsCfg)
+ return cfg.fsAgentCfg.loadFromJSONCfg(jsnSmFsCfg)
}
// loadKamAgentCfg loads the KamAgent section of the configuration
@@ -543,7 +543,7 @@ func (cfg *CGRConfig) loadKamAgentCfg(jsnCfg *CgrJsonCfg) (err error) {
if jsnKamAgentCfg, err = jsnCfg.KamAgentJsonCfg(); err != nil {
return
}
- return cfg.kamAgentCfg.loadFromJsonCfg(jsnKamAgentCfg)
+ return cfg.kamAgentCfg.loadFromJSONCfg(jsnKamAgentCfg)
}
// loadAsteriskAgentCfg loads the AsteriskAgent section of the configuration
@@ -552,7 +552,7 @@ func (cfg *CGRConfig) loadAsteriskAgentCfg(jsnCfg *CgrJsonCfg) (err error) {
if jsnSMAstCfg, err = jsnCfg.AsteriskAgentJsonCfg(); err != nil {
return
}
- return cfg.asteriskAgentCfg.loadFromJsonCfg(jsnSMAstCfg)
+ return cfg.asteriskAgentCfg.loadFromJSONCfg(jsnSMAstCfg)
}
// loadDiameterAgentCfg loads the DiameterAgent section of the configuration
@@ -561,7 +561,7 @@ func (cfg *CGRConfig) loadDiameterAgentCfg(jsnCfg *CgrJsonCfg) (err error) {
if jsnDACfg, err = jsnCfg.DiameterAgentJsonCfg(); err != nil {
return
}
- return cfg.diameterAgentCfg.loadFromJsonCfg(jsnDACfg, cfg.generalCfg.RSRSep)
+ return cfg.diameterAgentCfg.loadFromJSONCfg(jsnDACfg, cfg.generalCfg.RSRSep)
}
// loadRadiusAgentCfg loads the RadiusAgent section of the configuration
@@ -570,7 +570,7 @@ func (cfg *CGRConfig) loadRadiusAgentCfg(jsnCfg *CgrJsonCfg) (err error) {
if jsnRACfg, err = jsnCfg.RadiusAgentJsonCfg(); err != nil {
return
}
- return cfg.radiusAgentCfg.loadFromJsonCfg(jsnRACfg, cfg.generalCfg.RSRSep)
+ return cfg.radiusAgentCfg.loadFromJSONCfg(jsnRACfg, cfg.generalCfg.RSRSep)
}
// loadDNSAgentCfg loads the DNSAgent section of the configuration
@@ -588,7 +588,7 @@ func (cfg *CGRConfig) loadHTTPAgentCfg(jsnCfg *CgrJsonCfg) (err error) {
if jsnHTTPAgntCfg, err = jsnCfg.HttpAgentJsonCfg(); err != nil {
return
}
- return cfg.httpAgentCfg.loadFromJsonCfg(jsnHTTPAgntCfg, cfg.generalCfg.RSRSep)
+ return cfg.httpAgentCfg.loadFromJSONCfg(jsnHTTPAgntCfg, cfg.generalCfg.RSRSep)
}
// loadAttributeSCfg loads the AttributeS section of the configuration
@@ -655,7 +655,7 @@ func (cfg *CGRConfig) loadLoaderSCfg(jsnCfg *CgrJsonCfg) (err error) {
// cfg.loaderCfg = make(LoaderSCfgs, len(jsnLoaderCfg))
for _, profile := range jsnLoaderCfg {
loadSCfgp := NewDfltLoaderSCfg()
- if err = loadSCfgp.loadFromJsonCfg(profile, cfg.templates, cfg.generalCfg.RSRSep); err != nil {
+ if err = loadSCfgp.loadFromJSONCfg(profile, cfg.templates, cfg.generalCfg.RSRSep); err != nil {
return
}
cfg.loaderCfg = append(cfg.loaderCfg, loadSCfgp) // use apend so the loaderS profile to be loaded from multiple files
@@ -724,7 +724,7 @@ func (cfg *CGRConfig) loadTLSCgrCfg(jsnCfg *CgrJsonCfg) (err error) {
if jsnTLSCgrCfg, err = jsnCfg.TlsCfgJson(); err != nil {
return
}
- return cfg.tlsCfg.loadFromJsonCfg(jsnTLSCgrCfg)
+ return cfg.tlsCfg.loadFromJSONCfg(jsnTLSCgrCfg)
}
// loadAnalyzerCgrCfg loads the Analyzer section of the configuration
@@ -922,7 +922,7 @@ func (cfg *CGRConfig) AsteriskAgentCfg() *AsteriskAgentCfg {
}
// HTTPAgentCfg returns the config for HttpAgent
-func (cfg *CGRConfig) HTTPAgentCfg() HttpAgentCfgs {
+func (cfg *CGRConfig) HTTPAgentCfg() HTTPAgentCfgs {
cfg.lks[HttpAgentJson].Lock()
defer cfg.lks[HttpAgentJson].Unlock()
return cfg.httpAgentCfg
@@ -1006,7 +1006,7 @@ func (cfg *CGRConfig) GeneralCfg() *GeneralCfg {
}
// TLSCfg returns the config for Tls
-func (cfg *CGRConfig) TLSCfg() *TlsCfg {
+func (cfg *CGRConfig) TLSCfg() *TLSCfg {
cfg.lks[TlsCfgJson].Lock()
defer cfg.lks[TlsCfgJson].Unlock()
return cfg.tlsCfg
@@ -1095,7 +1095,7 @@ func (cfg *CGRConfig) SIPAgentCfg() *SIPAgentCfg {
}
// RPCConns reads the RPCConns configuration
-func (cfg *CGRConfig) RPCConns() RpcConns {
+func (cfg *CGRConfig) RPCConns() RPCConns {
cfg.lks[RPCConnsJsonName].RLock()
defer cfg.lks[RPCConnsJsonName].RUnlock()
return cfg.rpcConns
@@ -1249,7 +1249,7 @@ func (cfg *CGRConfig) loadCfgWithLocks(path, section string) (err error) {
func (*CGRConfig) loadConfigFromReader(rdr io.Reader, loadFuncs []func(jsnCfg *CgrJsonCfg) error, envOff bool) (err error) {
jsnCfg := new(CgrJsonCfg)
- var rjr *rjReader
+ var rjr *RjReader
if rjr, err = NewRjReader(rdr); err != nil {
return
}
@@ -1856,3 +1856,59 @@ func (cfg *CGRConfig) V1SetConfigFromJSON(args *SetConfigFromJSONArgs, reply *st
*reply = utils.OK
return
}
+
+// Clone returns a deep copy of CGRConfig
+func (cfg CGRConfig) Clone() (cln *CGRConfig) {
+ cln = &CGRConfig{
+ DataFolderPath: cfg.DataFolderPath,
+ ConfigPath: cfg.ConfigPath,
+
+ dfltEvRdr: cfg.dfltEvRdr.Clone(),
+ dfltEvExp: cfg.dfltEvExp.Clone(),
+ loaderCfg: cfg.loaderCfg.Clone(),
+ httpAgentCfg: cfg.httpAgentCfg.Clone(),
+ rpcConns: cfg.rpcConns.Clone(),
+ templates: cfg.templates.Clone(),
+ generalCfg: cfg.generalCfg.Clone(),
+ dataDbCfg: cfg.dataDbCfg.Clone(),
+ storDbCfg: cfg.storDbCfg.Clone(),
+ tlsCfg: cfg.tlsCfg.Clone(),
+ cacheCfg: cfg.cacheCfg.Clone(),
+ listenCfg: cfg.listenCfg.Clone(),
+ httpCfg: cfg.httpCfg.Clone(),
+ filterSCfg: cfg.filterSCfg.Clone(),
+ ralsCfg: cfg.ralsCfg.Clone(),
+ schedulerCfg: cfg.schedulerCfg.Clone(),
+ cdrsCfg: cfg.cdrsCfg.Clone(),
+ sessionSCfg: cfg.sessionSCfg.Clone(),
+ fsAgentCfg: cfg.fsAgentCfg.Clone(),
+ kamAgentCfg: cfg.kamAgentCfg.Clone(),
+ asteriskAgentCfg: cfg.asteriskAgentCfg.Clone(),
+ diameterAgentCfg: cfg.diameterAgentCfg.Clone(),
+ radiusAgentCfg: cfg.radiusAgentCfg.Clone(),
+ dnsAgentCfg: cfg.dnsAgentCfg.Clone(),
+ attributeSCfg: cfg.attributeSCfg.Clone(),
+ chargerSCfg: cfg.chargerSCfg.Clone(),
+ resourceSCfg: cfg.resourceSCfg.Clone(),
+ statsCfg: cfg.statsCfg.Clone(),
+ thresholdSCfg: cfg.thresholdSCfg.Clone(),
+ routeSCfg: cfg.routeSCfg.Clone(),
+ sureTaxCfg: cfg.sureTaxCfg.Clone(),
+ dispatcherSCfg: cfg.dispatcherSCfg.Clone(),
+ dispatcherHCfg: cfg.dispatcherHCfg.Clone(),
+ loaderCgrCfg: cfg.loaderCgrCfg.Clone(),
+ migratorCgrCfg: cfg.migratorCgrCfg.Clone(),
+ mailerCfg: cfg.mailerCfg.Clone(),
+ analyzerSCfg: cfg.analyzerSCfg.Clone(),
+ apier: cfg.apier.Clone(),
+ ersCfg: cfg.ersCfg.Clone(),
+ eesCfg: cfg.eesCfg.Clone(),
+ rateSCfg: cfg.rateSCfg.Clone(),
+ sipAgentCfg: cfg.sipAgentCfg.Clone(),
+ configSCfg: cfg.configSCfg.Clone(),
+ apiBanCfg: cfg.apiBanCfg.Clone(),
+ coreSCfg: cfg.coreSCfg.Clone(),
+ }
+ cln.initChanels()
+ return
+}
diff --git a/config/config_it_test.go b/config/config_it_test.go
index 47047b321..3aa96dfa5 100644
--- a/config/config_it_test.go
+++ b/config/config_it_test.go
@@ -471,7 +471,7 @@ func testCGRConfigReloadSessionS(t *testing.T) {
CDRsConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCDRs)},
ReplicationConns: []string{},
- SessionIndexes: utils.NewStringMap(),
+ SessionIndexes: utils.StringSet{},
ClientProtocol: 1,
TerminateAttempts: 5,
AlterableFields: utils.NewStringSet([]string{}),
@@ -845,7 +845,7 @@ func testCGRConfigReloadConfigFromJSONSessionS(t *testing.T) {
CDRsConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCDRs)},
ReplicationConns: []string{},
- SessionIndexes: utils.NewStringMap(),
+ SessionIndexes: utils.StringSet{},
ClientProtocol: 1,
TerminateAttempts: 5,
AlterableFields: utils.NewStringSet([]string{}),
@@ -897,7 +897,7 @@ func testCGRConfigReloadConfigFromStringSessionS(t *testing.T) {
CDRsConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCDRs)},
ReplicationConns: []string{},
- SessionIndexes: utils.NewStringMap(),
+ SessionIndexes: utils.StringSet{},
ClientProtocol: 1,
TerminateAttempts: 5,
AlterableFields: utils.NewStringSet([]string{}),
@@ -951,7 +951,7 @@ func testCGRConfigReloadAll(t *testing.T) {
CDRsConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCDRs)},
ReplicationConns: []string{},
- SessionIndexes: utils.NewStringMap(),
+ SessionIndexes: utils.StringSet{},
ClientProtocol: 1,
TerminateAttempts: 5,
AlterableFields: utils.NewStringSet([]string{}),
diff --git a/config/config_test.go b/config/config_test.go
index 143eecbdc..737da9aec 100644
--- a/config/config_test.go
+++ b/config/config_test.go
@@ -205,10 +205,10 @@ func TestHttpAgentCfg(t *testing.T) {
}
`
eCgrCfg, _ := NewDefaultCGRConfig()
- eCgrCfg.httpAgentCfg = []*HttpAgentCfg{
+ eCgrCfg.httpAgentCfg = []*HTTPAgentCfg{
{
ID: "conecto1",
- Url: "/conecto",
+ URL: "/conecto",
RequestPayload: utils.MetaUrl,
ReplyPayload: utils.MetaXml,
SessionSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS)},
@@ -480,7 +480,7 @@ func TestCgrCfgJSONDefaultsSMGenericCfg(t *testing.T) {
DebitInterval: 0,
StoreSCosts: false,
SessionTTL: 0,
- SessionIndexes: utils.StringMap{},
+ SessionIndexes: utils.StringSet{},
ClientProtocol: 1.0,
ChannelSyncInterval: 0,
TerminateAttempts: 5,
@@ -810,7 +810,7 @@ func TestCgrCfgJSONDefaultsDiameterAgentCfg(t *testing.T) {
SessionSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS)},
OriginHost: "CGR-DA",
OriginRealm: "cgrates.org",
- VendorId: 0,
+ VendorID: 0,
ProductName: "CGRateS",
ConcurrentReqs: -1,
RequestProcessors: nil,
@@ -834,8 +834,8 @@ func TestCgrCfgJSONDefaultsDiameterAgentCfg(t *testing.T) {
if !reflect.DeepEqual(cgrCfg.diameterAgentCfg.OriginRealm, testDA.OriginRealm) {
t.Errorf("received: %+v, expecting: %+v", cgrCfg.diameterAgentCfg.OriginRealm, testDA.OriginRealm)
}
- if !reflect.DeepEqual(cgrCfg.diameterAgentCfg.VendorId, testDA.VendorId) {
- t.Errorf("received: %+v, expecting: %+v", cgrCfg.diameterAgentCfg.VendorId, testDA.VendorId)
+ if !reflect.DeepEqual(cgrCfg.diameterAgentCfg.VendorID, testDA.VendorID) {
+ t.Errorf("received: %+v, expecting: %+v", cgrCfg.diameterAgentCfg.VendorID, testDA.VendorID)
}
if !reflect.DeepEqual(cgrCfg.diameterAgentCfg.ProductName, testDA.ProductName) {
t.Errorf("received: %+v, expecting: %+v", cgrCfg.diameterAgentCfg.ProductName, testDA.ProductName)
@@ -1941,7 +1941,7 @@ func TestDiameterAgentConfig(t *testing.T) {
SessionSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS)},
OriginHost: "CGR-DA",
OriginRealm: "cgrates.org",
- VendorId: 0,
+ VendorID: 0,
ProductName: "CGRateS",
ConcurrentReqs: -1,
SyncedConnReqs: false,
@@ -2141,7 +2141,7 @@ func TestSessionSConfig(t *testing.T) {
DebitInterval: 0,
StoreSCosts: false,
SessionTTL: 0,
- SessionIndexes: utils.StringMap{},
+ SessionIndexes: utils.StringSet{},
ClientProtocol: 1.0,
ChannelSyncInterval: 0,
TerminateAttempts: 5,
@@ -2261,7 +2261,7 @@ func TestLoaderConfig(t *testing.T) {
expected := LoaderSCfgs{
{
Enabled: false,
- Id: utils.MetaDefault,
+ ID: utils.MetaDefault,
Tenant: ten,
LockFileName: ".cgr.lck",
CacheSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCaches)},
@@ -2476,7 +2476,7 @@ func TestSIPAgentConfig(t *testing.T) {
}
func TestRPCConnsConfig(t *testing.T) {
- expected := RpcConns{
+ expected := RPCConns{
utils.MetaInternal: {
Strategy: utils.MetaFirst,
PoolSize: 0,
@@ -2633,7 +2633,7 @@ func TestRLockAndRUnlock(t *testing.T) {
func TestCgrLoaderCfgITDefaults(t *testing.T) {
eCfg := LoaderSCfgs{
{
- Id: utils.MetaDefault,
+ ID: utils.MetaDefault,
Enabled: false,
DryRun: false,
RunDelay: 0,
@@ -3457,7 +3457,7 @@ func TestCfgTlsCfg(t *testing.T) {
},
}`
eCgrCfg, _ := NewDefaultCGRConfig()
- eCgrCfg.tlsCfg = &TlsCfg{
+ eCgrCfg.tlsCfg = &TLSCfg{
ServerCerificate: "path/To/Server/Cert",
ServerKey: "path/To/Server/Key",
CaCertificate: "path/To/CA/Cert",
@@ -3907,7 +3907,7 @@ func TestV1GetConfigRals(t *testing.T) {
"*mms": "10000",
},
utils.MaxIncrementsCfg: 1000000,
- utils.BalanceRatingSubjectCfg: map[string]interface{}{
+ utils.BalanceRatingSubjectCfg: map[string]string{
"*any": "*zero1ns",
"*voice": "*zero1s",
},
@@ -4136,10 +4136,10 @@ func TestV1GetConfigRadiusAgent(t *testing.T) {
utils.ListenNetCfg: "udp",
utils.ListenAuthCfg: "127.0.0.1:1812",
utils.ListenAcctCfg: "127.0.0.1:1813",
- utils.ClientSecretsCfg: map[string]interface{}{
+ utils.ClientSecretsCfg: map[string]string{
utils.MetaDefault: "CGRateS.org",
},
- utils.ClientDictionariesCfg: map[string]interface{}{
+ utils.ClientDictionariesCfg: map[string]string{
utils.MetaDefault: "/usr/share/cgrates/radius/dict/",
},
utils.SessionSConnsCfg: []string{"*internal"},
@@ -5208,7 +5208,7 @@ func TestV1GetConfigAsJSONDispatcherH(t *testing.T) {
func TestV1GetConfigAsJSONLoaders(t *testing.T) {
var reply string
- expected := `{"loaders":[{"caches_conns":["*internal"],"data":[{"fields":[{"mandatory":true,"path":"Tenant","tag":"TenantID","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ProfileID","type":"*variable","value":"~*req.1"},{"path":"Contexts","tag":"Contexts","type":"*variable","value":"~*req.2"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.3"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.4"},{"path":"AttributeFilterIDs","tag":"AttributeFilterIDs","type":"*variable","value":"~*req.5"},{"path":"Path","tag":"Path","type":"*variable","value":"~*req.6"},{"path":"Type","tag":"Type","type":"*variable","value":"~*req.7"},{"path":"Value","tag":"Value","type":"*variable","value":"~*req.8"},{"path":"Blocker","tag":"Blocker","type":"*variable","value":"~*req.9"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.10"}],"file_name":"Attributes.csv","type":"*attributes"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"Type","tag":"Type","type":"*variable","value":"~*req.2"},{"path":"Element","tag":"Element","type":"*variable","value":"~*req.3"},{"path":"Values","tag":"Values","type":"*variable","value":"~*req.4"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.5"}],"file_name":"Filters.csv","type":"*filters"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.3"},{"path":"UsageTTL","tag":"TTL","type":"*variable","value":"~*req.4"},{"path":"Limit","tag":"Limit","type":"*variable","value":"~*req.5"},{"path":"AllocationMessage","tag":"AllocationMessage","type":"*variable","value":"~*req.6"},{"path":"Blocker","tag":"Blocker","type":"*variable","value":"~*req.7"},{"path":"Stored","tag":"Stored","type":"*variable","value":"~*req.8"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.9"},{"path":"ThresholdIDs","tag":"ThresholdIDs","type":"*variable","value":"~*req.10"}],"file_name":"Resources.csv","type":"*resources"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.3"},{"path":"QueueLength","tag":"QueueLength","type":"*variable","value":"~*req.4"},{"path":"TTL","tag":"TTL","type":"*variable","value":"~*req.5"},{"path":"MinItems","tag":"MinItems","type":"*variable","value":"~*req.6"},{"path":"MetricIDs","tag":"MetricIDs","type":"*variable","value":"~*req.7"},{"path":"MetricFilterIDs","tag":"MetricFilterIDs","type":"*variable","value":"~*req.8"},{"path":"Blocker","tag":"Blocker","type":"*variable","value":"~*req.9"},{"path":"Stored","tag":"Stored","type":"*variable","value":"~*req.10"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.11"},{"path":"ThresholdIDs","tag":"ThresholdIDs","type":"*variable","value":"~*req.12"}],"file_name":"Stats.csv","type":"*stats"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.3"},{"path":"MaxHits","tag":"MaxHits","type":"*variable","value":"~*req.4"},{"path":"MinHits","tag":"MinHits","type":"*variable","value":"~*req.5"},{"path":"MinSleep","tag":"MinSleep","type":"*variable","value":"~*req.6"},{"path":"Blocker","tag":"Blocker","type":"*variable","value":"~*req.7"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.8"},{"path":"ActionIDs","tag":"ActionIDs","type":"*variable","value":"~*req.9"},{"path":"Async","tag":"Async","type":"*variable","value":"~*req.10"}],"file_name":"Thresholds.csv","type":"*thresholds"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.3"},{"path":"Sorting","tag":"Sorting","type":"*variable","value":"~*req.4"},{"path":"SortingParameters","tag":"SortingParameters","type":"*variable","value":"~*req.5"},{"path":"RouteID","tag":"RouteID","type":"*variable","value":"~*req.6"},{"path":"RouteFilterIDs","tag":"RouteFilterIDs","type":"*variable","value":"~*req.7"},{"path":"RouteAccountIDs","tag":"RouteAccountIDs","type":"*variable","value":"~*req.8"},{"path":"RouteRatingPlanIDs","tag":"RouteRatingPlanIDs","type":"*variable","value":"~*req.9"},{"path":"RouteResourceIDs","tag":"RouteResourceIDs","type":"*variable","value":"~*req.10"},{"path":"RouteStatIDs","tag":"RouteStatIDs","type":"*variable","value":"~*req.11"},{"path":"RouteWeight","tag":"RouteWeight","type":"*variable","value":"~*req.12"},{"path":"RouteBlocker","tag":"RouteBlocker","type":"*variable","value":"~*req.13"},{"path":"RouteParameters","tag":"RouteParameters","type":"*variable","value":"~*req.14"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.15"}],"file_name":"Routes.csv","type":"*routes"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.3"},{"path":"RunID","tag":"RunID","type":"*variable","value":"~*req.4"},{"path":"AttributeIDs","tag":"AttributeIDs","type":"*variable","value":"~*req.5"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.6"}],"file_name":"Chargers.csv","type":"*chargers"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"Contexts","tag":"Contexts","type":"*variable","value":"~*req.2"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.3"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.4"},{"path":"Strategy","tag":"Strategy","type":"*variable","value":"~*req.5"},{"path":"StrategyParameters","tag":"StrategyParameters","type":"*variable","value":"~*req.6"},{"path":"ConnID","tag":"ConnID","type":"*variable","value":"~*req.7"},{"path":"ConnFilterIDs","tag":"ConnFilterIDs","type":"*variable","value":"~*req.8"},{"path":"ConnWeight","tag":"ConnWeight","type":"*variable","value":"~*req.9"},{"path":"ConnBlocker","tag":"ConnBlocker","type":"*variable","value":"~*req.10"},{"path":"ConnParameters","tag":"ConnParameters","type":"*variable","value":"~*req.11"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.12"}],"file_name":"DispatcherProfiles.csv","type":"*dispatchers"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"Address","tag":"Address","type":"*variable","value":"~*req.2"},{"path":"Transport","tag":"Transport","type":"*variable","value":"~*req.3"},{"path":"TLS","tag":"TLS","type":"*variable","value":"~*req.4"}],"file_name":"DispatcherHosts.csv","type":"*dispatcher_hosts"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.3"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.4"},{"path":"ConnectFee","tag":"ConnectFee","type":"*variable","value":"~*req.5"},{"path":"RoundingMethod","tag":"RoundingMethod","type":"*variable","value":"~*req.6"},{"path":"RoundingDecimals","tag":"RoundingDecimals","type":"*variable","value":"~*req.7"},{"path":"MinCost","tag":"MinCost","type":"*variable","value":"~*req.8"},{"path":"MaxCost","tag":"MaxCost","type":"*variable","value":"~*req.9"},{"path":"MaxCostStrategy","tag":"MaxCostStrategy","type":"*variable","value":"~*req.10"},{"path":"RateID","tag":"RateID","type":"*variable","value":"~*req.11"},{"path":"RateFilterIDs","tag":"RateFilterIDs","type":"*variable","value":"~*req.12"},{"path":"RateActivationStart","tag":"RateActivationStart","type":"*variable","value":"~*req.13"},{"path":"RateWeight","tag":"RateWeight","type":"*variable","value":"~*req.14"},{"path":"RateBlocker","tag":"RateBlocker","type":"*variable","value":"~*req.15"},{"path":"RateIntervalStart","tag":"RateIntervalStart","type":"*variable","value":"~*req.16"},{"path":"RateValue","tag":"RateValue","type":"*variable","value":"~*req.17"},{"path":"RateUnit","tag":"RateUnit","type":"*variable","value":"~*req.18"},{"path":"RateIncrement","tag":"RateIncrement","type":"*variable","value":"~*req.19"}],"file_name":"RateProfiles.csv","type":"*rate_profiles"}],"dry_run":false,"enabled":false,"field_separator":",","id":"*default","lock_filename":".cgr.lck","run_delay":"0","tenant":"","tp_in_dir":"/var/spool/cgrates/loader/in","tp_out_dir":"/var/spool/cgrates/loader/out"}]}`
+ expected := `{"loaders":[{"caches_conns":["*internal"],"data":[{"fields":[{"mandatory":true,"path":"Tenant","tag":"TenantID","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ProfileID","type":"*variable","value":"~*req.1"},{"path":"Contexts","tag":"Contexts","type":"*variable","value":"~*req.2"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.3"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.4"},{"path":"AttributeFilterIDs","tag":"AttributeFilterIDs","type":"*variable","value":"~*req.5"},{"path":"Path","tag":"Path","type":"*variable","value":"~*req.6"},{"path":"Type","tag":"Type","type":"*variable","value":"~*req.7"},{"path":"Value","tag":"Value","type":"*variable","value":"~*req.8"},{"path":"Blocker","tag":"Blocker","type":"*variable","value":"~*req.9"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.10"}],"file_name":"Attributes.csv","flags":null,"type":"*attributes"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"Type","tag":"Type","type":"*variable","value":"~*req.2"},{"path":"Element","tag":"Element","type":"*variable","value":"~*req.3"},{"path":"Values","tag":"Values","type":"*variable","value":"~*req.4"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.5"}],"file_name":"Filters.csv","flags":null,"type":"*filters"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.3"},{"path":"UsageTTL","tag":"TTL","type":"*variable","value":"~*req.4"},{"path":"Limit","tag":"Limit","type":"*variable","value":"~*req.5"},{"path":"AllocationMessage","tag":"AllocationMessage","type":"*variable","value":"~*req.6"},{"path":"Blocker","tag":"Blocker","type":"*variable","value":"~*req.7"},{"path":"Stored","tag":"Stored","type":"*variable","value":"~*req.8"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.9"},{"path":"ThresholdIDs","tag":"ThresholdIDs","type":"*variable","value":"~*req.10"}],"file_name":"Resources.csv","flags":null,"type":"*resources"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.3"},{"path":"QueueLength","tag":"QueueLength","type":"*variable","value":"~*req.4"},{"path":"TTL","tag":"TTL","type":"*variable","value":"~*req.5"},{"path":"MinItems","tag":"MinItems","type":"*variable","value":"~*req.6"},{"path":"MetricIDs","tag":"MetricIDs","type":"*variable","value":"~*req.7"},{"path":"MetricFilterIDs","tag":"MetricFilterIDs","type":"*variable","value":"~*req.8"},{"path":"Blocker","tag":"Blocker","type":"*variable","value":"~*req.9"},{"path":"Stored","tag":"Stored","type":"*variable","value":"~*req.10"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.11"},{"path":"ThresholdIDs","tag":"ThresholdIDs","type":"*variable","value":"~*req.12"}],"file_name":"Stats.csv","flags":null,"type":"*stats"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.3"},{"path":"MaxHits","tag":"MaxHits","type":"*variable","value":"~*req.4"},{"path":"MinHits","tag":"MinHits","type":"*variable","value":"~*req.5"},{"path":"MinSleep","tag":"MinSleep","type":"*variable","value":"~*req.6"},{"path":"Blocker","tag":"Blocker","type":"*variable","value":"~*req.7"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.8"},{"path":"ActionIDs","tag":"ActionIDs","type":"*variable","value":"~*req.9"},{"path":"Async","tag":"Async","type":"*variable","value":"~*req.10"}],"file_name":"Thresholds.csv","flags":null,"type":"*thresholds"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.3"},{"path":"Sorting","tag":"Sorting","type":"*variable","value":"~*req.4"},{"path":"SortingParameters","tag":"SortingParameters","type":"*variable","value":"~*req.5"},{"path":"RouteID","tag":"RouteID","type":"*variable","value":"~*req.6"},{"path":"RouteFilterIDs","tag":"RouteFilterIDs","type":"*variable","value":"~*req.7"},{"path":"RouteAccountIDs","tag":"RouteAccountIDs","type":"*variable","value":"~*req.8"},{"path":"RouteRatingPlanIDs","tag":"RouteRatingPlanIDs","type":"*variable","value":"~*req.9"},{"path":"RouteResourceIDs","tag":"RouteResourceIDs","type":"*variable","value":"~*req.10"},{"path":"RouteStatIDs","tag":"RouteStatIDs","type":"*variable","value":"~*req.11"},{"path":"RouteWeight","tag":"RouteWeight","type":"*variable","value":"~*req.12"},{"path":"RouteBlocker","tag":"RouteBlocker","type":"*variable","value":"~*req.13"},{"path":"RouteParameters","tag":"RouteParameters","type":"*variable","value":"~*req.14"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.15"}],"file_name":"Routes.csv","flags":null,"type":"*routes"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.3"},{"path":"RunID","tag":"RunID","type":"*variable","value":"~*req.4"},{"path":"AttributeIDs","tag":"AttributeIDs","type":"*variable","value":"~*req.5"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.6"}],"file_name":"Chargers.csv","flags":null,"type":"*chargers"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"Contexts","tag":"Contexts","type":"*variable","value":"~*req.2"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.3"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.4"},{"path":"Strategy","tag":"Strategy","type":"*variable","value":"~*req.5"},{"path":"StrategyParameters","tag":"StrategyParameters","type":"*variable","value":"~*req.6"},{"path":"ConnID","tag":"ConnID","type":"*variable","value":"~*req.7"},{"path":"ConnFilterIDs","tag":"ConnFilterIDs","type":"*variable","value":"~*req.8"},{"path":"ConnWeight","tag":"ConnWeight","type":"*variable","value":"~*req.9"},{"path":"ConnBlocker","tag":"ConnBlocker","type":"*variable","value":"~*req.10"},{"path":"ConnParameters","tag":"ConnParameters","type":"*variable","value":"~*req.11"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.12"}],"file_name":"DispatcherProfiles.csv","flags":null,"type":"*dispatchers"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"Address","tag":"Address","type":"*variable","value":"~*req.2"},{"path":"Transport","tag":"Transport","type":"*variable","value":"~*req.3"},{"path":"TLS","tag":"TLS","type":"*variable","value":"~*req.4"}],"file_name":"DispatcherHosts.csv","flags":null,"type":"*dispatcher_hosts"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.3"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.4"},{"path":"ConnectFee","tag":"ConnectFee","type":"*variable","value":"~*req.5"},{"path":"RoundingMethod","tag":"RoundingMethod","type":"*variable","value":"~*req.6"},{"path":"RoundingDecimals","tag":"RoundingDecimals","type":"*variable","value":"~*req.7"},{"path":"MinCost","tag":"MinCost","type":"*variable","value":"~*req.8"},{"path":"MaxCost","tag":"MaxCost","type":"*variable","value":"~*req.9"},{"path":"MaxCostStrategy","tag":"MaxCostStrategy","type":"*variable","value":"~*req.10"},{"path":"RateID","tag":"RateID","type":"*variable","value":"~*req.11"},{"path":"RateFilterIDs","tag":"RateFilterIDs","type":"*variable","value":"~*req.12"},{"path":"RateActivationStart","tag":"RateActivationStart","type":"*variable","value":"~*req.13"},{"path":"RateWeight","tag":"RateWeight","type":"*variable","value":"~*req.14"},{"path":"RateBlocker","tag":"RateBlocker","type":"*variable","value":"~*req.15"},{"path":"RateIntervalStart","tag":"RateIntervalStart","type":"*variable","value":"~*req.16"},{"path":"RateValue","tag":"RateValue","type":"*variable","value":"~*req.17"},{"path":"RateUnit","tag":"RateUnit","type":"*variable","value":"~*req.18"},{"path":"RateIncrement","tag":"RateIncrement","type":"*variable","value":"~*req.19"}],"file_name":"RateProfiles.csv","flags":null,"type":"*rate_profiles"}],"dry_run":false,"enabled":false,"field_separator":",","id":"*default","lock_filename":".cgr.lck","run_delay":"0","tenant":"","tp_in_dir":"/var/spool/cgrates/loader/in","tp_out_dir":"/var/spool/cgrates/loader/out"}]}`
if cgrCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
} else if err := cgrCfg.V1GetConfigAsJSON(&SectionWithOpts{Section: LoaderJson}, &reply); err != nil {
@@ -5445,7 +5445,7 @@ func TestV1GetConfigAsJSONAllConfig(t *testing.T) {
}
}`
var reply string
- expected := `{"analyzers":{"cleanup_interval":"1h0m0s","db_path":"/var/spool/cgrates/analyzers","enabled":false,"index_type":"*scorch","ttl":"24h0m0s"},"apiban":{"enabled":false,"keys":[]},"apiers":{"attributes_conns":[],"caches_conns":["*internal"],"ees_conns":[],"enabled":false,"scheduler_conns":[]},"asterisk_agent":{"asterisk_conns":[{"address":"127.0.0.1:8088","alias":"","connect_attempts":3,"password":"CGRateS.org","reconnects":5,"user":"cgrates"}],"create_cdr":false,"enabled":false,"sessions_conns":["*internal"]},"attributes":{"apiers_conns":[],"enabled":false,"indexed_selects":true,"nested_fields":false,"prefix_indexed_fields":[],"process_runs":1,"resources_conns":[],"stats_conns":[],"suffix_indexed_fields":[]},"caches":{"partitions":{"*account_action_plans":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*accounts":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*action_plans":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*action_triggers":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*actions":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*apiban":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":"2m0s"},"*attribute_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*attribute_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*caps_events":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*cdr_ids":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":"10m0s"},"*cdrs":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*charger_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*charger_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*closed_sessions":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":"10s"},"*destinations":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*diameter_messages":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":"3h0m0s"},"*dispatcher_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*dispatcher_hosts":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*dispatcher_loads":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*dispatcher_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*dispatcher_routes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*dispatchers":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*event_charges":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":"10s"},"*event_resources":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*filters":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*load_ids":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*rate_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*rate_profile_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*rate_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*rating_plans":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*rating_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*resource_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*resource_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*resources":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*reverse_destinations":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*reverse_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*route_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*route_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*rpc_connections":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*rpc_responses":{"limit":0,"precache":false,"replicate":false,"static_ttl":false,"ttl":"2s"},"*session_costs":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*shared_groups":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*stat_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*statqueue_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*statqueues":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*stir":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":"3h0m0s"},"*threshold_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*threshold_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*thresholds":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*timings":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_account_actions":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_action_plans":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_action_triggers":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_actions":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_attributes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_chargers":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_destination_rates":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_destinations":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_dispatcher_hosts":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_dispatcher_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_filters":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_rate_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_rates":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_rating_plans":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_rating_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_resources":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_routes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_shared_groups":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_stats":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_thresholds":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_timings":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*uch":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":"3h0m0s"},"*versions":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""}},"replication_conns":[]},"cdrs":{"attributes_conns":[],"chargers_conns":[],"ees_conns":[],"enabled":false,"extra_fields":[],"online_cdr_exports":[],"rals_conns":[],"scheduler_conns":[],"session_cost_retries":5,"stats_conns":[],"store_cdrs":true,"thresholds_conns":[]},"chargers":{"attributes_conns":[],"enabled":false,"indexed_selects":true,"nested_fields":false,"prefix_indexed_fields":[],"suffix_indexed_fields":[]},"configs":{"enabled":false,"root_dir":"/var/spool/cgrates/configs","url":"/configs/"},"cores":{"caps":0,"caps_stats_interval":"0","caps_strategy":"*busy","shutdown_timeout":"1s"},"data_db":{"db_host":"127.0.0.1","db_name":"10","db_password":"","db_port":6379,"db_type":"*redis","db_user":"cgrates","items":{"*account_action_plans":{"remote":false,"replicate":false},"*accounts":{"remote":false,"replicate":false},"*action_plans":{"remote":false,"replicate":false},"*action_triggers":{"remote":false,"replicate":false},"*actions":{"remote":false,"replicate":false},"*attribute_profiles":{"remote":false,"replicate":false},"*charger_profiles":{"remote":false,"replicate":false},"*destinations":{"remote":false,"replicate":false},"*dispatcher_hosts":{"remote":false,"replicate":false},"*dispatcher_profiles":{"remote":false,"replicate":false},"*filters":{"remote":false,"replicate":false},"*indexes":{"remote":false,"replicate":false},"*load_ids":{"remote":false,"replicate":false},"*rate_profiles":{"remote":false,"replicate":false},"*rating_plans":{"remote":false,"replicate":false},"*rating_profiles":{"remote":false,"replicate":false},"*resource_profiles":{"remote":false,"replicate":false},"*resources":{"remote":false,"replicate":false},"*reverse_destinations":{"remote":false,"replicate":false},"*route_profiles":{"remote":false,"replicate":false},"*shared_groups":{"remote":false,"replicate":false},"*statqueue_profiles":{"remote":false,"replicate":false},"*statqueues":{"remote":false,"replicate":false},"*threshold_profiles":{"remote":false,"replicate":false},"*thresholds":{"remote":false,"replicate":false},"*timings":{"remote":false,"replicate":false}},"opts":{"query_timeout":"10s","redis_ca_certificate":"","redis_client_certificate":"","redis_client_key":"","redis_cluster":false,"redis_cluster_ondown_delay":"0","redis_cluster_sync":"5s","redis_sentinel":"","redis_tls":false},"remote_conns":[],"replication_conns":[]},"diameter_agent":{"asr_template":"","concurrent_requests":-1,"dictionaries_path":"/usr/share/cgrates/diameter/dict/","enabled":false,"forced_disconnect":"*none","listen":"127.0.0.1:3868","listen_net":"tcp","origin_host":"CGR-DA","origin_realm":"cgrates.org","product_name":"CGRateS","rar_template":"","request_processors":[],"sessions_conns":["*internal"],"synced_conn_requests":false,"vendor_id":0},"dispatcherh":{"dispatchers_conns":[],"enabled":false,"hosts":{},"register_interval":"5m0s"},"dispatchers":{"attributes_conns":[],"enabled":false,"indexed_selects":true,"nested_fields":false,"prefix_indexed_fields":[],"suffix_indexed_fields":[]},"dns_agent":{"enabled":false,"listen":"127.0.0.1:2053","listen_net":"udp","request_processors":[],"sessions_conns":["*internal"],"timezone":""},"ees":{"attributes_conns":[],"cache":{"*file_csv":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":"5s"}},"enabled":false,"exporters":[{"attempts":1,"attribute_context":"","attribute_ids":[],"export_path":"/var/spool/cgrates/ees","field_separator":",","fields":[],"filters":[],"flags":[],"id":"*default","opts":{},"synchronous":false,"tenant":"","timezone":"","type":"*none"}]},"ers":{"enabled":false,"readers":[{"cache_dump_fields":[],"concurrent_requests":1024,"failed_calls_prefix":"","field_separator":",","fields":[{"mandatory":true,"path":"*cgreq.ToR","tag":"ToR","type":"*variable","value":"~*req.2"},{"mandatory":true,"path":"*cgreq.OriginID","tag":"OriginID","type":"*variable","value":"~*req.3"},{"mandatory":true,"path":"*cgreq.RequestType","tag":"RequestType","type":"*variable","value":"~*req.4"},{"mandatory":true,"path":"*cgreq.Tenant","tag":"Tenant","type":"*variable","value":"~*req.6"},{"mandatory":true,"path":"*cgreq.Category","tag":"Category","type":"*variable","value":"~*req.7"},{"mandatory":true,"path":"*cgreq.Account","tag":"Account","type":"*variable","value":"~*req.8"},{"mandatory":true,"path":"*cgreq.Subject","tag":"Subject","type":"*variable","value":"~*req.9"},{"mandatory":true,"path":"*cgreq.Destination","tag":"Destination","type":"*variable","value":"~*req.10"},{"mandatory":true,"path":"*cgreq.SetupTime","tag":"SetupTime","type":"*variable","value":"~*req.11"},{"mandatory":true,"path":"*cgreq.AnswerTime","tag":"AnswerTime","type":"*variable","value":"~*req.12"},{"mandatory":true,"path":"*cgreq.Usage","tag":"Usage","type":"*variable","value":"~*req.13"}],"filters":[],"flags":[],"header_define_character":":","id":"*default","opts":{},"partial_cache_expiry_action":"","partial_record_cache":"0","processed_path":"/var/spool/cgrates/ers/out","row_length":0,"run_delay":"0","source_path":"/var/spool/cgrates/ers/in","tenant":"","timezone":"","type":"*none","xml_root_path":[""]}],"sessions_conns":["*internal"]},"filters":{"apiers_conns":[],"resources_conns":[],"stats_conns":[]},"freeswitch_agent":{"create_cdr":false,"empty_balance_ann_file":"","empty_balance_context":"","enabled":false,"event_socket_conns":[{"address":"127.0.0.1:8021","alias":"127.0.0.1:8021","password":"ClueCon","reconnects":5}],"extra_fields":"","low_balance_ann_file":"","max_wait_connection":"2s","sessions_conns":["*internal"],"subscribe_park":true},"general":{"connect_attempts":5,"connect_timeout":"1s","dbdata_encoding":"*msgpack","default_caching":"*reload","default_category":"call","default_request_type":"*rated","default_tenant":"cgrates.org","default_timezone":"Local","digest_equal":":","digest_separator":",","failed_posts_dir":"/var/spool/cgrates/failed_posts","failed_posts_ttl":"5s","locking_timeout":"0","log_level":6,"logger":"*syslog","max_call_duration":"3h0m0s","max_parallel_conns":100,"min_call_duration":"0","node_id":"ENGINE1","poster_attempts":3,"reconnects":-1,"reply_timeout":"2s","rounding_decimals":5,"rsr_separator":";","tpexport_dir":"/var/spool/cgrates/tpe"},"http":{"auth_users":{},"client_opts":{"dialFallbackDelay":"300ms","dialKeepAlive":"30s","dialTimeout":"30s","disableCompression":false,"disableKeepAlives":false,"expectContinueTimeout":"0","forceAttemptHttp2":true,"idleConnTimeout":"90s","maxConnsPerHost":0,"maxIdleConns":100,"maxIdleConnsPerHost":2,"responseHeaderTimeout":"0","skipTlsVerify":false,"tlsHandshakeTimeout":"10s"},"dispatchers_registrar_url":"/dispatchers_registrar","freeswitch_cdrs_url":"/freeswitch_json","http_cdrs":"/cdr_http","json_rpc_url":"/jsonrpc","use_basic_auth":false,"ws_url":"/ws"},"http_agent":[],"kamailio_agent":{"create_cdr":false,"enabled":false,"evapi_conns":[{"address":"127.0.0.1:8448","alias":"","reconnects":5}],"sessions_conns":["*internal"],"timezone":""},"listen":{"http":"127.0.0.1:2080","http_tls":"127.0.0.1:2280","rpc_gob":"127.0.0.1:2013","rpc_gob_tls":"127.0.0.1:2023","rpc_json":"127.0.0.1:2012","rpc_json_tls":"127.0.0.1:2022"},"loader":{"caches_conns":["*localhost"],"data_path":"./","disable_reverse":false,"field_separator":",","gapi_credentials":".gapi/credentials.json","gapi_token":".gapi/token.json","scheduler_conns":["*localhost"],"tpid":""},"loaders":[{"caches_conns":["*internal"],"data":[{"fields":[{"mandatory":true,"path":"Tenant","tag":"TenantID","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ProfileID","type":"*variable","value":"~*req.1"},{"path":"Contexts","tag":"Contexts","type":"*variable","value":"~*req.2"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.3"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.4"},{"path":"AttributeFilterIDs","tag":"AttributeFilterIDs","type":"*variable","value":"~*req.5"},{"path":"Path","tag":"Path","type":"*variable","value":"~*req.6"},{"path":"Type","tag":"Type","type":"*variable","value":"~*req.7"},{"path":"Value","tag":"Value","type":"*variable","value":"~*req.8"},{"path":"Blocker","tag":"Blocker","type":"*variable","value":"~*req.9"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.10"}],"file_name":"Attributes.csv","type":"*attributes"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"Type","tag":"Type","type":"*variable","value":"~*req.2"},{"path":"Element","tag":"Element","type":"*variable","value":"~*req.3"},{"path":"Values","tag":"Values","type":"*variable","value":"~*req.4"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.5"}],"file_name":"Filters.csv","type":"*filters"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.3"},{"path":"UsageTTL","tag":"TTL","type":"*variable","value":"~*req.4"},{"path":"Limit","tag":"Limit","type":"*variable","value":"~*req.5"},{"path":"AllocationMessage","tag":"AllocationMessage","type":"*variable","value":"~*req.6"},{"path":"Blocker","tag":"Blocker","type":"*variable","value":"~*req.7"},{"path":"Stored","tag":"Stored","type":"*variable","value":"~*req.8"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.9"},{"path":"ThresholdIDs","tag":"ThresholdIDs","type":"*variable","value":"~*req.10"}],"file_name":"Resources.csv","type":"*resources"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.3"},{"path":"QueueLength","tag":"QueueLength","type":"*variable","value":"~*req.4"},{"path":"TTL","tag":"TTL","type":"*variable","value":"~*req.5"},{"path":"MinItems","tag":"MinItems","type":"*variable","value":"~*req.6"},{"path":"MetricIDs","tag":"MetricIDs","type":"*variable","value":"~*req.7"},{"path":"MetricFilterIDs","tag":"MetricFilterIDs","type":"*variable","value":"~*req.8"},{"path":"Blocker","tag":"Blocker","type":"*variable","value":"~*req.9"},{"path":"Stored","tag":"Stored","type":"*variable","value":"~*req.10"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.11"},{"path":"ThresholdIDs","tag":"ThresholdIDs","type":"*variable","value":"~*req.12"}],"file_name":"Stats.csv","type":"*stats"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.3"},{"path":"MaxHits","tag":"MaxHits","type":"*variable","value":"~*req.4"},{"path":"MinHits","tag":"MinHits","type":"*variable","value":"~*req.5"},{"path":"MinSleep","tag":"MinSleep","type":"*variable","value":"~*req.6"},{"path":"Blocker","tag":"Blocker","type":"*variable","value":"~*req.7"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.8"},{"path":"ActionIDs","tag":"ActionIDs","type":"*variable","value":"~*req.9"},{"path":"Async","tag":"Async","type":"*variable","value":"~*req.10"}],"file_name":"Thresholds.csv","type":"*thresholds"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.3"},{"path":"Sorting","tag":"Sorting","type":"*variable","value":"~*req.4"},{"path":"SortingParameters","tag":"SortingParameters","type":"*variable","value":"~*req.5"},{"path":"RouteID","tag":"RouteID","type":"*variable","value":"~*req.6"},{"path":"RouteFilterIDs","tag":"RouteFilterIDs","type":"*variable","value":"~*req.7"},{"path":"RouteAccountIDs","tag":"RouteAccountIDs","type":"*variable","value":"~*req.8"},{"path":"RouteRatingPlanIDs","tag":"RouteRatingPlanIDs","type":"*variable","value":"~*req.9"},{"path":"RouteResourceIDs","tag":"RouteResourceIDs","type":"*variable","value":"~*req.10"},{"path":"RouteStatIDs","tag":"RouteStatIDs","type":"*variable","value":"~*req.11"},{"path":"RouteWeight","tag":"RouteWeight","type":"*variable","value":"~*req.12"},{"path":"RouteBlocker","tag":"RouteBlocker","type":"*variable","value":"~*req.13"},{"path":"RouteParameters","tag":"RouteParameters","type":"*variable","value":"~*req.14"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.15"}],"file_name":"Routes.csv","type":"*routes"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.3"},{"path":"RunID","tag":"RunID","type":"*variable","value":"~*req.4"},{"path":"AttributeIDs","tag":"AttributeIDs","type":"*variable","value":"~*req.5"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.6"}],"file_name":"Chargers.csv","type":"*chargers"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"Contexts","tag":"Contexts","type":"*variable","value":"~*req.2"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.3"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.4"},{"path":"Strategy","tag":"Strategy","type":"*variable","value":"~*req.5"},{"path":"StrategyParameters","tag":"StrategyParameters","type":"*variable","value":"~*req.6"},{"path":"ConnID","tag":"ConnID","type":"*variable","value":"~*req.7"},{"path":"ConnFilterIDs","tag":"ConnFilterIDs","type":"*variable","value":"~*req.8"},{"path":"ConnWeight","tag":"ConnWeight","type":"*variable","value":"~*req.9"},{"path":"ConnBlocker","tag":"ConnBlocker","type":"*variable","value":"~*req.10"},{"path":"ConnParameters","tag":"ConnParameters","type":"*variable","value":"~*req.11"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.12"}],"file_name":"DispatcherProfiles.csv","type":"*dispatchers"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"Address","tag":"Address","type":"*variable","value":"~*req.2"},{"path":"Transport","tag":"Transport","type":"*variable","value":"~*req.3"},{"path":"TLS","tag":"TLS","type":"*variable","value":"~*req.4"}],"file_name":"DispatcherHosts.csv","type":"*dispatcher_hosts"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.3"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.4"},{"path":"ConnectFee","tag":"ConnectFee","type":"*variable","value":"~*req.5"},{"path":"RoundingMethod","tag":"RoundingMethod","type":"*variable","value":"~*req.6"},{"path":"RoundingDecimals","tag":"RoundingDecimals","type":"*variable","value":"~*req.7"},{"path":"MinCost","tag":"MinCost","type":"*variable","value":"~*req.8"},{"path":"MaxCost","tag":"MaxCost","type":"*variable","value":"~*req.9"},{"path":"MaxCostStrategy","tag":"MaxCostStrategy","type":"*variable","value":"~*req.10"},{"path":"RateID","tag":"RateID","type":"*variable","value":"~*req.11"},{"path":"RateFilterIDs","tag":"RateFilterIDs","type":"*variable","value":"~*req.12"},{"path":"RateActivationStart","tag":"RateActivationStart","type":"*variable","value":"~*req.13"},{"path":"RateWeight","tag":"RateWeight","type":"*variable","value":"~*req.14"},{"path":"RateBlocker","tag":"RateBlocker","type":"*variable","value":"~*req.15"},{"path":"RateIntervalStart","tag":"RateIntervalStart","type":"*variable","value":"~*req.16"},{"path":"RateValue","tag":"RateValue","type":"*variable","value":"~*req.17"},{"path":"RateUnit","tag":"RateUnit","type":"*variable","value":"~*req.18"},{"path":"RateIncrement","tag":"RateIncrement","type":"*variable","value":"~*req.19"}],"file_name":"RateProfiles.csv","type":"*rate_profiles"}],"dry_run":false,"enabled":false,"field_separator":",","id":"*default","lock_filename":".cgr.lck","run_delay":"0","tenant":"","tp_in_dir":"/var/spool/cgrates/loader/in","tp_out_dir":"/var/spool/cgrates/loader/out"}],"mailer":{"auth_password":"CGRateS.org","auth_user":"cgrates","from_address":"cgr-mailer@localhost.localdomain","server":"localhost"},"migrator":{"out_datadb_encoding":"msgpack","out_datadb_host":"127.0.0.1","out_datadb_name":"10","out_datadb_opts":{"redis_ca_certificate":"","redis_client_certificate":"","redis_client_key":"","redis_cluster":false,"redis_cluster_ondown_delay":"0","redis_cluster_sync":"5s","redis_sentinel":"","redis_tls":false},"out_datadb_password":"","out_datadb_port":"6379","out_datadb_type":"redis","out_datadb_user":"cgrates","out_stordb_host":"127.0.0.1","out_stordb_name":"cgrates","out_stordb_opts":{},"out_stordb_password":"","out_stordb_port":"3306","out_stordb_type":"mysql","out_stordb_user":"cgrates","users_filters":[]},"radius_agent":{"client_dictionaries":{"*default":"/usr/share/cgrates/radius/dict/"},"client_secrets":{"*default":"CGRateS.org"},"enabled":false,"listen_acct":"127.0.0.1:1813","listen_auth":"127.0.0.1:1812","listen_net":"udp","request_processors":[],"sessions_conns":["*internal"]},"rals":{"balance_rating_subject":{"*any":"*zero1ns","*voice":"*zero1s"},"caches_conns":["*internal"],"dynaprepaid_actionplans":[],"enabled":false,"max_computed_usage":{"*any":"189h0m0s","*data":"107374182400","*mms":"10000","*sms":"10000","*voice":"72h0m0s"},"max_increments":1000000,"remove_expired":true,"rp_subject_prefix_matching":false,"stats_conns":[],"thresholds_conns":[]},"rates":{"enabled":false,"indexed_selects":true,"nested_fields":false,"prefix_indexed_fields":[],"rate_indexed_selects":true,"rate_nested_fields":false,"rate_prefix_indexed_fields":[],"rate_suffix_indexed_fields":[],"suffix_indexed_fields":[]},"resources":{"enabled":false,"indexed_selects":true,"nested_fields":false,"prefix_indexed_fields":[],"store_interval":"","suffix_indexed_fields":[],"thresholds_conns":[]},"routes":{"attributes_conns":[],"default_ratio":1,"enabled":false,"indexed_selects":true,"nested_fields":false,"prefix_indexed_fields":[],"rals_conns":[],"rates_conns":[],"resources_conns":[],"stats_conns":[],"suffix_indexed_fields":[]},"rpc_conns":{"*internal":{"conns":[{"TLS":false,"address":"*internal","synchronous":false,"transport":""}],"poolSize":0,"strategy":"*first"},"*localhost":{"conns":[{"TLS":false,"address":"127.0.0.1:2012","synchronous":false,"transport":"*json"}],"poolSize":0,"strategy":"*first"}},"schedulers":{"cdrs_conns":[],"enabled":false,"filters":[],"stats_conns":[],"thresholds_conns":[]},"sessions":{"alterable_fields":[],"attributes_conns":[],"cdrs_conns":[],"channel_sync_interval":"0","chargers_conns":[],"client_protocol":1,"debit_interval":"0","enabled":false,"listen_bijson":"127.0.0.1:2014","min_dur_low_balance":"0","rals_conns":[],"replication_conns":[],"resources_conns":[],"routes_conns":[],"scheduler_conns":[],"session_indexes":[],"session_ttl":"0","stats_conns":[],"stir":{"allowed_attest":["*any"],"default_attest":"A","payload_maxduration":"-1","privatekey_path":"","publickey_path":""},"store_session_costs":false,"terminate_attempts":5,"thresholds_conns":[]},"sip_agent":{"enabled":false,"listen":"127.0.0.1:5060","listen_net":"udp","request_processors":[],"retransmission_timer":1000000000,"sessions_conns":["*internal"],"timezone":""},"stats":{"enabled":false,"indexed_selects":true,"nested_fields":false,"prefix_indexed_fields":[],"store_interval":"","store_uncompressed_limit":0,"suffix_indexed_fields":[],"thresholds_conns":[]},"stor_db":{"db_host":"127.0.0.1","db_name":"cgrates","db_password":"","db_port":3306,"db_type":"*mysql","db_user":"cgrates","items":{"*cdrs":{"remote":false,"replicate":false},"*session_costs":{"remote":false,"replicate":false},"*tp_account_actions":{"remote":false,"replicate":false},"*tp_action_plans":{"remote":false,"replicate":false},"*tp_action_triggers":{"remote":false,"replicate":false},"*tp_actions":{"remote":false,"replicate":false},"*tp_attributes":{"remote":false,"replicate":false},"*tp_chargers":{"remote":false,"replicate":false},"*tp_destination_rates":{"remote":false,"replicate":false},"*tp_destinations":{"remote":false,"replicate":false},"*tp_dispatcher_hosts":{"remote":false,"replicate":false},"*tp_dispatcher_profiles":{"remote":false,"replicate":false},"*tp_filters":{"remote":false,"replicate":false},"*tp_rate_profiles":{"remote":false,"replicate":false},"*tp_rates":{"remote":false,"replicate":false},"*tp_rating_plans":{"remote":false,"replicate":false},"*tp_rating_profiles":{"remote":false,"replicate":false},"*tp_resources":{"remote":false,"replicate":false},"*tp_routes":{"remote":false,"replicate":false},"*tp_shared_groups":{"remote":false,"replicate":false},"*tp_stats":{"remote":false,"replicate":false},"*tp_thresholds":{"remote":false,"replicate":false},"*tp_timings":{"remote":false,"replicate":false},"*versions":{"remote":false,"replicate":false}},"opts":{"conn_max_lifetime":0,"max_idle_conns":10,"max_open_conns":100,"query_timeout":"10s","sslmode":"disable"},"prefix_indexed_fields":[],"remote_conns":null,"replication_conns":null,"string_indexed_fields":[]},"suretax":{"bill_to_number":"","business_unit":"","client_number":"","client_tracking":"~*req.CGRID","customer_number":"~*req.Subject","include_local_cost":false,"orig_number":"~*req.Subject","p2pplus4":"","p2pzipcode":"","plus4":"","regulatory_code":"03","response_group":"03","response_type":"D4","return_file_code":"0","sales_type_code":"R","tax_exemption_code_list":"","tax_included":"0","tax_situs_rule":"04","term_number":"~*req.Destination","timezone":"UTC","trans_type_code":"010101","unit_type":"00","units":"1","url":"","validation_key":"","zipcode":""},"templates":{"*asr":[{"mandatory":true,"path":"*diamreq.Session-Id","tag":"SessionId","type":"*variable","value":"~*req.Session-Id"},{"mandatory":true,"path":"*diamreq.Origin-Host","tag":"OriginHost","type":"*variable","value":"~*req.Destination-Host"},{"mandatory":true,"path":"*diamreq.Origin-Realm","tag":"OriginRealm","type":"*variable","value":"~*req.Destination-Realm"},{"mandatory":true,"path":"*diamreq.Destination-Realm","tag":"DestinationRealm","type":"*variable","value":"~*req.Origin-Realm"},{"mandatory":true,"path":"*diamreq.Destination-Host","tag":"DestinationHost","type":"*variable","value":"~*req.Origin-Host"},{"mandatory":true,"path":"*diamreq.Auth-Application-Id","tag":"AuthApplicationId","type":"*variable","value":"~*vars.*appid"}],"*cca":[{"mandatory":true,"path":"*rep.Session-Id","tag":"SessionId","type":"*variable","value":"~*req.Session-Id"},{"path":"*rep.Result-Code","tag":"ResultCode","type":"*constant","value":"2001"},{"mandatory":true,"path":"*rep.Origin-Host","tag":"OriginHost","type":"*variable","value":"~*vars.OriginHost"},{"mandatory":true,"path":"*rep.Origin-Realm","tag":"OriginRealm","type":"*variable","value":"~*vars.OriginRealm"},{"mandatory":true,"path":"*rep.Auth-Application-Id","tag":"AuthApplicationId","type":"*variable","value":"~*vars.*appid"},{"mandatory":true,"path":"*rep.CC-Request-Type","tag":"CCRequestType","type":"*variable","value":"~*req.CC-Request-Type"},{"mandatory":true,"path":"*rep.CC-Request-Number","tag":"CCRequestNumber","type":"*variable","value":"~*req.CC-Request-Number"}],"*err":[{"mandatory":true,"path":"*rep.Session-Id","tag":"SessionId","type":"*variable","value":"~*req.Session-Id"},{"mandatory":true,"path":"*rep.Origin-Host","tag":"OriginHost","type":"*variable","value":"~*vars.OriginHost"},{"mandatory":true,"path":"*rep.Origin-Realm","tag":"OriginRealm","type":"*variable","value":"~*vars.OriginRealm"}],"*errSip":[{"mandatory":true,"path":"*rep.Request","tag":"Request","type":"*constant","value":"SIP/2.0 500 Internal Server Error"}],"*rar":[{"mandatory":true,"path":"*diamreq.Session-Id","tag":"SessionId","type":"*variable","value":"~*req.Session-Id"},{"mandatory":true,"path":"*diamreq.Origin-Host","tag":"OriginHost","type":"*variable","value":"~*req.Destination-Host"},{"mandatory":true,"path":"*diamreq.Origin-Realm","tag":"OriginRealm","type":"*variable","value":"~*req.Destination-Realm"},{"mandatory":true,"path":"*diamreq.Destination-Realm","tag":"DestinationRealm","type":"*variable","value":"~*req.Origin-Realm"},{"mandatory":true,"path":"*diamreq.Destination-Host","tag":"DestinationHost","type":"*variable","value":"~*req.Origin-Host"},{"mandatory":true,"path":"*diamreq.Auth-Application-Id","tag":"AuthApplicationId","type":"*variable","value":"~*vars.*appid"},{"path":"*diamreq.Re-Auth-Request-Type","tag":"ReAuthRequestType","type":"*constant","value":"0"}]},"thresholds":{"enabled":false,"indexed_selects":true,"nested_fields":false,"prefix_indexed_fields":[],"store_interval":"","suffix_indexed_fields":[]},"tls":{"ca_certificate":"","client_certificate":"","client_key":"","server_certificate":"","server_key":"","server_name":"","server_policy":4}}`
+ expected := `{"analyzers":{"cleanup_interval":"1h0m0s","db_path":"/var/spool/cgrates/analyzers","enabled":false,"index_type":"*scorch","ttl":"24h0m0s"},"apiban":{"enabled":false,"keys":[]},"apiers":{"attributes_conns":[],"caches_conns":["*internal"],"ees_conns":[],"enabled":false,"scheduler_conns":[]},"asterisk_agent":{"asterisk_conns":[{"address":"127.0.0.1:8088","alias":"","connect_attempts":3,"password":"CGRateS.org","reconnects":5,"user":"cgrates"}],"create_cdr":false,"enabled":false,"sessions_conns":["*internal"]},"attributes":{"apiers_conns":[],"enabled":false,"indexed_selects":true,"nested_fields":false,"prefix_indexed_fields":[],"process_runs":1,"resources_conns":[],"stats_conns":[],"suffix_indexed_fields":[]},"caches":{"partitions":{"*account_action_plans":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*accounts":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*action_plans":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*action_triggers":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*actions":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*apiban":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":"2m0s"},"*attribute_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*attribute_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*caps_events":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*cdr_ids":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":"10m0s"},"*cdrs":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*charger_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*charger_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*closed_sessions":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":"10s"},"*destinations":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*diameter_messages":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":"3h0m0s"},"*dispatcher_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*dispatcher_hosts":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*dispatcher_loads":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*dispatcher_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*dispatcher_routes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*dispatchers":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*event_charges":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":"10s"},"*event_resources":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*filters":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*load_ids":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*rate_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*rate_profile_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*rate_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*rating_plans":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*rating_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*resource_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*resource_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*resources":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*reverse_destinations":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*reverse_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*route_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*route_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*rpc_connections":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*rpc_responses":{"limit":0,"precache":false,"replicate":false,"static_ttl":false,"ttl":"2s"},"*session_costs":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*shared_groups":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*stat_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*statqueue_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*statqueues":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*stir":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":"3h0m0s"},"*threshold_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*threshold_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*thresholds":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*timings":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_account_actions":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_action_plans":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_action_triggers":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_actions":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_attributes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_chargers":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_destination_rates":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_destinations":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_dispatcher_hosts":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_dispatcher_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_filters":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_rate_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_rates":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_rating_plans":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_rating_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_resources":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_routes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_shared_groups":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_stats":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_thresholds":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*tp_timings":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*uch":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":"3h0m0s"},"*versions":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""}},"replication_conns":[]},"cdrs":{"attributes_conns":[],"chargers_conns":[],"ees_conns":[],"enabled":false,"extra_fields":[],"online_cdr_exports":[],"rals_conns":[],"scheduler_conns":[],"session_cost_retries":5,"stats_conns":[],"store_cdrs":true,"thresholds_conns":[]},"chargers":{"attributes_conns":[],"enabled":false,"indexed_selects":true,"nested_fields":false,"prefix_indexed_fields":[],"suffix_indexed_fields":[]},"configs":{"enabled":false,"root_dir":"/var/spool/cgrates/configs","url":"/configs/"},"cores":{"caps":0,"caps_stats_interval":"0","caps_strategy":"*busy","shutdown_timeout":"1s"},"data_db":{"db_host":"127.0.0.1","db_name":"10","db_password":"","db_port":6379,"db_type":"*redis","db_user":"cgrates","items":{"*account_action_plans":{"remote":false,"replicate":false},"*accounts":{"remote":false,"replicate":false},"*action_plans":{"remote":false,"replicate":false},"*action_triggers":{"remote":false,"replicate":false},"*actions":{"remote":false,"replicate":false},"*attribute_profiles":{"remote":false,"replicate":false},"*charger_profiles":{"remote":false,"replicate":false},"*destinations":{"remote":false,"replicate":false},"*dispatcher_hosts":{"remote":false,"replicate":false},"*dispatcher_profiles":{"remote":false,"replicate":false},"*filters":{"remote":false,"replicate":false},"*indexes":{"remote":false,"replicate":false},"*load_ids":{"remote":false,"replicate":false},"*rate_profiles":{"remote":false,"replicate":false},"*rating_plans":{"remote":false,"replicate":false},"*rating_profiles":{"remote":false,"replicate":false},"*resource_profiles":{"remote":false,"replicate":false},"*resources":{"remote":false,"replicate":false},"*reverse_destinations":{"remote":false,"replicate":false},"*route_profiles":{"remote":false,"replicate":false},"*shared_groups":{"remote":false,"replicate":false},"*statqueue_profiles":{"remote":false,"replicate":false},"*statqueues":{"remote":false,"replicate":false},"*threshold_profiles":{"remote":false,"replicate":false},"*thresholds":{"remote":false,"replicate":false},"*timings":{"remote":false,"replicate":false}},"opts":{"query_timeout":"10s","redis_ca_certificate":"","redis_client_certificate":"","redis_client_key":"","redis_cluster":false,"redis_cluster_ondown_delay":"0","redis_cluster_sync":"5s","redis_sentinel":"","redis_tls":false},"remote_conns":[],"replication_conns":[]},"diameter_agent":{"asr_template":"","concurrent_requests":-1,"dictionaries_path":"/usr/share/cgrates/diameter/dict/","enabled":false,"forced_disconnect":"*none","listen":"127.0.0.1:3868","listen_net":"tcp","origin_host":"CGR-DA","origin_realm":"cgrates.org","product_name":"CGRateS","rar_template":"","request_processors":[],"sessions_conns":["*internal"],"synced_conn_requests":false,"vendor_id":0},"dispatcherh":{"dispatchers_conns":[],"enabled":false,"hosts":{},"register_interval":"5m0s"},"dispatchers":{"attributes_conns":[],"enabled":false,"indexed_selects":true,"nested_fields":false,"prefix_indexed_fields":[],"suffix_indexed_fields":[]},"dns_agent":{"enabled":false,"listen":"127.0.0.1:2053","listen_net":"udp","request_processors":[],"sessions_conns":["*internal"],"timezone":""},"ees":{"attributes_conns":[],"cache":{"*file_csv":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":"5s"}},"enabled":false,"exporters":[{"attempts":1,"attribute_context":"","attribute_ids":[],"export_path":"/var/spool/cgrates/ees","field_separator":",","fields":[],"filters":[],"flags":[],"id":"*default","opts":{},"synchronous":false,"tenant":"","timezone":"","type":"*none"}]},"ers":{"enabled":false,"readers":[{"cache_dump_fields":[],"concurrent_requests":1024,"failed_calls_prefix":"","field_separator":",","fields":[{"mandatory":true,"path":"*cgreq.ToR","tag":"ToR","type":"*variable","value":"~*req.2"},{"mandatory":true,"path":"*cgreq.OriginID","tag":"OriginID","type":"*variable","value":"~*req.3"},{"mandatory":true,"path":"*cgreq.RequestType","tag":"RequestType","type":"*variable","value":"~*req.4"},{"mandatory":true,"path":"*cgreq.Tenant","tag":"Tenant","type":"*variable","value":"~*req.6"},{"mandatory":true,"path":"*cgreq.Category","tag":"Category","type":"*variable","value":"~*req.7"},{"mandatory":true,"path":"*cgreq.Account","tag":"Account","type":"*variable","value":"~*req.8"},{"mandatory":true,"path":"*cgreq.Subject","tag":"Subject","type":"*variable","value":"~*req.9"},{"mandatory":true,"path":"*cgreq.Destination","tag":"Destination","type":"*variable","value":"~*req.10"},{"mandatory":true,"path":"*cgreq.SetupTime","tag":"SetupTime","type":"*variable","value":"~*req.11"},{"mandatory":true,"path":"*cgreq.AnswerTime","tag":"AnswerTime","type":"*variable","value":"~*req.12"},{"mandatory":true,"path":"*cgreq.Usage","tag":"Usage","type":"*variable","value":"~*req.13"}],"filters":[],"flags":[],"header_define_character":":","id":"*default","opts":{},"partial_cache_expiry_action":"","partial_record_cache":"0","processed_path":"/var/spool/cgrates/ers/out","row_length":0,"run_delay":"0","source_path":"/var/spool/cgrates/ers/in","tenant":"","timezone":"","type":"*none","xml_root_path":[""]}],"sessions_conns":["*internal"]},"filters":{"apiers_conns":[],"resources_conns":[],"stats_conns":[]},"freeswitch_agent":{"create_cdr":false,"empty_balance_ann_file":"","empty_balance_context":"","enabled":false,"event_socket_conns":[{"address":"127.0.0.1:8021","alias":"127.0.0.1:8021","password":"ClueCon","reconnects":5}],"extra_fields":"","low_balance_ann_file":"","max_wait_connection":"2s","sessions_conns":["*internal"],"subscribe_park":true},"general":{"connect_attempts":5,"connect_timeout":"1s","dbdata_encoding":"*msgpack","default_caching":"*reload","default_category":"call","default_request_type":"*rated","default_tenant":"cgrates.org","default_timezone":"Local","digest_equal":":","digest_separator":",","failed_posts_dir":"/var/spool/cgrates/failed_posts","failed_posts_ttl":"5s","locking_timeout":"0","log_level":6,"logger":"*syslog","max_call_duration":"3h0m0s","max_parallel_conns":100,"min_call_duration":"0","node_id":"ENGINE1","poster_attempts":3,"reconnects":-1,"reply_timeout":"2s","rounding_decimals":5,"rsr_separator":";","tpexport_dir":"/var/spool/cgrates/tpe"},"http":{"auth_users":{},"client_opts":{"dialFallbackDelay":"300ms","dialKeepAlive":"30s","dialTimeout":"30s","disableCompression":false,"disableKeepAlives":false,"expectContinueTimeout":"0","forceAttemptHttp2":true,"idleConnTimeout":"90s","maxConnsPerHost":0,"maxIdleConns":100,"maxIdleConnsPerHost":2,"responseHeaderTimeout":"0","skipTlsVerify":false,"tlsHandshakeTimeout":"10s"},"dispatchers_registrar_url":"/dispatchers_registrar","freeswitch_cdrs_url":"/freeswitch_json","http_cdrs":"/cdr_http","json_rpc_url":"/jsonrpc","use_basic_auth":false,"ws_url":"/ws"},"http_agent":[],"kamailio_agent":{"create_cdr":false,"enabled":false,"evapi_conns":[{"address":"127.0.0.1:8448","alias":"","reconnects":5}],"sessions_conns":["*internal"],"timezone":""},"listen":{"http":"127.0.0.1:2080","http_tls":"127.0.0.1:2280","rpc_gob":"127.0.0.1:2013","rpc_gob_tls":"127.0.0.1:2023","rpc_json":"127.0.0.1:2012","rpc_json_tls":"127.0.0.1:2022"},"loader":{"caches_conns":["*localhost"],"data_path":"./","disable_reverse":false,"field_separator":",","gapi_credentials":".gapi/credentials.json","gapi_token":".gapi/token.json","scheduler_conns":["*localhost"],"tpid":""},"loaders":[{"caches_conns":["*internal"],"data":[{"fields":[{"mandatory":true,"path":"Tenant","tag":"TenantID","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ProfileID","type":"*variable","value":"~*req.1"},{"path":"Contexts","tag":"Contexts","type":"*variable","value":"~*req.2"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.3"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.4"},{"path":"AttributeFilterIDs","tag":"AttributeFilterIDs","type":"*variable","value":"~*req.5"},{"path":"Path","tag":"Path","type":"*variable","value":"~*req.6"},{"path":"Type","tag":"Type","type":"*variable","value":"~*req.7"},{"path":"Value","tag":"Value","type":"*variable","value":"~*req.8"},{"path":"Blocker","tag":"Blocker","type":"*variable","value":"~*req.9"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.10"}],"file_name":"Attributes.csv","flags":null,"type":"*attributes"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"Type","tag":"Type","type":"*variable","value":"~*req.2"},{"path":"Element","tag":"Element","type":"*variable","value":"~*req.3"},{"path":"Values","tag":"Values","type":"*variable","value":"~*req.4"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.5"}],"file_name":"Filters.csv","flags":null,"type":"*filters"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.3"},{"path":"UsageTTL","tag":"TTL","type":"*variable","value":"~*req.4"},{"path":"Limit","tag":"Limit","type":"*variable","value":"~*req.5"},{"path":"AllocationMessage","tag":"AllocationMessage","type":"*variable","value":"~*req.6"},{"path":"Blocker","tag":"Blocker","type":"*variable","value":"~*req.7"},{"path":"Stored","tag":"Stored","type":"*variable","value":"~*req.8"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.9"},{"path":"ThresholdIDs","tag":"ThresholdIDs","type":"*variable","value":"~*req.10"}],"file_name":"Resources.csv","flags":null,"type":"*resources"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.3"},{"path":"QueueLength","tag":"QueueLength","type":"*variable","value":"~*req.4"},{"path":"TTL","tag":"TTL","type":"*variable","value":"~*req.5"},{"path":"MinItems","tag":"MinItems","type":"*variable","value":"~*req.6"},{"path":"MetricIDs","tag":"MetricIDs","type":"*variable","value":"~*req.7"},{"path":"MetricFilterIDs","tag":"MetricFilterIDs","type":"*variable","value":"~*req.8"},{"path":"Blocker","tag":"Blocker","type":"*variable","value":"~*req.9"},{"path":"Stored","tag":"Stored","type":"*variable","value":"~*req.10"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.11"},{"path":"ThresholdIDs","tag":"ThresholdIDs","type":"*variable","value":"~*req.12"}],"file_name":"Stats.csv","flags":null,"type":"*stats"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.3"},{"path":"MaxHits","tag":"MaxHits","type":"*variable","value":"~*req.4"},{"path":"MinHits","tag":"MinHits","type":"*variable","value":"~*req.5"},{"path":"MinSleep","tag":"MinSleep","type":"*variable","value":"~*req.6"},{"path":"Blocker","tag":"Blocker","type":"*variable","value":"~*req.7"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.8"},{"path":"ActionIDs","tag":"ActionIDs","type":"*variable","value":"~*req.9"},{"path":"Async","tag":"Async","type":"*variable","value":"~*req.10"}],"file_name":"Thresholds.csv","flags":null,"type":"*thresholds"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.3"},{"path":"Sorting","tag":"Sorting","type":"*variable","value":"~*req.4"},{"path":"SortingParameters","tag":"SortingParameters","type":"*variable","value":"~*req.5"},{"path":"RouteID","tag":"RouteID","type":"*variable","value":"~*req.6"},{"path":"RouteFilterIDs","tag":"RouteFilterIDs","type":"*variable","value":"~*req.7"},{"path":"RouteAccountIDs","tag":"RouteAccountIDs","type":"*variable","value":"~*req.8"},{"path":"RouteRatingPlanIDs","tag":"RouteRatingPlanIDs","type":"*variable","value":"~*req.9"},{"path":"RouteResourceIDs","tag":"RouteResourceIDs","type":"*variable","value":"~*req.10"},{"path":"RouteStatIDs","tag":"RouteStatIDs","type":"*variable","value":"~*req.11"},{"path":"RouteWeight","tag":"RouteWeight","type":"*variable","value":"~*req.12"},{"path":"RouteBlocker","tag":"RouteBlocker","type":"*variable","value":"~*req.13"},{"path":"RouteParameters","tag":"RouteParameters","type":"*variable","value":"~*req.14"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.15"}],"file_name":"Routes.csv","flags":null,"type":"*routes"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.3"},{"path":"RunID","tag":"RunID","type":"*variable","value":"~*req.4"},{"path":"AttributeIDs","tag":"AttributeIDs","type":"*variable","value":"~*req.5"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.6"}],"file_name":"Chargers.csv","flags":null,"type":"*chargers"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"Contexts","tag":"Contexts","type":"*variable","value":"~*req.2"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.3"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.4"},{"path":"Strategy","tag":"Strategy","type":"*variable","value":"~*req.5"},{"path":"StrategyParameters","tag":"StrategyParameters","type":"*variable","value":"~*req.6"},{"path":"ConnID","tag":"ConnID","type":"*variable","value":"~*req.7"},{"path":"ConnFilterIDs","tag":"ConnFilterIDs","type":"*variable","value":"~*req.8"},{"path":"ConnWeight","tag":"ConnWeight","type":"*variable","value":"~*req.9"},{"path":"ConnBlocker","tag":"ConnBlocker","type":"*variable","value":"~*req.10"},{"path":"ConnParameters","tag":"ConnParameters","type":"*variable","value":"~*req.11"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.12"}],"file_name":"DispatcherProfiles.csv","flags":null,"type":"*dispatchers"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"Address","tag":"Address","type":"*variable","value":"~*req.2"},{"path":"Transport","tag":"Transport","type":"*variable","value":"~*req.3"},{"path":"TLS","tag":"TLS","type":"*variable","value":"~*req.4"}],"file_name":"DispatcherHosts.csv","flags":null,"type":"*dispatcher_hosts"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.3"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.4"},{"path":"ConnectFee","tag":"ConnectFee","type":"*variable","value":"~*req.5"},{"path":"RoundingMethod","tag":"RoundingMethod","type":"*variable","value":"~*req.6"},{"path":"RoundingDecimals","tag":"RoundingDecimals","type":"*variable","value":"~*req.7"},{"path":"MinCost","tag":"MinCost","type":"*variable","value":"~*req.8"},{"path":"MaxCost","tag":"MaxCost","type":"*variable","value":"~*req.9"},{"path":"MaxCostStrategy","tag":"MaxCostStrategy","type":"*variable","value":"~*req.10"},{"path":"RateID","tag":"RateID","type":"*variable","value":"~*req.11"},{"path":"RateFilterIDs","tag":"RateFilterIDs","type":"*variable","value":"~*req.12"},{"path":"RateActivationStart","tag":"RateActivationStart","type":"*variable","value":"~*req.13"},{"path":"RateWeight","tag":"RateWeight","type":"*variable","value":"~*req.14"},{"path":"RateBlocker","tag":"RateBlocker","type":"*variable","value":"~*req.15"},{"path":"RateIntervalStart","tag":"RateIntervalStart","type":"*variable","value":"~*req.16"},{"path":"RateValue","tag":"RateValue","type":"*variable","value":"~*req.17"},{"path":"RateUnit","tag":"RateUnit","type":"*variable","value":"~*req.18"},{"path":"RateIncrement","tag":"RateIncrement","type":"*variable","value":"~*req.19"}],"file_name":"RateProfiles.csv","flags":null,"type":"*rate_profiles"}],"dry_run":false,"enabled":false,"field_separator":",","id":"*default","lock_filename":".cgr.lck","run_delay":"0","tenant":"","tp_in_dir":"/var/spool/cgrates/loader/in","tp_out_dir":"/var/spool/cgrates/loader/out"}],"mailer":{"auth_password":"CGRateS.org","auth_user":"cgrates","from_address":"cgr-mailer@localhost.localdomain","server":"localhost"},"migrator":{"out_datadb_encoding":"msgpack","out_datadb_host":"127.0.0.1","out_datadb_name":"10","out_datadb_opts":{"redis_ca_certificate":"","redis_client_certificate":"","redis_client_key":"","redis_cluster":false,"redis_cluster_ondown_delay":"0","redis_cluster_sync":"5s","redis_sentinel":"","redis_tls":false},"out_datadb_password":"","out_datadb_port":"6379","out_datadb_type":"redis","out_datadb_user":"cgrates","out_stordb_host":"127.0.0.1","out_stordb_name":"cgrates","out_stordb_opts":{},"out_stordb_password":"","out_stordb_port":"3306","out_stordb_type":"mysql","out_stordb_user":"cgrates","users_filters":[]},"radius_agent":{"client_dictionaries":{"*default":"/usr/share/cgrates/radius/dict/"},"client_secrets":{"*default":"CGRateS.org"},"enabled":false,"listen_acct":"127.0.0.1:1813","listen_auth":"127.0.0.1:1812","listen_net":"udp","request_processors":[],"sessions_conns":["*internal"]},"rals":{"balance_rating_subject":{"*any":"*zero1ns","*voice":"*zero1s"},"caches_conns":["*internal"],"dynaprepaid_actionplans":[],"enabled":false,"max_computed_usage":{"*any":"189h0m0s","*data":"107374182400","*mms":"10000","*sms":"10000","*voice":"72h0m0s"},"max_increments":1000000,"remove_expired":true,"rp_subject_prefix_matching":false,"stats_conns":[],"thresholds_conns":[]},"rates":{"enabled":false,"indexed_selects":true,"nested_fields":false,"prefix_indexed_fields":[],"rate_indexed_selects":true,"rate_nested_fields":false,"rate_prefix_indexed_fields":[],"rate_suffix_indexed_fields":[],"suffix_indexed_fields":[]},"resources":{"enabled":false,"indexed_selects":true,"nested_fields":false,"prefix_indexed_fields":[],"store_interval":"","suffix_indexed_fields":[],"thresholds_conns":[]},"routes":{"attributes_conns":[],"default_ratio":1,"enabled":false,"indexed_selects":true,"nested_fields":false,"prefix_indexed_fields":[],"rals_conns":[],"rates_conns":[],"resources_conns":[],"stats_conns":[],"suffix_indexed_fields":[]},"rpc_conns":{"*internal":{"conns":[{"TLS":false,"address":"*internal","synchronous":false,"transport":""}],"poolSize":0,"strategy":"*first"},"*localhost":{"conns":[{"TLS":false,"address":"127.0.0.1:2012","synchronous":false,"transport":"*json"}],"poolSize":0,"strategy":"*first"}},"schedulers":{"cdrs_conns":[],"enabled":false,"filters":[],"stats_conns":[],"thresholds_conns":[]},"sessions":{"alterable_fields":[],"attributes_conns":[],"cdrs_conns":[],"channel_sync_interval":"0","chargers_conns":[],"client_protocol":1,"debit_interval":"0","enabled":false,"listen_bijson":"127.0.0.1:2014","min_dur_low_balance":"0","rals_conns":[],"replication_conns":[],"resources_conns":[],"routes_conns":[],"scheduler_conns":[],"session_indexes":[],"session_ttl":"0","stats_conns":[],"stir":{"allowed_attest":["*any"],"default_attest":"A","payload_maxduration":"-1","privatekey_path":"","publickey_path":""},"store_session_costs":false,"terminate_attempts":5,"thresholds_conns":[]},"sip_agent":{"enabled":false,"listen":"127.0.0.1:5060","listen_net":"udp","request_processors":[],"retransmission_timer":1000000000,"sessions_conns":["*internal"],"timezone":""},"stats":{"enabled":false,"indexed_selects":true,"nested_fields":false,"prefix_indexed_fields":[],"store_interval":"","store_uncompressed_limit":0,"suffix_indexed_fields":[],"thresholds_conns":[]},"stor_db":{"db_host":"127.0.0.1","db_name":"cgrates","db_password":"","db_port":3306,"db_type":"*mysql","db_user":"cgrates","items":{"*cdrs":{"remote":false,"replicate":false},"*session_costs":{"remote":false,"replicate":false},"*tp_account_actions":{"remote":false,"replicate":false},"*tp_action_plans":{"remote":false,"replicate":false},"*tp_action_triggers":{"remote":false,"replicate":false},"*tp_actions":{"remote":false,"replicate":false},"*tp_attributes":{"remote":false,"replicate":false},"*tp_chargers":{"remote":false,"replicate":false},"*tp_destination_rates":{"remote":false,"replicate":false},"*tp_destinations":{"remote":false,"replicate":false},"*tp_dispatcher_hosts":{"remote":false,"replicate":false},"*tp_dispatcher_profiles":{"remote":false,"replicate":false},"*tp_filters":{"remote":false,"replicate":false},"*tp_rate_profiles":{"remote":false,"replicate":false},"*tp_rates":{"remote":false,"replicate":false},"*tp_rating_plans":{"remote":false,"replicate":false},"*tp_rating_profiles":{"remote":false,"replicate":false},"*tp_resources":{"remote":false,"replicate":false},"*tp_routes":{"remote":false,"replicate":false},"*tp_shared_groups":{"remote":false,"replicate":false},"*tp_stats":{"remote":false,"replicate":false},"*tp_thresholds":{"remote":false,"replicate":false},"*tp_timings":{"remote":false,"replicate":false},"*versions":{"remote":false,"replicate":false}},"opts":{"conn_max_lifetime":0,"max_idle_conns":10,"max_open_conns":100,"query_timeout":"10s","sslmode":"disable"},"prefix_indexed_fields":[],"remote_conns":null,"replication_conns":null,"string_indexed_fields":[]},"suretax":{"bill_to_number":"","business_unit":"","client_number":"","client_tracking":"~*req.CGRID","customer_number":"~*req.Subject","include_local_cost":false,"orig_number":"~*req.Subject","p2pplus4":"","p2pzipcode":"","plus4":"","regulatory_code":"03","response_group":"03","response_type":"D4","return_file_code":"0","sales_type_code":"R","tax_exemption_code_list":"","tax_included":"0","tax_situs_rule":"04","term_number":"~*req.Destination","timezone":"UTC","trans_type_code":"010101","unit_type":"00","units":"1","url":"","validation_key":"","zipcode":""},"templates":{"*asr":[{"mandatory":true,"path":"*diamreq.Session-Id","tag":"SessionId","type":"*variable","value":"~*req.Session-Id"},{"mandatory":true,"path":"*diamreq.Origin-Host","tag":"OriginHost","type":"*variable","value":"~*req.Destination-Host"},{"mandatory":true,"path":"*diamreq.Origin-Realm","tag":"OriginRealm","type":"*variable","value":"~*req.Destination-Realm"},{"mandatory":true,"path":"*diamreq.Destination-Realm","tag":"DestinationRealm","type":"*variable","value":"~*req.Origin-Realm"},{"mandatory":true,"path":"*diamreq.Destination-Host","tag":"DestinationHost","type":"*variable","value":"~*req.Origin-Host"},{"mandatory":true,"path":"*diamreq.Auth-Application-Id","tag":"AuthApplicationId","type":"*variable","value":"~*vars.*appid"}],"*cca":[{"mandatory":true,"path":"*rep.Session-Id","tag":"SessionId","type":"*variable","value":"~*req.Session-Id"},{"path":"*rep.Result-Code","tag":"ResultCode","type":"*constant","value":"2001"},{"mandatory":true,"path":"*rep.Origin-Host","tag":"OriginHost","type":"*variable","value":"~*vars.OriginHost"},{"mandatory":true,"path":"*rep.Origin-Realm","tag":"OriginRealm","type":"*variable","value":"~*vars.OriginRealm"},{"mandatory":true,"path":"*rep.Auth-Application-Id","tag":"AuthApplicationId","type":"*variable","value":"~*vars.*appid"},{"mandatory":true,"path":"*rep.CC-Request-Type","tag":"CCRequestType","type":"*variable","value":"~*req.CC-Request-Type"},{"mandatory":true,"path":"*rep.CC-Request-Number","tag":"CCRequestNumber","type":"*variable","value":"~*req.CC-Request-Number"}],"*err":[{"mandatory":true,"path":"*rep.Session-Id","tag":"SessionId","type":"*variable","value":"~*req.Session-Id"},{"mandatory":true,"path":"*rep.Origin-Host","tag":"OriginHost","type":"*variable","value":"~*vars.OriginHost"},{"mandatory":true,"path":"*rep.Origin-Realm","tag":"OriginRealm","type":"*variable","value":"~*vars.OriginRealm"}],"*errSip":[{"mandatory":true,"path":"*rep.Request","tag":"Request","type":"*constant","value":"SIP/2.0 500 Internal Server Error"}],"*rar":[{"mandatory":true,"path":"*diamreq.Session-Id","tag":"SessionId","type":"*variable","value":"~*req.Session-Id"},{"mandatory":true,"path":"*diamreq.Origin-Host","tag":"OriginHost","type":"*variable","value":"~*req.Destination-Host"},{"mandatory":true,"path":"*diamreq.Origin-Realm","tag":"OriginRealm","type":"*variable","value":"~*req.Destination-Realm"},{"mandatory":true,"path":"*diamreq.Destination-Realm","tag":"DestinationRealm","type":"*variable","value":"~*req.Origin-Realm"},{"mandatory":true,"path":"*diamreq.Destination-Host","tag":"DestinationHost","type":"*variable","value":"~*req.Origin-Host"},{"mandatory":true,"path":"*diamreq.Auth-Application-Id","tag":"AuthApplicationId","type":"*variable","value":"~*vars.*appid"},{"path":"*diamreq.Re-Auth-Request-Type","tag":"ReAuthRequestType","type":"*constant","value":"0"}]},"thresholds":{"enabled":false,"indexed_selects":true,"nested_fields":false,"prefix_indexed_fields":[],"store_interval":"","suffix_indexed_fields":[]},"tls":{"ca_certificate":"","client_certificate":"","client_key":"","server_certificate":"","server_key":"","server_name":"","server_policy":4}}`
cgrCfg, err := NewCGRConfigFromJSONStringWithDefaults(cfgJSON)
if err != nil {
t.Fatal(err)
@@ -5646,7 +5646,8 @@ func TestCgrCfgEventExporterDefault(t *testing.T) {
ExportPath: "/var/spool/cgrates/ees",
Attempts: 1,
Timezone: utils.EmptyString,
- Filters: nil,
+ Filters: []string{},
+ AttributeSIDs: []string{},
Flags: utils.FlagsWithParams{},
contentFields: []*FCTemplate{},
Fields: []*FCTemplate{},
@@ -5661,7 +5662,7 @@ func TestCgrCfgEventExporterDefault(t *testing.T) {
}
func TestRpcConnsDefaults(t *testing.T) {
- eCfg := make(RpcConns)
+ eCfg := make(RPCConns)
// hardoded the *internal and *localhost connections
eCfg[utils.MetaInternal] = &RPCConn{
Strategy: rpcclient.PoolFirst,
@@ -5823,3 +5824,151 @@ func TestLoadCfgFromJSONWithLocksInvalidSeciton(t *testing.T) {
t.Errorf("Expected %+v, received %+v", expected, err)
}
}
+
+func TestCGRConfigClone(t *testing.T) {
+ cfg, _ := NewDefaultCGRConfig()
+ rcv := cfg.Clone()
+ cfg.rldChans = nil
+ rcv.rldChans = nil
+ cfg.lks = nil
+ rcv.lks = nil
+ if !reflect.DeepEqual(cfg, rcv) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(cfg), utils.ToJSON(rcv))
+ }
+
+ if !reflect.DeepEqual(cfg.dfltEvRdr, rcv.dfltEvRdr) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(cfg.dfltEvRdr), utils.ToJSON(rcv.dfltEvRdr))
+ }
+ if !reflect.DeepEqual(cfg.dfltEvExp, rcv.dfltEvExp) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(cfg.dfltEvExp), utils.ToJSON(rcv.dfltEvExp))
+ }
+ if !reflect.DeepEqual(cfg.loaderCfg, rcv.loaderCfg) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(cfg.loaderCfg), utils.ToJSON(rcv.loaderCfg))
+ }
+ if !reflect.DeepEqual(cfg.httpAgentCfg, rcv.httpAgentCfg) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(cfg.httpAgentCfg), utils.ToJSON(rcv.httpAgentCfg))
+ }
+ if !reflect.DeepEqual(cfg.rpcConns, rcv.rpcConns) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(cfg.rpcConns), utils.ToJSON(rcv.rpcConns))
+ }
+ if !reflect.DeepEqual(cfg.templates, rcv.templates) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(cfg.templates), utils.ToJSON(rcv.templates))
+ }
+ if !reflect.DeepEqual(cfg.generalCfg, rcv.generalCfg) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(cfg.generalCfg), utils.ToJSON(rcv.generalCfg))
+ }
+ if !reflect.DeepEqual(cfg.dataDbCfg, rcv.dataDbCfg) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(cfg.dataDbCfg), utils.ToJSON(rcv.dataDbCfg))
+ }
+ if !reflect.DeepEqual(cfg.storDbCfg, rcv.storDbCfg) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(cfg.storDbCfg), utils.ToJSON(rcv.storDbCfg))
+ }
+ if !reflect.DeepEqual(cfg.tlsCfg, rcv.tlsCfg) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(cfg.tlsCfg), utils.ToJSON(rcv.tlsCfg))
+ }
+ if !reflect.DeepEqual(cfg.cacheCfg, rcv.cacheCfg) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(cfg.cacheCfg), utils.ToJSON(rcv.cacheCfg))
+ }
+ if !reflect.DeepEqual(cfg.listenCfg, rcv.listenCfg) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(cfg.listenCfg), utils.ToJSON(rcv.listenCfg))
+ }
+ if !reflect.DeepEqual(cfg.httpCfg, rcv.httpCfg) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(cfg.httpCfg), utils.ToJSON(rcv.httpCfg))
+ }
+ if !reflect.DeepEqual(cfg.filterSCfg, rcv.filterSCfg) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(cfg.filterSCfg), utils.ToJSON(rcv.filterSCfg))
+ }
+ if !reflect.DeepEqual(cfg.ralsCfg, rcv.ralsCfg) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(cfg.ralsCfg), utils.ToJSON(rcv.ralsCfg))
+ }
+ if !reflect.DeepEqual(cfg.schedulerCfg, rcv.schedulerCfg) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(cfg.schedulerCfg), utils.ToJSON(rcv.schedulerCfg))
+ }
+ if !reflect.DeepEqual(cfg.cdrsCfg, rcv.cdrsCfg) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(cfg.cdrsCfg), utils.ToJSON(rcv.cdrsCfg))
+ }
+ if !reflect.DeepEqual(cfg.sessionSCfg, rcv.sessionSCfg) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(cfg.sessionSCfg), utils.ToJSON(rcv.sessionSCfg))
+ }
+ if !reflect.DeepEqual(cfg.fsAgentCfg, rcv.fsAgentCfg) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(cfg.fsAgentCfg), utils.ToJSON(rcv.fsAgentCfg))
+ }
+ if !reflect.DeepEqual(cfg.kamAgentCfg, rcv.kamAgentCfg) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(cfg.kamAgentCfg), utils.ToJSON(rcv.kamAgentCfg))
+ }
+ if !reflect.DeepEqual(cfg.asteriskAgentCfg, rcv.asteriskAgentCfg) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(cfg.asteriskAgentCfg), utils.ToJSON(rcv.asteriskAgentCfg))
+ }
+ if !reflect.DeepEqual(cfg.diameterAgentCfg, rcv.diameterAgentCfg) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(cfg.diameterAgentCfg), utils.ToJSON(rcv.diameterAgentCfg))
+ }
+ if !reflect.DeepEqual(cfg.radiusAgentCfg, rcv.radiusAgentCfg) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(cfg.radiusAgentCfg), utils.ToJSON(rcv.radiusAgentCfg))
+ }
+ if !reflect.DeepEqual(cfg.dnsAgentCfg, rcv.dnsAgentCfg) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(cfg.dnsAgentCfg), utils.ToJSON(rcv.dnsAgentCfg))
+ }
+ if !reflect.DeepEqual(cfg.attributeSCfg, rcv.attributeSCfg) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(cfg.attributeSCfg), utils.ToJSON(rcv.attributeSCfg))
+ }
+ if !reflect.DeepEqual(cfg.chargerSCfg, rcv.chargerSCfg) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(cfg.chargerSCfg), utils.ToJSON(rcv.chargerSCfg))
+ }
+ if !reflect.DeepEqual(cfg.resourceSCfg, rcv.resourceSCfg) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(cfg.resourceSCfg), utils.ToJSON(rcv.resourceSCfg))
+ }
+ if !reflect.DeepEqual(cfg.statsCfg, rcv.statsCfg) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(cfg.statsCfg), utils.ToJSON(rcv.statsCfg))
+ }
+ if !reflect.DeepEqual(cfg.thresholdSCfg, rcv.thresholdSCfg) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(cfg.thresholdSCfg), utils.ToJSON(rcv.thresholdSCfg))
+ }
+ if !reflect.DeepEqual(cfg.routeSCfg, rcv.routeSCfg) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(cfg.routeSCfg), utils.ToJSON(rcv.routeSCfg))
+ }
+ if !reflect.DeepEqual(cfg.sureTaxCfg, rcv.sureTaxCfg) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(cfg.sureTaxCfg), utils.ToJSON(rcv.sureTaxCfg))
+ }
+ if !reflect.DeepEqual(cfg.dispatcherSCfg, rcv.dispatcherSCfg) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(cfg.dispatcherSCfg), utils.ToJSON(rcv.dispatcherSCfg))
+ }
+ if !reflect.DeepEqual(cfg.dispatcherHCfg, rcv.dispatcherHCfg) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(cfg.dispatcherHCfg), utils.ToJSON(rcv.dispatcherHCfg))
+ }
+ if !reflect.DeepEqual(cfg.loaderCgrCfg, rcv.loaderCgrCfg) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(cfg.loaderCgrCfg), utils.ToJSON(rcv.loaderCgrCfg))
+ }
+ if !reflect.DeepEqual(cfg.migratorCgrCfg, rcv.migratorCgrCfg) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(cfg.migratorCgrCfg), utils.ToJSON(rcv.migratorCgrCfg))
+ }
+ if !reflect.DeepEqual(cfg.mailerCfg, rcv.mailerCfg) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(cfg.mailerCfg), utils.ToJSON(rcv.mailerCfg))
+ }
+ if !reflect.DeepEqual(cfg.analyzerSCfg, rcv.analyzerSCfg) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(cfg.analyzerSCfg), utils.ToJSON(rcv.analyzerSCfg))
+ }
+ if !reflect.DeepEqual(cfg.apier, rcv.apier) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(cfg.apier), utils.ToJSON(rcv.apier))
+ }
+ if !reflect.DeepEqual(cfg.ersCfg, rcv.ersCfg) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(cfg.ersCfg), utils.ToJSON(rcv.ersCfg))
+ }
+ if !reflect.DeepEqual(cfg.eesCfg, rcv.eesCfg) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(cfg.eesCfg), utils.ToJSON(rcv.eesCfg))
+ }
+ if !reflect.DeepEqual(cfg.rateSCfg, rcv.rateSCfg) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(cfg.rateSCfg), utils.ToJSON(rcv.rateSCfg))
+ }
+ if !reflect.DeepEqual(cfg.sipAgentCfg, rcv.sipAgentCfg) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(cfg.sipAgentCfg), utils.ToJSON(rcv.sipAgentCfg))
+ }
+ if !reflect.DeepEqual(cfg.configSCfg, rcv.configSCfg) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(cfg.configSCfg), utils.ToJSON(rcv.configSCfg))
+ }
+ if !reflect.DeepEqual(cfg.apiBanCfg, rcv.apiBanCfg) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(cfg.apiBanCfg), utils.ToJSON(rcv.apiBanCfg))
+ }
+ if !reflect.DeepEqual(cfg.coreSCfg, rcv.coreSCfg) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(cfg.coreSCfg), utils.ToJSON(rcv.coreSCfg))
+ }
+}
diff --git a/config/configsanity_test.go b/config/configsanity_test.go
index 6ffaa0ac6..0c9a6510a 100644
--- a/config/configsanity_test.go
+++ b/config/configsanity_test.go
@@ -592,8 +592,8 @@ func TestConfigSanityHTTPAgent1(t *testing.T) {
if err != nil {
t.Error(err)
}
- cfg.httpAgentCfg = HttpAgentCfgs{
- &HttpAgentCfg{
+ cfg.httpAgentCfg = HTTPAgentCfgs{
+ &HTTPAgentCfg{
SessionSConns: []string{utils.MetaInternal},
RequestProcessors: []*RequestProcessor{
{
@@ -1115,7 +1115,7 @@ func TestConfigSanityDispatcherH(t *testing.T) {
t.Errorf("Expecting: %+q received: %+q", expected, err)
}
- cfg.rpcConns = RpcConns{
+ cfg.rpcConns = RPCConns{
utils.MetaLocalHost: {},
"*conn1": {},
}
diff --git a/config/datadbcfg.go b/config/datadbcfg.go
index f20c245d2..9b94159f6 100644
--- a/config/datadbcfg.go
+++ b/config/datadbcfg.go
@@ -40,8 +40,8 @@ type DataDbCfg struct {
Opts map[string]interface{}
}
-//loadFromJsonCfg loads Database config from JsonCfg
-func (dbcfg *DataDbCfg) loadFromJsonCfg(jsnDbCfg *DbJsonCfg) (err error) {
+// loadFromJSONCfg loads Database config from JsonCfg
+func (dbcfg *DataDbCfg) loadFromJSONCfg(jsnDbCfg *DbJsonCfg) (err error) {
if jsnDbCfg == nil {
return nil
}
@@ -93,7 +93,7 @@ func (dbcfg *DataDbCfg) loadFromJsonCfg(jsnDbCfg *DbJsonCfg) (err error) {
if val == nil || !has {
val = new(ItemOpt)
}
- val.loadFromJsonCfg(vJsn) //To review if the function signature changes
+ val.loadFromJSONCfg(vJsn) //To review if the function signature changes
dbcfg.Items[kJsn] = val
}
}
@@ -106,29 +106,40 @@ func (dbcfg *DataDbCfg) loadFromJsonCfg(jsnDbCfg *DbJsonCfg) (err error) {
}
// Clone returns the cloned object
-func (dbcfg *DataDbCfg) Clone() *DataDbCfg {
- itms := make(map[string]*ItemOpt)
- for k, itm := range dbcfg.Items {
- itms[k] = itm.Clone()
- }
- opts := make(map[string]interface{})
- for k, v := range dbcfg.Opts {
- opts[k] = v
- }
- return &DataDbCfg{
+func (dbcfg *DataDbCfg) Clone() (cln *DataDbCfg) {
+ cln = &DataDbCfg{
DataDbType: dbcfg.DataDbType,
DataDbHost: dbcfg.DataDbHost,
DataDbPort: dbcfg.DataDbPort,
DataDbName: dbcfg.DataDbName,
DataDbUser: dbcfg.DataDbUser,
DataDbPass: dbcfg.DataDbPass,
- RplConns: dbcfg.RplConns,
- RmtConns: dbcfg.RmtConns,
- Items: itms,
- Opts: opts,
+ Items: make(map[string]*ItemOpt),
+ Opts: make(map[string]interface{}),
}
+ for k, itm := range dbcfg.Items {
+ cln.Items[k] = itm.Clone()
+ }
+ for k, v := range dbcfg.Opts {
+ cln.Opts[k] = v
+ }
+
+ if dbcfg.RmtConns != nil {
+ cln.RmtConns = make([]string, len(dbcfg.RmtConns))
+ for i, conn := range dbcfg.RmtConns {
+ cln.RmtConns[i] = conn
+ }
+ }
+ if dbcfg.RplConns != nil {
+ cln.RplConns = make([]string, len(dbcfg.RplConns))
+ for i, conn := range dbcfg.RplConns {
+ cln.RplConns[i] = conn
+ }
+ }
+ return
}
+// AsMapInterface returns the config as a map[string]interface{}
func (dbcfg *DataDbCfg) AsMapInterface() (initialMP map[string]interface{}, err error) {
initialMP = map[string]interface{}{
utils.DataDbTypeCfg: utils.Meta + dbcfg.DataDbType,
@@ -157,6 +168,7 @@ func (dbcfg *DataDbCfg) AsMapInterface() (initialMP map[string]interface{}, err
return
}
+// ItemOpt the options for the stored items
type ItemOpt struct {
Remote bool
Replicate bool
@@ -165,6 +177,7 @@ type ItemOpt struct {
APIKey string
}
+// AsMapInterface returns the config as a map[string]interface{}
func (itm *ItemOpt) AsMapInterface() (initialMP map[string]interface{}) {
initialMP = map[string]interface{}{
utils.RemoteCfg: itm.Remote,
@@ -179,7 +192,7 @@ func (itm *ItemOpt) AsMapInterface() (initialMP map[string]interface{}) {
return
}
-func (itm *ItemOpt) loadFromJsonCfg(jsonItm *ItemOptJson) {
+func (itm *ItemOpt) loadFromJSONCfg(jsonItm *ItemOptJson) {
if jsonItm == nil {
return
}
@@ -198,6 +211,7 @@ func (itm *ItemOpt) loadFromJsonCfg(jsonItm *ItemOptJson) {
return
}
+// Clone returns a deep copy of ItemOpt
func (itm *ItemOpt) Clone() *ItemOpt {
return &ItemOpt{
Remote: itm.Remote,
diff --git a/config/datadbcfg_test.go b/config/datadbcfg_test.go
index a21208e31..9388b7e6c 100644
--- a/config/datadbcfg_test.go
+++ b/config/datadbcfg_test.go
@@ -77,9 +77,9 @@ func TestDataDbCfgloadFromJsonCfg(t *testing.T) {
}
if jsnCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = jsnCfg.dataDbCfg.loadFromJsonCfg(nil); err != nil {
+ } else if err = jsnCfg.dataDbCfg.loadFromJSONCfg(nil); err != nil {
t.Error(err)
- } else if err = jsnCfg.dataDbCfg.loadFromJsonCfg(jsonCfg); err != nil {
+ } else if err = jsnCfg.dataDbCfg.loadFromJSONCfg(jsonCfg); err != nil {
t.Error(err)
} else {
if !reflect.DeepEqual(expected.Items[utils.MetaAccounts], jsnCfg.dataDbCfg.Items[utils.MetaAccounts]) {
@@ -101,7 +101,7 @@ func TestConnsloadFromJsonCfg(t *testing.T) {
expectedErrRmt := "Remote connection ID needs to be different than *internal"
if jsnCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = jsnCfg.dataDbCfg.loadFromJsonCfg(jsonCfg); err == nil || err.Error() != expectedErrRmt {
+ } else if err = jsnCfg.dataDbCfg.loadFromJSONCfg(jsonCfg); err == nil || err.Error() != expectedErrRmt {
t.Errorf("Expected %+v, received %+v", expectedErrRmt, err)
}
@@ -111,7 +111,7 @@ func TestConnsloadFromJsonCfg(t *testing.T) {
expectedErrRpl := "Replication connection ID needs to be different than *internal"
if jsnCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = jsnCfg.dataDbCfg.loadFromJsonCfg(jsonCfg); err == nil || err.Error() != expectedErrRpl {
+ } else if err = jsnCfg.dataDbCfg.loadFromJSONCfg(jsonCfg); err == nil || err.Error() != expectedErrRpl {
t.Errorf("Expected %+v, received %+v", expectedErrRpl, err)
}
}
@@ -130,8 +130,8 @@ func TestItemCfgloadFromJson(t *testing.T) {
RouteID: "randomID",
}
rcv := new(ItemOpt)
- rcv.loadFromJsonCfg(nil)
- rcv.loadFromJsonCfg(jsonCfg)
+ rcv.loadFromJSONCfg(nil)
+ rcv.loadFromJSONCfg(jsonCfg)
if !reflect.DeepEqual(rcv, expected) {
t.Errorf("Expected %+v \n, received %+v", utils.ToJSON(expected), utils.ToJSON(rcv))
}
@@ -153,7 +153,7 @@ func TestDataDbCfgloadFromJsonCfgPort(t *testing.T) {
t.Error(err)
} else if jsnDataDbCfg, err := jsnCfg.DbJsonCfg(DATADB_JSN); err != nil {
t.Error(err)
- } else if err = dbcfg.loadFromJsonCfg(jsnDataDbCfg); err != nil {
+ } else if err = dbcfg.loadFromJSONCfg(jsnDataDbCfg); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(expected, dbcfg) {
t.Errorf("Expected: %+v , received: %+v", expected, dbcfg)
@@ -173,7 +173,7 @@ func TestDataDbCfgloadFromJsonCfgPort(t *testing.T) {
t.Error(err)
} else if jsnDataDbCfg, err := jsnCfg.DbJsonCfg(DATADB_JSN); err != nil {
t.Error(err)
- } else if err = dbcfg.loadFromJsonCfg(jsnDataDbCfg); err != nil {
+ } else if err = dbcfg.loadFromJSONCfg(jsnDataDbCfg); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(expected, dbcfg) {
t.Errorf("Expected: %+v , received: %+v", expected, dbcfg)
@@ -193,7 +193,7 @@ func TestDataDbCfgloadFromJsonCfgPort(t *testing.T) {
t.Error(err)
} else if jsnDataDbCfg, err := jsnCfg.DbJsonCfg(DATADB_JSN); err != nil {
t.Error(err)
- } else if err = dbcfg.loadFromJsonCfg(jsnDataDbCfg); err != nil {
+ } else if err = dbcfg.loadFromJSONCfg(jsnDataDbCfg); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(expected, dbcfg) {
t.Errorf("Expected: %+v , received: %+v", expected, dbcfg)
@@ -234,7 +234,7 @@ func TestDataDBRemoteReplication(t *testing.T) {
t.Error(err)
} else if jsnDataDbCfg, err := jsnCfg.DbJsonCfg(DATADB_JSN); err != nil {
t.Error(err)
- } else if err = dbcfg.loadFromJsonCfg(jsnDataDbCfg); err != nil {
+ } else if err = dbcfg.loadFromJSONCfg(jsnDataDbCfg); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(expected, dbcfg) {
t.Errorf("Expected: %+v ,\n received: %+v", utils.ToJSON(expected), utils.ToJSON(dbcfg))
@@ -265,7 +265,7 @@ func TestDataDBRemoteReplication(t *testing.T) {
t.Error(err)
} else if jsnDataDbCfg, err := jsnCfg.DbJsonCfg(DATADB_JSN); err != nil {
t.Error(err)
- } else if err = dbcfg.loadFromJsonCfg(jsnDataDbCfg); err != nil {
+ } else if err = dbcfg.loadFromJSONCfg(jsnDataDbCfg); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(expected, dbcfg) {
t.Errorf("Expected: %+v ,\n received: %+v", utils.ToJSON(expected), utils.ToJSON(dbcfg))
@@ -296,7 +296,7 @@ func TestDataDBRemoteReplication(t *testing.T) {
t.Error(err)
} else if jsnDataDbCfg, err := jsnCfg.DbJsonCfg(DATADB_JSN); err != nil {
t.Error(err)
- } else if err = dbcfg.loadFromJsonCfg(jsnDataDbCfg); err != nil {
+ } else if err = dbcfg.loadFromJSONCfg(jsnDataDbCfg); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(expected, dbcfg) {
t.Errorf("Expected: %+v ,\n received: %+v", utils.ToJSON(expected), utils.ToJSON(dbcfg))
@@ -354,7 +354,7 @@ func TestDataDbCfgloadFromJsonCfgItems(t *testing.T) {
t.Error(err)
} else if jsnDataDbCfg, err := jsnCfg.DbJsonCfg(DATADB_JSN); err != nil {
t.Error(err)
- } else if err = dbcfg.loadFromJsonCfg(jsnDataDbCfg); err != nil {
+ } else if err = dbcfg.loadFromJSONCfg(jsnDataDbCfg); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(expected, dbcfg) {
t.Errorf("Expected: %+v ,\n received: %+v", utils.ToJSON(expected), utils.ToJSON(dbcfg))
@@ -412,7 +412,7 @@ func TestDataDbCfgloadFromJsonCfgItems(t *testing.T) {
t.Error(err)
} else if jsnDataDbCfg, err := jsnCfg.DbJsonCfg(DATADB_JSN); err != nil {
t.Error(err)
- } else if err = dbcfg.loadFromJsonCfg(jsnDataDbCfg); err != nil {
+ } else if err = dbcfg.loadFromJSONCfg(jsnDataDbCfg); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(expected, dbcfg) {
t.Errorf("Expected: %+v ,\n received: %+v", utils.ToJSON(expected), utils.ToJSON(dbcfg))
@@ -462,7 +462,7 @@ func TestDataDbCfgloadFromJsonCfgItems(t *testing.T) {
t.Error(err)
} else if jsnDataDbCfg, err := jsnCfg.DbJsonCfg(DATADB_JSN); err != nil {
t.Error(err)
- } else if err = dbcfg.loadFromJsonCfg(jsnDataDbCfg); err != nil {
+ } else if err = dbcfg.loadFromJSONCfg(jsnDataDbCfg); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(expected, dbcfg) {
t.Errorf("Expected: %+v ,\n received: %+v", utils.ToJSON(expected), utils.ToJSON(dbcfg))
@@ -572,7 +572,7 @@ func TestCloneDataDB(t *testing.T) {
}
if jsnCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = jsnCfg.dataDbCfg.loadFromJsonCfg(jsonCfg); err != nil {
+ } else if err = jsnCfg.dataDbCfg.loadFromJSONCfg(jsonCfg); err != nil {
t.Error(err)
} else {
rcv := jsnCfg.dataDbCfg.Clone()
diff --git a/config/diametercfg.go b/config/diametercfg.go
index c4f7a84d6..9f96661de 100644
--- a/config/diametercfg.go
+++ b/config/diametercfg.go
@@ -19,11 +19,10 @@ along with this program. If not, see
package config
import (
- "strings"
-
"github.com/cgrates/cgrates/utils"
)
+// DiameterAgentCfg the config section that describes the Diameter Agent
type DiameterAgentCfg struct {
Enabled bool // enables the diameter agent:
ListenNet string // sctp or tcp
@@ -32,7 +31,7 @@ type DiameterAgentCfg struct {
SessionSConns []string
OriginHost string
OriginRealm string
- VendorId int
+ VendorID int
ProductName string
ConcurrentReqs int // limit the maximum number of requests processed
SyncedConnReqs bool
@@ -42,7 +41,7 @@ type DiameterAgentCfg struct {
RequestProcessors []*RequestProcessor
}
-func (da *DiameterAgentCfg) loadFromJsonCfg(jsnCfg *DiameterAgentJsonCfg, separator string) (err error) {
+func (da *DiameterAgentCfg) loadFromJSONCfg(jsnCfg *DiameterAgentJsonCfg, separator string) (err error) {
if jsnCfg == nil {
return nil
}
@@ -62,10 +61,9 @@ func (da *DiameterAgentCfg) loadFromJsonCfg(jsnCfg *DiameterAgentJsonCfg, separa
da.SessionSConns = make([]string, len(*jsnCfg.Sessions_conns))
for idx, attrConn := range *jsnCfg.Sessions_conns {
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
+ da.SessionSConns[idx] = attrConn
if attrConn == utils.MetaInternal {
da.SessionSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS)
- } else {
- da.SessionSConns[idx] = attrConn
}
}
}
@@ -76,7 +74,7 @@ func (da *DiameterAgentCfg) loadFromJsonCfg(jsnCfg *DiameterAgentJsonCfg, separa
da.OriginRealm = *jsnCfg.Origin_realm
}
if jsnCfg.Vendor_id != nil {
- da.VendorId = *jsnCfg.Vendor_id
+ da.VendorID = *jsnCfg.Vendor_id
}
if jsnCfg.Product_name != nil {
da.ProductName = *jsnCfg.Product_name
@@ -118,40 +116,71 @@ func (da *DiameterAgentCfg) loadFromJsonCfg(jsnCfg *DiameterAgentJsonCfg, separa
return
}
-func (ds *DiameterAgentCfg) AsMapInterface(separator string) (initialMP map[string]interface{}) {
+// AsMapInterface returns the config as a map[string]interface{}
+func (da *DiameterAgentCfg) AsMapInterface(separator string) (initialMP map[string]interface{}) {
initialMP = map[string]interface{}{
- utils.EnabledCfg: ds.Enabled,
- utils.ListenNetCfg: ds.ListenNet,
- utils.ListenCfg: ds.Listen,
- utils.DictionariesPathCfg: ds.DictionariesPath,
- utils.OriginHostCfg: ds.OriginHost,
- utils.OriginRealmCfg: ds.OriginRealm,
- utils.VendorIDCfg: ds.VendorId,
- utils.ProductNameCfg: ds.ProductName,
- utils.ConcurrentRequestsCfg: ds.ConcurrentReqs,
- utils.SyncedConnReqsCfg: ds.SyncedConnReqs,
- utils.ASRTemplateCfg: ds.ASRTemplate,
- utils.RARTemplateCfg: ds.RARTemplate,
- utils.ForcedDisconnectCfg: ds.ForcedDisconnect,
+ utils.EnabledCfg: da.Enabled,
+ utils.ListenNetCfg: da.ListenNet,
+ utils.ListenCfg: da.Listen,
+ utils.DictionariesPathCfg: da.DictionariesPath,
+ utils.OriginHostCfg: da.OriginHost,
+ utils.OriginRealmCfg: da.OriginRealm,
+ utils.VendorIDCfg: da.VendorID,
+ utils.ProductNameCfg: da.ProductName,
+ utils.ConcurrentRequestsCfg: da.ConcurrentReqs,
+ utils.SyncedConnReqsCfg: da.SyncedConnReqs,
+ utils.ASRTemplateCfg: da.ASRTemplate,
+ utils.RARTemplateCfg: da.RARTemplate,
+ utils.ForcedDisconnectCfg: da.ForcedDisconnect,
}
- requestProcessors := make([]map[string]interface{}, len(ds.RequestProcessors))
- for i, item := range ds.RequestProcessors {
+ requestProcessors := make([]map[string]interface{}, len(da.RequestProcessors))
+ for i, item := range da.RequestProcessors {
requestProcessors[i] = item.AsMapInterface(separator)
}
initialMP[utils.RequestProcessorsCfg] = requestProcessors
- if ds.SessionSConns != nil {
- 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.TrimSuffix(item, utils.CONCATENATED_KEY_SEP+utils.MetaSessionS)
- } else {
- sessionSConns[i] = item
+ if da.SessionSConns != nil {
+ sessionSConns := make([]string, len(da.SessionSConns))
+ for i, item := range da.SessionSConns {
+ sessionSConns[i] = item
+ if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS) {
+ sessionSConns[i] = utils.MetaInternal
}
}
initialMP[utils.SessionSConnsCfg] = sessionSConns
}
return
}
+
+// Clone returns a deep copy of DiameterAgentCfg
+func (da DiameterAgentCfg) Clone() (cln *DiameterAgentCfg) {
+ cln = &DiameterAgentCfg{
+ Enabled: da.Enabled,
+ ListenNet: da.ListenNet,
+ Listen: da.Listen,
+ DictionariesPath: da.DictionariesPath,
+ OriginHost: da.OriginHost,
+ OriginRealm: da.OriginRealm,
+ VendorID: da.VendorID,
+ ProductName: da.ProductName,
+ ConcurrentReqs: da.ConcurrentReqs,
+ SyncedConnReqs: da.SyncedConnReqs,
+ ASRTemplate: da.ASRTemplate,
+ RARTemplate: da.RARTemplate,
+ ForcedDisconnect: da.ForcedDisconnect,
+ }
+ if da.SessionSConns != nil {
+ cln.SessionSConns = make([]string, len(da.SessionSConns))
+ for i, con := range da.SessionSConns {
+ cln.SessionSConns[i] = con
+ }
+ }
+ if da.RequestProcessors != nil {
+ cln.RequestProcessors = make([]*RequestProcessor, len(da.RequestProcessors))
+ for i, req := range da.RequestProcessors {
+ cln.RequestProcessors[i] = req.Clone()
+ }
+ }
+ return
+}
diff --git a/config/diametercfg_test.go b/config/diametercfg_test.go
index c34bf12be..061f7190d 100644
--- a/config/diametercfg_test.go
+++ b/config/diametercfg_test.go
@@ -56,7 +56,7 @@ func TestDiameterAgentCfgloadFromJsonCfg(t *testing.T) {
SessionSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS), "*conn1"},
OriginHost: "CGR-DA",
OriginRealm: "cgrates.org",
- VendorId: 0,
+ VendorID: 0,
ProductName: "randomName",
ConcurrentReqs: 10,
SyncedConnReqs: true,
@@ -72,7 +72,7 @@ func TestDiameterAgentCfgloadFromJsonCfg(t *testing.T) {
}
if jsnCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = jsnCfg.diameterAgentCfg.loadFromJsonCfg(jsonCFG, jsnCfg.generalCfg.RSRSep); err != nil {
+ } else if err = jsnCfg.diameterAgentCfg.loadFromJSONCfg(jsonCFG, jsnCfg.generalCfg.RSRSep); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(expected, jsnCfg.diameterAgentCfg) {
t.Errorf("Expected %+v \n, received %+v", utils.ToJSON(expected), utils.ToJSON(jsnCfg.diameterAgentCfg))
@@ -90,7 +90,7 @@ func TestRequestProcessorloadFromJsonCfg1(t *testing.T) {
expected := "invalid converter terminator in rule: "
if jsonCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err := jsonCfg.diameterAgentCfg.loadFromJsonCfg(cfgJSON, jsonCfg.generalCfg.RSRSep); err == nil || err.Error() != expected {
+ } else if err := jsonCfg.diameterAgentCfg.loadFromJSONCfg(cfgJSON, jsonCfg.generalCfg.RSRSep); err == nil || err.Error() != expected {
t.Errorf("Expected %+v, received %+v", expected, err)
}
}
@@ -114,7 +114,7 @@ func TestRequestProcessorloadFromJsonCfg2(t *testing.T) {
}
if jsonCfg, err := NewCGRConfigFromJSONStringWithDefaults(cfgJSONStr); err != nil {
t.Error(err)
- } else if err = jsonCfg.diameterAgentCfg.loadFromJsonCfg(cfgJSON, jsonCfg.generalCfg.RSRSep); err != nil {
+ } else if err = jsonCfg.diameterAgentCfg.loadFromJSONCfg(cfgJSON, jsonCfg.generalCfg.RSRSep); err != nil {
t.Error(err)
}
}
@@ -233,3 +233,38 @@ func TestDiameterAgentCfgAsMapInterface1(t *testing.T) {
t.Errorf("Expected %+v \n, received %+v", eMap, rcv)
}
}
+
+func TestDiameterAgentCfgClone(t *testing.T) {
+ ban := &DiameterAgentCfg{
+ Enabled: true,
+ ListenNet: "tcp",
+ Listen: "127.0.0.1:3868",
+ DictionariesPath: "/usr/share/cgrates/diameter/dict/",
+ SessionSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS), "*conn1"},
+ OriginHost: "CGR-DA",
+ OriginRealm: "cgrates.org",
+ VendorID: 0,
+ ProductName: "randomName",
+ ConcurrentReqs: 10,
+ SyncedConnReqs: true,
+ ASRTemplate: "randomTemplate",
+ RARTemplate: "randomTemplate",
+ ForcedDisconnect: "forced",
+ RequestProcessors: []*RequestProcessor{
+ {
+ ID: "cgrates",
+ Timezone: "Local",
+ },
+ },
+ }
+ rcv := ban.Clone()
+ if !reflect.DeepEqual(ban, rcv) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(ban), utils.ToJSON(rcv))
+ }
+ if rcv.SessionSConns[1] = ""; ban.SessionSConns[1] != "*conn1" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+ if rcv.RequestProcessors[0].ID = ""; ban.RequestProcessors[0].ID != "cgrates" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+}
diff --git a/config/dnsagentcfg_test.go b/config/dnsagentcfg_test.go
index dca7d9ca6..4468890be 100644
--- a/config/dnsagentcfg_test.go
+++ b/config/dnsagentcfg_test.go
@@ -299,3 +299,35 @@ func TestRequestProcessorClone(t *testing.T) {
t.Errorf("Expected clone to not modify the cloned")
}
}
+
+func TestDNSAgentCfgClone(t *testing.T) {
+ ban := &DNSAgentCfg{
+ Enabled: true,
+ Listen: "127.0.0.1:2053",
+ ListenNet: "udp",
+ SessionSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS), "*conn1"},
+ Timezone: "UTC",
+ RequestProcessors: []*RequestProcessor{
+ {
+ ID: "OutboundAUTHDryRun",
+ Filters: []string{"*string:~*req.request_type:OutboundAUTH", "*string:~*req.Msisdn:497700056231"},
+ Flags: utils.FlagsWithParamsFromSlice([]string{utils.MetaDryRun}),
+ Timezone: "UTC",
+ RequestFields: []*FCTemplate{},
+ ReplyFields: []*FCTemplate{
+ {Tag: "Allow", Path: "*rep.response.Allow", Type: "constant", Mandatory: true, Layout: utils.EmptyString},
+ },
+ },
+ },
+ }
+ rcv := ban.Clone()
+ if !reflect.DeepEqual(ban, rcv) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(ban), utils.ToJSON(rcv))
+ }
+ if rcv.SessionSConns[1] = ""; ban.SessionSConns[1] != "*conn1" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+ if rcv.RequestProcessors[0].ID = ""; ban.RequestProcessors[0].ID != "OutboundAUTHDryRun" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+}
diff --git a/config/dnsagntcfg.go b/config/dnsagntcfg.go
index 2bdd588b1..c23c96658 100644
--- a/config/dnsagntcfg.go
+++ b/config/dnsagntcfg.go
@@ -19,8 +19,6 @@ along with this program. If not, see
package config
import (
- "strings"
-
"github.com/cgrates/cgrates/utils"
)
@@ -100,10 +98,9 @@ func (da *DNSAgentCfg) AsMapInterface(separator string) (initialMP map[string]in
if da.SessionSConns != nil {
sessionSConns := make([]string, len(da.SessionSConns))
for i, item := range da.SessionSConns {
+ sessionSConns[i] = item
if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS) {
- sessionSConns[i] = strings.TrimSuffix(item, utils.CONCATENATED_KEY_SEP+utils.MetaSessionS)
- } else {
- sessionSConns[i] = item
+ sessionSConns[i] = utils.MetaInternal
}
}
initialMP[utils.SessionSConnsCfg] = sessionSConns
@@ -111,6 +108,29 @@ func (da *DNSAgentCfg) AsMapInterface(separator string) (initialMP map[string]in
return
}
+// Clone returns a deep copy of DNSAgentCfg
+func (da DNSAgentCfg) Clone() (cln *DNSAgentCfg) {
+ cln = &DNSAgentCfg{
+ Enabled: da.Enabled,
+ Listen: da.Listen,
+ ListenNet: da.ListenNet,
+ Timezone: da.Timezone,
+ }
+ if da.SessionSConns != nil {
+ cln.SessionSConns = make([]string, len(da.SessionSConns))
+ for i, con := range da.SessionSConns {
+ cln.SessionSConns[i] = con
+ }
+ }
+ if da.RequestProcessors != nil {
+ cln.RequestProcessors = make([]*RequestProcessor, len(da.RequestProcessors))
+ for i, req := range da.RequestProcessors {
+ cln.RequestProcessors[i] = req.Clone()
+ }
+ }
+ return
+}
+
// RequestProcessor is the request processor configuration
type RequestProcessor struct {
ID string
diff --git a/config/eescfg.go b/config/eescfg.go
index 56caebcce..cec00df66 100644
--- a/config/eescfg.go
+++ b/config/eescfg.go
@@ -292,13 +292,13 @@ func (eeC EventExporterCfg) Clone() (cln *EventExporterCfg) {
Opts: make(map[string]interface{}),
}
- if len(eeC.Filters) != 0 {
+ if eeC.Filters != nil {
cln.Filters = make([]string, len(eeC.Filters))
for idx, val := range eeC.Filters {
cln.Filters[idx] = val
}
}
- if len(eeC.AttributeSIDs) != 0 {
+ if eeC.AttributeSIDs != nil {
cln.AttributeSIDs = make([]string, len(eeC.AttributeSIDs))
for idx, val := range eeC.AttributeSIDs {
cln.AttributeSIDs[idx] = val
diff --git a/config/eescfg_test.go b/config/eescfg_test.go
index 035307e51..c0c222082 100644
--- a/config/eescfg_test.go
+++ b/config/eescfg_test.go
@@ -84,8 +84,8 @@ func TestEESClone(t *testing.T) {
Attempts: 1,
Timezone: utils.EmptyString,
AttributeSCtx: utils.EmptyString,
- Filters: nil,
- AttributeSIDs: nil,
+ Filters: []string{},
+ AttributeSIDs: []string{},
Flags: utils.FlagsWithParams{},
Fields: []*FCTemplate{},
contentFields: []*FCTemplate{},
@@ -320,15 +320,16 @@ func TestEventExporterSameID(t *testing.T) {
Opts: make(map[string]interface{}),
},
{
- ID: "file_exporter1",
- Type: utils.MetaFileCSV,
- FieldSep: ",",
- Tenant: nil,
- Timezone: utils.EmptyString,
- Filters: nil,
- ExportPath: "/var/spool/cgrates/ees",
- Attempts: 1,
- Flags: utils.FlagsWithParams{},
+ ID: "file_exporter1",
+ Type: utils.MetaFileCSV,
+ FieldSep: ",",
+ Tenant: nil,
+ Timezone: utils.EmptyString,
+ Filters: []string{},
+ AttributeSIDs: []string{},
+ ExportPath: "/var/spool/cgrates/ees",
+ Attempts: 1,
+ Flags: utils.FlagsWithParams{},
Fields: []*FCTemplate{
{Tag: "CustomTag2", Path: "*exp.CustomPath2", Type: utils.MetaVariable,
Value: NewRSRParsersMustCompile("CustomValue2", utils.INFIELD_SEP), Mandatory: true, Layout: time.RFC3339},
diff --git a/config/filterscfg.go b/config/filterscfg.go
index fbcbc98bd..dddbe4254 100644
--- a/config/filterscfg.go
+++ b/config/filterscfg.go
@@ -19,18 +19,17 @@ along with this program. If not, see
package config
import (
- "strings"
-
"github.com/cgrates/cgrates/utils"
)
+// FilterSCfg the filters config section
type FilterSCfg struct {
StatSConns []string
ResourceSConns []string
ApierSConns []string
}
-func (fSCfg *FilterSCfg) loadFromJsonCfg(jsnCfg *FilterSJsonCfg) (err error) {
+func (fSCfg *FilterSCfg) loadFromJSONCfg(jsnCfg *FilterSJsonCfg) (err error) {
if jsnCfg == nil {
return
}
@@ -38,10 +37,9 @@ func (fSCfg *FilterSCfg) loadFromJsonCfg(jsnCfg *FilterSJsonCfg) (err error) {
fSCfg.StatSConns = make([]string, len(*jsnCfg.Stats_conns))
for idx, connID := range *jsnCfg.Stats_conns {
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
+ fSCfg.StatSConns[idx] = connID
if connID == utils.MetaInternal {
fSCfg.StatSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStatS)
- } else {
- fSCfg.StatSConns[idx] = connID
}
}
}
@@ -49,10 +47,9 @@ func (fSCfg *FilterSCfg) loadFromJsonCfg(jsnCfg *FilterSJsonCfg) (err error) {
fSCfg.ResourceSConns = make([]string, len(*jsnCfg.Resources_conns))
for idx, connID := range *jsnCfg.Resources_conns {
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
+ fSCfg.ResourceSConns[idx] = connID
if connID == utils.MetaInternal {
fSCfg.ResourceSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaResources)
- } else {
- fSCfg.ResourceSConns[idx] = connID
}
}
}
@@ -60,25 +57,24 @@ func (fSCfg *FilterSCfg) loadFromJsonCfg(jsnCfg *FilterSJsonCfg) (err error) {
fSCfg.ApierSConns = make([]string, len(*jsnCfg.Apiers_conns))
for idx, connID := range *jsnCfg.Apiers_conns {
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
+ fSCfg.ApierSConns[idx] = connID
if connID == utils.MetaInternal {
fSCfg.ApierSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaApier)
- } else {
- fSCfg.ApierSConns[idx] = connID
}
}
}
return
}
+// AsMapInterface returns the config as a map[string]interface{}
func (fSCfg *FilterSCfg) AsMapInterface() (initialMP map[string]interface{}) {
initialMP = make(map[string]interface{})
if fSCfg.StatSConns != nil {
statSConns := make([]string, len(fSCfg.StatSConns))
for i, item := range fSCfg.StatSConns {
+ statSConns[i] = item
if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStatS) {
- statSConns[i] = strings.TrimSuffix(item, utils.CONCATENATED_KEY_SEP+utils.MetaStatS)
- } else {
- statSConns[i] = item
+ statSConns[i] = utils.MetaInternal
}
}
initialMP[utils.StatSConnsCfg] = statSConns
@@ -86,10 +82,9 @@ func (fSCfg *FilterSCfg) AsMapInterface() (initialMP map[string]interface{}) {
if fSCfg.ResourceSConns != nil {
resourceSConns := make([]string, len(fSCfg.ResourceSConns))
for i, item := range fSCfg.ResourceSConns {
+ resourceSConns[i] = item
if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaResources) {
- resourceSConns[i] = strings.TrimSuffix(item, utils.CONCATENATED_KEY_SEP+utils.MetaResources)
- } else {
- resourceSConns[i] = item
+ resourceSConns[i] = utils.MetaInternal
}
}
initialMP[utils.ResourceSConnsCfg] = resourceSConns
@@ -97,13 +92,36 @@ func (fSCfg *FilterSCfg) AsMapInterface() (initialMP map[string]interface{}) {
if fSCfg.ApierSConns != nil {
apierConns := make([]string, len(fSCfg.ApierSConns))
for i, item := range fSCfg.ApierSConns {
+ apierConns[i] = item
if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaApier) {
- apierConns[i] = strings.TrimSuffix(item, utils.CONCATENATED_KEY_SEP+utils.MetaApier)
- } else {
- apierConns[i] = item
+ apierConns[i] = utils.MetaInternal
}
}
initialMP[utils.ApierSConnsCfg] = apierConns
}
return
}
+
+// Clone returns a deep copy of FilterSCfg
+func (fSCfg FilterSCfg) Clone() (cln *FilterSCfg) {
+ cln = new(FilterSCfg)
+ if fSCfg.StatSConns != nil {
+ cln.StatSConns = make([]string, len(fSCfg.StatSConns))
+ for i, con := range fSCfg.StatSConns {
+ cln.StatSConns[i] = con
+ }
+ }
+ if fSCfg.ResourceSConns != nil {
+ cln.ResourceSConns = make([]string, len(fSCfg.ResourceSConns))
+ for i, con := range fSCfg.ResourceSConns {
+ cln.ResourceSConns[i] = con
+ }
+ }
+ if fSCfg.ApierSConns != nil {
+ cln.ApierSConns = make([]string, len(fSCfg.ApierSConns))
+ for i, con := range fSCfg.ApierSConns {
+ cln.ApierSConns[i] = con
+ }
+ }
+ return
+}
diff --git a/config/filterscfg_test.go b/config/filterscfg_test.go
index 829109b8d..a3f9d14da 100644
--- a/config/filterscfg_test.go
+++ b/config/filterscfg_test.go
@@ -37,7 +37,7 @@ func TestFilterSCfgloadFromJsonCfg(t *testing.T) {
}
if jsnCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = jsnCfg.filterSCfg.loadFromJsonCfg(cfgJSONS); err != nil {
+ } else if err = jsnCfg.filterSCfg.loadFromJSONCfg(cfgJSONS); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(expected, jsnCfg.filterSCfg) {
t.Errorf("Expected %+v \n, received %+v", utils.ToJSON(expected), utils.ToJSON(jsnCfg.filterSCfg))
@@ -79,3 +79,24 @@ func TestFilterSCfgAsMapInterface2(t *testing.T) {
t.Errorf("Expected %+v, received %+v", eMap, rcv)
}
}
+
+func TestFilterSCfgClone(t *testing.T) {
+ ban := &FilterSCfg{
+ StatSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStats), "*conn1"},
+ ResourceSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaResources), "*conn1"},
+ ApierSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaApier), "*conn1"},
+ }
+ rcv := ban.Clone()
+ if !reflect.DeepEqual(ban, rcv) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(ban), utils.ToJSON(rcv))
+ }
+ if rcv.StatSConns[1] = ""; ban.StatSConns[1] != "*conn1" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+ if rcv.ResourceSConns[1] = ""; ban.ResourceSConns[1] != "*conn1" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+ if rcv.ApierSConns[1] = ""; ban.ApierSConns[1] != "*conn1" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+}
diff --git a/config/generalcfg.go b/config/generalcfg.go
index 52dc40949..fa6f319aa 100644
--- a/config/generalcfg.go
+++ b/config/generalcfg.go
@@ -25,7 +25,7 @@ import (
"github.com/cgrates/cgrates/utils"
)
-// General config section
+// GeneralCfg is the general config section
type GeneralCfg struct {
NodeID string // Identifier for this engine instance
Logger string // dictates the way logs are displayed/stored
@@ -54,8 +54,8 @@ type GeneralCfg struct {
MaxParallelConns int // the maximum number of connection used by the *parallel strategy
}
-//loadFromJsonCfg loads General config from JsonCfg
-func (gencfg *GeneralCfg) loadFromJsonCfg(jsnGeneralCfg *GeneralJsonCfg) (err error) {
+// loadFromJSONCfg loads General config from JsonCfg
+func (gencfg *GeneralCfg) loadFromJSONCfg(jsnGeneralCfg *GeneralJsonCfg) (err error) {
if jsnGeneralCfg == nil {
return nil
}
@@ -151,6 +151,7 @@ func (gencfg *GeneralCfg) loadFromJsonCfg(jsnGeneralCfg *GeneralJsonCfg) (err er
return nil
}
+// AsMapInterface returns the config as a map[string]interface{}
func (gencfg *GeneralCfg) AsMapInterface() (initialMP map[string]interface{}) {
initialMP = map[string]interface{}{
utils.NodeIDCfg: gencfg.NodeID,
@@ -172,41 +173,66 @@ func (gencfg *GeneralCfg) AsMapInterface() (initialMP map[string]interface{}) {
utils.DigestEqualCfg: gencfg.DigestEqual,
utils.RSRSepCfg: gencfg.RSRSep,
utils.MaxParallelConnsCfg: gencfg.MaxParallelConns,
+ utils.LockingTimeoutCfg: "0",
+ utils.FailedPostsTTLCfg: "0",
+ utils.ConnectTimeoutCfg: "0",
+ utils.ReplyTimeoutCfg: "0",
+ utils.MinCallDurationCfg: "0",
+ utils.MaxCallDurationCfg: "0",
}
if gencfg.LockingTimeout != 0 {
initialMP[utils.LockingTimeoutCfg] = gencfg.LockingTimeout.String()
- } else {
- initialMP[utils.LockingTimeoutCfg] = "0"
}
if gencfg.FailedPostsTTL != 0 {
initialMP[utils.FailedPostsTTLCfg] = gencfg.FailedPostsTTL.String()
- } else {
- initialMP[utils.FailedPostsTTLCfg] = "0"
}
if gencfg.ConnectTimeout != 0 {
initialMP[utils.ConnectTimeoutCfg] = gencfg.ConnectTimeout.String()
- } else {
- initialMP[utils.ConnectTimeoutCfg] = "0"
}
if gencfg.ReplyTimeout != 0 {
initialMP[utils.ReplyTimeoutCfg] = gencfg.ReplyTimeout.String()
- } else {
- initialMP[utils.ReplyTimeoutCfg] = "0"
}
if gencfg.MinCallDuration != 0 {
initialMP[utils.MinCallDurationCfg] = gencfg.MinCallDuration.String()
- } else if gencfg.MinCallDuration == 0 {
- initialMP[utils.MinCallDurationCfg] = "0"
}
if gencfg.MaxCallDuration != 0 {
initialMP[utils.MaxCallDurationCfg] = gencfg.MaxCallDuration.String()
- } else if gencfg.MaxCallDuration == 0 {
- initialMP[utils.MaxCallDurationCfg] = "0"
}
return
}
+
+// Clone returns a deep copy of GeneralCfg
+func (gencfg GeneralCfg) Clone() *GeneralCfg {
+ return &GeneralCfg{
+ NodeID: gencfg.NodeID,
+ Logger: gencfg.Logger,
+ LogLevel: gencfg.LogLevel,
+ RoundingDecimals: gencfg.RoundingDecimals,
+ DBDataEncoding: gencfg.DBDataEncoding,
+ TpExportPath: gencfg.TpExportPath,
+ PosterAttempts: gencfg.PosterAttempts,
+ FailedPostsDir: gencfg.FailedPostsDir,
+ FailedPostsTTL: gencfg.FailedPostsTTL,
+ DefaultReqType: gencfg.DefaultReqType,
+ DefaultCategory: gencfg.DefaultCategory,
+ DefaultTenant: gencfg.DefaultTenant,
+ DefaultTimezone: gencfg.DefaultTimezone,
+ DefaultCaching: gencfg.DefaultCaching,
+ ConnectAttempts: gencfg.ConnectAttempts,
+ Reconnects: gencfg.Reconnects,
+ ConnectTimeout: gencfg.ConnectTimeout,
+ ReplyTimeout: gencfg.ReplyTimeout,
+ LockingTimeout: gencfg.LockingTimeout,
+ MinCallDuration: gencfg.MinCallDuration,
+ MaxCallDuration: gencfg.MaxCallDuration,
+ DigestSeparator: gencfg.DigestSeparator,
+ DigestEqual: gencfg.DigestEqual,
+ RSRSep: gencfg.RSRSep,
+ MaxParallelConns: gencfg.MaxParallelConns,
+ }
+}
diff --git a/config/generalcfg_test.go b/config/generalcfg_test.go
index 5047c9e8f..c5623382f 100644
--- a/config/generalcfg_test.go
+++ b/config/generalcfg_test.go
@@ -76,7 +76,7 @@ func TestGeneralCfgloadFromJsonCfg(t *testing.T) {
}
if jsnCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = jsnCfg.generalCfg.loadFromJsonCfg(cfgJSON); err != nil {
+ } else if err = jsnCfg.generalCfg.loadFromJSONCfg(cfgJSON); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(expected, jsnCfg.generalCfg) {
t.Errorf("Expected %+v \n, received %+v", utils.ToJSON(expected), utils.ToJSON(jsnCfg.generalCfg))
@@ -90,7 +90,7 @@ func TestGeneralParseDurationCfgloadFromJsonCfg(t *testing.T) {
expected := "time: unknown unit \"ss\" in duration \"1ss\""
if jsonCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = jsonCfg.generalCfg.loadFromJsonCfg(cfgJSON); err == nil || err.Error() != expected {
+ } else if err = jsonCfg.generalCfg.loadFromJSONCfg(cfgJSON); err == nil || err.Error() != expected {
t.Errorf("Expected %+v, received %v", expected, err)
}
@@ -99,7 +99,7 @@ func TestGeneralParseDurationCfgloadFromJsonCfg(t *testing.T) {
}
if jsonCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = jsonCfg.generalCfg.loadFromJsonCfg(cfgJSON1); err == nil || err.Error() != expected {
+ } else if err = jsonCfg.generalCfg.loadFromJSONCfg(cfgJSON1); err == nil || err.Error() != expected {
t.Errorf("Expected %+v, received %v", expected, err)
}
@@ -108,7 +108,7 @@ func TestGeneralParseDurationCfgloadFromJsonCfg(t *testing.T) {
}
if jsonCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = jsonCfg.generalCfg.loadFromJsonCfg(cfgJSON2); err == nil || err.Error() != expected {
+ } else if err = jsonCfg.generalCfg.loadFromJSONCfg(cfgJSON2); err == nil || err.Error() != expected {
t.Errorf("Expected %+v, received %v", expected, err)
}
@@ -117,7 +117,7 @@ func TestGeneralParseDurationCfgloadFromJsonCfg(t *testing.T) {
}
if jsonCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = jsonCfg.generalCfg.loadFromJsonCfg(cfgJSON3); err == nil || err.Error() != expected {
+ } else if err = jsonCfg.generalCfg.loadFromJSONCfg(cfgJSON3); err == nil || err.Error() != expected {
t.Errorf("Expected %+v, received %v", expected, err)
}
@@ -126,7 +126,7 @@ func TestGeneralParseDurationCfgloadFromJsonCfg(t *testing.T) {
}
if jsonCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = jsonCfg.generalCfg.loadFromJsonCfg(cfgJSON4); err == nil || err.Error() != expected {
+ } else if err = jsonCfg.generalCfg.loadFromJSONCfg(cfgJSON4); err == nil || err.Error() != expected {
t.Errorf("Expected %+v, received %v", expected, err)
}
@@ -135,7 +135,7 @@ func TestGeneralParseDurationCfgloadFromJsonCfg(t *testing.T) {
}
if jsonCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = jsonCfg.generalCfg.loadFromJsonCfg(cfgJSON5); err == nil || err.Error() != expected {
+ } else if err = jsonCfg.generalCfg.loadFromJSONCfg(cfgJSON5); err == nil || err.Error() != expected {
t.Errorf("Expected %+v, received %v", expected, err)
}
@@ -248,3 +248,39 @@ func TestGeneralCfgAsMapInterface1(t *testing.T) {
t.Errorf("Expected %+v \n, recevied %+v", utils.ToJSON(eMap), utils.ToJSON(rcv))
}
}
+
+func TestGeneralCfgClone(t *testing.T) {
+ ban := &GeneralCfg{
+ NodeID: "randomID",
+ Logger: utils.MetaSysLog,
+ LogLevel: 6,
+ RoundingDecimals: 5,
+ DBDataEncoding: "msgpack",
+ TpExportPath: "/var/spool/cgrates/tpe",
+ PosterAttempts: 3,
+ FailedPostsDir: "/var/spool/cgrates/failed_posts",
+ DefaultReqType: utils.META_RATED,
+ DefaultCategory: utils.CALL,
+ DefaultTenant: "cgrates.org",
+ DefaultTimezone: "Local",
+ ConnectAttempts: 3,
+ Reconnects: -1,
+ ConnectTimeout: time.Second,
+ ReplyTimeout: 2 * time.Second,
+ MinCallDuration: 0,
+ MaxCallDuration: 3 * time.Hour,
+ DigestSeparator: ",",
+ DigestEqual: ":",
+ MaxParallelConns: 100,
+ RSRSep: ";",
+ DefaultCaching: utils.MetaReload,
+ FailedPostsTTL: 2,
+ }
+ rcv := ban.Clone()
+ if !reflect.DeepEqual(ban, rcv) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(ban), utils.ToJSON(rcv))
+ }
+ if rcv.NodeID = ""; ban.NodeID != "randomID" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+}
diff --git a/config/httpagntcfg.go b/config/httpagntcfg.go
index 1f5046d5b..c384dbed1 100644
--- a/config/httpagntcfg.go
+++ b/config/httpagntcfg.go
@@ -22,14 +22,15 @@ import (
"github.com/cgrates/cgrates/utils"
)
-type HttpAgentCfgs []*HttpAgentCfg
+// HTTPAgentCfgs the config section for HTTP Agent
+type HTTPAgentCfgs []*HTTPAgentCfg
-func (hcfgs *HttpAgentCfgs) loadFromJsonCfg(jsnHttpAgntCfg *[]*HttpAgentJsonCfg, separator string) (err error) {
- if jsnHttpAgntCfg == nil {
+func (hcfgs *HTTPAgentCfgs) loadFromJSONCfg(jsnHTTPAgntCfg *[]*HttpAgentJsonCfg, separator string) (err error) {
+ if jsnHTTPAgntCfg == nil {
return nil
}
- for _, jsnCfg := range *jsnHttpAgntCfg {
- hac := new(HttpAgentCfg)
+ for _, jsnCfg := range *jsnHTTPAgntCfg {
+ hac := new(HTTPAgentCfg)
var haveID bool
if jsnCfg.Id != nil {
for _, val := range *hcfgs {
@@ -41,7 +42,7 @@ func (hcfgs *HttpAgentCfgs) loadFromJsonCfg(jsnHttpAgntCfg *[]*HttpAgentJsonCfg,
}
}
- if err := hac.loadFromJsonCfg(jsnCfg, separator); err != nil {
+ if err := hac.loadFromJSONCfg(jsnCfg, separator); err != nil {
return err
}
if !haveID {
@@ -51,7 +52,8 @@ func (hcfgs *HttpAgentCfgs) loadFromJsonCfg(jsnHttpAgntCfg *[]*HttpAgentJsonCfg,
return nil
}
-func (hcfgs HttpAgentCfgs) AsMapInterface(separator string) (mp []map[string]interface{}) {
+// AsMapInterface returns the config as a map[string]interface{}
+func (hcfgs HTTPAgentCfgs) AsMapInterface(separator string) (mp []map[string]interface{}) {
mp = make([]map[string]interface{}, len(hcfgs))
for i, item := range hcfgs {
mp[i] = item.AsMapInterface(separator)
@@ -59,16 +61,29 @@ func (hcfgs HttpAgentCfgs) AsMapInterface(separator string) (mp []map[string]int
return
}
-type HttpAgentCfg struct {
+// Clone returns a deep copy of HTTPAgentCfgs
+func (hcfgs HTTPAgentCfgs) Clone() (cln HTTPAgentCfgs) {
+ if hcfgs == nil {
+ return
+ }
+ cln = make(HTTPAgentCfgs, len(hcfgs))
+ for i, h := range hcfgs {
+ cln[i] = h.Clone()
+ }
+ return
+}
+
+// HTTPAgentCfg the config for a HTTP Agent
+type HTTPAgentCfg struct {
ID string // identifier for the agent, so we can update it's processors
- Url string
+ URL string
SessionSConns []string
RequestPayload string
ReplyPayload string
RequestProcessors []*RequestProcessor
}
-func (ca *HttpAgentCfg) appendHttpAgntProcCfgs(hps *[]*ReqProcessorJsnCfg, separator string) (err error) {
+func (ha *HTTPAgentCfg) appendHTTPAgntProcCfgs(hps *[]*ReqProcessorJsnCfg, separator string) (err error) {
if hps == nil {
return
}
@@ -76,7 +91,7 @@ func (ca *HttpAgentCfg) appendHttpAgntProcCfgs(hps *[]*ReqProcessorJsnCfg, separ
rp := new(RequestProcessor)
var haveID bool
if reqProcJsn.ID != nil {
- for _, rpSet := range ca.RequestProcessors {
+ for _, rpSet := range ha.RequestProcessors {
if rpSet.ID == *reqProcJsn.ID {
rp = rpSet // Will load data into the one set
haveID = true
@@ -88,58 +103,80 @@ func (ca *HttpAgentCfg) appendHttpAgntProcCfgs(hps *[]*ReqProcessorJsnCfg, separ
return
}
if !haveID {
- ca.RequestProcessors = append(ca.RequestProcessors, rp)
+ ha.RequestProcessors = append(ha.RequestProcessors, rp)
}
}
return
}
-func (ca *HttpAgentCfg) loadFromJsonCfg(jsnCfg *HttpAgentJsonCfg, separator string) (err error) {
+func (ha *HTTPAgentCfg) loadFromJSONCfg(jsnCfg *HttpAgentJsonCfg, separator string) (err error) {
if jsnCfg == nil {
return nil
}
if jsnCfg.Id != nil {
- ca.ID = *jsnCfg.Id
+ ha.ID = *jsnCfg.Id
}
if jsnCfg.Url != nil {
- ca.Url = *jsnCfg.Url
+ ha.URL = *jsnCfg.Url
}
if jsnCfg.Sessions_conns != nil {
- ca.SessionSConns = make([]string, len(*jsnCfg.Sessions_conns))
+ ha.SessionSConns = make([]string, len(*jsnCfg.Sessions_conns))
for idx, connID := range *jsnCfg.Sessions_conns {
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
if connID == utils.MetaInternal {
- ca.SessionSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS)
+ ha.SessionSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS)
} else {
- ca.SessionSConns[idx] = connID
+ ha.SessionSConns[idx] = connID
}
}
}
if jsnCfg.Request_payload != nil {
- ca.RequestPayload = *jsnCfg.Request_payload
+ ha.RequestPayload = *jsnCfg.Request_payload
}
if jsnCfg.Reply_payload != nil {
- ca.ReplyPayload = *jsnCfg.Reply_payload
+ ha.ReplyPayload = *jsnCfg.Reply_payload
}
- if err = ca.appendHttpAgntProcCfgs(jsnCfg.Request_processors, separator); err != nil {
+ if err = ha.appendHTTPAgntProcCfgs(jsnCfg.Request_processors, separator); err != nil {
return err
}
return nil
}
-func (ca *HttpAgentCfg) AsMapInterface(separator string) (initialMP map[string]interface{}) {
+// AsMapInterface returns the config as a map[string]interface{}
+func (ha *HTTPAgentCfg) AsMapInterface(separator string) (initialMP map[string]interface{}) {
initialMP = map[string]interface{}{
- utils.IDCfg: ca.ID,
- utils.URLCfg: ca.Url,
- utils.SessionSConnsCfg: ca.SessionSConns,
- utils.RequestPayloadCfg: ca.RequestPayload,
- utils.ReplyPayloadCfg: ca.ReplyPayload,
+ utils.IDCfg: ha.ID,
+ utils.URLCfg: ha.URL,
+ utils.SessionSConnsCfg: ha.SessionSConns,
+ utils.RequestPayloadCfg: ha.RequestPayload,
+ utils.ReplyPayloadCfg: ha.ReplyPayload,
}
- requestProcessors := make([]map[string]interface{}, len(ca.RequestProcessors))
- for i, item := range ca.RequestProcessors {
+ requestProcessors := make([]map[string]interface{}, len(ha.RequestProcessors))
+ for i, item := range ha.RequestProcessors {
requestProcessors[i] = item.AsMapInterface(separator)
}
initialMP[utils.RequestProcessorsCfg] = requestProcessors
return
}
+
+// Clone returns a deep copy of HTTPAgentCfg
+func (ha HTTPAgentCfg) Clone() (cln *HTTPAgentCfg) {
+ cln = &HTTPAgentCfg{
+ ID: ha.ID,
+ URL: ha.URL,
+ RequestPayload: ha.RequestPayload,
+ ReplyPayload: ha.ReplyPayload,
+ RequestProcessors: make([]*RequestProcessor, len(ha.RequestProcessors)),
+ }
+ if ha.SessionSConns != nil {
+ cln.SessionSConns = make([]string, len(ha.SessionSConns))
+ for i, con := range ha.SessionSConns {
+ cln.SessionSConns[i] = con
+ }
+ }
+ for i, req := range ha.RequestProcessors {
+ cln.RequestProcessors[i] = req.Clone()
+ }
+ return
+}
diff --git a/config/httpagntcfg_test.go b/config/httpagntcfg_test.go
index 15c599f7d..6d7e98512 100644
--- a/config/httpagntcfg_test.go
+++ b/config/httpagntcfg_test.go
@@ -54,10 +54,10 @@ func TestHttpAgentCfgsloadFromJsonCfgCase1(t *testing.T) {
},
},
}
- expected := HttpAgentCfgs{
+ expected := HTTPAgentCfgs{
{
ID: "RandomID",
- Url: "/randomURL",
+ URL: "/randomURL",
SessionSConns: []string{"*internal:*sessions"},
RequestPayload: "*url",
ReplyPayload: "*xml",
@@ -81,7 +81,7 @@ func TestHttpAgentCfgsloadFromJsonCfgCase1(t *testing.T) {
expected[0].RequestProcessors[0].ReplyFields[0].ComputePath()
if jsnCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = jsnCfg.httpAgentCfg.loadFromJsonCfg(cfgJSON, jsnCfg.generalCfg.RSRSep); err != nil {
+ } else if err = jsnCfg.httpAgentCfg.loadFromJSONCfg(cfgJSON, jsnCfg.generalCfg.RSRSep); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(&expected, &jsnCfg.httpAgentCfg) {
t.Errorf("Expected %+v \n, received %+v", utils.ToJSON(expected), utils.ToJSON(jsnCfg.httpAgentCfg))
@@ -158,10 +158,10 @@ func TestHttpAgentCfgsloadFromJsonCfgCase2(t *testing.T) {
},
},
}
- expected := HttpAgentCfgs{
- &HttpAgentCfg{
+ expected := HTTPAgentCfgs{
+ &HTTPAgentCfg{
ID: "conecto1",
- Url: "/conecto",
+ URL: "/conecto",
SessionSConns: []string{utils.MetaLocalHost},
RequestPayload: utils.MetaUrl,
ReplyPayload: utils.MetaXml,
@@ -203,9 +203,9 @@ func TestHttpAgentCfgsloadFromJsonCfgCase2(t *testing.T) {
Layout: time.RFC3339,
}},
}},
- }, &HttpAgentCfg{
+ }, &HTTPAgentCfg{
ID: "conecto_xml",
- Url: "/conecto_xml",
+ URL: "/conecto_xml",
SessionSConns: []string{utils.MetaLocalHost},
RequestPayload: utils.MetaXml,
ReplyPayload: utils.MetaXml,
@@ -222,7 +222,7 @@ func TestHttpAgentCfgsloadFromJsonCfgCase2(t *testing.T) {
expected[0].RequestProcessors[1].RequestFields[0].ComputePath()
if cfgJsn, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = cfgJsn.httpAgentCfg.loadFromJsonCfg(cfgJSON, cfgJsn.generalCfg.RSRSep); err != nil {
+ } else if err = cfgJsn.httpAgentCfg.loadFromJSONCfg(cfgJSON, cfgJsn.generalCfg.RSRSep); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(expected, cfgJsn.httpAgentCfg) {
t.Errorf("Expected %+v \n, received %+v", utils.ToJSON(expected), utils.ToJSON(cfgJsn.httpAgentCfg))
@@ -247,9 +247,9 @@ func TestHttpAgentCfgloadFromJsonCfgCase3(t *testing.T) {
},
},
}
- expected := HttpAgentCfg{
+ expected := HTTPAgentCfg{
ID: "conecto1",
- Url: "/conecto",
+ URL: "/conecto",
SessionSConns: []string{utils.MetaLocalHost},
RequestPayload: "*url",
ReplyPayload: "*xml",
@@ -262,8 +262,8 @@ func TestHttpAgentCfgloadFromJsonCfgCase3(t *testing.T) {
ReplyFields: []*FCTemplate{},
}},
}
- var httpcfg HttpAgentCfg
- if err = httpcfg.loadFromJsonCfg(jsnhttpCfg, utils.INFIELD_SEP); err != nil {
+ var httpcfg HTTPAgentCfg
+ if err = httpcfg.loadFromJSONCfg(jsnhttpCfg, utils.INFIELD_SEP); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(expected, httpcfg) {
t.Errorf("Expected: %+v \n, received: %+v", utils.ToJSON(expected), utils.ToJSON(httpcfg))
@@ -343,7 +343,7 @@ func TestHttpAgentCfgloadFromJsonCfgCase4(t *testing.T) {
expected := "invalid converter terminator in rule: "
if jsonCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = jsonCfg.httpAgentCfg.loadFromJsonCfg(cfgJSON, jsonCfg.generalCfg.RSRSep); err == nil || err.Error() != expected {
+ } else if err = jsonCfg.httpAgentCfg.loadFromJSONCfg(cfgJSON, jsonCfg.generalCfg.RSRSep); err == nil || err.Error() != expected {
t.Errorf("Expected %+v, received %+v", expected, err)
}
}
@@ -358,7 +358,7 @@ func TestHttpAgentCfgloadFromJsonCfgCase5(t *testing.T) {
if err != nil {
t.Error(err)
}
- if err := jsonCfg.httpAgentCfg.loadFromJsonCfg(cfgJSON, jsonCfg.generalCfg.RSRSep); err != nil {
+ if err := jsonCfg.httpAgentCfg.loadFromJSONCfg(cfgJSON, jsonCfg.generalCfg.RSRSep); err != nil {
t.Error(err)
}
}
@@ -368,8 +368,8 @@ func TestHttpAgentCfgloadFromJsonCfgCase6(t *testing.T) {
if err != nil {
t.Error(err)
}
- httpAgentCfg := new(HttpAgentCfg)
- if err := httpAgentCfg.loadFromJsonCfg(nil, jsonCfg.generalCfg.RSRSep); err != nil {
+ httpAgentCfg := new(HTTPAgentCfg)
+ if err := httpAgentCfg.loadFromJSONCfg(nil, jsonCfg.generalCfg.RSRSep); err != nil {
t.Error(err)
}
}
@@ -387,14 +387,14 @@ func TestHttpAgentCfgloadFromJsonCfgCase7(t *testing.T) {
Id: utils.StringPointer("RandomID"),
},
}
- expected := HttpAgentCfgs{
+ expected := HTTPAgentCfgs{
{
ID: "RandomID",
},
}
if jsnCfg, err := NewCGRConfigFromJSONStringWithDefaults(cfgJSONStr); err != nil {
t.Error(err)
- } else if err = jsnCfg.httpAgentCfg.loadFromJsonCfg(cfgJSON, jsnCfg.generalCfg.RSRSep); err != nil {
+ } else if err = jsnCfg.httpAgentCfg.loadFromJSONCfg(cfgJSON, jsnCfg.generalCfg.RSRSep); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(&expected, &jsnCfg.httpAgentCfg) {
t.Errorf("Expected %+v \n, received %+v", utils.ToJSON(expected), utils.ToJSON(jsnCfg.httpAgentCfg))
@@ -402,9 +402,9 @@ func TestHttpAgentCfgloadFromJsonCfgCase7(t *testing.T) {
}
func TestHttpAgentCfgappendHttpAgntProcCfgs(t *testing.T) {
- initial := &HttpAgentCfg{
+ initial := &HTTPAgentCfg{
ID: "conecto1",
- Url: "/conecto",
+ URL: "/conecto",
SessionSConns: []string{utils.MetaLocalHost},
RequestPayload: "*url",
ReplyPayload: "*xml",
@@ -452,9 +452,9 @@ func TestHttpAgentCfgappendHttpAgntProcCfgs(t *testing.T) {
}},
},
}
- expected := &HttpAgentCfg{
+ expected := &HTTPAgentCfg{
ID: "conecto1",
- Url: "/conecto",
+ URL: "/conecto",
SessionSConns: []string{utils.MetaLocalHost},
RequestPayload: "*url",
ReplyPayload: "*xml",
@@ -490,7 +490,7 @@ func TestHttpAgentCfgappendHttpAgntProcCfgs(t *testing.T) {
}
expected.RequestProcessors[0].ReplyFields[0].ComputePath()
expected.RequestProcessors[1].ReplyFields[0].ComputePath()
- if err = initial.appendHttpAgntProcCfgs(proceses, utils.INFIELD_SEP); err != nil {
+ if err = initial.appendHTTPAgntProcCfgs(proceses, utils.INFIELD_SEP); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(expected, initial) {
t.Errorf("Expected: %+v , received: %+v", utils.ToJSON(expected), utils.ToJSON(initial))
@@ -563,3 +563,40 @@ func TestHttpAgentCfgAsMapInterface(t *testing.T) {
t.Errorf("Expected %+v, recieved %+v", eMap, rcv)
}
}
+
+func TestHTTPAgentCfgsClone(t *testing.T) {
+ ban := HTTPAgentCfgs{
+ {
+ ID: "RandomID",
+ URL: "/randomURL",
+ SessionSConns: []string{"*internal:*sessions", "*conn1"},
+ RequestPayload: "*url",
+ ReplyPayload: "*xml",
+ RequestProcessors: []*RequestProcessor{{
+ ID: "OutboundAUTHDryRun",
+ Filters: []string{"*string:*req.request_type:OutboundAUTH", "*string:*req.Msisdn:497700056231"},
+ Tenant: NewRSRParsersMustCompile("cgrates.org", utils.INFIELD_SEP),
+ Flags: utils.FlagsWithParams{utils.MetaDryRun: {}},
+ RequestFields: []*FCTemplate{},
+ ReplyFields: []*FCTemplate{{
+ Tag: "Allow",
+ Path: "response.Allow",
+ Type: "*constant",
+ Value: NewRSRParsersMustCompile("1", utils.INFIELD_SEP),
+ Mandatory: true,
+ Layout: time.RFC3339,
+ }},
+ }},
+ },
+ }
+ rcv := ban.Clone()
+ if !reflect.DeepEqual(ban, rcv) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(ban), utils.ToJSON(rcv))
+ }
+ if rcv[0].SessionSConns[1] = ""; ban[0].SessionSConns[1] != "*conn1" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+ if rcv[0].RequestProcessors[0].ID = ""; ban[0].RequestProcessors[0].ID != "OutboundAUTHDryRun" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+}
diff --git a/config/httpcfg.go b/config/httpcfg.go
index 8caec6dd7..3bd08d68b 100644
--- a/config/httpcfg.go
+++ b/config/httpcfg.go
@@ -34,40 +34,41 @@ type HTTPCfg struct {
ClientOpts map[string]interface{}
}
-// loadFromJsonCfg loads Database config from JsonCfg
-func (httpcfg *HTTPCfg) loadFromJsonCfg(jsnHttpCfg *HTTPJsonCfg) (err error) {
- if jsnHttpCfg == nil {
+// loadFromJSONCfg loads Database config from JsonCfg
+func (httpcfg *HTTPCfg) loadFromJSONCfg(jsnHTTPCfg *HTTPJsonCfg) (err error) {
+ if jsnHTTPCfg == nil {
return nil
}
- if jsnHttpCfg.Json_rpc_url != nil {
- httpcfg.HTTPJsonRPCURL = *jsnHttpCfg.Json_rpc_url
+ if jsnHTTPCfg.Json_rpc_url != nil {
+ httpcfg.HTTPJsonRPCURL = *jsnHTTPCfg.Json_rpc_url
}
- if jsnHttpCfg.Dispatchers_registrar_url != nil {
- httpcfg.DispatchersRegistrarURL = *jsnHttpCfg.Dispatchers_registrar_url
+ if jsnHTTPCfg.Dispatchers_registrar_url != nil {
+ httpcfg.DispatchersRegistrarURL = *jsnHTTPCfg.Dispatchers_registrar_url
}
- if jsnHttpCfg.Ws_url != nil {
- httpcfg.HTTPWSURL = *jsnHttpCfg.Ws_url
+ if jsnHTTPCfg.Ws_url != nil {
+ httpcfg.HTTPWSURL = *jsnHTTPCfg.Ws_url
}
- if jsnHttpCfg.Freeswitch_cdrs_url != nil {
- httpcfg.HTTPFreeswitchCDRsURL = *jsnHttpCfg.Freeswitch_cdrs_url
+ if jsnHTTPCfg.Freeswitch_cdrs_url != nil {
+ httpcfg.HTTPFreeswitchCDRsURL = *jsnHTTPCfg.Freeswitch_cdrs_url
}
- if jsnHttpCfg.Http_Cdrs != nil {
- httpcfg.HTTPCDRsURL = *jsnHttpCfg.Http_Cdrs
+ if jsnHTTPCfg.Http_Cdrs != nil {
+ httpcfg.HTTPCDRsURL = *jsnHTTPCfg.Http_Cdrs
}
- if jsnHttpCfg.Use_basic_auth != nil {
- httpcfg.HTTPUseBasicAuth = *jsnHttpCfg.Use_basic_auth
+ if jsnHTTPCfg.Use_basic_auth != nil {
+ httpcfg.HTTPUseBasicAuth = *jsnHTTPCfg.Use_basic_auth
}
- if jsnHttpCfg.Auth_users != nil {
- httpcfg.HTTPAuthUsers = *jsnHttpCfg.Auth_users
+ if jsnHTTPCfg.Auth_users != nil {
+ httpcfg.HTTPAuthUsers = *jsnHTTPCfg.Auth_users
}
- if jsnHttpCfg.Client_opts != nil {
- for k, v := range jsnHttpCfg.Client_opts {
+ if jsnHTTPCfg.Client_opts != nil {
+ for k, v := range jsnHTTPCfg.Client_opts {
httpcfg.ClientOpts[k] = v
}
}
return nil
}
+// AsMapInterface returns the config as a map[string]interface{}
func (httpcfg *HTTPCfg) AsMapInterface() (initialMP map[string]interface{}) {
initialMP = map[string]interface{}{
utils.HTTPJsonRPCURLCfg: httpcfg.HTTPJsonRPCURL,
@@ -81,3 +82,24 @@ func (httpcfg *HTTPCfg) AsMapInterface() (initialMP map[string]interface{}) {
}
return
}
+
+// Clone returns a deep copy of HTTPCfg
+func (httpcfg HTTPCfg) Clone() (cln *HTTPCfg) {
+ cln = &HTTPCfg{
+ HTTPJsonRPCURL: httpcfg.HTTPJsonRPCURL,
+ DispatchersRegistrarURL: httpcfg.DispatchersRegistrarURL,
+ HTTPWSURL: httpcfg.HTTPWSURL,
+ HTTPFreeswitchCDRsURL: httpcfg.HTTPFreeswitchCDRsURL,
+ HTTPCDRsURL: httpcfg.HTTPCDRsURL,
+ HTTPUseBasicAuth: httpcfg.HTTPUseBasicAuth,
+ HTTPAuthUsers: make(map[string]string),
+ ClientOpts: make(map[string]interface{}),
+ }
+ for u, a := range httpcfg.HTTPAuthUsers {
+ cln.HTTPAuthUsers[u] = a
+ }
+ for o, val := range httpcfg.ClientOpts {
+ cln.ClientOpts[o] = val
+ }
+ return
+}
diff --git a/config/httpcfg_test.go b/config/httpcfg_test.go
index 77b9be70c..7543e4de6 100644
--- a/config/httpcfg_test.go
+++ b/config/httpcfg_test.go
@@ -61,7 +61,7 @@ func TestHTTPCfgloadFromJsonCfg(t *testing.T) {
}
if cfgJsn, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = cfgJsn.httpCfg.loadFromJsonCfg(cfgJSONStr); err != nil {
+ } else if err = cfgJsn.httpCfg.loadFromJSONCfg(cfgJSONStr); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(expected, cfgJsn.httpCfg) {
t.Errorf("Expected %+v \n, received %+v", utils.ToJSON(expected), utils.ToJSON(cfgJsn.httpCfg))
@@ -147,3 +147,30 @@ func TestHTTPCfgAsMapInterface1(t *testing.T) {
t.Errorf("Expected %+v, received %+v", eMap, rcv)
}
}
+
+func TestHTTPCfgClone(t *testing.T) {
+ ban := &HTTPCfg{
+ HTTPJsonRPCURL: "/jsonrpc",
+ HTTPWSURL: "/ws",
+ DispatchersRegistrarURL: "/randomUrl",
+ HTTPFreeswitchCDRsURL: "/freeswitch_json",
+ HTTPCDRsURL: "/cdr_http",
+ HTTPUseBasicAuth: false,
+ HTTPAuthUsers: map[string]string{
+ "user": "pass",
+ },
+ ClientOpts: map[string]interface{}{
+ utils.HTTPClientTLSClientConfigCfg: false,
+ },
+ }
+ rcv := ban.Clone()
+ if !reflect.DeepEqual(ban, rcv) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(ban), utils.ToJSON(rcv))
+ }
+ if rcv.ClientOpts[utils.HTTPClientTLSClientConfigCfg] = ""; ban.ClientOpts[utils.HTTPClientTLSClientConfigCfg] != false {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+ if rcv.HTTPAuthUsers["user"] = ""; ban.HTTPAuthUsers["user"] != "pass" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+}
diff --git a/config/kamagentcfg.go b/config/kamagentcfg.go
index e3d3216bd..1b34644a6 100644
--- a/config/kamagentcfg.go
+++ b/config/kamagentcfg.go
@@ -19,44 +19,60 @@ along with this program. If not, see
package config
import (
- "strings"
-
"github.com/cgrates/cgrates/utils"
)
-// Represents one connection instance towards Kamailio
+// NewDfltKamConnConfig returns the first cached default value for a KamConnCfg connection
+func NewDfltKamConnConfig() *KamConnCfg {
+ if dfltKamConnConfig == nil {
+ return new(KamConnCfg) // No defaults, most probably we are building the defaults now
+ }
+ dfltVal := *dfltKamConnConfig
+ return &dfltVal
+}
+
+// KamConnCfg represents one connection instance towards Kamailio
type KamConnCfg struct {
Alias string
Address string
Reconnects int
}
-func (self *KamConnCfg) loadFromJsonCfg(jsnCfg *KamConnJsonCfg) error {
+func (kamCfg *KamConnCfg) loadFromJSONCfg(jsnCfg *KamConnJsonCfg) error {
if jsnCfg == nil {
return nil
}
if jsnCfg.Address != nil {
- self.Address = *jsnCfg.Address
+ kamCfg.Address = *jsnCfg.Address
}
if jsnCfg.Alias != nil {
- self.Alias = *jsnCfg.Alias
+ kamCfg.Alias = *jsnCfg.Alias
}
if jsnCfg.Reconnects != nil {
- self.Reconnects = *jsnCfg.Reconnects
+ kamCfg.Reconnects = *jsnCfg.Reconnects
}
return nil
}
-func (kamCfg *KamConnCfg) AsMapInterface() (initialMP map[string]interface{}) {
- initialMP = map[string]interface{}{
+// AsMapInterface returns the config as a map[string]interface{}
+func (kamCfg *KamConnCfg) AsMapInterface() map[string]interface{} {
+ return map[string]interface{}{
utils.AliasCfg: kamCfg.Alias,
utils.AddressCfg: kamCfg.Address,
utils.ReconnectsCfg: kamCfg.Reconnects,
}
- return
}
-// SM-Kamailio config section
+// Clone returns a deep copy of KamConnCfg
+func (kamCfg KamConnCfg) Clone() *KamConnCfg {
+ return &KamConnCfg{
+ Alias: kamCfg.Alias,
+ Address: kamCfg.Address,
+ Reconnects: kamCfg.Reconnects,
+ }
+}
+
+// KamAgentCfg is the Kamailio config section
type KamAgentCfg struct {
Enabled bool
SessionSConns []string
@@ -65,7 +81,7 @@ type KamAgentCfg struct {
Timezone string
}
-func (ka *KamAgentCfg) loadFromJsonCfg(jsnCfg *KamAgentJsonCfg) error {
+func (ka *KamAgentCfg) loadFromJSONCfg(jsnCfg *KamAgentJsonCfg) error {
if jsnCfg == nil {
return nil
}
@@ -76,10 +92,9 @@ func (ka *KamAgentCfg) loadFromJsonCfg(jsnCfg *KamAgentJsonCfg) error {
ka.SessionSConns = make([]string, len(*jsnCfg.Sessions_conns))
for idx, attrConn := range *jsnCfg.Sessions_conns {
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
+ ka.SessionSConns[idx] = attrConn
if attrConn == utils.MetaInternal {
ka.SessionSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS)
- } else {
- ka.SessionSConns[idx] = attrConn
}
}
}
@@ -90,7 +105,7 @@ func (ka *KamAgentCfg) loadFromJsonCfg(jsnCfg *KamAgentJsonCfg) error {
ka.EvapiConns = make([]*KamConnCfg, len(*jsnCfg.Evapi_conns))
for idx, jsnConnCfg := range *jsnCfg.Evapi_conns {
ka.EvapiConns[idx] = NewDfltKamConnConfig()
- ka.EvapiConns[idx].loadFromJsonCfg(jsnConnCfg)
+ ka.EvapiConns[idx].loadFromJSONCfg(jsnConnCfg)
}
}
if jsnCfg.Timezone != nil {
@@ -99,6 +114,7 @@ func (ka *KamAgentCfg) loadFromJsonCfg(jsnCfg *KamAgentJsonCfg) error {
return nil
}
+// AsMapInterface returns the config as a map[string]interface{}
func (ka *KamAgentCfg) AsMapInterface() (initialMP map[string]interface{}) {
initialMP = map[string]interface{}{
utils.EnabledCfg: ka.Enabled,
@@ -115,13 +131,34 @@ func (ka *KamAgentCfg) AsMapInterface() (initialMP map[string]interface{}) {
if ka.SessionSConns != nil {
sessionSConns := make([]string, len(ka.SessionSConns))
for i, item := range ka.SessionSConns {
+ sessionSConns[i] = item
if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS) {
- sessionSConns[i] = strings.TrimSuffix(item, utils.CONCATENATED_KEY_SEP+utils.MetaSessionS)
- } else {
- sessionSConns[i] = item
+ sessionSConns[i] = utils.MetaInternal
}
}
initialMP[utils.SessionSConnsCfg] = sessionSConns
}
return
}
+
+// Clone returns a deep copy of KamAgentCfg
+func (ka KamAgentCfg) Clone() (cln *KamAgentCfg) {
+ cln = &KamAgentCfg{
+ Enabled: ka.Enabled,
+ CreateCdr: ka.CreateCdr,
+ Timezone: ka.Timezone,
+ }
+ if ka.SessionSConns != nil {
+ cln.SessionSConns = make([]string, len(ka.SessionSConns))
+ for i, con := range ka.SessionSConns {
+ cln.SessionSConns[i] = con
+ }
+ }
+ if ka.EvapiConns != nil {
+ cln.EvapiConns = make([]*KamConnCfg, len(ka.EvapiConns))
+ for i, req := range ka.EvapiConns {
+ cln.EvapiConns[i] = req.Clone()
+ }
+ }
+ return
+}
diff --git a/config/kamagentcfg_test.go b/config/kamagentcfg_test.go
index aa948bbab..33559fd24 100644
--- a/config/kamagentcfg_test.go
+++ b/config/kamagentcfg_test.go
@@ -25,7 +25,7 @@ import (
)
func TestKamAgentCfgloadFromJsonCfg(t *testing.T) {
- cfgJson := &KamAgentJsonCfg{
+ cfgJSON := &KamAgentJsonCfg{
Enabled: utils.BoolPointer(true),
Sessions_conns: &[]string{"*internal"},
Create_cdr: utils.BoolPointer(true),
@@ -47,7 +47,7 @@ func TestKamAgentCfgloadFromJsonCfg(t *testing.T) {
}
if jsnCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = jsnCfg.kamAgentCfg.loadFromJsonCfg(cfgJson); err != nil {
+ } else if err = jsnCfg.kamAgentCfg.loadFromJSONCfg(cfgJSON); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(expected, jsnCfg.kamAgentCfg) {
t.Errorf("Expected %+v \n, received %+v", utils.ToJSON(expected), utils.ToJSON(jsnCfg.kamAgentCfg))
@@ -56,12 +56,12 @@ func TestKamAgentCfgloadFromJsonCfg(t *testing.T) {
func TestKamConnCfgloadFromJsonCfg(t *testing.T) {
var kamcocfg, expected KamConnCfg
- if err := kamcocfg.loadFromJsonCfg(nil); err != nil {
+ if err := kamcocfg.loadFromJSONCfg(nil); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(kamcocfg, expected) {
t.Errorf("Expected: %+v ,received: %+v", expected, kamcocfg)
}
- if err := kamcocfg.loadFromJsonCfg(new(KamConnJsonCfg)); err != nil {
+ if err := kamcocfg.loadFromJSONCfg(new(KamConnJsonCfg)); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(kamcocfg, expected) {
t.Errorf("Expected: %+v ,received: %+v", expected, kamcocfg)
@@ -74,7 +74,7 @@ func TestKamConnCfgloadFromJsonCfg(t *testing.T) {
Address: "127.0.0.1:8448",
Reconnects: 5,
}
- if err = kamcocfg.loadFromJsonCfg(json); err != nil {
+ if err = kamcocfg.loadFromJSONCfg(json); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(expected, kamcocfg) {
t.Errorf("Expected: %+v , received: %+v", utils.ToJSON(expected), utils.ToJSON(kamcocfg))
@@ -127,3 +127,23 @@ func TestKamAgentCfgAsMapInterface1(t *testing.T) {
t.Errorf("Expected %+v \n, received %+v", eMap, rcv)
}
}
+
+func TestKamAgentCfgClone(t *testing.T) {
+ ban := &KamAgentCfg{
+ Enabled: true,
+ SessionSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS), "*conn1"},
+ CreateCdr: true,
+ EvapiConns: []*KamConnCfg{{Address: "127.0.0.1:8448", Reconnects: 10, Alias: "randomAlias"}},
+ Timezone: "Local",
+ }
+ rcv := ban.Clone()
+ if !reflect.DeepEqual(ban, rcv) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(ban), utils.ToJSON(rcv))
+ }
+ if rcv.SessionSConns[1] = ""; ban.SessionSConns[1] != "*conn1" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+ if rcv.EvapiConns[0].Alias = ""; ban.EvapiConns[0].Alias != "randomAlias" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+}
diff --git a/config/listencfg.go b/config/listencfg.go
index 537746e8e..95114b2a5 100644
--- a/config/listencfg.go
+++ b/config/listencfg.go
@@ -20,7 +20,7 @@ package config
import "github.com/cgrates/cgrates/utils"
-// Listen config section
+// ListenCfg is the listen config section
type ListenCfg struct {
RPCJSONListen string // RPC JSON listening address
RPCGOBListen string // RPC GOB listening address
@@ -30,8 +30,8 @@ type ListenCfg struct {
HTTPTLSListen string // HTTP TLS listening address
}
-//loadFromJsonCfg loads Database config from JsonCfg
-func (lstcfg *ListenCfg) loadFromJsonCfg(jsnListenCfg *ListenJsonCfg) (err error) {
+// loadFromJSONCfg loads Database config from JsonCfg
+func (lstcfg *ListenCfg) loadFromJSONCfg(jsnListenCfg *ListenJsonCfg) (err error) {
if jsnListenCfg == nil {
return nil
}
@@ -56,8 +56,9 @@ func (lstcfg *ListenCfg) loadFromJsonCfg(jsnListenCfg *ListenJsonCfg) (err error
return nil
}
-func (lstcfg *ListenCfg) AsMapInterface() (initialMP map[string]interface{}) {
- initialMP = map[string]interface{}{
+// AsMapInterface returns the config as a map[string]interface{}
+func (lstcfg *ListenCfg) AsMapInterface() map[string]interface{} {
+ return map[string]interface{}{
utils.RPCJSONListenCfg: lstcfg.RPCJSONListen,
utils.RPCGOBListenCfg: lstcfg.RPCGOBListen,
utils.HTTPListenCfg: lstcfg.HTTPListen,
@@ -65,5 +66,16 @@ func (lstcfg *ListenCfg) AsMapInterface() (initialMP map[string]interface{}) {
utils.RPCGOBTLSListenCfg: lstcfg.RPCGOBTLSListen,
utils.HTTPTLSListenCfg: lstcfg.HTTPTLSListen,
}
- return
+}
+
+// Clone returns a deep copy of ListenCfg
+func (lstcfg ListenCfg) Clone() *ListenCfg {
+ return &ListenCfg{
+ RPCJSONListen: lstcfg.RPCJSONListen,
+ RPCGOBListen: lstcfg.RPCGOBListen,
+ HTTPListen: lstcfg.HTTPListen,
+ RPCJSONTLSListen: lstcfg.RPCJSONTLSListen,
+ RPCGOBTLSListen: lstcfg.RPCGOBTLSListen,
+ HTTPTLSListen: lstcfg.HTTPTLSListen,
+ }
}
diff --git a/config/listencfg_test.go b/config/listencfg_test.go
index 8bd9b5b2a..be92eadc7 100644
--- a/config/listencfg_test.go
+++ b/config/listencfg_test.go
@@ -43,7 +43,7 @@ func TestListenCfgloadFromJsonCfg(t *testing.T) {
}
if jsnCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = jsnCfg.listenCfg.loadFromJsonCfg(jsonCfg); err != nil {
+ } else if err = jsnCfg.listenCfg.loadFromJSONCfg(jsonCfg); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(expected, jsnCfg.listenCfg) {
t.Errorf("Expected %+v \n, received %+v", utils.ToJSON(expected), utils.ToJSON(jsnCfg.listenCfg))
@@ -93,3 +93,21 @@ func TestListenCfgAsMapInterface1(t *testing.T) {
t.Errorf("Expected %+v, received %+v", eMap, rcv)
}
}
+
+func TestListenCfgClone(t *testing.T) {
+ ban := &ListenCfg{
+ RPCJSONListen: "127.0.0.1:2012",
+ RPCGOBListen: "127.0.0.1:2013",
+ HTTPListen: "127.0.0.1:2080",
+ RPCJSONTLSListen: "127.0.0.1:2022",
+ RPCGOBTLSListen: "127.0.0.1:2023",
+ HTTPTLSListen: "127.0.0.1:2280",
+ }
+ rcv := ban.Clone()
+ if !reflect.DeepEqual(ban, rcv) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(ban), utils.ToJSON(rcv))
+ }
+ if rcv.RPCJSONListen = ""; ban.RPCJSONListen != "127.0.0.1:2012" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+}
diff --git a/config/loaderscfg.go b/config/loaderscfg.go
index ef24f9600..8e50da459 100644
--- a/config/loaderscfg.go
+++ b/config/loaderscfg.go
@@ -19,12 +19,12 @@ along with this program. If not, see
package config
import (
- "strings"
"time"
"github.com/cgrates/cgrates/utils"
)
+// NewDfltLoaderSCfg returns the first cached default value for a LoaderSCfg connection
func NewDfltLoaderSCfg() *LoaderSCfg {
if dfltLoaderConfig == nil {
return new(LoaderSCfg)
@@ -36,6 +36,7 @@ func NewDfltLoaderSCfg() *LoaderSCfg {
// LoaderSCfgs to export some methods for LoaderS profiles
type LoaderSCfgs []*LoaderSCfg
+// AsMapInterface returns the config as a map[string]interface{}
func (ldrs LoaderSCfgs) AsMapInterface(separator string) (loaderCfg []map[string]interface{}) {
loaderCfg = make([]map[string]interface{}, len(ldrs))
for i, item := range ldrs {
@@ -54,8 +55,18 @@ func (ldrs LoaderSCfgs) Enabled() bool {
return false
}
+// Clone itself into a new LoaderSCfgs
+func (ldrs LoaderSCfgs) Clone() (cln LoaderSCfgs) {
+ cln = make(LoaderSCfgs, len(ldrs))
+ for i, ldr := range ldrs {
+ cln[i] = ldr.Clone()
+ }
+ return
+}
+
+// LoaderSCfg the config for a loader
type LoaderSCfg struct {
- Id string
+ ID string
Enabled bool
Tenant RSRParsers
DryRun bool
@@ -68,138 +79,144 @@ type LoaderSCfg struct {
Data []*LoaderDataType
}
-type LoaderDataType struct { //rename to LoaderDataType
+// LoaderDataType the template for profile loading
+type LoaderDataType struct {
Type string
Filename string
Flags utils.FlagsWithParams
Fields []*FCTemplate
}
-func (self *LoaderDataType) loadFromJsonCfg(jsnCfg *LoaderJsonDataType, msgTemplates map[string][]*FCTemplate, separator string) (err error) {
+func (lData *LoaderDataType) loadFromJSONCfg(jsnCfg *LoaderJsonDataType, msgTemplates map[string][]*FCTemplate, separator string) (err error) {
if jsnCfg == nil {
return nil
}
if jsnCfg.Type != nil {
- self.Type = *jsnCfg.Type
+ lData.Type = *jsnCfg.Type
}
if jsnCfg.File_name != nil {
- self.Filename = *jsnCfg.File_name
+ lData.Filename = *jsnCfg.File_name
}
if jsnCfg.Flags != nil {
- self.Flags = utils.FlagsWithParamsFromSlice(*jsnCfg.Flags)
+ lData.Flags = utils.FlagsWithParamsFromSlice(*jsnCfg.Flags)
}
if jsnCfg.Fields != nil {
- if self.Fields, err = FCTemplatesFromFCTemplatesJSONCfg(*jsnCfg.Fields, separator); err != nil {
+ if lData.Fields, err = FCTemplatesFromFCTemplatesJSONCfg(*jsnCfg.Fields, separator); err != nil {
return
}
- if tpls, err := InflateTemplates(self.Fields, msgTemplates); err != nil {
+ if tpls, err := InflateTemplates(lData.Fields, msgTemplates); err != nil {
return err
} else if tpls != nil {
- self.Fields = tpls
+ lData.Fields = tpls
}
}
return nil
}
-func (self *LoaderSCfg) loadFromJsonCfg(jsnCfg *LoaderJsonCfg, msgTemplates map[string][]*FCTemplate, separator string) (err error) {
+func (l *LoaderSCfg) loadFromJSONCfg(jsnCfg *LoaderJsonCfg, msgTemplates map[string][]*FCTemplate, separator string) (err error) {
if jsnCfg == nil {
return nil
}
if jsnCfg.ID != nil {
- self.Id = *jsnCfg.ID
+ l.ID = *jsnCfg.ID
}
if jsnCfg.Enabled != nil {
- self.Enabled = *jsnCfg.Enabled
+ l.Enabled = *jsnCfg.Enabled
}
if jsnCfg.Tenant != nil {
- if self.Tenant, err = NewRSRParsers(*jsnCfg.Tenant, separator); err != nil {
+ if l.Tenant, err = NewRSRParsers(*jsnCfg.Tenant, separator); err != nil {
return err
}
}
if jsnCfg.Dry_run != nil {
- self.DryRun = *jsnCfg.Dry_run
+ l.DryRun = *jsnCfg.Dry_run
}
if jsnCfg.Run_delay != nil {
- if self.RunDelay, err = utils.ParseDurationWithNanosecs(*jsnCfg.Run_delay); err != nil {
+ if l.RunDelay, err = utils.ParseDurationWithNanosecs(*jsnCfg.Run_delay); err != nil {
return
}
}
if jsnCfg.Lock_filename != nil {
- self.LockFileName = *jsnCfg.Lock_filename
+ l.LockFileName = *jsnCfg.Lock_filename
}
if jsnCfg.Caches_conns != nil {
- self.CacheSConns = make([]string, len(*jsnCfg.Caches_conns))
+ l.CacheSConns = make([]string, len(*jsnCfg.Caches_conns))
for idx, connID := range *jsnCfg.Caches_conns {
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
if connID == utils.MetaInternal {
- self.CacheSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCaches)
+ l.CacheSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCaches)
} else {
- self.CacheSConns[idx] = connID
+ l.CacheSConns[idx] = connID
}
}
}
if jsnCfg.Field_separator != nil {
- self.FieldSeparator = *jsnCfg.Field_separator
+ l.FieldSeparator = *jsnCfg.Field_separator
}
if jsnCfg.Tp_in_dir != nil {
- self.TpInDir = *jsnCfg.Tp_in_dir
+ l.TpInDir = *jsnCfg.Tp_in_dir
}
if jsnCfg.Tp_out_dir != nil {
- self.TpOutDir = *jsnCfg.Tp_out_dir
+ l.TpOutDir = *jsnCfg.Tp_out_dir
}
if jsnCfg.Data != nil {
data := make([]*LoaderDataType, len(*jsnCfg.Data))
for idx, jsnLoCfg := range *jsnCfg.Data {
data[idx] = new(LoaderDataType)
- if err := data[idx].loadFromJsonCfg(jsnLoCfg, msgTemplates, separator); err != nil {
+ if err := data[idx].loadFromJSONCfg(jsnLoCfg, msgTemplates, separator); err != nil {
return err
}
}
- self.Data = data
+ l.Data = data
}
return nil
}
// Clone itself into a new LoaderDataType
-func (self *LoaderDataType) Clone() *LoaderDataType {
- cln := new(LoaderDataType)
- cln.Type = self.Type
- cln.Filename = self.Filename
- cln.Fields = make([]*FCTemplate, len(self.Fields))
- for idx, val := range self.Fields {
+func (lData LoaderDataType) Clone() (cln *LoaderDataType) {
+ cln = &LoaderDataType{
+ Type: lData.Type,
+ Filename: lData.Filename,
+ Flags: lData.Flags.Clone(),
+ Fields: make([]*FCTemplate, len(lData.Fields)),
+ }
+ for idx, val := range lData.Fields {
cln.Fields[idx] = val.Clone()
}
- return cln
+ return
}
// Clone itself into a new LoadersConfig
-func (self *LoaderSCfg) Clone() *LoaderSCfg {
- clnLoader := new(LoaderSCfg)
- clnLoader.Id = self.Id
- clnLoader.Enabled = self.Enabled
- clnLoader.Tenant = self.Tenant
- clnLoader.DryRun = self.DryRun
- clnLoader.RunDelay = self.RunDelay
- clnLoader.LockFileName = self.LockFileName
- clnLoader.CacheSConns = make([]string, len(self.CacheSConns))
- for idx, connID := range self.CacheSConns {
- clnLoader.CacheSConns[idx] = connID
+func (l LoaderSCfg) Clone() (cln *LoaderSCfg) {
+ cln = &LoaderSCfg{
+ ID: l.ID,
+ Enabled: l.Enabled,
+ Tenant: l.Tenant,
+ DryRun: l.DryRun,
+ RunDelay: l.RunDelay,
+ LockFileName: l.LockFileName,
+ CacheSConns: make([]string, len(l.CacheSConns)),
+ FieldSeparator: l.FieldSeparator,
+ TpInDir: l.TpInDir,
+ TpOutDir: l.TpOutDir,
+ Data: make([]*LoaderDataType, len(l.Data)),
}
- clnLoader.FieldSeparator = self.FieldSeparator
- clnLoader.TpInDir = self.TpInDir
- clnLoader.TpOutDir = self.TpOutDir
- clnLoader.Data = make([]*LoaderDataType, len(self.Data))
- for idx, fld := range self.Data {
- clnLoader.Data[idx] = fld.Clone()
+ for idx, connID := range l.CacheSConns {
+ cln.CacheSConns[idx] = connID
}
- return clnLoader
+ for idx, fld := range l.Data {
+ cln.Data[idx] = fld.Clone()
+ }
+ return
}
+// AsMapInterface returns the config as a map[string]interface{}
func (lData *LoaderDataType) AsMapInterface(separator string) (initialMP map[string]interface{}) {
initialMP = map[string]interface{}{
utils.TypeCf: lData.Type,
utils.FilenameCfg: lData.Filename,
+ utils.FlagsCfg: lData.Flags.SliceFlags(),
}
fields := make([]map[string]interface{}, len(lData.Fields))
@@ -207,13 +224,14 @@ func (lData *LoaderDataType) AsMapInterface(separator string) (initialMP map[str
fields[i] = item.AsMapInterface(separator)
}
initialMP[utils.FieldsCfg] = fields
-
return
}
+// AsMapInterface returns the config as a map[string]interface{}
func (l *LoaderSCfg) AsMapInterface(separator string) (initialMP map[string]interface{}) {
initialMP = map[string]interface{}{
- utils.IDCfg: l.Id,
+ utils.IDCfg: l.ID,
+ utils.TenantCfg: l.Tenant.GetRule(separator),
utils.EnabledCfg: l.Enabled,
utils.DryRunCfg: l.DryRun,
utils.LockFileNameCfg: l.LockFileName,
@@ -222,11 +240,6 @@ func (l *LoaderSCfg) AsMapInterface(separator string) (initialMP map[string]inte
utils.TpOutDirCfg: l.TpOutDir,
utils.RunDelayCfg: "0",
}
- tenant := make([]string, len(l.Tenant))
- for i, item := range l.Tenant {
- tenant[i] = item.Rules
- }
- initialMP[utils.TenantCfg] = strings.Join(tenant, utils.EmptyString)
if l.Data != nil {
data := make([]map[string]interface{}, len(l.Data))
for i, item := range l.Data {
@@ -240,10 +253,9 @@ func (l *LoaderSCfg) AsMapInterface(separator string) (initialMP map[string]inte
if l.CacheSConns != nil {
cacheSConns := make([]string, len(l.CacheSConns))
for i, item := range l.CacheSConns {
+ cacheSConns[i] = item
if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCaches) {
- cacheSConns[i] = strings.TrimSuffix(item, utils.CONCATENATED_KEY_SEP+utils.MetaCaches)
- } else {
- cacheSConns[i] = item
+ cacheSConns[i] = utils.MetaInternal
}
}
initialMP[utils.CachesConnsCfg] = cacheSConns
diff --git a/config/loaderscfg_test.go b/config/loaderscfg_test.go
index 7193e7080..a8faf8f4e 100644
--- a/config/loaderscfg_test.go
+++ b/config/loaderscfg_test.go
@@ -61,7 +61,7 @@ func TestLoaderSCfgloadFromJsonCfgCase1(t *testing.T) {
expected := LoaderSCfgs{
{
Enabled: true,
- Id: utils.MetaDefault,
+ ID: utils.MetaDefault,
Tenant: ten,
LockFileName: ".cgr.lck",
CacheSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCaches), "*conn1"},
@@ -108,9 +108,9 @@ func TestLoaderSCfgloadFromJsonCfgCase2(t *testing.T) {
expected := "invalid converter terminator in rule: "
if jsonCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = jsonCfg.loaderCfg[0].loadFromJsonCfg(nil, jsonCfg.templates, jsonCfg.generalCfg.RSRSep); err != nil {
+ } else if err = jsonCfg.loaderCfg[0].loadFromJSONCfg(nil, jsonCfg.templates, jsonCfg.generalCfg.RSRSep); err != nil {
t.Error(err)
- } else if err = jsonCfg.loaderCfg[0].loadFromJsonCfg(cfgJSON, jsonCfg.templates, jsonCfg.generalCfg.RSRSep); err == nil || err.Error() != expected {
+ } else if err = jsonCfg.loaderCfg[0].loadFromJSONCfg(cfgJSON, jsonCfg.templates, jsonCfg.generalCfg.RSRSep); err == nil || err.Error() != expected {
t.Errorf("Expected %+v, received %+v", expected, err)
}
}
@@ -130,7 +130,7 @@ func TestLoaderSCfgloadFromJsonCfgCase3(t *testing.T) {
expected := "invalid converter terminator in rule: "
if jsonCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err := jsonCfg.loaderCfg[0].loadFromJsonCfg(cfg, jsonCfg.templates, jsonCfg.generalCfg.RSRSep); err == nil || err.Error() != expected {
+ } else if err := jsonCfg.loaderCfg[0].loadFromJSONCfg(cfg, jsonCfg.templates, jsonCfg.generalCfg.RSRSep); err == nil || err.Error() != expected {
t.Errorf("Expected %+v, received %+v", expected, err)
}
}
@@ -150,7 +150,7 @@ func TestLoaderSCfgloadFromJsonCfgCase4(t *testing.T) {
expected := "no template with id: <>"
if jsonCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = jsonCfg.loaderCfg[0].loadFromJsonCfg(cfg, jsonCfg.templates, jsonCfg.generalCfg.RSRSep); err == nil || err.Error() != expected {
+ } else if err = jsonCfg.loaderCfg[0].loadFromJSONCfg(cfg, jsonCfg.templates, jsonCfg.generalCfg.RSRSep); err == nil || err.Error() != expected {
t.Errorf("Expected %+v, received %+v", expected, err)
}
}
@@ -200,7 +200,7 @@ func TestLoaderSCfgloadFromJsonCfgCase5(t *testing.T) {
}
if jsonCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = jsonCfg.loaderCfg[0].loadFromJsonCfg(cfg, msgTemplates, jsonCfg.generalCfg.RSRSep); err != nil {
+ } else if err = jsonCfg.loaderCfg[0].loadFromJSONCfg(cfg, msgTemplates, jsonCfg.generalCfg.RSRSep); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(jsonCfg.loaderCfg[0].Data[0].Fields[0], expectedFields[0].Data[0].Fields[0]) {
t.Errorf("Expected %+v \n, received %+v", utils.ToJSON(expectedFields[0].Data[0].Fields[0]), utils.ToJSON(jsonCfg.loaderCfg[0].Data[0].Fields[0]))
@@ -213,7 +213,7 @@ func TestLoaderSCfgloadFromJsonCfgCase6(t *testing.T) {
}
if jsonCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = jsonCfg.loaderCfg[0].loadFromJsonCfg(cfg, jsonCfg.templates, jsonCfg.generalCfg.RSRSep); err != nil {
+ } else if err = jsonCfg.loaderCfg[0].loadFromJSONCfg(cfg, jsonCfg.templates, jsonCfg.generalCfg.RSRSep); err != nil {
t.Error(err)
}
}
@@ -409,3 +409,43 @@ func TestLoaderCfgAsMapInterfaceCase2(t *testing.T) {
t.Errorf("Expected %+v, received %+v", rcv[0][utils.Tenant], eMap[0][utils.Tenant])
}
}
+
+func TestLoaderSCfgsClone(t *testing.T) {
+ ban := LoaderSCfgs{{
+ Enabled: true,
+ ID: utils.MetaDefault,
+ Tenant: NewRSRParsersMustCompile("cgrate.org", utils.INFIELD_SEP),
+ LockFileName: ".cgr.lck",
+ CacheSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCaches), "*conn1"},
+ FieldSeparator: ",",
+ TpInDir: "/var/spool/cgrates/loader/in",
+ TpOutDir: "/var/spool/cgrates/loader/out",
+ Data: []*LoaderDataType{{
+ Type: "*attributes",
+ Filename: "Attributes.csv",
+ Flags: utils.FlagsWithParams{},
+ Fields: []*FCTemplate{
+ {
+ Tag: "TenantID",
+ Path: "Tenant",
+ pathSlice: []string{"Tenant"},
+ pathItems: utils.PathItems{{Field: "Tenant"}},
+ Type: utils.META_COMPOSED,
+ Value: NewRSRParsersMustCompile("cgrate.org", utils.INFIELD_SEP),
+ Mandatory: true,
+ Layout: time.RFC3339,
+ },
+ }},
+ },
+ }}
+ rcv := ban.Clone()
+ if !reflect.DeepEqual(ban, rcv) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(ban), utils.ToJSON(rcv))
+ }
+ if rcv[0].CacheSConns[1] = ""; ban[0].CacheSConns[1] != "*conn1" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+ if rcv[0].Data[0].Type = ""; ban[0].Data[0].Type != "*attributes" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+}
diff --git a/config/multifiles_it_test.go b/config/multifiles_it_test.go
index 04f0144b1..ba6fc07d2 100644
--- a/config/multifiles_it_test.go
+++ b/config/multifiles_it_test.go
@@ -87,10 +87,10 @@ func TestMfHttpAgentMultipleFields(t *testing.T) {
if len(mfCgrCfg.HTTPAgentCfg()) != 2 {
t.Errorf("Expected: 2, received: %+v", len(mfCgrCfg.HTTPAgentCfg()))
}
- expected := HttpAgentCfgs{
+ expected := HTTPAgentCfgs{
{
ID: "conecto1",
- Url: "/newConecto",
+ URL: "/newConecto",
SessionSConns: []string{utils.MetaLocalHost},
RequestPayload: "*url",
ReplyPayload: "*xml",
@@ -163,7 +163,7 @@ func TestMfHttpAgentMultipleFields(t *testing.T) {
},
{
ID: "conecto_xml",
- Url: "/conecto_xml",
+ URL: "/conecto_xml",
SessionSConns: []string{utils.MetaLocalHost},
RequestPayload: "*xml",
ReplyPayload: "*xml",
diff --git a/config/radiuscfg.go b/config/radiuscfg.go
index 918e5eb5a..422619517 100644
--- a/config/radiuscfg.go
+++ b/config/radiuscfg.go
@@ -19,11 +19,10 @@ along with this program. If not, see
package config
import (
- "strings"
-
"github.com/cgrates/cgrates/utils"
)
+// RadiusAgentCfg the config section that describes the Radius Agent
type RadiusAgentCfg struct {
Enabled bool
ListenNet string // udp or tcp
@@ -35,46 +34,45 @@ type RadiusAgentCfg struct {
RequestProcessors []*RequestProcessor
}
-func (self *RadiusAgentCfg) loadFromJsonCfg(jsnCfg *RadiusAgentJsonCfg, separator string) (err error) {
+func (ra *RadiusAgentCfg) loadFromJSONCfg(jsnCfg *RadiusAgentJsonCfg, separator string) (err error) {
if jsnCfg == nil {
return nil
}
if jsnCfg.Enabled != nil {
- self.Enabled = *jsnCfg.Enabled
+ ra.Enabled = *jsnCfg.Enabled
}
if jsnCfg.Listen_net != nil {
- self.ListenNet = *jsnCfg.Listen_net
+ ra.ListenNet = *jsnCfg.Listen_net
}
if jsnCfg.Listen_auth != nil {
- self.ListenAuth = *jsnCfg.Listen_auth
+ ra.ListenAuth = *jsnCfg.Listen_auth
}
if jsnCfg.Listen_acct != nil {
- self.ListenAcct = *jsnCfg.Listen_acct
+ ra.ListenAcct = *jsnCfg.Listen_acct
}
if jsnCfg.Client_secrets != nil {
- if self.ClientSecrets == nil {
- self.ClientSecrets = make(map[string]string)
+ if ra.ClientSecrets == nil {
+ ra.ClientSecrets = make(map[string]string)
}
for k, v := range *jsnCfg.Client_secrets {
- self.ClientSecrets[k] = v
+ ra.ClientSecrets[k] = v
}
}
if jsnCfg.Client_dictionaries != nil {
- if self.ClientDictionaries == nil {
- self.ClientDictionaries = make(map[string]string)
+ if ra.ClientDictionaries == nil {
+ ra.ClientDictionaries = make(map[string]string)
}
for k, v := range *jsnCfg.Client_dictionaries {
- self.ClientDictionaries[k] = v
+ ra.ClientDictionaries[k] = v
}
}
if jsnCfg.Sessions_conns != nil {
- self.SessionSConns = make([]string, len(*jsnCfg.Sessions_conns))
+ ra.SessionSConns = make([]string, len(*jsnCfg.Sessions_conns))
for idx, attrConn := range *jsnCfg.Sessions_conns {
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
+ ra.SessionSConns[idx] = attrConn
if attrConn == utils.MetaInternal {
- self.SessionSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS)
- } else {
- self.SessionSConns[idx] = attrConn
+ ra.SessionSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS)
}
}
}
@@ -82,7 +80,7 @@ func (self *RadiusAgentCfg) loadFromJsonCfg(jsnCfg *RadiusAgentJsonCfg, separato
for _, reqProcJsn := range *jsnCfg.Request_processors {
rp := new(RequestProcessor)
var haveID bool
- for _, rpSet := range self.RequestProcessors {
+ for _, rpSet := range ra.RequestProcessors {
if reqProcJsn.ID != nil && rpSet.ID == *reqProcJsn.ID {
rp = rpSet // Will load data into the one set
haveID = true
@@ -93,34 +91,22 @@ func (self *RadiusAgentCfg) loadFromJsonCfg(jsnCfg *RadiusAgentJsonCfg, separato
return
}
if !haveID {
- self.RequestProcessors = append(self.RequestProcessors, rp)
+ ra.RequestProcessors = append(ra.RequestProcessors, rp)
}
}
}
return
}
+// AsMapInterface returns the config as a map[string]interface{}
func (ra *RadiusAgentCfg) AsMapInterface(separator string) (initialMP map[string]interface{}) {
initialMP = map[string]interface{}{
- utils.EnabledCfg: ra.Enabled,
- utils.ListenNetCfg: ra.ListenNet,
- utils.ListenAuthCfg: ra.ListenAuth,
- utils.ListenAcctCfg: ra.ListenAcct,
- }
- if ra.ClientSecrets != nil {
- clientSecrets := make(map[string]interface{}, len(ra.ClientSecrets))
- for key, val := range ra.ClientSecrets {
- clientSecrets[key] = val
- }
- initialMP[utils.ClientSecretsCfg] = clientSecrets
- }
-
- if ra.ClientDictionaries != nil {
- clientDictionaries := make(map[string]interface{}, len(ra.ClientDictionaries))
- for key, val := range ra.ClientDictionaries {
- clientDictionaries[key] = val
- }
- initialMP[utils.ClientDictionariesCfg] = clientDictionaries
+ utils.EnabledCfg: ra.Enabled,
+ utils.ListenNetCfg: ra.ListenNet,
+ utils.ListenAuthCfg: ra.ListenAuth,
+ utils.ListenAcctCfg: ra.ListenAcct,
+ utils.ClientSecretsCfg: ra.ClientSecrets,
+ utils.ClientDictionariesCfg: ra.ClientDictionaries,
}
requestProcessors := make([]map[string]interface{}, len(ra.RequestProcessors))
@@ -132,13 +118,43 @@ func (ra *RadiusAgentCfg) AsMapInterface(separator string) (initialMP map[string
if ra.SessionSConns != nil {
sessionSConns := make([]string, len(ra.SessionSConns))
for i, item := range ra.SessionSConns {
+ sessionSConns[i] = item
if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS) {
- sessionSConns[i] = strings.TrimSuffix(item, utils.CONCATENATED_KEY_SEP+utils.MetaSessionS)
- } else {
- sessionSConns[i] = item
+ sessionSConns[i] = utils.MetaInternal
}
}
initialMP[utils.SessionSConnsCfg] = sessionSConns
}
return
}
+
+// Clone returns a deep copy of RadiusAgentCfg
+func (ra RadiusAgentCfg) Clone() (cln *RadiusAgentCfg) {
+ cln = &RadiusAgentCfg{
+ Enabled: ra.Enabled,
+ ListenNet: ra.ListenNet,
+ ListenAuth: ra.ListenAuth,
+ ListenAcct: ra.ListenAcct,
+ ClientSecrets: make(map[string]string),
+ ClientDictionaries: make(map[string]string),
+ }
+ if ra.SessionSConns != nil {
+ cln.SessionSConns = make([]string, len(ra.SessionSConns))
+ for i, con := range ra.SessionSConns {
+ cln.SessionSConns[i] = con
+ }
+ }
+ for k, v := range ra.ClientSecrets {
+ cln.ClientSecrets[k] = v
+ }
+ for k, v := range ra.ClientDictionaries {
+ cln.ClientDictionaries[k] = v
+ }
+ if ra.RequestProcessors != nil {
+ cln.RequestProcessors = make([]*RequestProcessor, len(ra.RequestProcessors))
+ for i, req := range ra.RequestProcessors {
+ cln.RequestProcessors[i] = req.Clone()
+ }
+ }
+ return
+}
diff --git a/config/radiuscfg_test.go b/config/radiuscfg_test.go
index 7bc310e0f..9acfd50c5 100644
--- a/config/radiuscfg_test.go
+++ b/config/radiuscfg_test.go
@@ -89,7 +89,7 @@ func TestRadiusAgentCfgloadFromJsonCfgCase1(t *testing.T) {
}
if cfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = cfg.radiusAgentCfg.loadFromJsonCfg(cfgJSON, cfg.generalCfg.RSRSep); err != nil {
+ } else if err = cfg.radiusAgentCfg.loadFromJSONCfg(cfgJSON, cfg.generalCfg.RSRSep); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(expected, cfg.radiusAgentCfg) {
t.Errorf("Expected %+v \n, received %+v", utils.ToJSON(expected), utils.ToJSON(cfg.radiusAgentCfg))
@@ -122,7 +122,7 @@ func TestRadiusAgentCfgloadFromJsonCfgCase2(t *testing.T) {
}
if jsonCfg, err := NewCGRConfigFromJSONStringWithDefaults(cfgJSONStr); err != nil {
t.Error(err)
- } else if err = jsonCfg.radiusAgentCfg.loadFromJsonCfg(cfgJSON, jsonCfg.generalCfg.RSRSep); err != nil {
+ } else if err = jsonCfg.radiusAgentCfg.loadFromJSONCfg(cfgJSON, jsonCfg.generalCfg.RSRSep); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(jsonCfg.radiusAgentCfg.RequestProcessors[0].ID, expected.RequestProcessors[0].ID) {
t.Errorf("Expected %+v, received %+v", utils.ToJSON(jsonCfg.radiusAgentCfg.RequestProcessors[0].ID),
@@ -141,7 +141,7 @@ func TestRadiusAgentCfgloadFromJsonCfgCase3(t *testing.T) {
expected := "invalid converter terminator in rule: "
if jsonCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = jsonCfg.radiusAgentCfg.loadFromJsonCfg(cfgJSON, jsonCfg.generalCfg.RSRSep); err == nil || err.Error() != expected {
+ } else if err = jsonCfg.radiusAgentCfg.loadFromJSONCfg(cfgJSON, jsonCfg.generalCfg.RSRSep); err == nil || err.Error() != expected {
t.Errorf("Expected %+v, received %+v", expected, err)
}
}
@@ -176,10 +176,10 @@ func TestRadiusAgentCfgAsMapInterface(t *testing.T) {
utils.ListenNetCfg: "udp",
utils.ListenAuthCfg: "127.0.0.1:1816",
utils.ListenAcctCfg: "127.0.0.1:1892",
- utils.ClientSecretsCfg: map[string]interface{}{
+ utils.ClientSecretsCfg: map[string]string{
utils.MetaDefault: "CGRateS.org",
},
- utils.ClientDictionariesCfg: map[string]interface{}{
+ utils.ClientDictionariesCfg: map[string]string{
utils.MetaDefault: "/usr/share/cgrates/",
},
utils.SessionSConnsCfg: []string{"*conn1", "*conn2"},
@@ -213,10 +213,10 @@ func TestRadiusAgentCfgAsMapInterface1(t *testing.T) {
utils.ListenNetCfg: "udp",
utils.ListenAuthCfg: "127.0.0.1:1812",
utils.ListenAcctCfg: "127.0.0.1:1813",
- utils.ClientSecretsCfg: map[string]interface{}{
+ utils.ClientSecretsCfg: map[string]string{
utils.MetaDefault: "CGRateS.org",
},
- utils.ClientDictionariesCfg: map[string]interface{}{
+ utils.ClientDictionariesCfg: map[string]string{
utils.MetaDefault: "/usr/share/cgrates/radius/dict/",
},
utils.SessionSConnsCfg: []string{"*internal"},
@@ -228,3 +228,51 @@ func TestRadiusAgentCfgAsMapInterface1(t *testing.T) {
t.Errorf("Expected %+v \n, received %+v", utils.ToJSON(eMap), utils.ToJSON(rcv))
}
}
+
+func TestRadiusAgentCfgClone(t *testing.T) {
+ ban := &RadiusAgentCfg{
+ Enabled: true,
+ ListenNet: "udp",
+ ListenAuth: "127.0.0.1:1812",
+ ListenAcct: "127.0.0.1:1813",
+ ClientSecrets: map[string]string{utils.MetaDefault: "CGRateS.org"},
+ ClientDictionaries: map[string]string{utils.MetaDefault: "/usr/share/cgrates/radius/dict/"},
+ SessionSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS), "*conn1"},
+ RequestProcessors: []*RequestProcessor{
+ {
+ ID: "OutboundAUTHDryRun",
+ Filters: []string{"*string:~*req.request_type:OutboundAUTH", "*string:~*req.Msisdn:497700056231"},
+ Flags: utils.FlagsWithParams{utils.MetaDryRun: {}},
+ Timezone: utils.EmptyString,
+ Tenant: NewRSRParsersMustCompile("~*req.CGRID", utils.INFIELD_SEP),
+ RequestFields: []*FCTemplate{},
+ ReplyFields: []*FCTemplate{
+ {
+ Tag: "Allow",
+ Path: "*rep.response.Allow",
+ Type: utils.META_CONSTANT,
+ Value: NewRSRParsersMustCompile("1", utils.INFIELD_SEP),
+ Mandatory: true,
+ Layout: time.RFC3339,
+ },
+ },
+ },
+ },
+ }
+ rcv := ban.Clone()
+ if !reflect.DeepEqual(ban, rcv) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(ban), utils.ToJSON(rcv))
+ }
+ if rcv.SessionSConns[1] = ""; ban.SessionSConns[1] != "*conn1" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+ if rcv.RequestProcessors[0].ID = ""; ban.RequestProcessors[0].ID != "OutboundAUTHDryRun" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+ if rcv.ClientSecrets[utils.MetaDefault] = ""; ban.ClientSecrets[utils.MetaDefault] != "CGRateS.org" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+ if rcv.ClientDictionaries[utils.MetaDefault] = ""; ban.ClientDictionaries[utils.MetaDefault] != "/usr/share/cgrates/radius/dict/" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+}
diff --git a/config/ralscfg.go b/config/ralscfg.go
index 9292ced5d..91f0d0bd7 100644
--- a/config/ralscfg.go
+++ b/config/ralscfg.go
@@ -20,13 +20,12 @@ package config
import (
"strconv"
- "strings"
"time"
"github.com/cgrates/cgrates/utils"
)
-// Rater config section
+// RalsCfg is rater config section
type RalsCfg struct {
Enabled bool // start standalone server (no balancer)
ThresholdSConns []string // address where to reach ThresholdS config
@@ -40,8 +39,8 @@ type RalsCfg struct {
DynaprepaidActionPlans []string
}
-//loadFromJsonCfg loads Rals config from JsonCfg
-func (ralsCfg *RalsCfg) loadFromJsonCfg(jsnRALsCfg *RalsJsonCfg) (err error) {
+// loadFromJSONCfg loads Rals config from JsonCfg
+func (ralsCfg *RalsCfg) loadFromJSONCfg(jsnRALsCfg *RalsJsonCfg) (err error) {
if jsnRALsCfg == nil {
return nil
}
@@ -52,10 +51,9 @@ func (ralsCfg *RalsCfg) loadFromJsonCfg(jsnRALsCfg *RalsJsonCfg) (err error) {
ralsCfg.ThresholdSConns = make([]string, len(*jsnRALsCfg.Thresholds_conns))
for idx, conn := range *jsnRALsCfg.Thresholds_conns {
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
+ ralsCfg.ThresholdSConns[idx] = conn
if conn == utils.MetaInternal {
ralsCfg.ThresholdSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds)
- } else {
- ralsCfg.ThresholdSConns[idx] = conn
}
}
}
@@ -63,10 +61,9 @@ func (ralsCfg *RalsCfg) loadFromJsonCfg(jsnRALsCfg *RalsJsonCfg) (err error) {
ralsCfg.StatSConns = make([]string, len(*jsnRALsCfg.Stats_conns))
for idx, conn := range *jsnRALsCfg.Stats_conns {
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
+ ralsCfg.StatSConns[idx] = conn
if conn == utils.MetaInternal {
ralsCfg.StatSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStatS)
- } else {
- ralsCfg.StatSConns[idx] = conn
}
}
}
@@ -74,10 +71,9 @@ func (ralsCfg *RalsCfg) loadFromJsonCfg(jsnRALsCfg *RalsJsonCfg) (err error) {
ralsCfg.CacheSConns = make([]string, len(*jsnRALsCfg.CacheS_conns))
for idx, conn := range *jsnRALsCfg.CacheS_conns {
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
+ ralsCfg.CacheSConns[idx] = conn
if conn == utils.MetaInternal {
ralsCfg.CacheSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCaches)
- } else {
- ralsCfg.CacheSConns[idx] = conn
}
}
}
@@ -112,6 +108,7 @@ func (ralsCfg *RalsCfg) loadFromJsonCfg(jsnRALsCfg *RalsJsonCfg) (err error) {
return nil
}
+// AsMapInterface returns the config as a map[string]interface{}
func (ralsCfg *RalsCfg) AsMapInterface() (initialMP map[string]interface{}) {
initialMP = map[string]interface{}{
utils.EnabledCfg: ralsCfg.Enabled,
@@ -119,14 +116,14 @@ func (ralsCfg *RalsCfg) AsMapInterface() (initialMP map[string]interface{}) {
utils.RemoveExpiredCfg: ralsCfg.RemoveExpired,
utils.MaxIncrementsCfg: ralsCfg.MaxIncrements,
utils.DynaprepaidActionplansCfg: ralsCfg.DynaprepaidActionPlans,
+ utils.BalanceRatingSubjectCfg: ralsCfg.BalanceRatingSubject,
}
if ralsCfg.ThresholdSConns != nil {
threSholds := make([]string, len(ralsCfg.ThresholdSConns))
for i, item := range ralsCfg.ThresholdSConns {
+ threSholds[i] = item
if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds) {
- threSholds[i] = strings.TrimSuffix(item, utils.CONCATENATED_KEY_SEP+utils.MetaThresholds)
- } else {
- threSholds[i] = item
+ threSholds[i] = utils.MetaInternal
}
}
initialMP[utils.ThresholdSConnsCfg] = threSholds
@@ -134,42 +131,76 @@ func (ralsCfg *RalsCfg) AsMapInterface() (initialMP map[string]interface{}) {
if ralsCfg.StatSConns != nil {
statS := make([]string, len(ralsCfg.StatSConns))
for i, item := range ralsCfg.StatSConns {
+ statS[i] = item
if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStatS) {
- statS[i] = strings.TrimSuffix(item, utils.CONCATENATED_KEY_SEP+utils.MetaStatS)
- } else {
- statS[i] = item
+ statS[i] = utils.MetaInternal
}
}
initialMP[utils.StatSConnsCfg] = statS
}
- if ralsCfg.MaxComputedUsage != nil {
- maxComputed := make(map[string]interface{})
- for key, item := range ralsCfg.MaxComputedUsage {
- if key == utils.ANY || key == utils.VOICE {
- maxComputed[key] = item.String()
- } else {
- maxComputed[key] = strconv.Itoa(int(item))
- }
- }
- initialMP[utils.MaxComputedUsageCfg] = maxComputed
- }
if ralsCfg.CacheSConns != nil {
cacheSConns := make([]string, len(ralsCfg.CacheSConns))
for i, item := range ralsCfg.CacheSConns {
+ cacheSConns[i] = item
if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCaches) {
- cacheSConns[i] = strings.TrimSuffix(item, utils.CONCATENATED_KEY_SEP+utils.MetaCaches)
- } else {
- cacheSConns[i] = item
+ cacheSConns[i] = utils.MetaInternal
}
}
initialMP[utils.CachesConnsCfg] = cacheSConns
}
- if ralsCfg.BalanceRatingSubject != nil {
- balanceRating := make(map[string]interface{})
- for key, item := range ralsCfg.BalanceRatingSubject {
- balanceRating[key] = item
+ maxComputed := make(map[string]interface{})
+ for key, item := range ralsCfg.MaxComputedUsage {
+ if key == utils.ANY || key == utils.VOICE {
+ maxComputed[key] = item.String()
+ } else {
+ maxComputed[key] = strconv.Itoa(int(item))
}
- initialMP[utils.BalanceRatingSubjectCfg] = balanceRating
+ }
+ initialMP[utils.MaxComputedUsageCfg] = maxComputed
+ return
+}
+
+// Clone returns a deep copy of RalsCfg
+func (ralsCfg RalsCfg) Clone() (cln *RalsCfg) {
+ cln = &RalsCfg{
+ Enabled: ralsCfg.Enabled,
+ RpSubjectPrefixMatching: ralsCfg.RpSubjectPrefixMatching,
+ RemoveExpired: ralsCfg.RemoveExpired,
+ MaxIncrements: ralsCfg.MaxIncrements,
+
+ MaxComputedUsage: make(map[string]time.Duration),
+ BalanceRatingSubject: make(map[string]string),
+ }
+ if ralsCfg.ThresholdSConns != nil {
+ cln.ThresholdSConns = make([]string, len(ralsCfg.ThresholdSConns))
+ for i, con := range ralsCfg.ThresholdSConns {
+ cln.ThresholdSConns[i] = con
+ }
+ }
+ if ralsCfg.StatSConns != nil {
+ cln.StatSConns = make([]string, len(ralsCfg.StatSConns))
+ for i, con := range ralsCfg.StatSConns {
+ cln.StatSConns[i] = con
+ }
+ }
+ if ralsCfg.CacheSConns != nil {
+ cln.CacheSConns = make([]string, len(ralsCfg.CacheSConns))
+ for i, con := range ralsCfg.CacheSConns {
+ cln.CacheSConns[i] = con
+ }
+ }
+ if ralsCfg.DynaprepaidActionPlans != nil {
+ cln.DynaprepaidActionPlans = make([]string, len(ralsCfg.DynaprepaidActionPlans))
+ for i, con := range ralsCfg.DynaprepaidActionPlans {
+ cln.DynaprepaidActionPlans[i] = con
+ }
+ }
+
+ for k, u := range ralsCfg.MaxComputedUsage {
+ cln.MaxComputedUsage[k] = u
+ }
+ for k, r := range ralsCfg.BalanceRatingSubject {
+ cln.BalanceRatingSubject[k] = r
}
return
}
diff --git a/config/ralscfg_test.go b/config/ralscfg_test.go
index b7bef963d..35d6086a6 100644
--- a/config/ralscfg_test.go
+++ b/config/ralscfg_test.go
@@ -68,12 +68,12 @@ func TestRalsCfgFromJsonCfgCase1(t *testing.T) {
},
DynaprepaidActionPlans: []string{"randomPlans"},
}
- if cfgJson, err := NewDefaultCGRConfig(); err != nil {
+ if cfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = cfgJson.ralsCfg.loadFromJsonCfg(cfgJSON); err != nil {
+ } else if err = cfg.ralsCfg.loadFromJSONCfg(cfgJSON); err != nil {
t.Error(err)
- } else if !reflect.DeepEqual(expected, cfgJson.ralsCfg) {
- t.Errorf("Expected %+v \n, received %+v", utils.ToJSON(expected), utils.ToJSON(cfgJson.ralsCfg))
+ } else if !reflect.DeepEqual(expected, cfg.ralsCfg) {
+ t.Errorf("Expected %+v \n, received %+v", utils.ToJSON(expected), utils.ToJSON(cfg.ralsCfg))
}
}
@@ -86,7 +86,7 @@ func TestRalsCfgFromJsonCfgCase2(t *testing.T) {
expected := "time: unknown unit \"hh\" in duration \"189hh\""
if jsonCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = jsonCfg.ralsCfg.loadFromJsonCfg(cfgJSON); err == nil || err.Error() != expected {
+ } else if err = jsonCfg.ralsCfg.loadFromJSONCfg(cfgJSON); err == nil || err.Error() != expected {
t.Errorf("Expected %+v, received %+v", expected, err)
}
}
@@ -120,7 +120,7 @@ func TestRalsCfgAsMapInterfaceCase1(t *testing.T) {
"*mms": "10000",
},
utils.MaxIncrementsCfg: 1000000,
- utils.BalanceRatingSubjectCfg: map[string]interface{}{
+ utils.BalanceRatingSubjectCfg: map[string]string{
"*any": "*zero1ns",
"*voice": "*zero1s",
},
@@ -155,7 +155,7 @@ func TestRalsCfgAsMapInterfaceCase2(t *testing.T) {
"*mms": "10000",
},
utils.MaxIncrementsCfg: 1000000,
- utils.BalanceRatingSubjectCfg: map[string]interface{}{
+ utils.BalanceRatingSubjectCfg: map[string]string{
"*any": "*zero1ns",
"*voice": "*zero1s",
},
@@ -167,3 +167,46 @@ func TestRalsCfgAsMapInterfaceCase2(t *testing.T) {
t.Errorf("Expected %+v \n, received %+v", utils.ToJSON(eMap), utils.ToJSON(rcv))
}
}
+
+func TestRalsCfgClone(t *testing.T) {
+ ban := &RalsCfg{
+ Enabled: true,
+ ThresholdSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds), "*conn1"},
+ StatSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStatS), "*conn1"},
+ CacheSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCaches), "*conn1"},
+ RpSubjectPrefixMatching: true,
+ RemoveExpired: true,
+ MaxComputedUsage: map[string]time.Duration{
+ utils.ANY: 189 * time.Hour,
+ utils.VOICE: 72 * time.Hour,
+ utils.DATA: 107374182400,
+ utils.SMS: 5000,
+ utils.MMS: 10000,
+ },
+ MaxIncrements: 1000000,
+ BalanceRatingSubject: map[string]string{
+ utils.META_ANY: "*zero1ns",
+ utils.META_VOICE: "*zero1s",
+ },
+ DynaprepaidActionPlans: []string{"randomPlans"},
+ }
+ rcv := ban.Clone()
+ if !reflect.DeepEqual(ban, rcv) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(ban), utils.ToJSON(rcv))
+ }
+ if rcv.ThresholdSConns[1] = ""; ban.ThresholdSConns[1] != "*conn1" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+ if rcv.StatSConns[1] = ""; ban.StatSConns[1] != "*conn1" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+ if rcv.CacheSConns[1] = ""; ban.CacheSConns[1] != "*conn1" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+ if rcv.MaxComputedUsage[utils.ANY] = 0; ban.MaxComputedUsage[utils.ANY] != 189*time.Hour {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+ if rcv.BalanceRatingSubject[utils.META_ANY] = ""; ban.BalanceRatingSubject[utils.META_ANY] != "*zero1ns" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+}
diff --git a/config/rjreader.go b/config/rjreader.go
index 5dd03667c..cf501b377 100644
--- a/config/rjreader.go
+++ b/config/rjreader.go
@@ -31,7 +31,7 @@ import (
)
// NewRjReader creates a new rjReader from a io.Reader
-func NewRjReader(rdr io.Reader) (r *rjReader, err error) {
+func NewRjReader(rdr io.Reader) (r *RjReader, err error) {
var b []byte
b, err = ioutil.ReadAll(rdr)
if err != nil {
@@ -41,8 +41,8 @@ func NewRjReader(rdr io.Reader) (r *rjReader, err error) {
}
// NewRjReaderFromBytes creates a new rjReader from a slice of bytes
-func NewRjReaderFromBytes(b []byte) *rjReader {
- return &rjReader{buf: b}
+func NewRjReaderFromBytes(b []byte) *RjReader {
+ return &RjReader{buf: b}
}
// isNewLine check if byte is new line
@@ -70,8 +70,8 @@ func isAlfanum(bit byte) bool {
(bit >= '0' && bit <= '9')
}
-// structure that implements io.Reader to read json files ignoring C style comments and replacing *env:
-type rjReader struct {
+// RjReader structure that implements io.Reader to read json files ignoring C style comments and replacing *env:
+type RjReader struct {
buf []byte
isInString bool // ignore character in strings
indx int // used to parse the buffer
@@ -79,7 +79,7 @@ type rjReader struct {
}
// Read implementation
-func (rjr *rjReader) Read(p []byte) (n int, err error) {
+func (rjr *RjReader) Read(p []byte) (n int, err error) {
for n = range p {
p[n], err = rjr.ReadByte()
if !rjr.envOff &&
@@ -99,13 +99,13 @@ func (rjr *rjReader) Read(p []byte) (n int, err error) {
}
// Close implementation
-func (rjr *rjReader) Close() error {
+func (rjr *RjReader) Close() error {
rjr.buf = nil
return nil
}
// ReadByte implementation
-func (rjr *rjReader) ReadByte() (bit byte, err error) {
+func (rjr *RjReader) ReadByte() (bit byte, err error) {
if rjr.isInString { //ignore commas in strings
return rjr.ReadByteWC()
}
@@ -126,7 +126,8 @@ func (rjr *rjReader) ReadByte() (bit byte, err error) {
return
}
-func (rjr *rjReader) UnreadByte() (err error) {
+// UnreadByte implementation
+func (rjr *RjReader) UnreadByte() (err error) {
if rjr.indx <= 0 {
return bufio.ErrInvalidUnreadByte
}
@@ -135,12 +136,12 @@ func (rjr *rjReader) UnreadByte() (err error) {
}
// returns true if the file was parsed completly
-func (rjr *rjReader) isEndOfFile() bool {
+func (rjr *RjReader) isEndOfFile() bool {
return rjr.indx >= len(rjr.buf)
}
// consumeComent consumes the comment based on the peeked byte
-func (rjr *rjReader) consumeComent(pkbit byte) (bool, error) {
+func (rjr *RjReader) consumeComent(pkbit byte) (bool, error) {
switch pkbit {
case '/':
for !rjr.isEndOfFile() {
@@ -167,7 +168,7 @@ func (rjr *rjReader) consumeComent(pkbit byte) (bool, error) {
}
//readFirstNonWhiteSpace reads first non white space byte
-func (rjr *rjReader) readFirstNonWhiteSpace() (bit byte, err error) {
+func (rjr *RjReader) readFirstNonWhiteSpace() (bit byte, err error) {
for !rjr.isEndOfFile() {
bit = rjr.buf[rjr.indx]
rjr.indx++
@@ -179,7 +180,7 @@ func (rjr *rjReader) readFirstNonWhiteSpace() (bit byte, err error) {
}
// ReadByteWC reads next byte skiping the comments
-func (rjr *rjReader) ReadByteWC() (bit byte, err error) {
+func (rjr *RjReader) ReadByteWC() (bit byte, err error) {
if rjr.isEndOfFile() {
return 0, io.EOF
}
@@ -209,7 +210,7 @@ func (rjr *rjReader) ReadByteWC() (bit byte, err error) {
}
// PeekByteWC peeks next byte skiping the comments
-func (rjr *rjReader) PeekByteWC() (bit byte, err error) {
+func (rjr *RjReader) PeekByteWC() (bit byte, err error) {
for !rjr.isEndOfFile() {
bit = rjr.buf[rjr.indx]
if !rjr.isInString && rjr.indx+1 < len(rjr.buf) && bit == '/' { //try consume comment
@@ -234,13 +235,13 @@ func (rjr *rjReader) PeekByteWC() (bit byte, err error) {
}
//checkMeta check if char mach with next char from MetaEnv if not reset the counting
-func (rjr *rjReader) checkMeta() bool {
+func (rjr *RjReader) checkMeta() bool {
return rjr.indx-1+len(utils.MetaEnv) < len(rjr.buf) &&
utils.MetaEnv == string(rjr.buf[rjr.indx-1:rjr.indx-1+len(utils.MetaEnv)])
}
//readEnvName reads the enviorment key
-func (rjr *rjReader) readEnvName(indx int) (name []byte, endindx int) { //0 if not set
+func (rjr *RjReader) readEnvName(indx int) (name []byte, endindx int) { //0 if not set
for indx < len(rjr.buf) { //read byte by byte
bit := rjr.buf[indx]
if !isAlfanum(bit) && bit != '_' { //[a-zA-Z_]+[a-zA-Z0-9_]*
@@ -253,7 +254,7 @@ func (rjr *rjReader) readEnvName(indx int) (name []byte, endindx int) { //0 if n
}
//replaceEnv replaces the EnvMeta and enviorment key with enviorment variable value in specific buffer
-func (rjr *rjReader) replaceEnv(startEnv int) error {
+func (rjr *RjReader) replaceEnv(startEnv int) error {
midEnv := len(utils.MetaEnv)
key, endEnv := rjr.readEnvName(startEnv + midEnv)
value, err := ReadEnv(string(key))
@@ -264,8 +265,8 @@ func (rjr *rjReader) replaceEnv(startEnv int) error {
return nil
}
-// warning: needs to read file again
-func (rjr *rjReader) HandleJSONError(err error) error {
+// HandleJSONError warning: needs to read file again
+func (rjr *RjReader) HandleJSONError(err error) error {
var offset int64
switch realErr := err.(type) {
case nil:
@@ -291,7 +292,7 @@ func (rjr *rjReader) HandleJSONError(err error) error {
strings.Split(string(rjr.buf), "\n")[line-1])
}
-func (rjr *rjReader) getJSONOffsetLine(offset int64) (line, character int64) {
+func (rjr *RjReader) getJSONOffsetLine(offset int64) (line, character int64) {
line = 1 // start line counting from 1
var lastChar byte
@@ -411,8 +412,8 @@ func (rjr *rjReader) getJSONOffsetLine(offset int64) (line, character int64) {
return
}
-// Loads the json config out of rjReader
-func (rjr *rjReader) Decode(cfg interface{}) (err error) {
+// Decode loads the json config out of rjReader
+func (rjr *RjReader) Decode(cfg interface{}) (err error) {
if err = json.NewDecoder(rjr).Decode(cfg); err != nil {
return rjr.HandleJSONError(err)
}
diff --git a/config/rjreader_test.go b/config/rjreader_test.go
index 3a8c8fd61..b8ef0c3a6 100644
--- a/config/rjreader_test.go
+++ b/config/rjreader_test.go
@@ -79,7 +79,7 @@ func TestNewRjReaderError(t *testing.T) {
}
func TestUnreadByte(t *testing.T) {
- reader := rjReader{
+ reader := RjReader{
indx: -1,
}
expected := "bufio: invalid use of UnreadByte"
@@ -121,7 +121,7 @@ a/*comment*/b`))
}
func TestConsumeComent(t *testing.T) {
- rjreader := new(rjReader)
+ rjreader := new(RjReader)
var pkbit byte = '*'
expectedErr := "JSON_INCOMPLETE_COMMENT"
if _, err := rjreader.consumeComent(pkbit); err == nil || err.Error() != expectedErr {
diff --git a/config/rpcconn.go b/config/rpcconn.go
index 58d8a9ce7..9d7a991b6 100644
--- a/config/rpcconn.go
+++ b/config/rpcconn.go
@@ -23,7 +23,7 @@ import (
"github.com/cgrates/rpcclient"
)
-// Returns the first cached default value for a RemoteHost connection
+// NewDfltRemoteHost returns the first cached default value for a RemoteHost connection
func NewDfltRemoteHost() *RemoteHost {
if dfltRemoteHost == nil {
return new(RemoteHost) // No defaults, most probably we are building the defaults now
@@ -32,17 +32,40 @@ func NewDfltRemoteHost() *RemoteHost {
return &dfltVal
}
+// NewDfltRPCConn returns the default value for a RPCConn
func NewDfltRPCConn() *RPCConn {
return &RPCConn{Strategy: rpcclient.PoolFirst}
}
+// RPCConns the config for all rpc pools
+type RPCConns map[string]*RPCConn
+
+// AsMapInterface returns the config as a map[string]interface{}
+func (rC RPCConns) AsMapInterface() (rpcConns map[string]interface{}) {
+ rpcConns = make(map[string]interface{})
+ for key, value := range rC {
+ rpcConns[key] = value.AsMapInterface()
+ }
+ return
+}
+
+// Clone returns a deep copy of RPCConns
+func (rC RPCConns) Clone() (cln RPCConns) {
+ cln = make(RPCConns)
+ for id, conn := range rC {
+ cln[id] = conn.Clone()
+ }
+ return
+}
+
+// RPCConn the connection pool config
type RPCConn struct {
Strategy string
PoolSize int
Conns []*RemoteHost
}
-func (rC *RPCConn) loadFromJsonCfg(jsnCfg *RPCConnsJson) {
+func (rC *RPCConn) loadFromJSONCfg(jsnCfg *RPCConnsJson) {
if jsnCfg == nil {
return
}
@@ -56,22 +79,13 @@ func (rC *RPCConn) loadFromJsonCfg(jsnCfg *RPCConnsJson) {
rC.Conns = make([]*RemoteHost, len(*jsnCfg.Conns))
for idx, jsnHaCfg := range *jsnCfg.Conns {
rC.Conns[idx] = NewDfltRemoteHost()
- rC.Conns[idx].loadFromJsonCfg(jsnHaCfg) //To review if the function signature changes
+ rC.Conns[idx].loadFromJSONCfg(jsnHaCfg) //To review if the function signature changes
}
}
return
}
-type RpcConns map[string]*RPCConn
-
-func (rC RpcConns) AsMapInterface() (rpcConns map[string]interface{}) {
- rpcConns = make(map[string]interface{})
- for key, value := range rC {
- rpcConns[key] = value.AsMapInterface()
- }
- return
-}
-
+// AsMapInterface returns the config as a map[string]interface{}
func (rC *RPCConn) AsMapInterface() (initialMP map[string]interface{}) {
initialMP = map[string]interface{}{
utils.StrategyCfg: rC.Strategy,
@@ -87,7 +101,22 @@ func (rC *RPCConn) AsMapInterface() (initialMP map[string]interface{}) {
return
}
-// One connection to Rater
+// Clone returns a deep copy of RPCConn
+func (rC RPCConn) Clone() (cln *RPCConn) {
+ cln = &RPCConn{
+ Strategy: rC.Strategy,
+ PoolSize: rC.PoolSize,
+ }
+ if rC.Conns != nil {
+ cln.Conns = make([]*RemoteHost, len(rC.Conns))
+ for i, req := range rC.Conns {
+ cln.Conns[i] = req.Clone()
+ }
+ }
+ return
+}
+
+// RemoteHost connection config
type RemoteHost struct {
Address string
Transport string
@@ -95,25 +124,26 @@ type RemoteHost struct {
TLS bool
}
-func (self *RemoteHost) loadFromJsonCfg(jsnCfg *RemoteHostJson) {
+func (rh *RemoteHost) loadFromJSONCfg(jsnCfg *RemoteHostJson) {
if jsnCfg == nil {
return
}
if jsnCfg.Address != nil {
- self.Address = *jsnCfg.Address
+ rh.Address = *jsnCfg.Address
}
if jsnCfg.Transport != nil {
- self.Transport = *jsnCfg.Transport
+ rh.Transport = *jsnCfg.Transport
}
if jsnCfg.Synchronous != nil {
- self.Synchronous = *jsnCfg.Synchronous
+ rh.Synchronous = *jsnCfg.Synchronous
}
if jsnCfg.Tls != nil {
- self.TLS = *jsnCfg.Tls
+ rh.TLS = *jsnCfg.Tls
}
return
}
+// AsMapInterface returns the config as a map[string]interface{}
func (rh *RemoteHost) AsMapInterface() map[string]interface{} {
return map[string]interface{}{
utils.AddressCfg: rh.Address,
@@ -122,3 +152,13 @@ func (rh *RemoteHost) AsMapInterface() map[string]interface{} {
utils.TLS: rh.TLS,
}
}
+
+// Clone returns a deep copy of RemoteHost
+func (rh RemoteHost) Clone() (cln *RemoteHost) {
+ return &RemoteHost{
+ Address: rh.Address,
+ Transport: rh.Transport,
+ Synchronous: rh.Synchronous,
+ TLS: rh.TLS,
+ }
+}
diff --git a/config/rpcconn_test.go b/config/rpcconn_test.go
index 5a0645c06..027e076ec 100644
--- a/config/rpcconn_test.go
+++ b/config/rpcconn_test.go
@@ -38,7 +38,7 @@ func TestRPCConnsloadFromJsonCfgCase1(t *testing.T) {
},
},
}
- expected := RpcConns{
+ expected := RPCConns{
utils.MetaInternal: {
Strategy: utils.MetaFirst,
PoolSize: 0,
@@ -67,7 +67,7 @@ func TestRPCConnsloadFromJsonCfgCase1(t *testing.T) {
if jsonCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
} else {
- jsonCfg.rpcConns[utils.MetaLocalHost].loadFromJsonCfg(cfgJSON)
+ jsonCfg.rpcConns[utils.MetaLocalHost].loadFromJSONCfg(cfgJSON)
if !reflect.DeepEqual(jsonCfg.rpcConns, expected) {
t.Errorf("Expected %+v \n, received %+v", utils.ToJSON(expected), utils.ToJSON(jsonCfg.rpcConns))
}
@@ -75,7 +75,7 @@ func TestRPCConnsloadFromJsonCfgCase1(t *testing.T) {
}
func TestRPCConnsloadFromJsonCfgCase2(t *testing.T) {
- expected := RpcConns{
+ expected := RPCConns{
utils.MetaInternal: {
Strategy: utils.MetaFirst,
PoolSize: 0,
@@ -105,7 +105,7 @@ func TestRPCConnsloadFromJsonCfgCase2(t *testing.T) {
if err != nil {
t.Error(err)
}
- jsonCfg.rpcConns[utils.MetaLocalHost].loadFromJsonCfg(nil)
+ jsonCfg.rpcConns[utils.MetaLocalHost].loadFromJSONCfg(nil)
if !reflect.DeepEqual(expected, jsonCfg.rpcConns) {
t.Errorf("Expected %+v, received %+v", utils.ToJSON(expected), utils.ToJSON(jsonCfg.rpcConns))
}
@@ -195,3 +195,39 @@ func TestRpcConnAsMapInterface1(t *testing.T) {
t.Errorf("Expected %+v \n, received %+v", utils.ToJSON(eMap), utils.ToJSON(rcv))
}
}
+
+func TestRPCConnsClone(t *testing.T) {
+ ban := RPCConns{
+ utils.MetaInternal: {
+ Strategy: utils.MetaFirst,
+ PoolSize: 0,
+ Conns: []*RemoteHost{
+ {
+ Address: utils.MetaInternal,
+ Transport: utils.EmptyString,
+ Synchronous: false,
+ TLS: false,
+ },
+ },
+ },
+ utils.MetaLocalHost: {
+ Strategy: utils.MetaFirst,
+ PoolSize: 1,
+ Conns: []*RemoteHost{
+ {
+ Address: "127.0.0.1:2012",
+ Transport: "*json",
+ Synchronous: false,
+ TLS: false,
+ },
+ },
+ },
+ }
+ rcv := ban.Clone()
+ if !reflect.DeepEqual(ban, rcv) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(ban), utils.ToJSON(rcv))
+ }
+ if rcv[utils.MetaInternal].Conns[0].Address = ""; ban[utils.MetaInternal].Conns[0].Address != utils.MetaInternal {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+}
diff --git a/config/schedulercfg.go b/config/schedulercfg.go
index 8626c97c2..ee818b878 100644
--- a/config/schedulercfg.go
+++ b/config/schedulercfg.go
@@ -19,11 +19,10 @@ along with this program. If not, see
package config
import (
- "strings"
-
"github.com/cgrates/cgrates/utils"
)
+// SchedulerCfg the condig section for scheduler
type SchedulerCfg struct {
Enabled bool
CDRsConns []string
@@ -43,10 +42,9 @@ func (schdcfg *SchedulerCfg) loadFromJSONCfg(jsnCfg *SchedulerJsonCfg) error {
schdcfg.CDRsConns = make([]string, len(*jsnCfg.Cdrs_conns))
for idx, conn := range *jsnCfg.Cdrs_conns {
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
+ schdcfg.CDRsConns[idx] = conn
if conn == utils.MetaInternal {
schdcfg.CDRsConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCDRs)
- } else {
- schdcfg.CDRsConns[idx] = conn
}
}
}
@@ -60,10 +58,9 @@ func (schdcfg *SchedulerCfg) loadFromJSONCfg(jsnCfg *SchedulerJsonCfg) error {
schdcfg.ThreshSConns = make([]string, len(*jsnCfg.Thresholds_conns))
for idx, connID := range *jsnCfg.Thresholds_conns {
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
+ schdcfg.ThreshSConns[idx] = connID
if connID == utils.MetaInternal {
schdcfg.ThreshSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds)
- } else {
- schdcfg.ThreshSConns[idx] = connID
}
}
}
@@ -71,16 +68,16 @@ func (schdcfg *SchedulerCfg) loadFromJSONCfg(jsnCfg *SchedulerJsonCfg) error {
schdcfg.StatSConns = make([]string, len(*jsnCfg.Stats_conns))
for idx, connID := range *jsnCfg.Stats_conns {
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
+ schdcfg.StatSConns[idx] = connID
if connID == utils.MetaInternal {
schdcfg.StatSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStats)
- } else {
- schdcfg.StatSConns[idx] = connID
}
}
}
return nil
}
+// AsMapInterface returns the config as a map[string]interface{}
func (schdcfg *SchedulerCfg) AsMapInterface() (initialMP map[string]interface{}) {
initialMP = map[string]interface{}{
utils.EnabledCfg: schdcfg.Enabled,
@@ -89,10 +86,9 @@ func (schdcfg *SchedulerCfg) AsMapInterface() (initialMP map[string]interface{})
if schdcfg.CDRsConns != nil {
cdrsConns := make([]string, len(schdcfg.CDRsConns))
for i, item := range schdcfg.CDRsConns {
+ cdrsConns[i] = item
if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCDRs) {
- cdrsConns[i] = strings.TrimSuffix(item, utils.CONCATENATED_KEY_SEP+utils.MetaCDRs)
- } else {
- cdrsConns[i] = item
+ cdrsConns[i] = utils.MetaInternal
}
}
initialMP[utils.CDRsConnsCfg] = cdrsConns
@@ -100,10 +96,9 @@ func (schdcfg *SchedulerCfg) AsMapInterface() (initialMP map[string]interface{})
if schdcfg.ThreshSConns != nil {
thrsConns := make([]string, len(schdcfg.ThreshSConns))
for i, item := range schdcfg.ThreshSConns {
+ thrsConns[i] = item
if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds) {
- thrsConns[i] = strings.TrimSuffix(item, utils.CONCATENATED_KEY_SEP+utils.MetaThresholds)
- } else {
- thrsConns[i] = item
+ thrsConns[i] = utils.MetaInternal
}
}
initialMP[utils.ThreshSConnsCfg] = thrsConns
@@ -111,13 +106,45 @@ func (schdcfg *SchedulerCfg) AsMapInterface() (initialMP map[string]interface{})
if schdcfg.StatSConns != nil {
stsConns := make([]string, len(schdcfg.StatSConns))
for i, item := range schdcfg.StatSConns {
+ stsConns[i] = item
if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStats) {
- stsConns[i] = strings.TrimSuffix(item, utils.CONCATENATED_KEY_SEP+utils.MetaStats)
- } else {
- stsConns[i] = item
+ stsConns[i] = utils.MetaInternal
}
}
initialMP[utils.StatSConnsCfg] = stsConns
}
return
}
+
+// Clone returns a deep copy of SchedulerCfg
+func (schdcfg SchedulerCfg) Clone() (cln *SchedulerCfg) {
+ cln = &SchedulerCfg{
+ Enabled: schdcfg.Enabled,
+ }
+ if schdcfg.CDRsConns != nil {
+ cln.CDRsConns = make([]string, len(schdcfg.CDRsConns))
+ for i, con := range schdcfg.CDRsConns {
+ cln.CDRsConns[i] = con
+ }
+ }
+ if schdcfg.ThreshSConns != nil {
+ cln.ThreshSConns = make([]string, len(schdcfg.ThreshSConns))
+ for i, con := range schdcfg.ThreshSConns {
+ cln.ThreshSConns[i] = con
+ }
+ }
+ if schdcfg.StatSConns != nil {
+ cln.StatSConns = make([]string, len(schdcfg.StatSConns))
+ for i, con := range schdcfg.StatSConns {
+ cln.StatSConns[i] = con
+ }
+ }
+ if schdcfg.Filters != nil {
+ cln.Filters = make([]string, len(schdcfg.Filters))
+ for i, con := range schdcfg.Filters {
+ cln.Filters[i] = con
+ }
+ }
+
+ return
+}
diff --git a/config/schedulercfg_test.go b/config/schedulercfg_test.go
index 69788e429..9b6d50afa 100644
--- a/config/schedulercfg_test.go
+++ b/config/schedulercfg_test.go
@@ -91,3 +91,29 @@ func TestSchedulerCfgAsMapInterface1(t *testing.T) {
}
}
+
+func TestSchedulerCfgClone(t *testing.T) {
+ ban := &SchedulerCfg{
+ Enabled: true,
+ CDRsConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCDRs), "*conn1"},
+ ThreshSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds), "*conn1"},
+ StatSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStats), "*conn1"},
+ Filters: []string{"randomFilter"},
+ }
+ rcv := ban.Clone()
+ if !reflect.DeepEqual(ban, rcv) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(ban), utils.ToJSON(rcv))
+ }
+ if rcv.CDRsConns[1] = ""; ban.CDRsConns[1] != "*conn1" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+ if rcv.ThreshSConns[1] = ""; ban.ThreshSConns[1] != "*conn1" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+ if rcv.StatSConns[1] = ""; ban.StatSConns[1] != "*conn1" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+ if rcv.Filters[0] = ""; ban.Filters[0] != "randomFilter" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+}
diff --git a/config/sessionscfg.go b/config/sessionscfg.go
index d7dd0126c..e913fd27a 100644
--- a/config/sessionscfg.go
+++ b/config/sessionscfg.go
@@ -20,13 +20,12 @@ package config
import (
"fmt"
- "strings"
"time"
"github.com/cgrates/cgrates/utils"
)
-// Returns the first cached default value for a FreeSWITCHAgent connection
+// NewDfltFsConnConfig returns the first cached default value for a FreeSWITCHAgent connection
func NewDfltFsConnConfig() *FsConnCfg {
if dfltFsConnConfig == nil {
return new(FsConnCfg) // No defaults, most probably we are building the defaults now
@@ -35,7 +34,7 @@ func NewDfltFsConnConfig() *FsConnCfg {
return &dfltVal
}
-// One connection to FreeSWITCH server
+// FsConnCfg one connection to FreeSWITCH server
type FsConnCfg struct {
Address string
Password string
@@ -43,27 +42,28 @@ type FsConnCfg struct {
Alias string
}
-func (self *FsConnCfg) loadFromJsonCfg(jsnCfg *FsConnJsonCfg) error {
+func (fs *FsConnCfg) loadFromJSONCfg(jsnCfg *FsConnJsonCfg) error {
if jsnCfg == nil {
return nil
}
if jsnCfg.Address != nil {
- self.Address = *jsnCfg.Address
+ fs.Address = *jsnCfg.Address
}
if jsnCfg.Password != nil {
- self.Password = *jsnCfg.Password
+ fs.Password = *jsnCfg.Password
}
if jsnCfg.Reconnects != nil {
- self.Reconnects = *jsnCfg.Reconnects
+ fs.Reconnects = *jsnCfg.Reconnects
}
- self.Alias = self.Address
+ fs.Alias = fs.Address
if jsnCfg.Alias != nil && *jsnCfg.Alias != "" {
- self.Alias = *jsnCfg.Alias
+ fs.Alias = *jsnCfg.Alias
}
return nil
}
+// AsMapInterface returns the config as a map[string]interface{}
func (fs *FsConnCfg) AsMapInterface() map[string]interface{} {
return map[string]interface{}{
utils.AddressCfg: fs.Address,
@@ -73,6 +73,17 @@ func (fs *FsConnCfg) AsMapInterface() map[string]interface{} {
}
}
+// Clone returns a deep copy of AsteriskAgentCfg
+func (fs FsConnCfg) Clone() *FsConnCfg {
+ return &FsConnCfg{
+ Address: fs.Address,
+ Password: fs.Password,
+ Reconnects: fs.Reconnects,
+ Alias: fs.Alias,
+ }
+}
+
+// SessionSCfg is the config section for SessionS
type SessionSCfg struct {
Enabled bool
ListenBijson string
@@ -92,7 +103,7 @@ type SessionSCfg struct {
SessionTTLLastUsed *time.Duration
SessionTTLUsage *time.Duration
SessionTTLLastUsage *time.Duration
- SessionIndexes utils.StringMap
+ SessionIndexes utils.StringSet
ClientProtocol float64
ChannelSyncInterval time.Duration
TerminateAttempts int
@@ -102,7 +113,7 @@ type SessionSCfg struct {
STIRCfg *STIRcfg
}
-func (scfg *SessionSCfg) loadFromJsonCfg(jsnCfg *SessionSJsonCfg) (err error) {
+func (scfg *SessionSCfg) loadFromJSONCfg(jsnCfg *SessionSJsonCfg) (err error) {
if jsnCfg == nil {
return nil
}
@@ -116,10 +127,9 @@ func (scfg *SessionSCfg) loadFromJsonCfg(jsnCfg *SessionSJsonCfg) (err error) {
scfg.ChargerSConns = make([]string, len(*jsnCfg.Chargers_conns))
for idx, connID := range *jsnCfg.Chargers_conns {
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
+ scfg.ChargerSConns[idx] = connID
if connID == utils.MetaInternal {
scfg.ChargerSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaChargers)
- } else {
- scfg.ChargerSConns[idx] = connID
}
}
}
@@ -127,10 +137,9 @@ func (scfg *SessionSCfg) loadFromJsonCfg(jsnCfg *SessionSJsonCfg) (err error) {
scfg.RALsConns = make([]string, len(*jsnCfg.Rals_conns))
for idx, connID := range *jsnCfg.Rals_conns {
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
+ scfg.RALsConns[idx] = connID
if connID == utils.MetaInternal {
scfg.RALsConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaResponder)
- } else {
- scfg.RALsConns[idx] = connID
}
}
}
@@ -138,10 +147,9 @@ func (scfg *SessionSCfg) loadFromJsonCfg(jsnCfg *SessionSJsonCfg) (err error) {
scfg.ResSConns = make([]string, len(*jsnCfg.Resources_conns))
for idx, connID := range *jsnCfg.Resources_conns {
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
+ scfg.ResSConns[idx] = connID
if connID == utils.MetaInternal {
scfg.ResSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaResources)
- } else {
- scfg.ResSConns[idx] = connID
}
}
}
@@ -149,10 +157,9 @@ func (scfg *SessionSCfg) loadFromJsonCfg(jsnCfg *SessionSJsonCfg) (err error) {
scfg.ThreshSConns = make([]string, len(*jsnCfg.Thresholds_conns))
for idx, connID := range *jsnCfg.Thresholds_conns {
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
+ scfg.ThreshSConns[idx] = connID
if connID == utils.MetaInternal {
scfg.ThreshSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds)
- } else {
- scfg.ThreshSConns[idx] = connID
}
}
}
@@ -160,10 +167,9 @@ func (scfg *SessionSCfg) loadFromJsonCfg(jsnCfg *SessionSJsonCfg) (err error) {
scfg.StatSConns = make([]string, len(*jsnCfg.Stats_conns))
for idx, connID := range *jsnCfg.Stats_conns {
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
+ scfg.StatSConns[idx] = connID
if connID == utils.MetaInternal {
scfg.StatSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStatS)
- } else {
- scfg.StatSConns[idx] = connID
}
}
}
@@ -171,10 +177,9 @@ func (scfg *SessionSCfg) loadFromJsonCfg(jsnCfg *SessionSJsonCfg) (err error) {
scfg.RouteSConns = make([]string, len(*jsnCfg.Routes_conns))
for idx, connID := range *jsnCfg.Routes_conns {
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
+ scfg.RouteSConns[idx] = connID
if connID == utils.MetaInternal {
scfg.RouteSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaRoutes)
- } else {
- scfg.RouteSConns[idx] = connID
}
}
}
@@ -182,10 +187,9 @@ func (scfg *SessionSCfg) loadFromJsonCfg(jsnCfg *SessionSJsonCfg) (err error) {
scfg.AttrSConns = make([]string, len(*jsnCfg.Attributes_conns))
for idx, connID := range *jsnCfg.Attributes_conns {
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
+ scfg.AttrSConns[idx] = connID
if connID == utils.MetaInternal {
scfg.AttrSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAttributes)
- } else {
- scfg.AttrSConns[idx] = connID
}
}
}
@@ -193,17 +197,15 @@ func (scfg *SessionSCfg) loadFromJsonCfg(jsnCfg *SessionSJsonCfg) (err error) {
scfg.CDRsConns = make([]string, len(*jsnCfg.Cdrs_conns))
for idx, connID := range *jsnCfg.Cdrs_conns {
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
+ scfg.CDRsConns[idx] = connID
if connID == utils.MetaInternal {
scfg.CDRsConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCDRs)
- } else {
- scfg.CDRsConns[idx] = connID
}
}
}
if jsnCfg.Replication_conns != nil {
scfg.ReplicationConns = make([]string, len(*jsnCfg.Replication_conns))
for idx, connID := range *jsnCfg.Replication_conns {
- // if we have the connection internal we change the name so we can have internal rpc for each subsystem
if connID == utils.MetaInternal {
return fmt.Errorf("Replication connection ID needs to be different than *internal")
}
@@ -224,35 +226,35 @@ func (scfg *SessionSCfg) loadFromJsonCfg(jsnCfg *SessionSJsonCfg) (err error) {
}
}
if jsnCfg.Session_ttl_max_delay != nil {
- if maxTTLDelay, err := utils.ParseDurationWithNanosecs(*jsnCfg.Session_ttl_max_delay); err != nil {
+ var maxTTLDelay time.Duration
+ if maxTTLDelay, err = utils.ParseDurationWithNanosecs(*jsnCfg.Session_ttl_max_delay); err != nil {
return err
- } else {
- scfg.SessionTTLMaxDelay = &maxTTLDelay
}
+ scfg.SessionTTLMaxDelay = &maxTTLDelay
}
if jsnCfg.Session_ttl_last_used != nil {
- if sessionTTLLastUsed, err := utils.ParseDurationWithNanosecs(*jsnCfg.Session_ttl_last_used); err != nil {
+ var sessionTTLLastUsed time.Duration
+ if sessionTTLLastUsed, err = utils.ParseDurationWithNanosecs(*jsnCfg.Session_ttl_last_used); err != nil {
return err
- } else {
- scfg.SessionTTLLastUsed = &sessionTTLLastUsed
}
+ scfg.SessionTTLLastUsed = &sessionTTLLastUsed
}
if jsnCfg.Session_ttl_usage != nil {
- if sessionTTLUsage, err := utils.ParseDurationWithNanosecs(*jsnCfg.Session_ttl_usage); err != nil {
+ var sessionTTLUsage time.Duration
+ if sessionTTLUsage, err = utils.ParseDurationWithNanosecs(*jsnCfg.Session_ttl_usage); err != nil {
return err
- } else {
- scfg.SessionTTLUsage = &sessionTTLUsage
}
+ scfg.SessionTTLUsage = &sessionTTLUsage
}
if jsnCfg.Session_ttl_last_usage != nil {
- if sessionTTLLastUsage, err := utils.ParseDurationWithNanosecs(*jsnCfg.Session_ttl_last_usage); err != nil {
+ var sessionTTLLastUsage time.Duration
+ if sessionTTLLastUsage, err = utils.ParseDurationWithNanosecs(*jsnCfg.Session_ttl_last_usage); err != nil {
return err
- } else {
- scfg.SessionTTLLastUsage = &sessionTTLLastUsage
}
+ scfg.SessionTTLLastUsage = &sessionTTLLastUsage
}
if jsnCfg.Session_indexes != nil {
- scfg.SessionIndexes = utils.StringMapFromSlice(*jsnCfg.Session_indexes)
+ scfg.SessionIndexes = utils.NewStringSet(*jsnCfg.Session_indexes)
}
if jsnCfg.Client_protocol != nil {
scfg.ClientProtocol = *jsnCfg.Client_protocol
@@ -277,38 +279,37 @@ func (scfg *SessionSCfg) loadFromJsonCfg(jsnCfg *SessionSJsonCfg) (err error) {
scfg.SchedulerConns = make([]string, len(*jsnCfg.Scheduler_conns))
for idx, connID := range *jsnCfg.Scheduler_conns {
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
+ scfg.SchedulerConns[idx] = connID
if connID == utils.MetaInternal {
scfg.SchedulerConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaScheduler)
- } else {
- scfg.SchedulerConns[idx] = connID
}
}
}
return scfg.STIRCfg.loadFromJSONCfg(jsnCfg.Stir)
}
+// AsMapInterface returns the config as a map[string]interface{}
func (scfg *SessionSCfg) AsMapInterface() (initialMP map[string]interface{}) {
initialMP = map[string]interface{}{
- utils.EnabledCfg: scfg.Enabled,
- utils.ListenBijsonCfg: scfg.ListenBijson,
- utils.ReplicationConnsCfg: scfg.ReplicationConns,
- utils.StoreSCostsCfg: scfg.StoreSCosts,
- utils.SessionIndexesCfg: scfg.SessionIndexes.Slice(),
- utils.ClientProtocolCfg: scfg.ClientProtocol,
- utils.TerminateAttemptsCfg: scfg.TerminateAttempts,
- utils.AlterableFieldsCfg: scfg.AlterableFields.AsSlice(),
- utils.STIRCfg: scfg.STIRCfg.AsMapInterface(),
- utils.MinDurLowBalanceCfg: "0",
+ utils.EnabledCfg: scfg.Enabled,
+ utils.ListenBijsonCfg: scfg.ListenBijson,
+ utils.ReplicationConnsCfg: scfg.ReplicationConns,
+ utils.StoreSCostsCfg: scfg.StoreSCosts,
+ utils.SessionIndexesCfg: scfg.SessionIndexes.AsSlice(),
+ utils.ClientProtocolCfg: scfg.ClientProtocol,
+ utils.TerminateAttemptsCfg: scfg.TerminateAttempts,
+ utils.AlterableFieldsCfg: scfg.AlterableFields.AsSlice(),
+ utils.STIRCfg: scfg.STIRCfg.AsMapInterface(),
+ utils.MinDurLowBalanceCfg: "0",
+ utils.ChannelSyncIntervalCfg: "0",
+ utils.DebitIntervalCfg: "0",
+ utils.SessionTTLCfg: "0",
}
if scfg.DebitInterval != 0 {
initialMP[utils.DebitIntervalCfg] = scfg.DebitInterval.String()
- } else if scfg.DebitInterval == 0 {
- initialMP[utils.DebitIntervalCfg] = "0"
}
if scfg.SessionTTL != 0 {
initialMP[utils.SessionTTLCfg] = scfg.SessionTTL.String()
- } else if scfg.SessionTTL == 0 {
- initialMP[utils.SessionTTLCfg] = "0"
}
if scfg.SessionTTLMaxDelay != nil {
initialMP[utils.SessionTTLMaxDelayCfg] = scfg.SessionTTLMaxDelay.String()
@@ -324,8 +325,6 @@ func (scfg *SessionSCfg) AsMapInterface() (initialMP map[string]interface{}) {
}
if scfg.ChannelSyncInterval != 0 {
initialMP[utils.ChannelSyncIntervalCfg] = scfg.ChannelSyncInterval.String()
- } else if scfg.ChannelSyncInterval == 0 {
- initialMP[utils.ChannelSyncIntervalCfg] = "0"
}
if scfg.MinDurLowBalance != 0 {
initialMP[utils.MinDurLowBalanceCfg] = scfg.MinDurLowBalance.String()
@@ -333,10 +332,9 @@ func (scfg *SessionSCfg) AsMapInterface() (initialMP map[string]interface{}) {
if scfg.ChargerSConns != nil {
chargerSConns := make([]string, len(scfg.ChargerSConns))
for i, item := range scfg.ChargerSConns {
+ chargerSConns[i] = item
if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaChargers) {
- chargerSConns[i] = strings.TrimSuffix(item, utils.CONCATENATED_KEY_SEP+utils.MetaChargers)
- } else {
- chargerSConns[i] = item
+ chargerSConns[i] = utils.MetaInternal
}
}
initialMP[utils.ChargerSConnsCfg] = chargerSConns
@@ -344,10 +342,9 @@ func (scfg *SessionSCfg) AsMapInterface() (initialMP map[string]interface{}) {
if scfg.RALsConns != nil {
RALsConns := make([]string, len(scfg.RALsConns))
for i, item := range scfg.RALsConns {
+ RALsConns[i] = item
if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaResponder) {
- RALsConns[i] = strings.TrimSuffix(item, utils.CONCATENATED_KEY_SEP+utils.MetaResponder)
- } else {
- RALsConns[i] = item
+ RALsConns[i] = utils.MetaInternal
}
}
initialMP[utils.RALsConnsCfg] = RALsConns
@@ -355,11 +352,9 @@ func (scfg *SessionSCfg) AsMapInterface() (initialMP map[string]interface{}) {
if scfg.ResSConns != nil {
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.TrimSuffix(item, utils.CONCATENATED_KEY_SEP+utils.MetaResources)
- } else {
- resSConns[i] = item
+ resSConns[i] = item
+ if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaResources) {
+ resSConns[i] = utils.MetaInternal
}
}
initialMP[utils.ResourceSConnsCfg] = resSConns
@@ -367,11 +362,9 @@ func (scfg *SessionSCfg) AsMapInterface() (initialMP map[string]interface{}) {
if scfg.ThreshSConns != nil {
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.TrimSuffix(item, utils.CONCATENATED_KEY_SEP+utils.MetaThresholds)
- } else {
- threshSConns[i] = item
+ threshSConns[i] = item
+ if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds) {
+ threshSConns[i] = utils.MetaInternal
}
}
initialMP[utils.ThresholdSConnsCfg] = threshSConns
@@ -379,11 +372,9 @@ func (scfg *SessionSCfg) AsMapInterface() (initialMP map[string]interface{}) {
if scfg.StatSConns != nil {
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.TrimSuffix(item, utils.CONCATENATED_KEY_SEP+utils.MetaStatS)
- } else {
- statSConns[i] = item
+ statSConns[i] = item
+ if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStatS) {
+ statSConns[i] = utils.MetaInternal
}
}
initialMP[utils.StatSConnsCfg] = statSConns
@@ -391,11 +382,9 @@ func (scfg *SessionSCfg) AsMapInterface() (initialMP map[string]interface{}) {
if scfg.RouteSConns != nil {
routesConns := make([]string, len(scfg.RouteSConns))
for i, item := range scfg.RouteSConns {
- buf := utils.ConcatenatedKey(utils.MetaInternal, utils.MetaRoutes)
- if item == buf {
- routesConns[i] = strings.TrimSuffix(item, utils.CONCATENATED_KEY_SEP+utils.MetaRoutes)
- } else {
- routesConns[i] = item
+ routesConns[i] = item
+ if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaRoutes) {
+ routesConns[i] = utils.MetaInternal
}
}
initialMP[utils.RouteSConnsCfg] = routesConns
@@ -403,11 +392,9 @@ func (scfg *SessionSCfg) AsMapInterface() (initialMP map[string]interface{}) {
if scfg.AttrSConns != nil {
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.TrimSuffix(item, utils.CONCATENATED_KEY_SEP+utils.MetaAttributes)
- } else {
- attrSConns[i] = item
+ attrSConns[i] = item
+ if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAttributes) {
+ attrSConns[i] = utils.MetaInternal
}
}
initialMP[utils.AttributeSConnsCfg] = attrSConns
@@ -415,11 +402,9 @@ func (scfg *SessionSCfg) AsMapInterface() (initialMP map[string]interface{}) {
if scfg.CDRsConns != nil {
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.TrimSuffix(item, utils.CONCATENATED_KEY_SEP+utils.MetaCDRs)
- } else {
- CDRsConns[i] = item
+ CDRsConns[i] = item
+ if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCDRs) {
+ CDRsConns[i] = utils.MetaInternal
}
}
initialMP[utils.CDRsConnsCfg] = CDRsConns
@@ -427,11 +412,9 @@ func (scfg *SessionSCfg) AsMapInterface() (initialMP map[string]interface{}) {
if scfg.SchedulerConns != nil {
schedulerConns := make([]string, len(scfg.SchedulerConns))
for i, item := range scfg.SchedulerConns {
- buf := utils.ConcatenatedKey(utils.MetaInternal, utils.MetaScheduler)
- if item == buf {
- schedulerConns[i] = strings.TrimSuffix(item, utils.CONCATENATED_KEY_SEP+utils.MetaScheduler)
- } else {
- schedulerConns[i] = item
+ schedulerConns[i] = item
+ if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaScheduler) {
+ schedulerConns[i] = utils.MetaInternal
}
}
initialMP[utils.SchedulerConnsCfg] = schedulerConns
@@ -439,6 +422,101 @@ func (scfg *SessionSCfg) AsMapInterface() (initialMP map[string]interface{}) {
return
}
+// Clone returns a deep copy of SessionSCfg
+func (scfg SessionSCfg) Clone() (cln *SessionSCfg) {
+ cln = &SessionSCfg{
+ Enabled: scfg.Enabled,
+ ListenBijson: scfg.ListenBijson,
+ DebitInterval: scfg.DebitInterval,
+ StoreSCosts: scfg.StoreSCosts,
+ SessionTTL: scfg.SessionTTL,
+ ClientProtocol: scfg.ClientProtocol,
+ ChannelSyncInterval: scfg.ChannelSyncInterval,
+ TerminateAttempts: scfg.TerminateAttempts,
+ MinDurLowBalance: scfg.MinDurLowBalance,
+
+ SessionIndexes: scfg.SessionIndexes.Clone(),
+ AlterableFields: scfg.AlterableFields.Clone(),
+ STIRCfg: scfg.STIRCfg.Clone(),
+ }
+ if scfg.SessionTTLMaxDelay != nil {
+ cln.SessionTTLMaxDelay = utils.DurationPointer(*scfg.SessionTTLMaxDelay)
+ }
+ if scfg.SessionTTLLastUsed != nil {
+ cln.SessionTTLLastUsed = utils.DurationPointer(*scfg.SessionTTLLastUsed)
+ }
+ if scfg.SessionTTLUsage != nil {
+ cln.SessionTTLUsage = utils.DurationPointer(*scfg.SessionTTLUsage)
+ }
+ if scfg.SessionTTLLastUsage != nil {
+ cln.SessionTTLLastUsage = utils.DurationPointer(*scfg.SessionTTLLastUsage)
+ }
+
+ if scfg.ChargerSConns != nil {
+ cln.ChargerSConns = make([]string, len(scfg.ChargerSConns))
+ for i, con := range scfg.ChargerSConns {
+ cln.ChargerSConns[i] = con
+ }
+ }
+ if scfg.RALsConns != nil {
+ cln.RALsConns = make([]string, len(scfg.RALsConns))
+ for i, con := range scfg.RALsConns {
+ cln.RALsConns[i] = con
+ }
+ }
+ if scfg.ResSConns != nil {
+ cln.ResSConns = make([]string, len(scfg.ResSConns))
+ for i, con := range scfg.ResSConns {
+ cln.ResSConns[i] = con
+ }
+ }
+ if scfg.ThreshSConns != nil {
+ cln.ThreshSConns = make([]string, len(scfg.ThreshSConns))
+ for i, con := range scfg.ThreshSConns {
+ cln.ThreshSConns[i] = con
+ }
+ }
+ if scfg.StatSConns != nil {
+ cln.StatSConns = make([]string, len(scfg.StatSConns))
+ for i, con := range scfg.StatSConns {
+ cln.StatSConns[i] = con
+ }
+ }
+ if scfg.RouteSConns != nil {
+ cln.RouteSConns = make([]string, len(scfg.RouteSConns))
+ for i, con := range scfg.RouteSConns {
+ cln.RouteSConns[i] = con
+ }
+ }
+ if scfg.AttrSConns != nil {
+ cln.AttrSConns = make([]string, len(scfg.AttrSConns))
+ for i, con := range scfg.AttrSConns {
+ cln.AttrSConns[i] = con
+ }
+ }
+ if scfg.CDRsConns != nil {
+ cln.CDRsConns = make([]string, len(scfg.CDRsConns))
+ for i, con := range scfg.CDRsConns {
+ cln.CDRsConns[i] = con
+ }
+ }
+ if scfg.ReplicationConns != nil {
+ cln.ReplicationConns = make([]string, len(scfg.ReplicationConns))
+ for i, con := range scfg.ReplicationConns {
+ cln.ReplicationConns[i] = con
+ }
+ }
+ if scfg.SchedulerConns != nil {
+ cln.SchedulerConns = make([]string, len(scfg.SchedulerConns))
+ for i, con := range scfg.SchedulerConns {
+ cln.SchedulerConns[i] = con
+ }
+ }
+
+ return
+}
+
+// FsAgentCfg the config section that describes the FreeSWITCH Agent
type FsAgentCfg struct {
Enabled bool
SessionSConns []string
@@ -452,7 +530,7 @@ type FsAgentCfg struct {
EventSocketConns []*FsConnCfg
}
-func (fscfg *FsAgentCfg) loadFromJsonCfg(jsnCfg *FreeswitchAgentJsonCfg) error {
+func (fscfg *FsAgentCfg) loadFromJSONCfg(jsnCfg *FreeswitchAgentJsonCfg) error {
if jsnCfg == nil {
return nil
}
@@ -464,10 +542,9 @@ func (fscfg *FsAgentCfg) loadFromJsonCfg(jsnCfg *FreeswitchAgentJsonCfg) error {
fscfg.SessionSConns = make([]string, len(*jsnCfg.Sessions_conns))
for idx, connID := range *jsnCfg.Sessions_conns {
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
+ fscfg.SessionSConns[idx] = connID
if connID == utils.MetaInternal {
fscfg.SessionSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS)
- } else {
- fscfg.SessionSConns[idx] = connID
}
}
}
@@ -501,12 +578,13 @@ func (fscfg *FsAgentCfg) loadFromJsonCfg(jsnCfg *FreeswitchAgentJsonCfg) error {
fscfg.EventSocketConns = make([]*FsConnCfg, len(*jsnCfg.Event_socket_conns))
for idx, jsnConnCfg := range *jsnCfg.Event_socket_conns {
fscfg.EventSocketConns[idx] = NewDfltFsConnConfig()
- fscfg.EventSocketConns[idx].loadFromJsonCfg(jsnConnCfg)
+ fscfg.EventSocketConns[idx].loadFromJSONCfg(jsnConnCfg)
}
}
return nil
}
+// AsMapInterface returns the config as a map[string]interface{}
func (fscfg *FsAgentCfg) AsMapInterface(separator string) (initialMP map[string]interface{}) {
initialMP = map[string]interface{}{
utils.EnabledCfg: fscfg.Enabled,
@@ -519,21 +597,15 @@ func (fscfg *FsAgentCfg) AsMapInterface(separator string) (initialMP map[string]
if fscfg.SessionSConns != nil {
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.TrimSuffix(item, utils.CONCATENATED_KEY_SEP+utils.MetaSessionS)
- } else {
- sessionSConns[i] = item
+ sessionSConns[i] = item
+ if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS) {
+ sessionSConns[i] = utils.MetaInternal
}
}
initialMP[utils.SessionSConnsCfg] = sessionSConns
}
if fscfg.ExtraFields != nil {
- values := make([]string, len(fscfg.ExtraFields))
- for i, item := range fscfg.ExtraFields {
- values[i] = item.Rules
- }
- initialMP[utils.ExtraFieldsCfg] = strings.Join(values, separator)
+ initialMP[utils.ExtraFieldsCfg] = fscfg.ExtraFields.GetRule(separator)
}
if fscfg.MaxWaitConnection != 0 {
@@ -551,16 +623,34 @@ func (fscfg *FsAgentCfg) AsMapInterface(separator string) (initialMP map[string]
return
}
-// Returns the first cached default value for a FreeSWITCHAgent connection
-func NewDfltKamConnConfig() *KamConnCfg {
- if dfltKamConnConfig == nil {
- return new(KamConnCfg) // No defaults, most probably we are building the defaults now
+// Clone returns a deep copy of FsAgentCfg
+func (fscfg FsAgentCfg) Clone() (cln *FsAgentCfg) {
+ cln = &FsAgentCfg{
+ Enabled: fscfg.Enabled,
+ SubscribePark: fscfg.SubscribePark,
+ CreateCdr: fscfg.CreateCdr,
+ ExtraFields: fscfg.ExtraFields.Clone(),
+ LowBalanceAnnFile: fscfg.LowBalanceAnnFile,
+ EmptyBalanceContext: fscfg.EmptyBalanceContext,
+ EmptyBalanceAnnFile: fscfg.EmptyBalanceAnnFile,
+ MaxWaitConnection: fscfg.MaxWaitConnection,
}
- dfltVal := *dfltKamConnConfig
- return &dfltVal
+ if fscfg.SessionSConns != nil {
+ cln.SessionSConns = make([]string, len(fscfg.SessionSConns))
+ for i, con := range fscfg.SessionSConns {
+ cln.SessionSConns[i] = con
+ }
+ }
+ if fscfg.EventSocketConns != nil {
+ cln.EventSocketConns = make([]*FsConnCfg, len(fscfg.EventSocketConns))
+ for i, req := range fscfg.EventSocketConns {
+ cln.EventSocketConns[i] = req.Clone()
+ }
+ }
+ return
}
-// Uses stored defaults so we can pre-populate by loading from JSON config
+// NewDefaultAsteriskConnCfg is uses stored defaults so we can pre-populate by loading from JSON config
func NewDefaultAsteriskConnCfg() *AsteriskConnCfg {
if dfltAstConnCfg == nil {
return new(AsteriskConnCfg) // No defaults, most probably we are building the defaults now
@@ -569,6 +659,7 @@ func NewDefaultAsteriskConnCfg() *AsteriskConnCfg {
return &dfltVal
}
+// AsteriskConnCfg the config for a Asterisk connection
type AsteriskConnCfg struct {
Alias string
Address string
@@ -578,7 +669,7 @@ type AsteriskConnCfg struct {
Reconnects int
}
-func (aConnCfg *AsteriskConnCfg) loadFromJsonCfg(jsnCfg *AstConnJsonCfg) error {
+func (aConnCfg *AsteriskConnCfg) loadFromJSONCfg(jsnCfg *AstConnJsonCfg) error {
if jsnCfg == nil {
return nil
}
@@ -603,6 +694,7 @@ func (aConnCfg *AsteriskConnCfg) loadFromJsonCfg(jsnCfg *AstConnJsonCfg) error {
return nil
}
+// AsMapInterface returns the config as a map[string]interface{}
func (aConnCfg *AsteriskConnCfg) AsMapInterface() map[string]interface{} {
return map[string]interface{}{
utils.AliasCfg: aConnCfg.Alias,
@@ -614,6 +706,19 @@ func (aConnCfg *AsteriskConnCfg) AsMapInterface() map[string]interface{} {
}
}
+// Clone returns a deep copy of AsteriskConnCfg
+func (aConnCfg AsteriskConnCfg) Clone() *AsteriskConnCfg {
+ return &AsteriskConnCfg{
+ Alias: aConnCfg.Alias,
+ Address: aConnCfg.Address,
+ User: aConnCfg.User,
+ Password: aConnCfg.Password,
+ ConnectAttempts: aConnCfg.ConnectAttempts,
+ Reconnects: aConnCfg.Reconnects,
+ }
+}
+
+// AsteriskAgentCfg the config section that describes the Asterisk Agent
type AsteriskAgentCfg struct {
Enabled bool
SessionSConns []string
@@ -621,7 +726,7 @@ type AsteriskAgentCfg struct {
AsteriskConns []*AsteriskConnCfg
}
-func (aCfg *AsteriskAgentCfg) loadFromJsonCfg(jsnCfg *AsteriskAgentJsonCfg) (err error) {
+func (aCfg *AsteriskAgentCfg) loadFromJSONCfg(jsnCfg *AsteriskAgentJsonCfg) (err error) {
if jsnCfg == nil {
return nil
}
@@ -632,10 +737,9 @@ func (aCfg *AsteriskAgentCfg) loadFromJsonCfg(jsnCfg *AsteriskAgentJsonCfg) (err
aCfg.SessionSConns = make([]string, len(*jsnCfg.Sessions_conns))
for idx, attrConn := range *jsnCfg.Sessions_conns {
// if we have the connection internal we change the name so we can have internal rpc for each subsystem
+ aCfg.SessionSConns[idx] = attrConn
if attrConn == utils.MetaInternal {
aCfg.SessionSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS)
- } else {
- aCfg.SessionSConns[idx] = attrConn
}
}
}
@@ -647,12 +751,13 @@ func (aCfg *AsteriskAgentCfg) loadFromJsonCfg(jsnCfg *AsteriskAgentJsonCfg) (err
aCfg.AsteriskConns = make([]*AsteriskConnCfg, len(*jsnCfg.Asterisk_conns))
for i, jsnAConn := range *jsnCfg.Asterisk_conns {
aCfg.AsteriskConns[i] = NewDefaultAsteriskConnCfg()
- aCfg.AsteriskConns[i].loadFromJsonCfg(jsnAConn)
+ aCfg.AsteriskConns[i].loadFromJSONCfg(jsnAConn)
}
}
return nil
}
+// AsMapInterface returns the config as a map[string]interface{}
func (aCfg *AsteriskAgentCfg) AsMapInterface() (initialMP map[string]interface{}) {
initialMP = map[string]interface{}{
utils.EnabledCfg: aCfg.Enabled,
@@ -668,10 +773,9 @@ func (aCfg *AsteriskAgentCfg) AsMapInterface() (initialMP map[string]interface{}
if aCfg.SessionSConns != nil {
sessionSConns := make([]string, len(aCfg.SessionSConns))
for i, item := range aCfg.SessionSConns {
+ sessionSConns[i] = item
if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS) {
- sessionSConns[i] = strings.TrimSuffix(item, utils.CONCATENATED_KEY_SEP+utils.MetaSessionS)
- } else {
- sessionSConns[i] = item
+ sessionSConns[i] = utils.MetaInternal
}
}
initialMP[utils.SessionSConnsCfg] = sessionSConns
@@ -679,6 +783,27 @@ func (aCfg *AsteriskAgentCfg) AsMapInterface() (initialMP map[string]interface{}
return
}
+// Clone returns a deep copy of AsteriskAgentCfg
+func (aCfg AsteriskAgentCfg) Clone() (cln *AsteriskAgentCfg) {
+ cln = &AsteriskAgentCfg{
+ Enabled: aCfg.Enabled,
+ CreateCDR: aCfg.CreateCDR,
+ }
+ if aCfg.SessionSConns != nil {
+ cln.SessionSConns = make([]string, len(aCfg.SessionSConns))
+ for i, con := range aCfg.SessionSConns {
+ cln.SessionSConns[i] = con
+ }
+ }
+ if aCfg.AsteriskConns != nil {
+ cln.AsteriskConns = make([]*AsteriskConnCfg, len(aCfg.AsteriskConns))
+ for i, req := range aCfg.AsteriskConns {
+ cln.AsteriskConns[i] = req.Clone()
+ }
+ }
+ return
+}
+
// STIRcfg the confuguration structure for STIR
type STIRcfg struct {
AllowedAttest utils.StringSet
@@ -712,21 +837,30 @@ func (stirCfg *STIRcfg) loadFromJSONCfg(jsnCfg *STIRJsonCfg) (err error) {
return nil
}
+// AsMapInterface returns the config as a map[string]interface{}
func (stirCfg *STIRcfg) AsMapInterface() (initialMP map[string]interface{}) {
initialMP = map[string]interface{}{
- utils.DefaultAttestCfg: stirCfg.DefaultAttest,
- utils.PublicKeyPathCfg: stirCfg.PublicKeyPath,
- utils.PrivateKeyPathCfg: stirCfg.PrivateKeyPath,
- utils.AllowedAtestCfg: stirCfg.AllowedAttest.AsSlice(),
+ utils.DefaultAttestCfg: stirCfg.DefaultAttest,
+ utils.PublicKeyPathCfg: stirCfg.PublicKeyPath,
+ utils.PrivateKeyPathCfg: stirCfg.PrivateKeyPath,
+ utils.AllowedAtestCfg: stirCfg.AllowedAttest.AsSlice(),
+ utils.PayloadMaxdurationCfg: "0",
}
- var payloadMaxduration string
if stirCfg.PayloadMaxduration > 0 {
- payloadMaxduration = stirCfg.PayloadMaxduration.String()
- } else if stirCfg.PayloadMaxduration == 0 {
- payloadMaxduration = "0"
- } else {
- payloadMaxduration = "-1"
+ initialMP[utils.PayloadMaxdurationCfg] = stirCfg.PayloadMaxduration.String()
+ } else if stirCfg.PayloadMaxduration < 0 {
+ initialMP[utils.PayloadMaxdurationCfg] = "-1"
}
- initialMP[utils.PayloadMaxdurationCfg] = payloadMaxduration
return
}
+
+// Clone returns a deep copy of STIRcfg
+func (stirCfg STIRcfg) Clone() *STIRcfg {
+ return &STIRcfg{
+ AllowedAttest: stirCfg.AllowedAttest.Clone(),
+ PayloadMaxduration: stirCfg.PayloadMaxduration,
+ DefaultAttest: stirCfg.DefaultAttest,
+ PublicKeyPath: stirCfg.PublicKeyPath,
+ PrivateKeyPath: stirCfg.PrivateKeyPath,
+ }
+}
diff --git a/config/sessionscfg_test.go b/config/sessionscfg_test.go
index 8999b8823..45cf69916 100644
--- a/config/sessionscfg_test.go
+++ b/config/sessionscfg_test.go
@@ -21,6 +21,7 @@ import (
"reflect"
"sort"
"testing"
+ "time"
"github.com/cgrates/cgrates/utils"
)
@@ -53,7 +54,7 @@ func TestFsAgentCfgloadFromJsonCfg1(t *testing.T) {
},
}
fsAgentCfg := new(FsAgentCfg)
- if err := fsAgentCfg.loadFromJsonCfg(fsAgentJsnCfg); err != nil {
+ if err := fsAgentCfg.loadFromJSONCfg(fsAgentJsnCfg); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(eFsAgentConfig, fsAgentCfg) {
t.Errorf("Expected: %+v , received: %+v", utils.ToJSON(eFsAgentConfig), utils.ToJSON(fsAgentCfg))
@@ -106,7 +107,7 @@ func TestSessionSCfgloadFromJsonCfgCase1(t *testing.T) {
DebitInterval: 2,
StoreSCosts: true,
SessionTTL: 0,
- SessionIndexes: utils.StringMap{},
+ SessionIndexes: utils.StringSet{},
ClientProtocol: 2.5,
ChannelSyncInterval: 10,
TerminateAttempts: 6,
@@ -123,7 +124,7 @@ func TestSessionSCfgloadFromJsonCfgCase1(t *testing.T) {
}
if jsonCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = jsonCfg.sessionSCfg.loadFromJsonCfg(cfgJSON); err != nil {
+ } else if err = jsonCfg.sessionSCfg.loadFromJSONCfg(cfgJSON); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(expected, jsonCfg.sessionSCfg) {
t.Errorf("Expected %+v \n, received %+v", utils.ToJSON(expected), utils.ToJSON(jsonCfg.sessionSCfg))
@@ -137,7 +138,7 @@ func TestSessionSCfgloadFromJsonCfgCase2(t *testing.T) {
expected := "Replication connection ID needs to be different than *internal"
if jsonCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = jsonCfg.sessionSCfg.loadFromJsonCfg(cfgJSON); err == nil || err.Error() != expected {
+ } else if err = jsonCfg.sessionSCfg.loadFromJSONCfg(cfgJSON); err == nil || err.Error() != expected {
t.Errorf("Expected %+v, received %+v", expected, err)
}
}
@@ -149,7 +150,7 @@ func TestSessionSCfgloadFromJsonCfgCase3(t *testing.T) {
expected := "time: unknown unit \"ss\" in duration \"1ss\""
if jsonCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = jsonCfg.sessionSCfg.loadFromJsonCfg(cfgJSON); err == nil || err.Error() != expected {
+ } else if err = jsonCfg.sessionSCfg.loadFromJSONCfg(cfgJSON); err == nil || err.Error() != expected {
t.Errorf("Expected %+v, received %+v", expected, err)
}
}
@@ -161,7 +162,7 @@ func TestSessionSCfgloadFromJsonCfgCase5(t *testing.T) {
expected := "time: unknown unit \"ss\" in duration \"1ss\""
if jsonCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = jsonCfg.sessionSCfg.loadFromJsonCfg(cfgJSON); err == nil || err.Error() != expected {
+ } else if err = jsonCfg.sessionSCfg.loadFromJSONCfg(cfgJSON); err == nil || err.Error() != expected {
t.Errorf("Expected %+v, received %+v", expected, err)
}
}
@@ -173,7 +174,7 @@ func TestSessionSCfgloadFromJsonCfgCase7(t *testing.T) {
expected := "time: unknown unit \"ss\" in duration \"1ss\""
if jsonCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = jsonCfg.sessionSCfg.loadFromJsonCfg(cfgJSON); err == nil || err.Error() != expected {
+ } else if err = jsonCfg.sessionSCfg.loadFromJSONCfg(cfgJSON); err == nil || err.Error() != expected {
t.Errorf("Expected %+v, received %+v", expected, err)
}
}
@@ -185,7 +186,7 @@ func TestSessionSCfgloadFromJsonCfgCase8(t *testing.T) {
expected := "time: unknown unit \"ss\" in duration \"1ss\""
if jsonCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = jsonCfg.sessionSCfg.loadFromJsonCfg(cfgJSON); err == nil || err.Error() != expected {
+ } else if err = jsonCfg.sessionSCfg.loadFromJSONCfg(cfgJSON); err == nil || err.Error() != expected {
t.Errorf("Expected %+v, received %+v", expected, err)
}
}
@@ -197,7 +198,7 @@ func TestSessionSCfgloadFromJsonCfgCase9(t *testing.T) {
expected := "time: unknown unit \"ss\" in duration \"1ss\""
if jsonCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = jsonCfg.sessionSCfg.loadFromJsonCfg(cfgJSON); err == nil || err.Error() != expected {
+ } else if err = jsonCfg.sessionSCfg.loadFromJSONCfg(cfgJSON); err == nil || err.Error() != expected {
t.Errorf("Expected %+v, received %+v", expected, err)
}
cfgJSON1 := &SessionSJsonCfg{
@@ -205,7 +206,7 @@ func TestSessionSCfgloadFromJsonCfgCase9(t *testing.T) {
}
if jsonCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = jsonCfg.sessionSCfg.loadFromJsonCfg(cfgJSON1); err == nil || err.Error() != expected {
+ } else if err = jsonCfg.sessionSCfg.loadFromJSONCfg(cfgJSON1); err == nil || err.Error() != expected {
t.Errorf("Expected %+v, received %+v", expected, err)
}
cfgJSON2 := &SessionSJsonCfg{
@@ -213,7 +214,7 @@ func TestSessionSCfgloadFromJsonCfgCase9(t *testing.T) {
}
if jsonCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = jsonCfg.sessionSCfg.loadFromJsonCfg(cfgJSON2); err == nil || err.Error() != expected {
+ } else if err = jsonCfg.sessionSCfg.loadFromJSONCfg(cfgJSON2); err == nil || err.Error() != expected {
t.Errorf("Expected %+v, received %+v", expected, err)
}
cfgJSON3 := &SessionSJsonCfg{
@@ -221,7 +222,7 @@ func TestSessionSCfgloadFromJsonCfgCase9(t *testing.T) {
}
if jsonCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = jsonCfg.sessionSCfg.loadFromJsonCfg(cfgJSON3); err == nil || err.Error() != expected {
+ } else if err = jsonCfg.sessionSCfg.loadFromJSONCfg(cfgJSON3); err == nil || err.Error() != expected {
t.Errorf("Expected %+v, received %+v", expected, err)
}
}
@@ -248,7 +249,7 @@ func TestSessionSCfgloadFromJsonCfgCase10(t *testing.T) {
DebitInterval: 0,
StoreSCosts: false,
SessionTTL: 0,
- SessionIndexes: utils.StringMap{},
+ SessionIndexes: utils.StringSet{},
ClientProtocol: 1.0,
ChannelSyncInterval: 0,
TerminateAttempts: 5,
@@ -269,7 +270,7 @@ func TestSessionSCfgloadFromJsonCfgCase10(t *testing.T) {
}
if jsonCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = jsonCfg.sessionSCfg.loadFromJsonCfg(cfgJSON); err != nil {
+ } else if err = jsonCfg.sessionSCfg.loadFromJSONCfg(cfgJSON); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(jsonCfg.sessionSCfg, expected) {
t.Errorf("Expected %+v \n, received %+v", utils.ToJSON(expected), utils.ToJSON(jsonCfg.sessionSCfg))
@@ -285,7 +286,7 @@ func TestSessionSCfgloadFromJsonCfgCase11(t *testing.T) {
expected := "time: unknown unit \"ss\" in duration \"1ss\""
if jsonCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = jsonCfg.sessionSCfg.loadFromJsonCfg(cfgJSON); err == nil || err.Error() != expected {
+ } else if err = jsonCfg.sessionSCfg.loadFromJSONCfg(cfgJSON); err == nil || err.Error() != expected {
t.Errorf("Expected %+v, received %+v", expected, err)
}
}
@@ -483,7 +484,7 @@ func TestFsAgentCfgloadFromJsonCfgCase1(t *testing.T) {
}
if jsonCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = jsonCfg.fsAgentCfg.loadFromJsonCfg(fsAgentJsnCfg); err != nil {
+ } else if err = jsonCfg.fsAgentCfg.loadFromJSONCfg(fsAgentJsnCfg); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(expected, jsonCfg.fsAgentCfg) {
t.Errorf("Expected %+v \n, received %+v", utils.ToJSON(expected), utils.ToJSON(jsonCfg.fsAgentCfg))
@@ -497,7 +498,7 @@ func TestFsAgentCfgloadFromJsonCfgCase2(t *testing.T) {
expected := "time: unknown unit \"ss\" in duration \"1ss\""
if jsonCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = jsonCfg.fsAgentCfg.loadFromJsonCfg(fsAgentJsnCfg); err == nil || err.Error() != expected {
+ } else if err = jsonCfg.fsAgentCfg.loadFromJSONCfg(fsAgentJsnCfg); err == nil || err.Error() != expected {
t.Errorf("Expected %+v, received %+v", expected, err)
}
}
@@ -509,7 +510,7 @@ func TestFsAgentCfgloadFromJsonCfgCase3(t *testing.T) {
expected := "invalid converter terminator in rule: "
if jsonCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = jsonCfg.fsAgentCfg.loadFromJsonCfg(fsAgentJsnCfg); err == nil || err.Error() != expected {
+ } else if err = jsonCfg.fsAgentCfg.loadFromJSONCfg(fsAgentJsnCfg); err == nil || err.Error() != expected {
t.Errorf("Expected %+v, received %+v", expected, err)
}
}
@@ -603,12 +604,12 @@ func TestFsAgentCfgAsMapInterfaceCase3(t *testing.T) {
func TestFsConnCfgloadFromJsonCfg(t *testing.T) {
var fscocfg, expected FsConnCfg
- if err := fscocfg.loadFromJsonCfg(nil); err != nil {
+ if err := fscocfg.loadFromJSONCfg(nil); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(fscocfg, expected) {
t.Errorf("Expected: %+v ,received: %+v", expected, fscocfg)
}
- if err := fscocfg.loadFromJsonCfg(new(FsConnJsonCfg)); err != nil {
+ if err := fscocfg.loadFromJSONCfg(new(FsConnJsonCfg)); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(fscocfg, expected) {
t.Errorf("Expected: %+v ,received: %+v", expected, fscocfg)
@@ -625,7 +626,7 @@ func TestFsConnCfgloadFromJsonCfg(t *testing.T) {
Reconnects: 5,
Alias: "127.0.0.1:8448",
}
- if err = fscocfg.loadFromJsonCfg(json); err != nil {
+ if err = fscocfg.loadFromJSONCfg(json); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(expected, fscocfg) {
t.Errorf("Expected: %+v , received: %+v", utils.ToJSON(expected), utils.ToJSON(fscocfg))
@@ -634,11 +635,11 @@ func TestFsConnCfgloadFromJsonCfg(t *testing.T) {
func TestRemoteHostloadFromJsonCfg(t *testing.T) {
var hpoolcfg, expected RemoteHost
- hpoolcfg.loadFromJsonCfg(nil)
+ hpoolcfg.loadFromJSONCfg(nil)
if !reflect.DeepEqual(hpoolcfg, expected) {
t.Errorf("Expected: %+v ,received: %+v", expected, hpoolcfg)
}
- hpoolcfg.loadFromJsonCfg(new(RemoteHostJson))
+ hpoolcfg.loadFromJSONCfg(new(RemoteHostJson))
if !reflect.DeepEqual(hpoolcfg, expected) {
t.Errorf("Expected: %+v ,received: %+v", expected, hpoolcfg)
}
@@ -650,7 +651,7 @@ func TestRemoteHostloadFromJsonCfg(t *testing.T) {
Address: "127.0.0.1:8448",
Synchronous: true,
}
- hpoolcfg.loadFromJsonCfg(json)
+ hpoolcfg.loadFromJSONCfg(json)
if !reflect.DeepEqual(expected, hpoolcfg) {
t.Errorf("Expected: %+v , received: %+v", utils.ToJSON(expected), utils.ToJSON(hpoolcfg))
}
@@ -687,7 +688,7 @@ func TestAsteriskAgentCfgloadFromJsonCfg(t *testing.T) {
}
if jsonCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = jsonCfg.asteriskAgentCfg.loadFromJsonCfg(cfgJSON); err != nil {
+ } else if err = jsonCfg.asteriskAgentCfg.loadFromJSONCfg(cfgJSON); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(expected, jsonCfg.asteriskAgentCfg) {
t.Errorf("Expected %+v \n, received %+v", utils.ToJSON(expected), utils.ToJSON(jsonCfg.asteriskAgentCfg))
@@ -741,12 +742,12 @@ func TestAsteriskAgentCfgAsMapInterface1(t *testing.T) {
func TestAsteriskConnCfgloadFromJsonCfg(t *testing.T) {
var asconcfg, expected AsteriskConnCfg
- if err := asconcfg.loadFromJsonCfg(nil); err != nil {
+ if err := asconcfg.loadFromJSONCfg(nil); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(asconcfg, expected) {
t.Errorf("Expected: %+v ,received: %+v", expected, asconcfg)
}
- if err := asconcfg.loadFromJsonCfg(new(AstConnJsonCfg)); err != nil {
+ if err := asconcfg.loadFromJSONCfg(new(AstConnJsonCfg)); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(asconcfg, expected) {
t.Errorf("Expected: %+v ,received: %+v", expected, asconcfg)
@@ -765,9 +766,136 @@ func TestAsteriskConnCfgloadFromJsonCfg(t *testing.T) {
ConnectAttempts: 3,
Reconnects: 5,
}
- if err = asconcfg.loadFromJsonCfg(json); err != nil {
+ if err = asconcfg.loadFromJSONCfg(json); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(expected, asconcfg) {
t.Errorf("Expected: %+v , received: %+v", utils.ToJSON(expected), utils.ToJSON(asconcfg))
}
}
+
+func TestAsteriskAgentCfgClone(t *testing.T) {
+ ban := &AsteriskAgentCfg{
+ Enabled: true,
+ SessionSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS), "*conn1"},
+ CreateCDR: true,
+ AsteriskConns: []*AsteriskConnCfg{{
+ Alias: "127.0.0.1:8448",
+ Address: "127.0.0.1:8088",
+ User: "cgrates",
+ Password: "CGRateS.org",
+ ConnectAttempts: 3,
+ Reconnects: 5,
+ }},
+ }
+ rcv := ban.Clone()
+ if !reflect.DeepEqual(ban, rcv) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(ban), utils.ToJSON(rcv))
+ }
+ if rcv.SessionSConns[1] = ""; ban.SessionSConns[1] != "*conn1" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+ if rcv.AsteriskConns[0].User = ""; ban.AsteriskConns[0].User != "cgrates" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+}
+
+func TestFsAgentCfgClone(t *testing.T) {
+ ban := &FsAgentCfg{
+ Enabled: true,
+ CreateCdr: true,
+ SubscribePark: true,
+ EmptyBalanceAnnFile: "file",
+ EmptyBalanceContext: "context",
+ ExtraFields: NewRSRParsersMustCompile("tenant", utils.INFIELD_SEP),
+ LowBalanceAnnFile: "file2",
+ MaxWaitConnection: time.Second,
+ SessionSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS), "*conn1"},
+ EventSocketConns: []*FsConnCfg{
+ {Address: "1.2.3.4:8021", Password: "ClueCon", Reconnects: 5, Alias: "1.2.3.4:8021"},
+ {Address: "2.3.4.5:8021", Password: "ClueCon", Reconnects: 5, Alias: "2.3.4.5:8021"},
+ },
+ }
+ rcv := ban.Clone()
+ if !reflect.DeepEqual(ban, rcv) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(ban), utils.ToJSON(rcv))
+ }
+ if rcv.SessionSConns[1] = ""; ban.SessionSConns[1] != "*conn1" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+ if rcv.EventSocketConns[0].Password = ""; ban.EventSocketConns[0].Password != "ClueCon" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+}
+
+func TestSessionSCfgClone(t *testing.T) {
+ ban := &SessionSCfg{
+ Enabled: true,
+ ListenBijson: "127.0.0.1:2018",
+ ChargerSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaChargers), "*conn1"},
+ RALsConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaResponder), "*conn1"},
+ ResSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaResources), "*conn1"},
+ ThreshSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaThresholds), "*conn1"},
+ StatSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStatS), "*conn1"},
+ RouteSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaRoutes), "*conn1"},
+ AttrSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAttributes), "*conn1"},
+ CDRsConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCDRs), "*conn1"},
+ ReplicationConns: []string{"*conn1"},
+ DebitInterval: 2,
+ StoreSCosts: true,
+ SessionTTL: 0,
+ SessionIndexes: utils.StringSet{},
+ ClientProtocol: 2.5,
+ ChannelSyncInterval: 10,
+ TerminateAttempts: 6,
+ AlterableFields: utils.StringSet{},
+ MinDurLowBalance: 1,
+ SchedulerConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaScheduler), "*conn1"},
+ SessionTTLMaxDelay: utils.DurationPointer(time.Second),
+ SessionTTLLastUsed: utils.DurationPointer(time.Second),
+ SessionTTLUsage: utils.DurationPointer(time.Second),
+ SessionTTLLastUsage: utils.DurationPointer(time.Second),
+ STIRCfg: &STIRcfg{
+ AllowedAttest: utils.StringSet{utils.META_ANY: {}},
+ PayloadMaxduration: -1,
+ DefaultAttest: "A",
+ PrivateKeyPath: "randomPath",
+ PublicKeyPath: "randomPath",
+ },
+ }
+ rcv := ban.Clone()
+ if !reflect.DeepEqual(ban, rcv) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(ban), utils.ToJSON(rcv))
+ }
+ if rcv.ChargerSConns[1] = ""; ban.ChargerSConns[1] != "*conn1" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+
+ if rcv.RALsConns[1] = ""; ban.RALsConns[1] != "*conn1" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+ if rcv.ResSConns[1] = ""; ban.ResSConns[1] != "*conn1" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+ if rcv.ThreshSConns[1] = ""; ban.ThreshSConns[1] != "*conn1" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+ if rcv.StatSConns[1] = ""; ban.StatSConns[1] != "*conn1" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+ if rcv.RouteSConns[1] = ""; ban.RouteSConns[1] != "*conn1" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+ if rcv.AttrSConns[1] = ""; ban.AttrSConns[1] != "*conn1" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+ if rcv.CDRsConns[1] = ""; ban.CDRsConns[1] != "*conn1" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+ if rcv.ReplicationConns[0] = ""; ban.ReplicationConns[0] != "*conn1" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+
+ if rcv.STIRCfg.DefaultAttest = ""; ban.STIRCfg.DefaultAttest != "A" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+}
diff --git a/config/stordbcfg.go b/config/stordbcfg.go
index babad649d..da6f35e1a 100644
--- a/config/stordbcfg.go
+++ b/config/stordbcfg.go
@@ -42,8 +42,8 @@ type StorDbCfg struct {
Opts map[string]interface{}
}
-// loadFromJsonCfg loads StoreDb config from JsonCfg
-func (dbcfg *StorDbCfg) loadFromJsonCfg(jsnDbCfg *DbJsonCfg) (err error) {
+// loadFromJSONCfg loads StoreDb config from JsonCfg
+func (dbcfg *StorDbCfg) loadFromJSONCfg(jsnDbCfg *DbJsonCfg) (err error) {
if jsnDbCfg == nil {
return nil
}
@@ -101,7 +101,7 @@ func (dbcfg *StorDbCfg) loadFromJsonCfg(jsnDbCfg *DbJsonCfg) (err error) {
if jsnDbCfg.Items != nil {
for kJsn, vJsn := range *jsnDbCfg.Items {
val := new(ItemOpt)
- val.loadFromJsonCfg(vJsn) //To review if the function signature changes
+ val.loadFromJSONCfg(vJsn) //To review if the function signature changes
dbcfg.Items[kJsn] = val
}
}
@@ -109,27 +109,52 @@ func (dbcfg *StorDbCfg) loadFromJsonCfg(jsnDbCfg *DbJsonCfg) (err error) {
}
// Clone returns the cloned object
-func (dbcfg *StorDbCfg) Clone() *StorDbCfg {
- items := make(map[string]*ItemOpt)
+func (dbcfg *StorDbCfg) Clone() (cln *StorDbCfg) {
+ cln = &StorDbCfg{
+ Type: dbcfg.Type,
+ Host: dbcfg.Host,
+ Port: dbcfg.Port,
+ Name: dbcfg.Name,
+ User: dbcfg.User,
+ Password: dbcfg.Password,
+
+ Items: make(map[string]*ItemOpt),
+ Opts: make(map[string]interface{}),
+ }
for key, item := range dbcfg.Items {
- items[key] = item.Clone()
+ cln.Items[key] = item.Clone()
}
- return &StorDbCfg{
- Type: dbcfg.Type,
- Host: dbcfg.Host,
- Port: dbcfg.Port,
- Name: dbcfg.Name,
- User: dbcfg.User,
- Password: dbcfg.Password,
- StringIndexedFields: dbcfg.StringIndexedFields,
- PrefixIndexedFields: dbcfg.PrefixIndexedFields,
- RmtConns: dbcfg.RmtConns,
- RplConns: dbcfg.RplConns,
- Items: items,
- Opts: dbcfg.Opts,
+ for key, val := range dbcfg.Opts {
+ cln.Opts[key] = val
}
+ if dbcfg.StringIndexedFields != nil {
+ cln.StringIndexedFields = make([]string, len(dbcfg.StringIndexedFields))
+ for i, idx := range dbcfg.StringIndexedFields {
+ cln.StringIndexedFields[i] = idx
+ }
+ }
+ if dbcfg.PrefixIndexedFields != nil {
+ cln.PrefixIndexedFields = make([]string, len(dbcfg.PrefixIndexedFields))
+ for i, idx := range dbcfg.PrefixIndexedFields {
+ cln.PrefixIndexedFields[i] = idx
+ }
+ }
+ if dbcfg.RmtConns != nil {
+ cln.RmtConns = make([]string, len(dbcfg.RmtConns))
+ for i, conn := range dbcfg.RmtConns {
+ cln.RmtConns[i] = conn
+ }
+ }
+ if dbcfg.RplConns != nil {
+ cln.RplConns = make([]string, len(dbcfg.RplConns))
+ for i, conn := range dbcfg.RplConns {
+ cln.RplConns[i] = conn
+ }
+ }
+ return
}
+// AsMapInterface returns the config as a map[string]interface{}
func (dbcfg *StorDbCfg) AsMapInterface() (initialMP map[string]interface{}) {
initialMP = map[string]interface{}{
utils.DataDbTypeCfg: utils.Meta + dbcfg.Type,
diff --git a/config/stordbcfg_test.go b/config/stordbcfg_test.go
index 0a102000c..5829d8b2b 100644
--- a/config/stordbcfg_test.go
+++ b/config/stordbcfg_test.go
@@ -83,7 +83,7 @@ func TestStoreDbCfgloadFromJsonCfgCase1(t *testing.T) {
}
if jsonCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = jsonCfg.storDbCfg.loadFromJsonCfg(cfgJSON); err != nil {
+ } else if err = jsonCfg.storDbCfg.loadFromJSONCfg(cfgJSON); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(expected.Items[utils.MetaSessionsCosts], jsonCfg.storDbCfg.Items[utils.MetaSessionsCosts]) {
t.Errorf("Expected %+v \n, recevied %+v", utils.ToJSON(expected.Items[utils.MetaSessionsCosts]),
@@ -104,7 +104,7 @@ func TestStoreDbCfgloadFromJsonCfgCase2(t *testing.T) {
expected := "Replication connection ID needs to be different than *internal"
if jsonCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = jsonCfg.storDbCfg.loadFromJsonCfg(storDbJSON); err == nil || err.Error() != expected {
+ } else if err = jsonCfg.storDbCfg.loadFromJSONCfg(storDbJSON); err == nil || err.Error() != expected {
t.Errorf("Expected %+v, received %+v", storDbJSON, expected)
}
}
@@ -116,7 +116,7 @@ func TestStoreDbCfgloadFromJsonCfgCase3(t *testing.T) {
expected := "Remote connection ID needs to be different than *internal"
if jsonCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = jsonCfg.storDbCfg.loadFromJsonCfg(storDbJSON); err == nil || err.Error() != expected {
+ } else if err = jsonCfg.storDbCfg.loadFromJSONCfg(storDbJSON); err == nil || err.Error() != expected {
t.Errorf("Expected %+v, received %+v", storDbJSON, expected)
}
}
@@ -148,7 +148,7 @@ func TestStoreDbCfgloadFromJsonCfgPort(t *testing.T) {
t.Error(err)
} else if jsnDataDbCfg, err := jsnCfg.DbJsonCfg(STORDB_JSN); err != nil {
t.Error(err)
- } else if err = dbcfg.loadFromJsonCfg(jsnDataDbCfg); err != nil {
+ } else if err = dbcfg.loadFromJSONCfg(jsnDataDbCfg); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(expected, dbcfg) {
t.Errorf("Expected: %+v , received: %+v", expected, dbcfg)
@@ -168,7 +168,7 @@ func TestStoreDbCfgloadFromJsonCfgPort(t *testing.T) {
t.Error(err)
} else if jsnDataDbCfg, err := jsnCfg.DbJsonCfg(STORDB_JSN); err != nil {
t.Error(err)
- } else if err = dbcfg.loadFromJsonCfg(jsnDataDbCfg); err != nil {
+ } else if err = dbcfg.loadFromJSONCfg(jsnDataDbCfg); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(expected, dbcfg) {
t.Errorf("Expected: %+v , received: %+v", expected, dbcfg)
@@ -188,7 +188,7 @@ func TestStoreDbCfgloadFromJsonCfgPort(t *testing.T) {
t.Error(err)
} else if jsnDataDbCfg, err := jsnCfg.DbJsonCfg(STORDB_JSN); err != nil {
t.Error(err)
- } else if err = dbcfg.loadFromJsonCfg(jsnDataDbCfg); err != nil {
+ } else if err = dbcfg.loadFromJSONCfg(jsnDataDbCfg); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(expected, dbcfg) {
t.Errorf("Expected: %+v , received: %+v", expected, dbcfg)
@@ -264,3 +264,60 @@ func TestStorDbCfgAsMapInterface(t *testing.T) {
}
}
}
+
+func TestStorDbCfgClone(t *testing.T) {
+ ban := &StorDbCfg{
+ Type: utils.MYSQL,
+ Host: "127.0.0.1",
+ Port: "-1",
+ Name: utils.CGRATES,
+ User: utils.CGRATES,
+ Password: "pass123",
+ StringIndexedFields: []string{"*req.index1"},
+ PrefixIndexedFields: []string{"*req.index1"},
+ RmtConns: []string{"*conn1"},
+ RplConns: []string{"*conn1"},
+ Items: map[string]*ItemOpt{
+ utils.MetaSessionsCosts: {
+ Remote: true,
+ Replicate: true,
+ },
+ utils.MetaCDRs: {
+ Remote: true,
+ Replicate: false,
+ },
+ },
+ Opts: map[string]interface{}{
+ utils.MaxOpenConnsCfg: 100.,
+ utils.MaxIdleConnsCfg: 10.,
+ utils.ConnMaxLifetimeCfg: 0.,
+ utils.QueryTimeoutCfg: "10s",
+ utils.SSLModeCfg: "disable",
+ },
+ }
+ rcv := ban.Clone()
+ if !reflect.DeepEqual(ban, rcv) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(ban), utils.ToJSON(rcv))
+ }
+ if rcv.StringIndexedFields[0] = ""; ban.StringIndexedFields[0] != "*req.index1" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+ if rcv.PrefixIndexedFields[0] = ""; ban.PrefixIndexedFields[0] != "*req.index1" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+
+ if rcv.RmtConns[0] = ""; ban.RmtConns[0] != "*conn1" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+ if rcv.RplConns[0] = ""; ban.RplConns[0] != "*conn1" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+
+ if rcv.Items[utils.MetaCDRs].Remote = false; !ban.Items[utils.MetaCDRs].Remote {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+ if rcv.Opts[utils.SSLModeCfg] = ""; ban.Opts[utils.SSLModeCfg] != "disable" {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+
+}
diff --git a/config/tlscfg.go b/config/tlscfg.go
index d3bb3a763..8fe87332c 100644
--- a/config/tlscfg.go
+++ b/config/tlscfg.go
@@ -20,8 +20,8 @@ package config
import "github.com/cgrates/cgrates/utils"
-// AttributeSCfg is the configuration of attribute service
-type TlsCfg struct {
+// TLSCfg is the configuration for tls
+type TLSCfg struct {
ServerCerificate string
ServerKey string
ServerPolicy int
@@ -31,7 +31,7 @@ type TlsCfg struct {
CaCertificate string
}
-func (tls *TlsCfg) loadFromJsonCfg(jsnCfg *TlsJsonCfg) (err error) {
+func (tls *TLSCfg) loadFromJSONCfg(jsnCfg *TlsJsonCfg) (err error) {
if jsnCfg == nil {
return nil
}
@@ -59,7 +59,8 @@ func (tls *TlsCfg) loadFromJsonCfg(jsnCfg *TlsJsonCfg) (err error) {
return
}
-func (tls *TlsCfg) AsMapInterface() map[string]interface{} {
+// AsMapInterface returns the config as a map[string]interface{}
+func (tls *TLSCfg) AsMapInterface() map[string]interface{} {
return map[string]interface{}{
utils.ServerCerificateCfg: tls.ServerCerificate,
utils.ServerKeyCfg: tls.ServerKey,
@@ -71,3 +72,16 @@ func (tls *TlsCfg) AsMapInterface() map[string]interface{} {
}
}
+
+// Clone returns a deep copy of TLSCfg
+func (tls TLSCfg) Clone() *TLSCfg {
+ return &TLSCfg{
+ ServerCerificate: tls.ServerCerificate,
+ ServerKey: tls.ServerKey,
+ ServerPolicy: tls.ServerPolicy,
+ ServerName: tls.ServerName,
+ ClientCerificate: tls.ClientCerificate,
+ ClientKey: tls.ClientKey,
+ CaCertificate: tls.CaCertificate,
+ }
+}
diff --git a/config/tlscfg_test.go b/config/tlscfg_test.go
index d457e9a8c..40f917bb6 100644
--- a/config/tlscfg_test.go
+++ b/config/tlscfg_test.go
@@ -34,7 +34,7 @@ func TestTlsCfgloadFromJsonCfg(t *testing.T) {
Server_name: utils.StringPointer("TestServerName"),
Server_policy: utils.IntPointer(3),
}
- expected := &TlsCfg{
+ expected := &TLSCfg{
ServerCerificate: "path/To/Server/Cert",
ServerKey: "path/To/Server/Key",
CaCertificate: "path/To/CA/Cert",
@@ -45,7 +45,7 @@ func TestTlsCfgloadFromJsonCfg(t *testing.T) {
}
if jsonCfg, err := NewDefaultCGRConfig(); err != nil {
t.Error(err)
- } else if err = jsonCfg.tlsCfg.loadFromJsonCfg(cfgJSON); err != nil {
+ } else if err = jsonCfg.tlsCfg.loadFromJSONCfg(cfgJSON); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(expected, jsonCfg.tlsCfg) {
t.Errorf("Expected %+v \n, received %+v", utils.ToJSON(expected), utils.ToJSON(jsonCfg.tlsCfg))
@@ -99,3 +99,22 @@ func TestTlsCfgAsMapInterface1(t *testing.T) {
t.Errorf("Expected %+v \n, received %+v", utils.ToJSON(eMap), utils.ToJSON(rcv))
}
}
+
+func TestTLSCfgClone(t *testing.T) {
+ ban := &TLSCfg{
+ ServerCerificate: "path/To/Server/Cert",
+ ServerKey: "path/To/Server/Key",
+ CaCertificate: "path/To/CA/Cert",
+ ClientCerificate: "path/To/Client/Cert",
+ ClientKey: "path/To/Client/Key",
+ ServerName: "TestServerName",
+ ServerPolicy: 3,
+ }
+ rcv := ban.Clone()
+ if !reflect.DeepEqual(ban, rcv) {
+ t.Errorf("Expected: %+v\nReceived: %+v", utils.ToJSON(ban), utils.ToJSON(rcv))
+ }
+ if rcv.ServerPolicy = 0; ban.ServerPolicy != 3 {
+ t.Errorf("Expected clone to not modify the cloned")
+ }
+}
diff --git a/loaders/loader.go b/loaders/loader.go
index 5ae4881a6..206fc51af 100644
--- a/loaders/loader.go
+++ b/loaders/loader.go
@@ -46,7 +46,7 @@ func NewLoader(dm *engine.DataManager, cfg *config.LoaderSCfg,
enabled: cfg.Enabled,
tenant: cfg.Tenant,
dryRun: cfg.DryRun,
- ldrID: cfg.Id,
+ ldrID: cfg.ID,
tpInDir: cfg.TpInDir,
tpOutDir: cfg.TpOutDir,
lockFilename: cfg.LockFileName,
diff --git a/loaders/loaders.go b/loaders/loaders.go
index 34e656b1c..ace113f50 100644
--- a/loaders/loaders.go
+++ b/loaders/loaders.go
@@ -34,7 +34,7 @@ func NewLoaderService(dm *engine.DataManager, ldrsCfg []*config.LoaderSCfg,
ldrS = &LoaderService{ldrs: make(map[string]*Loader)}
for _, ldrCfg := range ldrsCfg {
if ldrCfg.Enabled {
- ldrS.ldrs[ldrCfg.Id] = NewLoader(dm, ldrCfg, timezone, filterS, connMgr, ldrCfg.CacheSConns)
+ ldrS.ldrs[ldrCfg.ID] = NewLoader(dm, ldrCfg, timezone, filterS, connMgr, ldrCfg.CacheSConns)
}
}
return
@@ -141,7 +141,7 @@ func (ldrS *LoaderService) Reload(dm *engine.DataManager, ldrsCfg []*config.Load
ldrS.ldrs = make(map[string]*Loader)
for _, ldrCfg := range ldrsCfg {
if ldrCfg.Enabled {
- ldrS.ldrs[ldrCfg.Id] = NewLoader(dm, ldrCfg, timezone, filterS, connMgr, ldrCfg.CacheSConns)
+ ldrS.ldrs[ldrCfg.ID] = NewLoader(dm, ldrCfg, timezone, filterS, connMgr, ldrCfg.CacheSConns)
}
}
ldrS.Unlock()
diff --git a/migrator/rateprofiles_it_test.go b/migrator/rateprofiles_it_test.go
index 7deb598c3..202cd73d7 100644
--- a/migrator/rateprofiles_it_test.go
+++ b/migrator/rateprofiles_it_test.go
@@ -183,7 +183,6 @@ func testRatePrfITMigrateAndMove(t *testing.T) {
ID: "RP1",
FilterIDs: []string{"*string:~*req.Subject:1001"},
Weight: 0,
- ConnectFee: 0.1,
RoundingMethod: "*up",
RoundingDecimals: 4,
MinCost: 0.1,
@@ -196,9 +195,9 @@ func testRatePrfITMigrateAndMove(t *testing.T) {
Weight: 0,
IntervalRates: []*engine.IntervalRate{
{
- Value: 0.12,
- Unit: time.Minute,
- Increment: time.Minute,
+ RecurrentFee: 0.12,
+ Unit: time.Minute,
+ Increment: time.Minute,
},
},
Blocker: false,
@@ -209,9 +208,9 @@ func testRatePrfITMigrateAndMove(t *testing.T) {
Weight: 10,
IntervalRates: []*engine.IntervalRate{
{
- Value: 0.06,
- Unit: time.Minute,
- Increment: time.Second,
+ RecurrentFee: 0.06,
+ Unit: time.Minute,
+ Increment: time.Second,
},
},
Blocker: false,
diff --git a/services/httpagent.go b/services/httpagent.go
index aa7b95801..f90440d41 100644
--- a/services/httpagent.go
+++ b/services/httpagent.go
@@ -64,7 +64,7 @@ func (ha *HTTPAgent) Start() (err error) {
ha.Lock()
utils.Logger.Info(fmt.Sprintf("<%s> successfully started HTTPAgent", utils.HTTPAgent))
for _, agntCfg := range ha.cfg.HTTPAgentCfg() {
- ha.server.RegisterHttpHandler(agntCfg.Url,
+ ha.server.RegisterHttpHandler(agntCfg.URL,
agents.NewHTTPAgent(ha.connMgr, agntCfg.SessionSConns, filterS,
ha.cfg.GeneralCfg().DefaultTenant, agntCfg.RequestPayload,
agntCfg.ReplyPayload, agntCfg.RequestProcessors))
diff --git a/sessions/sessions.go b/sessions/sessions.go
index ec64590be..c10c277c4 100644
--- a/sessions/sessions.go
+++ b/sessions/sessions.go
@@ -46,7 +46,7 @@ var (
func NewSessionS(cgrCfg *config.CGRConfig,
dm *engine.DataManager,
connMgr *engine.ConnManager) *SessionS {
- cgrCfg.SessionSCfg().SessionIndexes[utils.OriginID] = true // Make sure we have indexing for OriginID since it is a requirement on prefix searching
+ cgrCfg.SessionSCfg().SessionIndexes.Add(utils.OriginID) // Make sure we have indexing for OriginID since it is a requirement on prefix searching
return &SessionS{
cgrCfg: cgrCfg,
@@ -55,10 +55,10 @@ func NewSessionS(cgrCfg *config.CGRConfig,
biJClnts: make(map[rpcclient.ClientConnector]string),
biJIDs: make(map[string]*biJClient),
aSessions: make(map[string]*Session),
- aSessionsIdx: make(map[string]map[string]map[string]utils.StringMap),
+ aSessionsIdx: make(map[string]map[string]map[string]utils.StringSet),
aSessionsRIdx: make(map[string][]*riFieldNameVal),
pSessions: make(map[string]*Session),
- pSessionsIdx: make(map[string]map[string]map[string]utils.StringMap),
+ pSessionsIdx: make(map[string]map[string]map[string]utils.StringSet),
pSessionsRIdx: make(map[string][]*riFieldNameVal),
}
}
@@ -83,14 +83,14 @@ type SessionS struct {
aSessions map[string]*Session // group sessions per sessionId
aSIMux sync.RWMutex // protects aSessionsIdx
- aSessionsIdx map[string]map[string]map[string]utils.StringMap // map[fieldName]map[fieldValue][cgrID]utils.StringMap[runID]sID
+ aSessionsIdx map[string]map[string]map[string]utils.StringSet // map[fieldName]map[fieldValue][cgrID]utils.StringSet[runID]sID
aSessionsRIdx map[string][]*riFieldNameVal // reverse indexes for active sessions, used on remove
pSsMux sync.RWMutex // protects pSessions
pSessions map[string]*Session // group passive sessions based on cgrID
pSIMux sync.RWMutex // protects pSessionsIdx
- pSessionsIdx map[string]map[string]map[string]utils.StringMap // map[fieldName]map[fieldValue][cgrID]utils.StringMap[runID]sID
+ pSessionsIdx map[string]map[string]map[string]utils.StringSet // map[fieldName]map[fieldValue][cgrID]utils.StringSet[runID]sID
pSessionsRIdx map[string][]*riFieldNameVal // reverse indexes for passive sessions, used on remove
}
@@ -857,15 +857,15 @@ func (sS *SessionS) indexSession(s *Session, pSessions bool) {
fieldVal = utils.MetaEmpty
}
if _, hasFieldName := ssIndx[fieldName]; !hasFieldName { // Init it here
- ssIndx[fieldName] = make(map[string]map[string]utils.StringMap)
+ ssIndx[fieldName] = make(map[string]map[string]utils.StringSet)
}
if _, hasFieldVal := ssIndx[fieldName][fieldVal]; !hasFieldVal {
- ssIndx[fieldName][fieldVal] = make(map[string]utils.StringMap)
+ ssIndx[fieldName][fieldVal] = make(map[string]utils.StringSet)
}
if _, hasCGRID := ssIndx[fieldName][fieldVal][s.CGRID]; !hasCGRID {
- ssIndx[fieldName][fieldVal][s.CGRID] = make(utils.StringMap)
+ ssIndx[fieldName][fieldVal][s.CGRID] = make(utils.StringSet)
}
- ssIndx[fieldName][fieldVal][s.CGRID][sr.CD.RunID] = true
+ ssIndx[fieldName][fieldVal][s.CGRID].Add(sr.CD.RunID)
// reverse index
if _, hasIt := ssRIdx[s.CGRID]; !hasIt {
@@ -925,7 +925,7 @@ func (sS *SessionS) getIndexedFilters(tenant string, fltrs []string) (
for _, fltr := range f.Rules {
fldName := strings.TrimPrefix(fltr.Element, utils.DynamicDataPrefix+utils.MetaReq+utils.NestingSep) // remove ~req. prefix
if fltr.Type != utils.MetaString ||
- !sS.cgrCfg.SessionSCfg().SessionIndexes.HasKey(fldName) {
+ !sS.cgrCfg.SessionSCfg().SessionIndexes.Has(fldName) {
unindexedFltr = append(unindexedFltr, fltr)
continue
}
@@ -937,7 +937,7 @@ func (sS *SessionS) getIndexedFilters(tenant string, fltrs []string) (
// getSessionIDsMatchingIndexes returns map[matchedFieldName]possibleMatchedFieldVal so we optimize further to avoid checking them
func (sS *SessionS) getSessionIDsMatchingIndexes(fltrs map[string][]string,
- pSessions bool) ([]string, map[string]utils.StringMap) {
+ pSessions bool) ([]string, map[string]utils.StringSet) {
idxMux := &sS.aSIMux
ssIndx := sS.aSessionsIdx
if pSessions {
@@ -946,10 +946,10 @@ func (sS *SessionS) getSessionIDsMatchingIndexes(fltrs map[string][]string,
}
idxMux.RLock()
defer idxMux.RUnlock()
- matchingSessions := make(map[string]utils.StringMap)
+ matchingSessions := make(map[string]utils.StringSet)
checkNr := 0
- getMatchingIndexes := func(fltrName string, values []string) (matchingSessionsbyValue map[string]utils.StringMap) {
- matchingSessionsbyValue = make(map[string]utils.StringMap)
+ getMatchingIndexes := func(fltrName string, values []string) (matchingSessionsbyValue map[string]utils.StringSet) {
+ matchingSessionsbyValue = make(map[string]utils.StringSet)
// fltrName = strings.TrimPrefix(fltrName, utils.DynamicDataPrefix+utils.MetaReq+utils.NestingSep) //
if _, hasFldName := ssIndx[fltrName]; !hasFldName {
return
@@ -960,10 +960,10 @@ func (sS *SessionS) getSessionIDsMatchingIndexes(fltrs map[string][]string,
}
for cgrID, runIDs := range ssIndx[fltrName][fltrVal] {
if _, hasCGRID := matchingSessionsbyValue[cgrID]; !hasCGRID {
- matchingSessionsbyValue[cgrID] = utils.NewStringMap()
+ matchingSessionsbyValue[cgrID] = utils.StringSet{}
}
for runID := range runIDs {
- matchingSessionsbyValue[cgrID][runID] = true
+ matchingSessionsbyValue[cgrID].Add(runID)
}
}
}
@@ -983,14 +983,14 @@ func (sS *SessionS) getSessionIDsMatchingIndexes(fltrs map[string][]string,
continue
} else {
for runID := range runIDs {
- if !matchedRunIDs.HasKey(runID) {
+ if !matchedRunIDs.Has(runID) {
delete(matchingSessions[cgrID], runID)
}
}
}
}
if len(matchingSessions) == 0 {
- return make([]string, 0), make(map[string]utils.StringMap)
+ return make([]string, 0), make(map[string]utils.StringSet)
}
}
cgrIDs := []string{}
@@ -1044,7 +1044,7 @@ func (sS *SessionS) filterSessions(sf *utils.SessionFilter, psv bool) (aSs []*Ex
s.RLock()
runIDs := matchingSRuns[s.CGRID]
for _, sr := range s.SRuns {
- if len(cgrIDs) != 0 && !runIDs.HasKey(sr.CD.RunID) {
+ if len(cgrIDs) != 0 && !runIDs.Has(sr.CD.RunID) {
continue
}
if pass(unindx, sr.Event) {
@@ -1099,7 +1099,7 @@ func (sS *SessionS) filterSessionsCount(sf *utils.SessionFilter, psv bool) (coun
s.RLock()
runIDs := matchingSRuns[s.CGRID]
for _, sr := range s.SRuns {
- if len(cgrIDs) != 0 && !runIDs.HasKey(sr.CD.RunID) {
+ if len(cgrIDs) != 0 && !runIDs.Has(sr.CD.RunID) {
continue
}
if pass(unindx, sr.Event) {
diff --git a/sessions/sessions_test.go b/sessions/sessions_test.go
index ac9291ef9..67b6c340b 100644
--- a/sessions/sessions_test.go
+++ b/sessions/sessions_test.go
@@ -89,11 +89,11 @@ func TestIsIndexed(t *testing.T) {
func TestSessionSIndexAndUnindexSessions(t *testing.T) {
sSCfg, _ := config.NewDefaultCGRConfig()
- sSCfg.SessionSCfg().SessionIndexes = utils.StringMap{
- "Tenant": true,
- "Account": true,
- "Extra3": true,
- "Extra4": true,
+ sSCfg.SessionSCfg().SessionIndexes = utils.StringSet{
+ "Tenant": {},
+ "Account": {},
+ "Extra3": {},
+ "Extra4": {},
}
sS := NewSessionS(sSCfg, nil, nil)
sEv := engine.NewMapEvent(map[string]interface{}{
@@ -133,30 +133,30 @@ func TestSessionSIndexAndUnindexSessions(t *testing.T) {
}
cgrID := GetSetCGRID(sEv)
sS.indexSession(session, false)
- eIndexes := map[string]map[string]map[string]utils.StringMap{
+ eIndexes := map[string]map[string]map[string]utils.StringSet{
"OriginID": {
- "12345": map[string]utils.StringMap{
- cgrID: {utils.MetaDefault: true},
+ "12345": map[string]utils.StringSet{
+ cgrID: {utils.MetaDefault: {}},
},
},
"Tenant": {
- "cgrates.org": map[string]utils.StringMap{
- cgrID: {utils.MetaDefault: true},
+ "cgrates.org": map[string]utils.StringSet{
+ cgrID: {utils.MetaDefault: {}},
},
},
"Account": {
- "account1": map[string]utils.StringMap{
- cgrID: {utils.MetaDefault: true},
+ "account1": map[string]utils.StringSet{
+ cgrID: {utils.MetaDefault: {}},
},
},
"Extra3": {
- utils.MetaEmpty: map[string]utils.StringMap{
- cgrID: {utils.MetaDefault: true},
+ utils.MetaEmpty: map[string]utils.StringSet{
+ cgrID: {utils.MetaDefault: {}},
},
},
"Extra4": {
- utils.NOT_AVAILABLE: map[string]utils.StringMap{
- cgrID: {utils.MetaDefault: true},
+ utils.NOT_AVAILABLE: map[string]utils.StringSet{
+ cgrID: {utils.MetaDefault: {}},
},
},
}
@@ -222,52 +222,52 @@ func TestSessionSIndexAndUnindexSessions(t *testing.T) {
},
}
sS.indexSession(session3, false)
- eIndexes = map[string]map[string]map[string]utils.StringMap{
+ eIndexes = map[string]map[string]map[string]utils.StringSet{
"OriginID": {
- "12345": map[string]utils.StringMap{
- cgrID: {utils.MetaDefault: true},
+ "12345": map[string]utils.StringSet{
+ cgrID: {utils.MetaDefault: {}},
},
- "12346": map[string]utils.StringMap{
- cgrID2: {utils.MetaDefault: true},
+ "12346": map[string]utils.StringSet{
+ cgrID2: {utils.MetaDefault: {}},
},
- "12347": map[string]utils.StringMap{
- cgrID3: {utils.MetaDefault: true},
+ "12347": map[string]utils.StringSet{
+ cgrID3: {utils.MetaDefault: {}},
},
},
"Tenant": {
- "cgrates.org": map[string]utils.StringMap{
- cgrID: {utils.MetaDefault: true},
- cgrID3: {utils.MetaDefault: true},
+ "cgrates.org": map[string]utils.StringSet{
+ cgrID: {utils.MetaDefault: {}},
+ cgrID3: {utils.MetaDefault: {}},
},
- "itsyscom.com": map[string]utils.StringMap{
- cgrID2: {utils.MetaDefault: true},
+ "itsyscom.com": map[string]utils.StringSet{
+ cgrID2: {utils.MetaDefault: {}},
},
},
"Account": {
- "account1": map[string]utils.StringMap{
- cgrID: {utils.MetaDefault: true},
+ "account1": map[string]utils.StringSet{
+ cgrID: {utils.MetaDefault: {}},
},
- "account2": map[string]utils.StringMap{
- cgrID2: {utils.MetaDefault: true},
- cgrID3: {utils.MetaDefault: true},
+ "account2": map[string]utils.StringSet{
+ cgrID2: {utils.MetaDefault: {}},
+ cgrID3: {utils.MetaDefault: {}},
},
},
"Extra3": {
- utils.MetaEmpty: map[string]utils.StringMap{
- cgrID: {utils.MetaDefault: true},
- cgrID2: {utils.MetaDefault: true},
+ utils.MetaEmpty: map[string]utils.StringSet{
+ cgrID: {utils.MetaDefault: {}},
+ cgrID2: {utils.MetaDefault: {}},
},
- utils.NOT_AVAILABLE: map[string]utils.StringMap{
- cgrID3: {utils.MetaDefault: true},
+ utils.NOT_AVAILABLE: map[string]utils.StringSet{
+ cgrID3: {utils.MetaDefault: {}},
},
},
"Extra4": {
- utils.NOT_AVAILABLE: map[string]utils.StringMap{
- cgrID: {utils.MetaDefault: true},
- cgrID3: {utils.MetaDefault: true},
+ utils.NOT_AVAILABLE: map[string]utils.StringSet{
+ cgrID: {utils.MetaDefault: {}},
+ cgrID3: {utils.MetaDefault: {}},
},
- "info2": map[string]utils.StringMap{
- cgrID2: {utils.MetaDefault: true},
+ "info2": map[string]utils.StringSet{
+ cgrID2: {utils.MetaDefault: {}},
},
},
}
@@ -304,43 +304,43 @@ func TestSessionSIndexAndUnindexSessions(t *testing.T) {
}
// Unidex first session
sS.unindexSession(cgrID, false)
- eIndexes = map[string]map[string]map[string]utils.StringMap{
+ eIndexes = map[string]map[string]map[string]utils.StringSet{
"OriginID": {
- "12346": map[string]utils.StringMap{
- cgrID2: {utils.MetaDefault: true},
+ "12346": map[string]utils.StringSet{
+ cgrID2: {utils.MetaDefault: {}},
},
- "12347": map[string]utils.StringMap{
- cgrID3: {utils.MetaDefault: true},
+ "12347": map[string]utils.StringSet{
+ cgrID3: {utils.MetaDefault: {}},
},
},
"Tenant": {
- "cgrates.org": map[string]utils.StringMap{
- cgrID3: {utils.MetaDefault: true},
+ "cgrates.org": map[string]utils.StringSet{
+ cgrID3: {utils.MetaDefault: {}},
},
- "itsyscom.com": map[string]utils.StringMap{
- cgrID2: {utils.MetaDefault: true},
+ "itsyscom.com": map[string]utils.StringSet{
+ cgrID2: {utils.MetaDefault: {}},
},
},
"Account": {
- "account2": map[string]utils.StringMap{
- cgrID2: {utils.MetaDefault: true},
- cgrID3: {utils.MetaDefault: true},
+ "account2": map[string]utils.StringSet{
+ cgrID2: {utils.MetaDefault: {}},
+ cgrID3: {utils.MetaDefault: {}},
},
},
"Extra3": {
- utils.MetaEmpty: map[string]utils.StringMap{
- cgrID2: {utils.MetaDefault: true},
+ utils.MetaEmpty: map[string]utils.StringSet{
+ cgrID2: {utils.MetaDefault: {}},
},
- utils.NOT_AVAILABLE: map[string]utils.StringMap{
- cgrID3: {utils.MetaDefault: true},
+ utils.NOT_AVAILABLE: map[string]utils.StringSet{
+ cgrID3: {utils.MetaDefault: {}},
},
},
"Extra4": {
- "info2": map[string]utils.StringMap{
- cgrID2: {utils.MetaDefault: true},
+ "info2": map[string]utils.StringSet{
+ cgrID2: {utils.MetaDefault: {}},
},
- utils.NOT_AVAILABLE: map[string]utils.StringMap{
- cgrID3: {utils.MetaDefault: true},
+ utils.NOT_AVAILABLE: map[string]utils.StringSet{
+ cgrID3: {utils.MetaDefault: {}},
},
},
}
@@ -368,30 +368,30 @@ func TestSessionSIndexAndUnindexSessions(t *testing.T) {
t.Errorf("Expecting: %+v, received: %+v", eRIdxes, sS.aSessionsRIdx)
}
sS.unindexSession(cgrID3, false)
- eIndexes = map[string]map[string]map[string]utils.StringMap{
+ eIndexes = map[string]map[string]map[string]utils.StringSet{
"OriginID": {
- "12346": map[string]utils.StringMap{
- cgrID2: {utils.MetaDefault: true},
+ "12346": map[string]utils.StringSet{
+ cgrID2: {utils.MetaDefault: {}},
},
},
"Tenant": {
- "itsyscom.com": map[string]utils.StringMap{
- cgrID2: {utils.MetaDefault: true},
+ "itsyscom.com": map[string]utils.StringSet{
+ cgrID2: {utils.MetaDefault: {}},
},
},
"Account": {
- "account2": map[string]utils.StringMap{
- cgrID2: {utils.MetaDefault: true},
+ "account2": map[string]utils.StringSet{
+ cgrID2: {utils.MetaDefault: {}},
},
},
"Extra3": {
- utils.MetaEmpty: map[string]utils.StringMap{
- cgrID2: {utils.MetaDefault: true},
+ utils.MetaEmpty: map[string]utils.StringSet{
+ cgrID2: {utils.MetaDefault: {}},
},
},
"Extra4": {
- "info2": map[string]utils.StringMap{
- cgrID2: {utils.MetaDefault: true},
+ "info2": map[string]utils.StringSet{
+ cgrID2: {utils.MetaDefault: {}},
},
},
}
@@ -455,10 +455,10 @@ func TestSessionSRegisterAndUnregisterASessions(t *testing.T) {
}
//verify if the index was created according to session
- eIndexes := map[string]map[string]map[string]utils.StringMap{
+ eIndexes := map[string]map[string]map[string]utils.StringSet{
"OriginID": {
- "111": map[string]utils.StringMap{
- "session1": {utils.MetaDefault: true},
+ "111": map[string]utils.StringSet{
+ "session1": {utils.MetaDefault: {}},
},
},
}
@@ -512,13 +512,13 @@ func TestSessionSRegisterAndUnregisterASessions(t *testing.T) {
}
// verify if the index was created according to session
- eIndexes = map[string]map[string]map[string]utils.StringMap{
+ eIndexes = map[string]map[string]map[string]utils.StringSet{
"OriginID": {
- "111": map[string]utils.StringMap{
- "session1": {utils.MetaDefault: true},
+ "111": map[string]utils.StringSet{
+ "session1": {utils.MetaDefault: {}},
},
- "222": map[string]utils.StringMap{
- "session2": {utils.MetaDefault: true},
+ "222": map[string]utils.StringSet{
+ "session2": {utils.MetaDefault: {}},
},
},
}
@@ -588,10 +588,10 @@ func TestSessionSRegisterAndUnregisterASessions(t *testing.T) {
t.Error("Expectinv: false, received: true")
}
- eIndexes = map[string]map[string]map[string]utils.StringMap{
+ eIndexes = map[string]map[string]map[string]utils.StringSet{
"OriginID": {
- "222": map[string]utils.StringMap{
- "session2": {utils.MetaDefault: true},
+ "222": map[string]utils.StringSet{
+ "session2": {utils.MetaDefault: {}},
},
},
}
@@ -615,7 +615,7 @@ func TestSessionSRegisterAndUnregisterASessions(t *testing.T) {
sS.unregisterSession("session2", false)
- eIndexes = map[string]map[string]map[string]utils.StringMap{}
+ eIndexes = map[string]map[string]map[string]utils.StringSet{}
if !reflect.DeepEqual(eIndexes, sS.aSessionsIdx) {
t.Errorf("Expecting: %s, received: %s",
utils.ToJSON(eIndexes), utils.ToJSON(sS.aSessionsIdx))
@@ -673,10 +673,10 @@ func TestSessionSRegisterAndUnregisterPSessions(t *testing.T) {
}
//verify if the index was created according to session
- eIndexes := map[string]map[string]map[string]utils.StringMap{
+ eIndexes := map[string]map[string]map[string]utils.StringSet{
"OriginID": {
- "111": map[string]utils.StringMap{
- "session1": {utils.MetaDefault: true},
+ "111": map[string]utils.StringSet{
+ "session1": {utils.MetaDefault: {}},
},
},
}
@@ -733,13 +733,13 @@ func TestSessionSRegisterAndUnregisterPSessions(t *testing.T) {
}
//verify if the index was created according to session
- eIndexes = map[string]map[string]map[string]utils.StringMap{
+ eIndexes = map[string]map[string]map[string]utils.StringSet{
"OriginID": {
- "111": map[string]utils.StringMap{
- "session1": {utils.MetaDefault: true},
+ "111": map[string]utils.StringSet{
+ "session1": {utils.MetaDefault: {}},
},
- "222": map[string]utils.StringMap{
- "session2": {utils.MetaDefault: true},
+ "222": map[string]utils.StringSet{
+ "session2": {utils.MetaDefault: {}},
},
},
}
@@ -802,10 +802,10 @@ func TestSessionSRegisterAndUnregisterPSessions(t *testing.T) {
//unregister the session and check if the index was removed
sS.unregisterSession("session1", true)
- eIndexes = map[string]map[string]map[string]utils.StringMap{
+ eIndexes = map[string]map[string]map[string]utils.StringSet{
"OriginID": {
- "222": map[string]utils.StringMap{
- "session2": {utils.MetaDefault: true},
+ "222": map[string]utils.StringSet{
+ "session2": {utils.MetaDefault: {}},
},
},
}
@@ -829,7 +829,7 @@ func TestSessionSRegisterAndUnregisterPSessions(t *testing.T) {
sS.unregisterSession("session2", true)
- eIndexes = map[string]map[string]map[string]utils.StringMap{}
+ eIndexes = map[string]map[string]map[string]utils.StringSet{}
if !reflect.DeepEqual(eIndexes, sS.pSessionsIdx) {
t.Errorf("Expecting: %s, received: %s",
utils.ToJSON(eIndexes), utils.ToJSON(sS.pSessionsIdx))
@@ -1632,8 +1632,8 @@ func TestSessionSGetIndexedFilters(t *testing.T) {
} else if !reflect.DeepEqual(expUindx, rplyUnindx) {
t.Errorf("Expected %s , received: %s", utils.ToJSON(expUindx), utils.ToJSON(rplyUnindx))
}
- sSCfg.SessionSCfg().SessionIndexes = utils.StringMap{
- "ToR": true,
+ sSCfg.SessionSCfg().SessionIndexes = utils.StringSet{
+ "ToR": {},
}
sS = NewSessionS(sSCfg, engine.NewDataManager(mpStr, config.CgrConfig().CacheCfg(), nil), nil)
expIndx = map[string][]string{(utils.ToR): {utils.VOICE}}
@@ -1666,8 +1666,8 @@ func TestSessionSGetIndexedFilters(t *testing.T) {
func TestSessionSgetSessionIDsMatchingIndexes(t *testing.T) {
sSCfg, _ := config.NewDefaultCGRConfig()
- sSCfg.SessionSCfg().SessionIndexes = utils.StringMap{
- "ToR": true,
+ sSCfg.SessionSCfg().SessionIndexes = utils.StringSet{
+ "ToR": {},
}
sS := NewSessionS(sSCfg, nil, nil)
sEv := engine.NewMapEvent(map[string]interface{}{
@@ -1709,17 +1709,17 @@ func TestSessionSgetSessionIDsMatchingIndexes(t *testing.T) {
sS.indexSession(session, false)
indx := map[string][]string{"ToR": {utils.VOICE, utils.DATA}}
expCGRIDs := []string{cgrID}
- expmatchingSRuns := map[string]utils.StringMap{cgrID: {
- "RunID": true,
+ expmatchingSRuns := map[string]utils.StringSet{cgrID: {
+ "RunID": {},
}}
if cgrIDs, matchingSRuns := sS.getSessionIDsMatchingIndexes(indx, false); !reflect.DeepEqual(expCGRIDs, cgrIDs) {
t.Errorf("Expected %s , received: %s", utils.ToJSON(expCGRIDs), utils.ToJSON(cgrIDs))
} else if !reflect.DeepEqual(expmatchingSRuns, matchingSRuns) {
t.Errorf("Expected %s , received: %s", utils.ToJSON(expmatchingSRuns), utils.ToJSON(matchingSRuns))
}
- sSCfg.SessionSCfg().SessionIndexes = utils.StringMap{
- "ToR": true,
- "Extra3": true,
+ sSCfg.SessionSCfg().SessionIndexes = utils.StringSet{
+ "ToR": {},
+ "Extra3": {},
}
sS = NewSessionS(sSCfg, nil, nil)
sS.indexSession(session, false)
@@ -1728,7 +1728,7 @@ func TestSessionSgetSessionIDsMatchingIndexes(t *testing.T) {
"Extra2": {"55"},
}
expCGRIDs = []string{}
- expmatchingSRuns = map[string]utils.StringMap{}
+ expmatchingSRuns = map[string]utils.StringSet{}
if cgrIDs, matchingSRuns := sS.getSessionIDsMatchingIndexes(indx, false); !reflect.DeepEqual(expCGRIDs, cgrIDs) {
t.Errorf("Expected %s , received: %s", utils.ToJSON(expCGRIDs), utils.ToJSON(cgrIDs))
} else if !reflect.DeepEqual(expmatchingSRuns, matchingSRuns) {
@@ -1751,9 +1751,9 @@ func TestSessionSgetSessionIDsMatchingIndexes(t *testing.T) {
},
},
}
- sSCfg.SessionSCfg().SessionIndexes = utils.StringMap{
- "ToR": true,
- "Extra2": true,
+ sSCfg.SessionSCfg().SessionIndexes = utils.StringSet{
+ "ToR": {},
+ "Extra2": {},
}
sS = NewSessionS(sSCfg, nil, nil)
sS.indexSession(session, true)
@@ -1763,8 +1763,8 @@ func TestSessionSgetSessionIDsMatchingIndexes(t *testing.T) {
}
expCGRIDs = []string{cgrID}
- expmatchingSRuns = map[string]utils.StringMap{cgrID: {
- "RunID": true,
+ expmatchingSRuns = map[string]utils.StringSet{cgrID: {
+ "RunID": {},
}}
if cgrIDs, matchingSRuns := sS.getSessionIDsMatchingIndexes(indx, true); !reflect.DeepEqual(expCGRIDs, cgrIDs) {
t.Errorf("Expected %s , received: %s", utils.ToJSON(expCGRIDs), utils.ToJSON(cgrIDs))
@@ -1786,10 +1786,10 @@ func TestNewSessionS(t *testing.T) {
biJClnts: make(map[rpcclient.ClientConnector]string),
biJIDs: make(map[string]*biJClient),
aSessions: make(map[string]*Session),
- aSessionsIdx: make(map[string]map[string]map[string]utils.StringMap),
+ aSessionsIdx: make(map[string]map[string]map[string]utils.StringSet),
aSessionsRIdx: make(map[string][]*riFieldNameVal),
pSessions: make(map[string]*Session),
- pSessionsIdx: make(map[string]map[string]map[string]utils.StringMap),
+ pSessionsIdx: make(map[string]map[string]map[string]utils.StringSet),
pSessionsRIdx: make(map[string][]*riFieldNameVal),
}
sS := NewSessionS(cgrCGF, nil, nil)
@@ -1989,8 +1989,8 @@ func TestSessionSgetSession(t *testing.T) {
func TestSessionSfilterSessions(t *testing.T) {
sSCfg, _ := config.NewDefaultCGRConfig()
- sSCfg.SessionSCfg().SessionIndexes = utils.StringMap{
- "ToR": true,
+ sSCfg.SessionSCfg().SessionIndexes = utils.StringSet{
+ "ToR": {},
}
sS := NewSessionS(sSCfg, nil, nil)
sEv := engine.NewMapEvent(map[string]interface{}{
@@ -2119,9 +2119,9 @@ func TestSessionSfilterSessions(t *testing.T) {
if sess := sS.filterSessions(fltrs, false); !reflect.DeepEqual(expSess, sess) {
t.Errorf("Expected %s , received: %s", utils.ToJSON(expSess), utils.ToJSON(sess))
}
- sSCfg.SessionSCfg().SessionIndexes = utils.StringMap{
- "ToR": true,
- "Extra3": true,
+ sSCfg.SessionSCfg().SessionIndexes = utils.StringSet{
+ "ToR": {},
+ "Extra3": {},
}
sS = NewSessionS(sSCfg, nil, nil)
sS.registerSession(session, false)
@@ -2165,8 +2165,8 @@ func TestSessionSfilterSessions(t *testing.T) {
func TestSessionSfilterSessionsCount(t *testing.T) {
sSCfg, _ := config.NewDefaultCGRConfig()
- sSCfg.SessionSCfg().SessionIndexes = utils.StringMap{
- "ToR": true,
+ sSCfg.SessionSCfg().SessionIndexes = utils.StringSet{
+ "ToR": {},
}
sS := NewSessionS(sSCfg, nil, nil)
sEv := engine.NewMapEvent(map[string]interface{}{
@@ -2231,9 +2231,9 @@ func TestSessionSfilterSessionsCount(t *testing.T) {
if noSess := sS.filterSessionsCount(fltrs, false); noSess != 1 {
t.Errorf("Expected %v , received: %s", 1, utils.ToJSON(noSess))
}
- sSCfg.SessionSCfg().SessionIndexes = utils.StringMap{
- "ToR": true,
- "Extra3": true,
+ sSCfg.SessionSCfg().SessionIndexes = utils.StringSet{
+ "ToR": {},
+ "Extra3": {},
}
sS = NewSessionS(sSCfg, nil, nil)
sS.registerSession(session, false)