From 9f75ab918c0a6a46688f1654cd2c182345098858 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Wed, 17 Feb 2021 16:06:12 +0200 Subject: [PATCH] Updated biRPC support in connmanager --- agents/astagent.go | 55 ++++++++++++-- agents/diamagent.go | 44 +++++++++++ agents/diamagent_test.go | 20 +++-- agents/fsagent.go | 44 +++++++++++ agents/kamagent.go | 44 +++++++++++ apier/v1/sessions_thresholds_it_test.go | 4 +- apier/v1/tpdispatchers_it_test.go | 2 +- cmd/cgr-engine/cgr-engine.go | 2 + cmd/cgr-loader/cgr-loader_it_test.go | 7 ++ config/config.go | 7 ++ config/config_defaults.go | 8 +- config/config_it_test.go | 3 +- config/config_json_test.go | 9 ++- config/config_test.go | 74 ++++++++++++++----- config/configsanity.go | 25 ++++--- config/diametercfg.go | 8 +- config/diametercfg_test.go | 7 +- config/httpagntcfg.go | 11 ++- config/httpagntcfg_test.go | 5 +- config/kamagentcfg.go | 8 +- config/kamagentcfg_test.go | 7 +- config/radiuscfg_test.go | 5 +- config/rjreader_test.go | 22 +++--- config/rpcconn_test.go | 49 ++++++++++++ config/sessionscfg.go | 15 +++- config/sessionscfg_test.go | 15 ++-- data/conf/samples/diam_tutmysql/cgrates.json | 2 +- .../diamsctpagent_internal/cgrates.json | 2 +- .../samples/diamsctpagent_mongo/cgrates.json | 2 +- .../samples/diamsctpagent_mysql/cgrates.json | 2 +- .../cgrates/etc/cgrates/cgrates.json | 2 +- .../cgrates/etc/cgrates/cgrates.json | 2 +- .../kamevapi/cgrates/etc/cgrates/cgrates.json | 2 +- .../cgrates/etc/cgrates/cgrates.json | 2 +- .../cgrates/etc/cgrates/cgrates.json | 2 +- .../kamevapi/cgrates/etc/cgrates/cgrates.json | 2 +- engine/connmanager.go | 46 +++++++----- go.mod | 6 +- go.sum | 8 +- sessions/libsessions.go | 9 ++- sessions/sessions.go | 50 +++++++++++-- sessions/sessions_test.go | 8 +- sessions/sessionscover_it_test.go | 18 ++--- utils/coreutils.go | 39 ++++++++++ 44 files changed, 552 insertions(+), 152 deletions(-) diff --git a/agents/astagent.go b/agents/astagent.go index 8131b0155..246ebfee9 100644 --- a/agents/astagent.go +++ b/agents/astagent.go @@ -32,6 +32,7 @@ import ( "github.com/cgrates/cgrates/engine" "github.com/cgrates/cgrates/sessions" "github.com/cgrates/cgrates/utils" + "github.com/cgrates/rpcclient" ) // constants used by AsteriskAgent @@ -321,9 +322,9 @@ func (sma *AsteriskAgent) handleChannelDestroyed(ev *SMAsteriskEvent) { } -// ServiceShutdown is called to shutdown the service -func (sma *AsteriskAgent) ServiceShutdown() error { - return nil +// Call implements rpcclient.ClientConnector interface +func (sma *AsteriskAgent) Call(serviceMethod string, args interface{}, reply interface{}) error { + return utils.RPCCall(sma, serviceMethod, args, reply) } // V1DisconnectSession is internal method to disconnect session in asterisk @@ -334,11 +335,6 @@ func (sma *AsteriskAgent) V1DisconnectSession(args utils.AttrDisconnectSession, return nil } -// Call implements rpcclient.ClientConnector interface -func (sma *AsteriskAgent) Call(serviceMethod string, args interface{}, reply interface{}) error { - return utils.RPCCall(sma, serviceMethod, args, reply) -} - // V1GetActiveSessionIDs is internal method to get all active sessions in asterisk func (sma *AsteriskAgent) V1GetActiveSessionIDs(ignParam string, sessionIDs *[]*sessions.SessionID) error { @@ -378,3 +374,46 @@ func (*AsteriskAgent) V1DisconnectPeer(args *utils.DPRArgs, reply *string) (err func (sma *AsteriskAgent) V1WarnDisconnect(args map[string]interface{}, reply *string) (err error) { return utils.ErrNotImplemented } + +// CallBiRPC is part of utils.BiRPCServer interface to help internal connections do calls over rpcclient.ClientConnector interface +func (sma *AsteriskAgent) CallBiRPC(clnt rpcclient.ClientConnector, serviceMethod string, args interface{}, reply interface{}) error { + return utils.BiRPCCall(sma, clnt, serviceMethod, args, reply) +} + +// BiRPCv1DisconnectSession is internal method to disconnect session in asterisk +func (sma *AsteriskAgent) BiRPCv1DisconnectSession(clnt rpcclient.ClientConnector, args utils.AttrDisconnectSession, reply *string) error { + return sma.V1DisconnectSession(args, reply) +} + +// BiRPCv1GetActiveSessionIDs is internal method to get all active sessions in asterisk +func (sma *AsteriskAgent) BiRPCv1GetActiveSessionIDs(clnt rpcclient.ClientConnector, ignParam string, + sessionIDs *[]*sessions.SessionID) error { + return sma.V1GetActiveSessionIDs(ignParam, sessionIDs) + +} + +// BiRPCv1ReAuthorize is used to implement the sessions.BiRPClient interface +func (sma *AsteriskAgent) BiRPCv1ReAuthorize(clnt rpcclient.ClientConnector, originID string, reply *string) (err error) { + return sma.V1ReAuthorize(originID, reply) +} + +// BiRPCv1DisconnectPeer is used to implement the sessions.BiRPClient interface +func (sma *AsteriskAgent) BiRPCv1DisconnectPeer(clnt rpcclient.ClientConnector, args *utils.DPRArgs, reply *string) (err error) { + return sma.V1DisconnectPeer(args, reply) +} + +// BiRPCv1WarnDisconnect is used to implement the sessions.BiRPClient interface +func (sma *AsteriskAgent) BiRPCv1WarnDisconnect(clnt rpcclient.ClientConnector, args map[string]interface{}, reply *string) (err error) { + return sma.V1WarnDisconnect(args, reply) +} + +// Handlers is used to implement the rpcclient.BiRPCConector interface +func (sma *AsteriskAgent) Handlers() map[string]interface{} { + return map[string]interface{}{ + utils.SessionSv1DisconnectSession: sma.BiRPCv1DisconnectSession, + utils.SessionSv1GetActiveSessionIDs: sma.BiRPCv1GetActiveSessionIDs, + utils.SessionSv1ReAuthorize: sma.BiRPCv1ReAuthorize, + utils.SessionSv1DisconnectPeer: sma.BiRPCv1DisconnectPeer, + utils.SessionSv1WarnDisconnect: sma.BiRPCv1WarnDisconnect, + } +} diff --git a/agents/diamagent.go b/agents/diamagent.go index fecfcead4..9bdd8d1ac 100644 --- a/agents/diamagent.go +++ b/agents/diamagent.go @@ -30,6 +30,7 @@ import ( "github.com/cgrates/cgrates/engine" "github.com/cgrates/cgrates/sessions" "github.com/cgrates/cgrates/utils" + "github.com/cgrates/rpcclient" "github.com/fiorix/go-diameter/v4/diam" "github.com/fiorix/go-diameter/v4/diam/avp" "github.com/fiorix/go-diameter/v4/diam/datatype" @@ -743,3 +744,46 @@ func (da *DiameterAgent) V1DisconnectPeer(args *utils.DPRArgs, reply *string) (e func (*DiameterAgent) V1WarnDisconnect(args map[string]interface{}, reply *string) (err error) { return utils.ErrNotImplemented } + +// CallBiRPC is part of utils.BiRPCServer interface to help internal connections do calls over rpcclient.ClientConnector interface +func (da *DiameterAgent) CallBiRPC(clnt rpcclient.ClientConnector, serviceMethod string, args interface{}, reply interface{}) error { + return utils.BiRPCCall(da, clnt, serviceMethod, args, reply) +} + +// BiRPCv1DisconnectSession is internal method to disconnect session in asterisk +func (da *DiameterAgent) BiRPCv1DisconnectSession(clnt rpcclient.ClientConnector, args utils.AttrDisconnectSession, reply *string) error { + return da.V1DisconnectSession(args, reply) +} + +// BiRPCv1GetActiveSessionIDs is internal method to get all active sessions in asterisk +func (da *DiameterAgent) BiRPCv1GetActiveSessionIDs(clnt rpcclient.ClientConnector, ignParam string, + sessionIDs *[]*sessions.SessionID) error { + return da.V1GetActiveSessionIDs(ignParam, sessionIDs) + +} + +// BiRPCv1ReAuthorize is used to implement the sessions.BiRPClient interface +func (da *DiameterAgent) BiRPCv1ReAuthorize(clnt rpcclient.ClientConnector, originID string, reply *string) (err error) { + return da.V1ReAuthorize(originID, reply) +} + +// BiRPCv1DisconnectPeer is used to implement the sessions.BiRPClient interface +func (da *DiameterAgent) BiRPCv1DisconnectPeer(clnt rpcclient.ClientConnector, args *utils.DPRArgs, reply *string) (err error) { + return da.V1DisconnectPeer(args, reply) +} + +// BiRPCv1WarnDisconnect is used to implement the sessions.BiRPClient interface +func (da *DiameterAgent) BiRPCv1WarnDisconnect(clnt rpcclient.ClientConnector, args map[string]interface{}, reply *string) (err error) { + return da.V1WarnDisconnect(args, reply) +} + +// Handlers is used to implement the rpcclient.BiRPCConector interface +func (da *DiameterAgent) Handlers() map[string]interface{} { + return map[string]interface{}{ + utils.SessionSv1DisconnectSession: da.BiRPCv1DisconnectSession, + utils.SessionSv1GetActiveSessionIDs: da.BiRPCv1GetActiveSessionIDs, + utils.SessionSv1ReAuthorize: da.BiRPCv1ReAuthorize, + utils.SessionSv1DisconnectPeer: da.BiRPCv1DisconnectPeer, + utils.SessionSv1WarnDisconnect: da.BiRPCv1WarnDisconnect, + } +} diff --git a/agents/diamagent_test.go b/agents/diamagent_test.go index dfac2809b..539c73515 100644 --- a/agents/diamagent_test.go +++ b/agents/diamagent_test.go @@ -39,19 +39,22 @@ type testMockSessionConn struct { } func (s *testMockSessionConn) Call(method string, arg interface{}, rply interface{}) error { - if call, has := s.calls[method]; !has { - return rpcclient.ErrUnsupporteServiceMethod - } else { + if call, has := s.calls[method]; has { return call(arg, rply) } + return rpcclient.ErrUnsupporteServiceMethod } func (s *testMockSessionConn) CallBiRPC(_ rpcclient.ClientConnector, method string, arg interface{}, rply interface{}) error { - if call, has := s.calls[method]; !has { - return rpcclient.ErrUnsupporteServiceMethod - } else { - return call(arg, rply) + return s.Call(method, arg, rply) +} + +func (s *testMockSessionConn) Handlers() (b map[string]interface{}) { + b = make(map[string]interface{}) + for n, f := range s.calls { + b[n] = f } + return } func TestProcessRequest(t *testing.T) { @@ -446,7 +449,8 @@ func TestProcessRequest(t *testing.T) { internalSessionSChan := make(chan rpcclient.ClientConnector, 1) internalSessionSChan <- sS connMgr := engine.NewConnManager(config.CgrConfig(), map[string]chan rpcclient.ClientConnector{ - utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS): internalSessionSChan, + utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS): internalSessionSChan, + utils.ConcatenatedKey(rpcclient.BiRPCInternal, utils.MetaSessionS): internalSessionSChan, }) da := &DiameterAgent{ cgrCfg: config.CgrConfig(), diff --git a/agents/fsagent.go b/agents/fsagent.go index fbfea859d..cbc142527 100644 --- a/agents/fsagent.go +++ b/agents/fsagent.go @@ -29,6 +29,7 @@ import ( "github.com/cgrates/cgrates/sessions" "github.com/cgrates/cgrates/utils" "github.com/cgrates/fsock" + "github.com/cgrates/rpcclient" ) func NewFSsessions(fsAgentConfig *config.FsAgentCfg, @@ -479,3 +480,46 @@ func (fsa *FSsessions) V1WarnDisconnect(args map[string]interface{}, reply *stri *reply = utils.OK return } + +// CallBiRPC is part of utils.BiRPCServer interface to help internal connections do calls over rpcclient.ClientConnector interface +func (fsa *FSsessions) CallBiRPC(clnt rpcclient.ClientConnector, serviceMethod string, args interface{}, reply interface{}) error { + return utils.BiRPCCall(fsa, clnt, serviceMethod, args, reply) +} + +// BiRPCv1DisconnectSession is internal method to disconnect session in asterisk +func (fsa *FSsessions) BiRPCv1DisconnectSession(clnt rpcclient.ClientConnector, args utils.AttrDisconnectSession, reply *string) error { + return fsa.V1DisconnectSession(args, reply) +} + +// BiRPCv1GetActiveSessionIDs is internal method to get all active sessions in asterisk +func (fsa *FSsessions) BiRPCv1GetActiveSessionIDs(clnt rpcclient.ClientConnector, ignParam string, + sessionIDs *[]*sessions.SessionID) error { + return fsa.V1GetActiveSessionIDs(ignParam, sessionIDs) + +} + +// BiRPCv1ReAuthorize is used to implement the sessions.BiRPClient interface +func (fsa *FSsessions) BiRPCv1ReAuthorize(clnt rpcclient.ClientConnector, originID string, reply *string) (err error) { + return fsa.V1ReAuthorize(originID, reply) +} + +// BiRPCv1DisconnectPeer is used to implement the sessions.BiRPClient interface +func (fsa *FSsessions) BiRPCv1DisconnectPeer(clnt rpcclient.ClientConnector, args *utils.DPRArgs, reply *string) (err error) { + return fsa.V1DisconnectPeer(args, reply) +} + +// BiRPCv1WarnDisconnect is used to implement the sessions.BiRPClient interface +func (fsa *FSsessions) BiRPCv1WarnDisconnect(clnt rpcclient.ClientConnector, args map[string]interface{}, reply *string) (err error) { + return fsa.V1WarnDisconnect(args, reply) +} + +// Handlers is used to implement the rpcclient.BiRPCConector interface +func (fsa *FSsessions) Handlers() map[string]interface{} { + return map[string]interface{}{ + utils.SessionSv1DisconnectSession: fsa.BiRPCv1DisconnectSession, + utils.SessionSv1GetActiveSessionIDs: fsa.BiRPCv1GetActiveSessionIDs, + utils.SessionSv1ReAuthorize: fsa.BiRPCv1ReAuthorize, + utils.SessionSv1DisconnectPeer: fsa.BiRPCv1DisconnectPeer, + utils.SessionSv1WarnDisconnect: fsa.BiRPCv1WarnDisconnect, + } +} diff --git a/agents/kamagent.go b/agents/kamagent.go index a8e294271..31aa17e66 100644 --- a/agents/kamagent.go +++ b/agents/kamagent.go @@ -27,6 +27,7 @@ import ( "time" "github.com/cgrates/cgrates/engine" + "github.com/cgrates/rpcclient" "github.com/cgrates/cgrates/config" "github.com/cgrates/cgrates/sessions" @@ -443,3 +444,46 @@ func (*KamailioAgent) V1DisconnectPeer(args *utils.DPRArgs, reply *string) (err func (*KamailioAgent) V1WarnDisconnect(args map[string]interface{}, reply *string) (err error) { return utils.ErrNotImplemented } + +// CallBiRPC is part of utils.BiRPCServer interface to help internal connections do calls over rpcclient.ClientConnector interface +func (ka *KamailioAgent) CallBiRPC(clnt rpcclient.ClientConnector, serviceMethod string, args interface{}, reply interface{}) error { + return utils.BiRPCCall(ka, clnt, serviceMethod, args, reply) +} + +// BiRPCv1DisconnectSession is internal method to disconnect session in asterisk +func (ka *KamailioAgent) BiRPCv1DisconnectSession(clnt rpcclient.ClientConnector, args utils.AttrDisconnectSession, reply *string) error { + return ka.V1DisconnectSession(args, reply) +} + +// BiRPCv1GetActiveSessionIDs is internal method to get all active sessions in asterisk +func (ka *KamailioAgent) BiRPCv1GetActiveSessionIDs(clnt rpcclient.ClientConnector, ignParam string, + sessionIDs *[]*sessions.SessionID) error { + return ka.V1GetActiveSessionIDs(ignParam, sessionIDs) + +} + +// BiRPCv1ReAuthorize is used to implement the sessions.BiRPClient interface +func (ka *KamailioAgent) BiRPCv1ReAuthorize(clnt rpcclient.ClientConnector, originID string, reply *string) (err error) { + return ka.V1ReAuthorize(originID, reply) +} + +// BiRPCv1DisconnectPeer is used to implement the sessions.BiRPClient interface +func (ka *KamailioAgent) BiRPCv1DisconnectPeer(clnt rpcclient.ClientConnector, args *utils.DPRArgs, reply *string) (err error) { + return ka.V1DisconnectPeer(args, reply) +} + +// BiRPCv1WarnDisconnect is used to implement the sessions.BiRPClient interface +func (ka *KamailioAgent) BiRPCv1WarnDisconnect(clnt rpcclient.ClientConnector, args map[string]interface{}, reply *string) (err error) { + return ka.V1WarnDisconnect(args, reply) +} + +// Handlers is used to implement the rpcclient.BiRPCConector interface +func (ka *KamailioAgent) Handlers() map[string]interface{} { + return map[string]interface{}{ + utils.SessionSv1DisconnectSession: ka.BiRPCv1DisconnectSession, + utils.SessionSv1GetActiveSessionIDs: ka.BiRPCv1GetActiveSessionIDs, + utils.SessionSv1ReAuthorize: ka.BiRPCv1ReAuthorize, + utils.SessionSv1DisconnectPeer: ka.BiRPCv1DisconnectPeer, + utils.SessionSv1WarnDisconnect: ka.BiRPCv1WarnDisconnect, + } +} diff --git a/apier/v1/sessions_thresholds_it_test.go b/apier/v1/sessions_thresholds_it_test.go index a11195ddc..b77010052 100755 --- a/apier/v1/sessions_thresholds_it_test.go +++ b/apier/v1/sessions_thresholds_it_test.go @@ -493,10 +493,10 @@ func testSessionSv1ItTerminateNotFoundThreshold(t *testing.T) { var rply string if err := sSv1BiRpc2.Call(utils.SessionSv1TerminateSession, args, &rply); err != nil { - t.Error(err) + t.Fatal(err) } if rply != utils.OK { - t.Errorf("Unexpected reply: %s", rply) + t.Fatalf("Unexpected reply: %s", rply) } aSessions := make([]*sessions.ExternalSession, 0) if err := sSv1BiRpc2.Call(utils.SessionSv1GetActiveSessions, nil, &aSessions); err == nil || diff --git a/apier/v1/tpdispatchers_it_test.go b/apier/v1/tpdispatchers_it_test.go index 4bf25f09c..e778b46e6 100644 --- a/apier/v1/tpdispatchers_it_test.go +++ b/apier/v1/tpdispatchers_it_test.go @@ -149,7 +149,7 @@ func testTPDispatcherGetTPDispatcherAfterSet(t *testing.T) { &utils.TPTntID{TPid: "TP1", Tenant: "cgrates.org", ID: "Dsp1"}, &reply); err != nil { t.Error(err) } else if !reflect.DeepEqual(tpDispatcher, reply) { - t.Errorf("Expecting : %+v, received: %+v", tpDispatcher, reply) + t.Errorf("Expecting : %+v, received: %+v", utils.ToJSON(tpDispatcher), utils.ToJSON(reply)) } } diff --git a/cmd/cgr-engine/cgr-engine.go b/cmd/cgr-engine/cgr-engine.go index f46a4e243..dc341e093 100644 --- a/cmd/cgr-engine/cgr-engine.go +++ b/cmd/cgr-engine/cgr-engine.go @@ -529,6 +529,8 @@ func main() { utils.ConcatenatedKey(utils.MetaInternal, utils.MetaActions): internalActionSChan, utils.ConcatenatedKey(utils.MetaInternal, utils.MetaDispatchers): internalDispatcherSChan, utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAccounts): internalAccountSChan, + + utils.ConcatenatedKey(rpcclient.BiRPCInternal, utils.MetaSessionS): internalSessionSChan, }) srvDep := map[string]*sync.WaitGroup{ utils.AnalyzerS: new(sync.WaitGroup), diff --git a/cmd/cgr-loader/cgr-loader_it_test.go b/cmd/cgr-loader/cgr-loader_it_test.go index 4f2f2627c..af3101e9f 100644 --- a/cmd/cgr-loader/cgr-loader_it_test.go +++ b/cmd/cgr-loader/cgr-loader_it_test.go @@ -165,6 +165,13 @@ func TestLoadConfig(t *testing.T) { Address: utils.MetaInternal, }}, }, + rpcclient.BiRPCInternal: { + Strategy: rpcclient.PoolFirst, + PoolSize: 0, + Conns: []*config.RemoteHost{{ + Address: rpcclient.BiRPCInternal, + }}, + }, "*localhost": { Strategy: rpcclient.PoolFirst, Conns: []*config.RemoteHost{{Address: "127.0.0.1:2012", Transport: utils.MetaJSON}}, diff --git a/config/config.go b/config/config.go index 3db39ec93..6eb6b3a17 100644 --- a/config/config.go +++ b/config/config.go @@ -430,6 +430,13 @@ func (cfg *CGRConfig) loadRPCConns(jsnCfg *CgrJsonCfg) (err error) { Address: utils.MetaInternal, }}, } + cfg.rpcConns[rpcclient.BiRPCInternal] = &RPCConn{ + Strategy: rpcclient.PoolFirst, + PoolSize: 0, + Conns: []*RemoteHost{{ + Address: rpcclient.BiRPCInternal, + }}, + } for key, val := range jsnRPCConns { cfg.rpcConns[key] = NewDfltRPCConn() cfg.rpcConns[key].loadFromJSONCfg(val) diff --git a/config/config_defaults.go b/config/config_defaults.go index 85a05d9ad..f37ce9097 100644 --- a/config/config_defaults.go +++ b/config/config_defaults.go @@ -475,7 +475,7 @@ const CGRATES_CFG_JSON = ` "asterisk_agent": { "enabled": false, // starts the Asterisk agent: - "sessions_conns": ["*internal"], + "sessions_conns": ["*birpc_internal"], "create_cdr": false, // create CDR out of events and sends it to CDRS component "asterisk_conns":[ // instantiate connections to multiple Asterisk servers {"address": "127.0.0.1:8088", "user": "cgrates", "password": "CGRateS.org", "connect_attempts": 3,"reconnects": 5} @@ -485,7 +485,7 @@ const CGRATES_CFG_JSON = ` "freeswitch_agent": { "enabled": false, // starts the FreeSWITCH agent: - "sessions_conns": ["*internal"], + "sessions_conns": ["*birpc_internal"], "subscribe_park": true, // subscribe via fsock to receive park events "create_cdr": false, // creates CDR out of events and sends them to CDRS component "extra_fields": [], // extra fields to store in auth/CDRs when creating them @@ -501,7 +501,7 @@ const CGRATES_CFG_JSON = ` "kamailio_agent": { "enabled": false, // starts Kamailio agent: - "sessions_conns": ["*internal"], + "sessions_conns": ["*birpc_internal"], "create_cdr": false, // create CDR out of events and sends them to CDRS component "timezone": "", // timezone of the Kamailio server "evapi_conns":[ // instantiate connections to multiple Kamailio servers @@ -515,7 +515,7 @@ const CGRATES_CFG_JSON = ` "listen": "127.0.0.1:3868", // address where to listen for diameter requests "listen_net": "tcp", // transport type for diameter "dictionaries_path": "/usr/share/cgrates/diameter/dict/", // path towards directory holding additional dictionaries to load - "sessions_conns": ["*internal"], + "sessions_conns": ["*birpc_internal"], "origin_host": "CGR-DA", // diameter Origin-Host AVP used in replies "origin_realm": "cgrates.org", // diameter Origin-Realm AVP used in replies "vendor_id": 0, // diameter Vendor-Id AVP used in replies diff --git a/config/config_it_test.go b/config/config_it_test.go index f7eec2180..923ef482e 100644 --- a/config/config_it_test.go +++ b/config/config_it_test.go @@ -33,6 +33,7 @@ import ( "time" "github.com/cgrates/cgrates/utils" + "github.com/cgrates/rpcclient" ) var ( @@ -613,7 +614,7 @@ func testCGRConfigReloadFreeswitchAgent(t *testing.T) { } expAttr := &FsAgentCfg{ Enabled: true, - SessionSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS)}, + SessionSConns: []string{utils.ConcatenatedKey(rpcclient.BiRPCInternal, utils.MetaSessionS)}, SubscribePark: true, ExtraFields: RSRParsers{}, MaxWaitConnection: 2 * time.Second, diff --git a/config/config_json_test.go b/config/config_json_test.go index 668f2f0a7..d5c957647 100644 --- a/config/config_json_test.go +++ b/config/config_json_test.go @@ -24,6 +24,7 @@ import ( "testing" "github.com/cgrates/cgrates/utils" + "github.com/cgrates/rpcclient" ) func TestDfGeneralJsonCfg(t *testing.T) { @@ -769,7 +770,7 @@ func TestSmgJsonCfg(t *testing.T) { func TestFsAgentJsonCfg(t *testing.T) { eCfg := &FreeswitchAgentJsonCfg{ Enabled: utils.BoolPointer(false), - Sessions_conns: &[]string{utils.MetaInternal}, + Sessions_conns: &[]string{rpcclient.BiRPCInternal}, Subscribe_park: utils.BoolPointer(true), Create_cdr: utils.BoolPointer(false), Extra_fields: &[]string{}, @@ -799,7 +800,7 @@ func TestFsAgentJsonCfg(t *testing.T) { func TestKamAgentJsonCfg(t *testing.T) { eCfg := &KamAgentJsonCfg{ Enabled: utils.BoolPointer(false), - Sessions_conns: &[]string{utils.MetaInternal}, + Sessions_conns: &[]string{rpcclient.BiRPCInternal}, Create_cdr: utils.BoolPointer(false), Evapi_conns: &[]*KamConnJsonCfg{ { @@ -824,7 +825,7 @@ func TestKamAgentJsonCfg(t *testing.T) { func TestAsteriskAgentJsonCfg(t *testing.T) { eCfg := &AsteriskAgentJsonCfg{ Enabled: utils.BoolPointer(false), - Sessions_conns: &[]string{utils.MetaInternal}, + Sessions_conns: &[]string{rpcclient.BiRPCInternal}, Create_cdr: utils.BoolPointer(false), Asterisk_conns: &[]*AstConnJsonCfg{ { @@ -853,7 +854,7 @@ func TestDiameterAgentJsonCfg(t *testing.T) { Listen: utils.StringPointer("127.0.0.1:3868"), Listen_net: utils.StringPointer(utils.TCP), Dictionaries_path: utils.StringPointer("/usr/share/cgrates/diameter/dict/"), - Sessions_conns: &[]string{utils.MetaInternal}, + Sessions_conns: &[]string{rpcclient.BiRPCInternal}, Origin_host: utils.StringPointer("CGR-DA"), Origin_realm: utils.StringPointer("cgrates.org"), Vendor_id: utils.IntPointer(0), diff --git a/config/config_test.go b/config/config_test.go index ebf204dac..2f745a9d7 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -697,7 +697,7 @@ func TestCgrCfgJSONDefaultsCacheCFG(t *testing.T) { func TestCgrCfgJSONDefaultsFsAgentConfig(t *testing.T) { eFsAgentCfg := &FsAgentCfg{ Enabled: false, - SessionSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS)}, + SessionSConns: []string{utils.ConcatenatedKey(rpcclient.BiRPCInternal, utils.MetaSessionS)}, SubscribePark: true, CreateCdr: false, ExtraFields: RSRParsers{}, @@ -720,7 +720,7 @@ func TestCgrCfgJSONDefaultsFsAgentConfig(t *testing.T) { func TestCgrCfgJSONDefaultsKamAgentConfig(t *testing.T) { eKamAgentCfg := &KamAgentCfg{ Enabled: false, - SessionSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS)}, + SessionSConns: []string{utils.ConcatenatedKey(rpcclient.BiRPCInternal, utils.MetaSessionS)}, CreateCdr: false, EvapiConns: []*KamConnCfg{{ Address: "127.0.0.1:8448", @@ -736,7 +736,7 @@ func TestCgrCfgJSONDefaultsKamAgentConfig(t *testing.T) { func TestCgrCfgJSONDefaultssteriskAgentCfg(t *testing.T) { eAstAgentCfg := &AsteriskAgentCfg{ Enabled: false, - SessionSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS)}, + SessionSConns: []string{utils.ConcatenatedKey(rpcclient.BiRPCInternal, utils.MetaSessionS)}, CreateCDR: false, AsteriskConns: []*AsteriskConnCfg{ {Address: "127.0.0.1:8088", @@ -843,7 +843,7 @@ func TestCgrCfgJSONDefaultsDiameterAgentCfg(t *testing.T) { Listen: "127.0.0.1:3868", ListenNet: utils.TCP, DictionariesPath: "/usr/share/cgrates/diameter/dict/", - SessionSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS)}, + SessionSConns: []string{utils.ConcatenatedKey(rpcclient.BiRPCInternal, utils.MetaSessionS)}, OriginHost: "CGR-DA", OriginRealm: "cgrates.org", VendorID: 0, @@ -1972,7 +1972,7 @@ func TestDiameterAgentConfig(t *testing.T) { ListenNet: "tcp", Listen: "127.0.0.1:3868", DictionariesPath: "/usr/share/cgrates/diameter/dict/", - SessionSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS)}, + SessionSConns: []string{utils.ConcatenatedKey(rpcclient.BiRPCInternal, utils.MetaSessionS)}, OriginHost: "CGR-DA", OriginRealm: "cgrates.org", VendorID: 0, @@ -2207,7 +2207,7 @@ func TestSessionSConfig(t *testing.T) { func TestFsAgentConfig(t *testing.T) { expected := &FsAgentCfg{ Enabled: false, - SessionSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS)}, + SessionSConns: []string{utils.ConcatenatedKey(rpcclient.BiRPCInternal, utils.MetaSessionS)}, SubscribePark: true, CreateCdr: false, LowBalanceAnnFile: "", @@ -2237,7 +2237,7 @@ func TestFsAgentConfig(t *testing.T) { func TestKamAgentConfig(t *testing.T) { expected := &KamAgentCfg{ Enabled: false, - SessionSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS)}, + SessionSConns: []string{utils.ConcatenatedKey(rpcclient.BiRPCInternal, utils.MetaSessionS)}, CreateCdr: false, EvapiConns: []*KamConnCfg{{Address: "127.0.0.1:8448", Reconnects: 5, Alias: ""}}, Timezone: "", @@ -2255,7 +2255,7 @@ func TestKamAgentConfig(t *testing.T) { func TestAsteriskAgentConfig(t *testing.T) { expected := &AsteriskAgentCfg{ Enabled: false, - SessionSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS)}, + SessionSConns: []string{utils.ConcatenatedKey(rpcclient.BiRPCInternal, utils.MetaSessionS)}, CreateCDR: false, AsteriskConns: []*AsteriskConnCfg{{ Alias: "", @@ -2529,6 +2529,18 @@ func TestRPCConnsConfig(t *testing.T) { }, }, }, + rpcclient.BiRPCInternal: { + Strategy: utils.MetaFirst, + PoolSize: 0, + Conns: []*RemoteHost{ + { + Address: rpcclient.BiRPCInternal, + Transport: utils.EmptyString, + Synchronous: false, + TLS: false, + }, + }, + }, utils.MetaLocalHost: { Strategy: utils.MetaFirst, PoolSize: 0, @@ -4213,7 +4225,7 @@ func TestV1GetConfigFsAgent(t *testing.T) { expected := map[string]interface{}{ FreeSWITCHAgentJSN: map[string]interface{}{ utils.EnabledCfg: false, - utils.SessionSConnsCfg: []string{"*internal"}, + utils.SessionSConnsCfg: []string{rpcclient.BiRPCInternal}, utils.SubscribeParkCfg: true, utils.CreateCdrCfg: false, utils.ExtraFieldsCfg: "", @@ -4243,7 +4255,7 @@ func TestV1GetConfigKamailioAgent(t *testing.T) { expected := map[string]interface{}{ KamailioAgentJSN: map[string]interface{}{ utils.EnabledCfg: false, - utils.SessionSConnsCfg: []string{"*internal"}, + utils.SessionSConnsCfg: []string{rpcclient.BiRPCInternal}, utils.CreateCdrCfg: false, utils.TimezoneCfg: "", utils.EvapiConnsCfg: []map[string]interface{}{ @@ -4268,7 +4280,7 @@ func TestV1GetConfigAsteriskAgent(t *testing.T) { expected := map[string]interface{}{ AsteriskAgentJSN: map[string]interface{}{ utils.EnabledCfg: false, - utils.SessionSConnsCfg: []string{"*internal"}, + utils.SessionSConnsCfg: []string{rpcclient.BiRPCInternal}, utils.CreateCdrCfg: false, utils.AsteriskConnsCfg: []map[string]interface{}{ { @@ -4305,7 +4317,7 @@ func TestV1GetConfigDiameterAgent(t *testing.T) { utils.OriginRealmCfg: "cgrates.org", utils.ProductNameCfg: "CGRateS", utils.RARTemplateCfg: "", - utils.SessionSConnsCfg: []string{"*internal"}, + utils.SessionSConnsCfg: []string{rpcclient.BiRPCInternal}, utils.SyncedConnReqsCfg: false, utils.VendorIDCfg: 0, utils.RequestProcessorsCfg: []map[string]interface{}{}, @@ -4798,6 +4810,18 @@ func TestV1GetConfigSectionRPConns(t *testing.T) { }, }, }, + rpcclient.BiRPCInternal: map[string]interface{}{ + utils.StrategyCfg: utils.MetaFirst, + utils.PoolSize: 0, + utils.Conns: []map[string]interface{}{ + { + utils.AddressCfg: rpcclient.BiRPCInternal, + utils.TransportCfg: utils.EmptyString, + utils.SynchronousCfg: false, + utils.TLS: false, + }, + }, + }, }, } cfgCgr := NewDefaultCGRConfig() @@ -5209,7 +5233,7 @@ func TestV1GetConfigAsJSONSessionS(t *testing.T) { func TestV1GetConfigAsJSONFreeSwitchAgent(t *testing.T) { var reply string - expected := `{"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}}` + expected := `{"freeswitch_agent":{"create_cdr":false,"empty_balance_ann_file":"","empty_balance_context":"","enabled":false,"event_socket_conns":[{"address":"127.0.0.1:8021","alias":"127.0.0.1:8021","password":"ClueCon","reconnects":5}],"extra_fields":"","low_balance_ann_file":"","max_wait_connection":"2s","sessions_conns":["*birpc_internal"],"subscribe_park":true}}` cfgCgr := NewDefaultCGRConfig() if err := cfgCgr.V1GetConfigAsJSON(&SectionWithOpts{Section: FreeSWITCHAgentJSN}, &reply); err != nil { t.Error(err) @@ -5220,7 +5244,7 @@ func TestV1GetConfigAsJSONFreeSwitchAgent(t *testing.T) { func TestV1GetConfigAsJSONFKamailioAgent(t *testing.T) { var reply string - expected := `{"kamailio_agent":{"create_cdr":false,"enabled":false,"evapi_conns":[{"address":"127.0.0.1:8448","alias":"","reconnects":5}],"sessions_conns":["*internal"],"timezone":""}}` + expected := `{"kamailio_agent":{"create_cdr":false,"enabled":false,"evapi_conns":[{"address":"127.0.0.1:8448","alias":"","reconnects":5}],"sessions_conns":["*birpc_internal"],"timezone":""}}` cfgCgr := NewDefaultCGRConfig() if err := cfgCgr.V1GetConfigAsJSON(&SectionWithOpts{Section: KamailioAgentJSN}, &reply); err != nil { t.Error(err) @@ -5231,7 +5255,7 @@ func TestV1GetConfigAsJSONFKamailioAgent(t *testing.T) { func TestV1GetConfigAsJSONAsteriskAgent(t *testing.T) { var reply string - expected := `{"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"]}}` + expected := `{"asterisk_agent":{"asterisk_conns":[{"address":"127.0.0.1:8088","alias":"","connect_attempts":3,"password":"CGRateS.org","reconnects":5,"user":"cgrates"}],"create_cdr":false,"enabled":false,"sessions_conns":["*birpc_internal"]}}` cfgCgr := NewDefaultCGRConfig() if err := cfgCgr.V1GetConfigAsJSON(&SectionWithOpts{Section: AsteriskAgentJSN}, &reply); err != nil { t.Error(err) @@ -5242,7 +5266,7 @@ func TestV1GetConfigAsJSONAsteriskAgent(t *testing.T) { func TestV1GetConfigAsJSONADiameterAgent(t *testing.T) { var reply string - expected := `{"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}}` + expected := `{"diameter_agent":{"asr_template":"","concurrent_requests":-1,"dictionaries_path":"/usr/share/cgrates/diameter/dict/","enabled":false,"forced_disconnect":"*none","listen":"127.0.0.1:3868","listen_net":"tcp","origin_host":"CGR-DA","origin_realm":"cgrates.org","product_name":"CGRateS","rar_template":"","request_processors":[],"sessions_conns":["*birpc_internal"],"synced_conn_requests":false,"vendor_id":0}}` cfgCgr := NewDefaultCGRConfig() if err := cfgCgr.V1GetConfigAsJSON(&SectionWithOpts{Section: DA_JSN}, &reply); err != nil { t.Error(err) @@ -5475,7 +5499,7 @@ func TestV1GetConfigAsJSONApiBan(t *testing.T) { func TestV1GetConfigAsJSONRPCConns(t *testing.T) { var reply string - expected := `{"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"}}}` + expected := `{"rpc_conns":{"*birpc_internal":{"conns":[{"TLS":false,"address":"*birpc_internal","synchronous":false,"transport":""}],"poolSize":0,"strategy":"*first"},"*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"}}}` cgrCfg := NewDefaultCGRConfig() if err := cgrCfg.V1GetConfigAsJSON(&SectionWithOpts{Section: RPCConnsJsonName}, &reply); err != nil { t.Error(err) @@ -5601,7 +5625,7 @@ func TestV1GetConfigAsJSONAllConfig(t *testing.T) { } }` var reply string - expected := `{"accounts":{"attributes_conns":[],"enabled":false,"indexed_selects":true,"max_iterations":1000,"max_usage":259200000000000,"nested_fields":false,"prefix_indexed_fields":[],"rates_conns":[],"suffix_indexed_fields":[],"thresholds_conns":[]},"actions":{"cdrs_conns":[],"ees_conns":[],"enabled":false,"indexed_selects":true,"nested_fields":false,"prefix_indexed_fields":[],"stats_conns":[],"suffix_indexed_fields":[],"tenants":[],"thresholds_conns":[]},"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":""},"*account_profile_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*account_profiles":{"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_profile_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*action_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*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_account_profiles":{"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_profiles":{"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},"*account_profiles":{"remote":false,"replicate":false},"*accounts":{"remote":false,"replicate":false},"*action_plans":{"remote":false,"replicate":false},"*action_profiles":{"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_parallel_conns":100,"node_id":"ENGINE1","poster_attempts":3,"reconnects":-1,"reply_timeout":"2s","rounding_decimals":5,"rsr_separator":";","tpexport_dir":"/var/spool/cgrates/tpe"},"http":{"auth_users":{},"client_opts":{"dialFallbackDelay":"300ms","dialKeepAlive":"30s","dialTimeout":"30s","disableCompression":false,"disableKeepAlives":false,"expectContinueTimeout":"0","forceAttemptHttp2":true,"idleConnTimeout":"90s","maxConnsPerHost":0,"maxIdleConns":100,"maxIdleConnsPerHost":2,"responseHeaderTimeout":"0","skipTlsVerify":false,"tlsHandshakeTimeout":"10s"},"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":"MinCost","tag":"MinCost","type":"*variable","value":"~*req.5"},{"path":"MaxCost","tag":"MaxCost","type":"*variable","value":"~*req.6"},{"path":"MaxCostStrategy","tag":"MaxCostStrategy","type":"*variable","value":"~*req.7"},{"path":"RateID","tag":"RateID","type":"*variable","value":"~*req.8"},{"path":"RateFilterIDs","tag":"RateFilterIDs","type":"*variable","value":"~*req.9"},{"path":"RateActivationTimes","tag":"RateActivationTimes","type":"*variable","value":"~*req.10"},{"path":"RateWeight","tag":"RateWeight","type":"*variable","value":"~*req.11"},{"path":"RateBlocker","tag":"RateBlocker","type":"*variable","value":"~*req.12"},{"path":"RateIntervalStart","tag":"RateIntervalStart","type":"*variable","value":"~*req.13"},{"path":"RateFixedFee","tag":"RateFixedFee","type":"*variable","value":"~*req.14"},{"path":"RateRecurrentFee","tag":"RateRecurrentFee","type":"*variable","value":"~*req.15"},{"path":"RateUnit","tag":"RateUnit","type":"*variable","value":"~*req.16"},{"path":"RateIncrement","tag":"RateIncrement","type":"*variable","value":"~*req.17"}],"file_name":"RateProfiles.csv","flags":null,"type":"*rate_profiles"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.3"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.4"},{"path":"Schedule","tag":"Schedule","type":"*variable","value":"~*req.5"},{"path":"TargetType","tag":"TargetType","type":"*variable","value":"~*req.6"},{"path":"TargetIDs","tag":"TargetIDs","type":"*variable","value":"~*req.7"},{"path":"ActionID","tag":"ActionID","type":"*variable","value":"~*req.8"},{"path":"ActionFilterIDs","tag":"ActionFilterIDs","type":"*variable","value":"~*req.9"},{"path":"ActionBlocker","tag":"ActionBlocker","type":"*variable","value":"~*req.10"},{"path":"ActionTTL","tag":"ActionTTL","type":"*variable","value":"~*req.11"},{"path":"ActionType","tag":"ActionType","type":"*variable","value":"~*req.12"},{"path":"ActionOpts","tag":"ActionOpts","type":"*variable","value":"~*req.13"},{"path":"ActionPath","tag":"ActionPath","type":"*variable","value":"~*req.14"},{"path":"ActionValue","tag":"ActionValue","type":"*variable","value":"~*req.15"}],"file_name":"ActionProfiles.csv","flags":null,"type":"*action_profiles"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.3"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.4"},{"path":"BalanceID","tag":"BalanceID","type":"*variable","value":"~*req.5"},{"path":"BalanceFilterIDs","tag":"BalanceFilterIDs","type":"*variable","value":"~*req.6"},{"path":"BalanceWeight","tag":"BalanceWeight","type":"*variable","value":"~*req.7"},{"path":"BalanceBlocker","tag":"BalanceBlocker","type":"*variable","value":"~*req.8"},{"path":"BalanceType","tag":"BalanceType","type":"*variable","value":"~*req.9"},{"path":"BalanceOpts","tag":"BalanceOpts","type":"*variable","value":"~*req.10"},{"path":"BalanceCostIncrements","tag":"BalanceCostIncrements","type":"*variable","value":"~*req.11"},{"path":"BalanceAttributeIDs","tag":"BalanceAttributeIDs","type":"*variable","value":"~*req.12"},{"path":"BalanceRateProfileIDs","tag":"BalanceRateProfileIDs","type":"*variable","value":"~*req.13"},{"path":"BalanceUnitFactors","tag":"BalanceUnitFactors","type":"*variable","value":"~*req.14"},{"path":"BalanceUnits","tag":"BalanceUnits","type":"*variable","value":"~*req.15"},{"path":"ThresholdIDs","tag":"ThresholdIDs","type":"*variable","value":"~*req.16"}],"file_name":"AccountProfiles.csv","flags":null,"type":"*account_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":[],"verbosity":1000},"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":[],"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","default_usage":{"*any":"3h0m0s","*data":"1048576","*sms":"1","*voice":"3h0m0s"},"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_account_profiles":{"remote":false,"replicate":false},"*tp_action_plans":{"remote":false,"replicate":false},"*tp_action_profiles":{"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"}],"*cdrLog":[{"mandatory":true,"path":"*cdr.ToR","tag":"ToR","type":"*variable","value":"~*req.BalanceType"},{"mandatory":true,"path":"*cdr.OriginHost","tag":"OriginHost","type":"*constant","value":"127.0.0.1"},{"mandatory":true,"path":"*cdr.RequestType","tag":"RequestType","type":"*constant","value":"*none"},{"mandatory":true,"path":"*cdr.Tenant","tag":"Tenant","type":"*variable","value":"~*req.Tenant"},{"mandatory":true,"path":"*cdr.Account","tag":"Account","type":"*variable","value":"~*req.Account"},{"mandatory":true,"path":"*cdr.Subject","tag":"Subject","type":"*variable","value":"~*req.Account"},{"mandatory":true,"path":"*cdr.Cost","tag":"Cost","type":"*variable","value":"~*req.Cost"},{"mandatory":true,"path":"*cdr.Source","tag":"Source","type":"*constant","value":"*cdrLog"},{"mandatory":true,"path":"*cdr.Usage","tag":"Usage","type":"*constant","value":"1"},{"mandatory":true,"path":"*cdr.RunID","tag":"RunID","type":"*variable","value":"~*req.ActionType"},{"mandatory":true,"path":"*cdr.SetupTime","tag":"SetupTime","type":"*constant","value":"*now"},{"mandatory":true,"path":"*cdr.AnswerTime","tag":"AnswerTime","type":"*constant","value":"*now"},{"mandatory":true,"path":"*cdr.PreRated","tag":"PreRated","type":"*constant","value":"true"}],"*err":[{"mandatory":true,"path":"*rep.Session-Id","tag":"SessionId","type":"*variable","value":"~*req.Session-Id"},{"mandatory":true,"path":"*rep.Origin-Host","tag":"OriginHost","type":"*variable","value":"~*vars.OriginHost"},{"mandatory":true,"path":"*rep.Origin-Realm","tag":"OriginRealm","type":"*variable","value":"~*vars.OriginRealm"}],"*errSip":[{"mandatory":true,"path":"*rep.Request","tag":"Request","type":"*constant","value":"SIP/2.0 500 Internal Server Error"}],"*rar":[{"mandatory":true,"path":"*diamreq.Session-Id","tag":"SessionId","type":"*variable","value":"~*req.Session-Id"},{"mandatory":true,"path":"*diamreq.Origin-Host","tag":"OriginHost","type":"*variable","value":"~*req.Destination-Host"},{"mandatory":true,"path":"*diamreq.Origin-Realm","tag":"OriginRealm","type":"*variable","value":"~*req.Destination-Realm"},{"mandatory":true,"path":"*diamreq.Destination-Realm","tag":"DestinationRealm","type":"*variable","value":"~*req.Origin-Realm"},{"mandatory":true,"path":"*diamreq.Destination-Host","tag":"DestinationHost","type":"*variable","value":"~*req.Origin-Host"},{"mandatory":true,"path":"*diamreq.Auth-Application-Id","tag":"AuthApplicationId","type":"*variable","value":"~*vars.*appid"},{"path":"*diamreq.Re-Auth-Request-Type","tag":"ReAuthRequestType","type":"*constant","value":"0"}]},"thresholds":{"enabled":false,"indexed_selects":true,"nested_fields":false,"prefix_indexed_fields":[],"store_interval":"","suffix_indexed_fields":[]},"tls":{"ca_certificate":"","client_certificate":"","client_key":"","server_certificate":"","server_key":"","server_name":"","server_policy":4}}` + expected := `{"accounts":{"attributes_conns":[],"enabled":false,"indexed_selects":true,"max_iterations":1000,"max_usage":259200000000000,"nested_fields":false,"prefix_indexed_fields":[],"rates_conns":[],"suffix_indexed_fields":[],"thresholds_conns":[]},"actions":{"cdrs_conns":[],"ees_conns":[],"enabled":false,"indexed_selects":true,"nested_fields":false,"prefix_indexed_fields":[],"stats_conns":[],"suffix_indexed_fields":[],"tenants":[],"thresholds_conns":[]},"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":["*birpc_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":""},"*account_profile_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*account_profiles":{"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_profile_filter_indexes":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*action_profiles":{"limit":-1,"precache":false,"replicate":false,"static_ttl":false,"ttl":""},"*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_account_profiles":{"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_profiles":{"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},"*account_profiles":{"remote":false,"replicate":false},"*accounts":{"remote":false,"replicate":false},"*action_plans":{"remote":false,"replicate":false},"*action_profiles":{"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":["*birpc_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":["*birpc_internal"],"subscribe_park":true},"general":{"connect_attempts":5,"connect_timeout":"1s","dbdata_encoding":"*msgpack","default_caching":"*reload","default_category":"call","default_request_type":"*rated","default_tenant":"cgrates.org","default_timezone":"Local","digest_equal":":","digest_separator":",","failed_posts_dir":"/var/spool/cgrates/failed_posts","failed_posts_ttl":"5s","locking_timeout":"0","log_level":6,"logger":"*syslog","max_parallel_conns":100,"node_id":"ENGINE1","poster_attempts":3,"reconnects":-1,"reply_timeout":"2s","rounding_decimals":5,"rsr_separator":";","tpexport_dir":"/var/spool/cgrates/tpe"},"http":{"auth_users":{},"client_opts":{"dialFallbackDelay":"300ms","dialKeepAlive":"30s","dialTimeout":"30s","disableCompression":false,"disableKeepAlives":false,"expectContinueTimeout":"0","forceAttemptHttp2":true,"idleConnTimeout":"90s","maxConnsPerHost":0,"maxIdleConns":100,"maxIdleConnsPerHost":2,"responseHeaderTimeout":"0","skipTlsVerify":false,"tlsHandshakeTimeout":"10s"},"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":["*birpc_internal"],"timezone":""},"listen":{"http":"127.0.0.1:2080","http_tls":"127.0.0.1:2280","rpc_gob":"127.0.0.1:2013","rpc_gob_tls":"127.0.0.1:2023","rpc_json":"127.0.0.1:2012","rpc_json_tls":"127.0.0.1:2022"},"loader":{"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":"MinCost","tag":"MinCost","type":"*variable","value":"~*req.5"},{"path":"MaxCost","tag":"MaxCost","type":"*variable","value":"~*req.6"},{"path":"MaxCostStrategy","tag":"MaxCostStrategy","type":"*variable","value":"~*req.7"},{"path":"RateID","tag":"RateID","type":"*variable","value":"~*req.8"},{"path":"RateFilterIDs","tag":"RateFilterIDs","type":"*variable","value":"~*req.9"},{"path":"RateActivationTimes","tag":"RateActivationTimes","type":"*variable","value":"~*req.10"},{"path":"RateWeight","tag":"RateWeight","type":"*variable","value":"~*req.11"},{"path":"RateBlocker","tag":"RateBlocker","type":"*variable","value":"~*req.12"},{"path":"RateIntervalStart","tag":"RateIntervalStart","type":"*variable","value":"~*req.13"},{"path":"RateFixedFee","tag":"RateFixedFee","type":"*variable","value":"~*req.14"},{"path":"RateRecurrentFee","tag":"RateRecurrentFee","type":"*variable","value":"~*req.15"},{"path":"RateUnit","tag":"RateUnit","type":"*variable","value":"~*req.16"},{"path":"RateIncrement","tag":"RateIncrement","type":"*variable","value":"~*req.17"}],"file_name":"RateProfiles.csv","flags":null,"type":"*rate_profiles"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.3"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.4"},{"path":"Schedule","tag":"Schedule","type":"*variable","value":"~*req.5"},{"path":"TargetType","tag":"TargetType","type":"*variable","value":"~*req.6"},{"path":"TargetIDs","tag":"TargetIDs","type":"*variable","value":"~*req.7"},{"path":"ActionID","tag":"ActionID","type":"*variable","value":"~*req.8"},{"path":"ActionFilterIDs","tag":"ActionFilterIDs","type":"*variable","value":"~*req.9"},{"path":"ActionBlocker","tag":"ActionBlocker","type":"*variable","value":"~*req.10"},{"path":"ActionTTL","tag":"ActionTTL","type":"*variable","value":"~*req.11"},{"path":"ActionType","tag":"ActionType","type":"*variable","value":"~*req.12"},{"path":"ActionOpts","tag":"ActionOpts","type":"*variable","value":"~*req.13"},{"path":"ActionPath","tag":"ActionPath","type":"*variable","value":"~*req.14"},{"path":"ActionValue","tag":"ActionValue","type":"*variable","value":"~*req.15"}],"file_name":"ActionProfiles.csv","flags":null,"type":"*action_profiles"},{"fields":[{"mandatory":true,"path":"Tenant","tag":"Tenant","type":"*variable","value":"~*req.0"},{"mandatory":true,"path":"ID","tag":"ID","type":"*variable","value":"~*req.1"},{"path":"FilterIDs","tag":"FilterIDs","type":"*variable","value":"~*req.2"},{"path":"ActivationInterval","tag":"ActivationInterval","type":"*variable","value":"~*req.3"},{"path":"Weight","tag":"Weight","type":"*variable","value":"~*req.4"},{"path":"BalanceID","tag":"BalanceID","type":"*variable","value":"~*req.5"},{"path":"BalanceFilterIDs","tag":"BalanceFilterIDs","type":"*variable","value":"~*req.6"},{"path":"BalanceWeight","tag":"BalanceWeight","type":"*variable","value":"~*req.7"},{"path":"BalanceBlocker","tag":"BalanceBlocker","type":"*variable","value":"~*req.8"},{"path":"BalanceType","tag":"BalanceType","type":"*variable","value":"~*req.9"},{"path":"BalanceOpts","tag":"BalanceOpts","type":"*variable","value":"~*req.10"},{"path":"BalanceCostIncrements","tag":"BalanceCostIncrements","type":"*variable","value":"~*req.11"},{"path":"BalanceAttributeIDs","tag":"BalanceAttributeIDs","type":"*variable","value":"~*req.12"},{"path":"BalanceRateProfileIDs","tag":"BalanceRateProfileIDs","type":"*variable","value":"~*req.13"},{"path":"BalanceUnitFactors","tag":"BalanceUnitFactors","type":"*variable","value":"~*req.14"},{"path":"BalanceUnits","tag":"BalanceUnits","type":"*variable","value":"~*req.15"},{"path":"ThresholdIDs","tag":"ThresholdIDs","type":"*variable","value":"~*req.16"}],"file_name":"AccountProfiles.csv","flags":null,"type":"*account_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":[],"verbosity":1000},"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":[],"resources_conns":[],"stats_conns":[],"suffix_indexed_fields":[]},"rpc_conns":{"*birpc_internal":{"conns":[{"TLS":false,"address":"*birpc_internal","synchronous":false,"transport":""}],"poolSize":0,"strategy":"*first"},"*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","default_usage":{"*any":"3h0m0s","*data":"1048576","*sms":"1","*voice":"3h0m0s"},"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_account_profiles":{"remote":false,"replicate":false},"*tp_action_plans":{"remote":false,"replicate":false},"*tp_action_profiles":{"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"}],"*cdrLog":[{"mandatory":true,"path":"*cdr.ToR","tag":"ToR","type":"*variable","value":"~*req.BalanceType"},{"mandatory":true,"path":"*cdr.OriginHost","tag":"OriginHost","type":"*constant","value":"127.0.0.1"},{"mandatory":true,"path":"*cdr.RequestType","tag":"RequestType","type":"*constant","value":"*none"},{"mandatory":true,"path":"*cdr.Tenant","tag":"Tenant","type":"*variable","value":"~*req.Tenant"},{"mandatory":true,"path":"*cdr.Account","tag":"Account","type":"*variable","value":"~*req.Account"},{"mandatory":true,"path":"*cdr.Subject","tag":"Subject","type":"*variable","value":"~*req.Account"},{"mandatory":true,"path":"*cdr.Cost","tag":"Cost","type":"*variable","value":"~*req.Cost"},{"mandatory":true,"path":"*cdr.Source","tag":"Source","type":"*constant","value":"*cdrLog"},{"mandatory":true,"path":"*cdr.Usage","tag":"Usage","type":"*constant","value":"1"},{"mandatory":true,"path":"*cdr.RunID","tag":"RunID","type":"*variable","value":"~*req.ActionType"},{"mandatory":true,"path":"*cdr.SetupTime","tag":"SetupTime","type":"*constant","value":"*now"},{"mandatory":true,"path":"*cdr.AnswerTime","tag":"AnswerTime","type":"*constant","value":"*now"},{"mandatory":true,"path":"*cdr.PreRated","tag":"PreRated","type":"*constant","value":"true"}],"*err":[{"mandatory":true,"path":"*rep.Session-Id","tag":"SessionId","type":"*variable","value":"~*req.Session-Id"},{"mandatory":true,"path":"*rep.Origin-Host","tag":"OriginHost","type":"*variable","value":"~*vars.OriginHost"},{"mandatory":true,"path":"*rep.Origin-Realm","tag":"OriginRealm","type":"*variable","value":"~*vars.OriginRealm"}],"*errSip":[{"mandatory":true,"path":"*rep.Request","tag":"Request","type":"*constant","value":"SIP/2.0 500 Internal Server Error"}],"*rar":[{"mandatory":true,"path":"*diamreq.Session-Id","tag":"SessionId","type":"*variable","value":"~*req.Session-Id"},{"mandatory":true,"path":"*diamreq.Origin-Host","tag":"OriginHost","type":"*variable","value":"~*req.Destination-Host"},{"mandatory":true,"path":"*diamreq.Origin-Realm","tag":"OriginRealm","type":"*variable","value":"~*req.Destination-Realm"},{"mandatory":true,"path":"*diamreq.Destination-Realm","tag":"DestinationRealm","type":"*variable","value":"~*req.Origin-Realm"},{"mandatory":true,"path":"*diamreq.Destination-Host","tag":"DestinationHost","type":"*variable","value":"~*req.Origin-Host"},{"mandatory":true,"path":"*diamreq.Auth-Application-Id","tag":"AuthApplicationId","type":"*variable","value":"~*vars.*appid"},{"path":"*diamreq.Re-Auth-Request-Type","tag":"ReAuthRequestType","type":"*constant","value":"0"}]},"thresholds":{"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) @@ -5612,6 +5636,11 @@ func TestV1GetConfigAsJSONAllConfig(t *testing.T) { } else if expected != reply { t.Fatalf("Expected %+v \n, received %+v", expected, reply) } + if err := cgrCfg.V1GetConfigAsJSON(&SectionWithOpts{Section: utils.EmptyString}, &reply); err != nil { + t.Fatal(err) + } else if expected != reply { + t.Fatalf("Expected %+v \n, received %+v", expected, reply) + } } func TestV1ReloadConfigFromJSONEmptyConfig(t *testing.T) { @@ -5814,6 +5843,15 @@ func TestRpcConnsDefaults(t *testing.T) { }, }, } + eCfg[rpcclient.BiRPCInternal] = &RPCConn{ + Strategy: rpcclient.PoolFirst, + PoolSize: 0, + Conns: []*RemoteHost{ + { + Address: rpcclient.BiRPCInternal, + }, + }, + } eCfg[utils.MetaLocalHost] = &RPCConn{ Strategy: rpcclient.PoolFirst, PoolSize: 0, diff --git a/config/configsanity.go b/config/configsanity.go index caa2be5d0..3886f3d87 100644 --- a/config/configsanity.go +++ b/config/configsanity.go @@ -235,10 +235,11 @@ func (cfg *CGRConfig) checkConfigSanity() error { utils.FreeSWITCHAgent, utils.SessionS) } for _, connID := range cfg.fsAgentCfg.SessionSConns { - if strings.HasPrefix(connID, utils.MetaInternal) && !cfg.sessionSCfg.Enabled { + isInternal := strings.HasPrefix(connID, utils.MetaInternal) || strings.HasPrefix(connID, rpcclient.BiRPCInternal) + if isInternal && !cfg.sessionSCfg.Enabled { return fmt.Errorf("<%s> not enabled but requested by <%s> component", utils.SessionS, utils.FreeSWITCHAgent) } - if _, has := cfg.rpcConns[connID]; !has && !strings.HasPrefix(connID, utils.MetaInternal) { + if _, has := cfg.rpcConns[connID]; !has && !isInternal { return fmt.Errorf("<%s> connection with id: <%s> not defined", utils.FreeSWITCHAgent, connID) } } @@ -250,10 +251,11 @@ func (cfg *CGRConfig) checkConfigSanity() error { utils.KamailioAgent, utils.SessionS) } for _, connID := range cfg.kamAgentCfg.SessionSConns { - if strings.HasPrefix(connID, utils.MetaInternal) && !cfg.sessionSCfg.Enabled { + isInternal := strings.HasPrefix(connID, utils.MetaInternal) || strings.HasPrefix(connID, rpcclient.BiRPCInternal) + if isInternal && !cfg.sessionSCfg.Enabled { return fmt.Errorf("<%s> not enabled but requested by <%s> component", utils.SessionS, utils.KamailioAgent) } - if _, has := cfg.rpcConns[connID]; !has && !strings.HasPrefix(connID, utils.MetaInternal) { + if _, has := cfg.rpcConns[connID]; !has && !isInternal { return fmt.Errorf("<%s> connection with id: <%s> not defined", utils.KamailioAgent, connID) } } @@ -265,10 +267,11 @@ func (cfg *CGRConfig) checkConfigSanity() error { utils.AsteriskAgent, utils.SessionS) } for _, connID := range cfg.asteriskAgentCfg.SessionSConns { - if strings.HasPrefix(connID, utils.MetaInternal) && !cfg.sessionSCfg.Enabled { + isInternal := strings.HasPrefix(connID, utils.MetaInternal) || strings.HasPrefix(connID, rpcclient.BiRPCInternal) + if isInternal && !cfg.sessionSCfg.Enabled { return fmt.Errorf("<%s> not enabled but requested by <%s> component", utils.SessionS, utils.AsteriskAgent) } - if _, has := cfg.rpcConns[connID]; !has && !strings.HasPrefix(connID, utils.MetaInternal) { + if _, has := cfg.rpcConns[connID]; !has && !isInternal { return fmt.Errorf("<%s> connection with id: <%s> not defined", utils.AsteriskAgent, connID) } } @@ -280,10 +283,11 @@ func (cfg *CGRConfig) checkConfigSanity() error { utils.DiameterAgent, utils.SessionS) } for _, connID := range cfg.diameterAgentCfg.SessionSConns { - if strings.HasPrefix(connID, utils.MetaInternal) && !cfg.sessionSCfg.Enabled { + isInternal := strings.HasPrefix(connID, utils.MetaInternal) || strings.HasPrefix(connID, rpcclient.BiRPCInternal) + if isInternal && !cfg.sessionSCfg.Enabled { return fmt.Errorf("<%s> not enabled but requested by <%s> component", utils.SessionS, utils.DiameterAgent) } - if _, has := cfg.rpcConns[connID]; !has && !strings.HasPrefix(connID, utils.MetaInternal) { + if _, has := cfg.rpcConns[connID]; !has && !isInternal { return fmt.Errorf("<%s> connection with id: <%s> not defined", utils.DiameterAgent, connID) } } @@ -369,10 +373,11 @@ func (cfg *CGRConfig) checkConfigSanity() error { for _, httpAgentCfg := range cfg.httpAgentCfg { // httpAgent checks for _, connID := range httpAgentCfg.SessionSConns { - if strings.HasPrefix(connID, utils.MetaInternal) && !cfg.sessionSCfg.Enabled { + isInternal := strings.HasPrefix(connID, utils.MetaInternal) || strings.HasPrefix(connID, rpcclient.BiRPCInternal) + if isInternal && !cfg.sessionSCfg.Enabled { return fmt.Errorf("<%s> not enabled but requested by <%s> HTTPAgent Template", utils.SessionS, httpAgentCfg.ID) } - if _, has := cfg.rpcConns[connID]; !has && !strings.HasPrefix(connID, utils.MetaInternal) { + if _, has := cfg.rpcConns[connID]; !has && !isInternal { return fmt.Errorf("<%s> template with ID <%s> has connection with id: <%s> not defined", utils.HTTPAgent, httpAgentCfg.ID, connID) } } diff --git a/config/diametercfg.go b/config/diametercfg.go index 9f96661de..150fd83fa 100644 --- a/config/diametercfg.go +++ b/config/diametercfg.go @@ -20,6 +20,7 @@ package config import ( "github.com/cgrates/cgrates/utils" + "github.com/cgrates/rpcclient" ) // DiameterAgentCfg the config section that describes the Diameter Agent @@ -62,8 +63,9 @@ func (da *DiameterAgentCfg) loadFromJSONCfg(jsnCfg *DiameterAgentJsonCfg, separa 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) + if attrConn == utils.MetaInternal || + attrConn == rpcclient.BiRPCInternal { + da.SessionSConns[idx] = utils.ConcatenatedKey(attrConn, utils.MetaSessionS) } } } @@ -146,6 +148,8 @@ func (da *DiameterAgentCfg) AsMapInterface(separator string) (initialMP map[stri sessionSConns[i] = item if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS) { sessionSConns[i] = utils.MetaInternal + } else if item == utils.ConcatenatedKey(rpcclient.BiRPCInternal, utils.MetaSessionS) { + sessionSConns[i] = rpcclient.BiRPCInternal } } initialMP[utils.SessionSConnsCfg] = sessionSConns diff --git a/config/diametercfg_test.go b/config/diametercfg_test.go index d53909795..5445d256d 100644 --- a/config/diametercfg_test.go +++ b/config/diametercfg_test.go @@ -23,6 +23,7 @@ import ( "testing" "github.com/cgrates/cgrates/utils" + "github.com/cgrates/rpcclient" ) func TestDiameterAgentCfgloadFromJsonCfg(t *testing.T) { @@ -123,7 +124,7 @@ func TestDiameterAgentCfgAsMapInterface(t *testing.T) { "enabled": false, "listen": "127.0.0.1:3868", "dictionaries_path": "/usr/share/cgrates/diameter/dict/", - "sessions_conns": ["*internal:*sessions", "*conn1"], + "sessions_conns": ["*birpc_internal","*internal", "*conn1"], "origin_host": "CGR-DA", "origin_realm": "cgrates.org", "vendor_id": 0, @@ -157,7 +158,7 @@ func TestDiameterAgentCfgAsMapInterface(t *testing.T) { utils.OriginRealmCfg: "cgrates.org", utils.ProductNameCfg: "CGRateS", utils.RARTemplateCfg: "", - utils.SessionSConnsCfg: []string{utils.MetaInternal, "*conn1"}, + utils.SessionSConnsCfg: []string{rpcclient.BiRPCInternal, utils.MetaInternal, "*conn1"}, utils.SyncedConnReqsCfg: true, utils.VendorIDCfg: 0, utils.RequestProcessorsCfg: []map[string]interface{}{ @@ -220,7 +221,7 @@ func TestDiameterAgentCfgAsMapInterface1(t *testing.T) { utils.OriginRealmCfg: "cgrates.org", utils.ProductNameCfg: "CGRateS", utils.RARTemplateCfg: "", - utils.SessionSConnsCfg: []string{"*internal"}, + utils.SessionSConnsCfg: []string{rpcclient.BiRPCInternal}, utils.SyncedConnReqsCfg: false, utils.VendorIDCfg: 0, utils.RequestProcessorsCfg: []map[string]interface{}{}, diff --git a/config/httpagntcfg.go b/config/httpagntcfg.go index 7200c452d..e48a68a91 100644 --- a/config/httpagntcfg.go +++ b/config/httpagntcfg.go @@ -20,6 +20,7 @@ package config import ( "github.com/cgrates/cgrates/utils" + "github.com/cgrates/rpcclient" ) // HTTPAgentCfgs the config section for HTTP Agent @@ -123,10 +124,10 @@ func (ha *HTTPAgentCfg) loadFromJSONCfg(jsnCfg *HttpAgentJsonCfg, separator stri 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 { - ha.SessionSConns[idx] = utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS) - } else { - ha.SessionSConns[idx] = connID + ha.SessionSConns[idx] = connID + if connID == utils.MetaInternal || + connID == rpcclient.BiRPCInternal { + ha.SessionSConns[idx] = utils.ConcatenatedKey(connID, utils.MetaSessionS) } } } @@ -157,6 +158,8 @@ func (ha *HTTPAgentCfg) AsMapInterface(separator string) (initialMP map[string]i sessionSConns[i] = item if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS) { sessionSConns[i] = utils.MetaInternal + } else if item == utils.ConcatenatedKey(rpcclient.BiRPCInternal, utils.MetaSessionS) { + sessionSConns[i] = rpcclient.BiRPCInternal } } initialMP[utils.SessionSConnsCfg] = sessionSConns diff --git a/config/httpagntcfg_test.go b/config/httpagntcfg_test.go index c03e01b0d..ad713cfb1 100644 --- a/config/httpagntcfg_test.go +++ b/config/httpagntcfg_test.go @@ -23,6 +23,7 @@ import ( "time" "github.com/cgrates/cgrates/utils" + "github.com/cgrates/rpcclient" ) func TestHttpAgentCfgsloadFromJsonCfgCase1(t *testing.T) { @@ -496,7 +497,7 @@ func TestHttpAgentCfgAsMapInterface(t *testing.T) { { "id": "conecto1", "url": "/conecto", - "sessions_conns": ["*localhost","*internal"], + "sessions_conns": ["*birpc_internal", "*localhost","*internal"], "request_payload": "*url", "reply_payload": "*xml", "request_processors": [ @@ -528,7 +529,7 @@ func TestHttpAgentCfgAsMapInterface(t *testing.T) { { utils.IDCfg: "conecto1", utils.URLCfg: "/conecto", - utils.SessionSConnsCfg: []string{"*localhost", "*internal"}, + utils.SessionSConnsCfg: []string{rpcclient.BiRPCInternal, "*localhost", "*internal"}, utils.RequestPayloadCfg: "*url", utils.ReplyPayloadCfg: "*xml", utils.RequestProcessorsCfg: []map[string]interface{}{ diff --git a/config/kamagentcfg.go b/config/kamagentcfg.go index 1b34644a6..e1f7ab2d6 100644 --- a/config/kamagentcfg.go +++ b/config/kamagentcfg.go @@ -20,6 +20,7 @@ package config import ( "github.com/cgrates/cgrates/utils" + "github.com/cgrates/rpcclient" ) // NewDfltKamConnConfig returns the first cached default value for a KamConnCfg connection @@ -93,8 +94,9 @@ func (ka *KamAgentCfg) loadFromJSONCfg(jsnCfg *KamAgentJsonCfg) error { 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) + if attrConn == utils.MetaInternal || + attrConn == rpcclient.BiRPCInternal { + ka.SessionSConns[idx] = utils.ConcatenatedKey(attrConn, utils.MetaSessionS) } } } @@ -134,6 +136,8 @@ func (ka *KamAgentCfg) AsMapInterface() (initialMP map[string]interface{}) { sessionSConns[i] = item if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS) { sessionSConns[i] = utils.MetaInternal + } else if item == utils.ConcatenatedKey(rpcclient.BiRPCInternal, utils.MetaSessionS) { + sessionSConns[i] = rpcclient.BiRPCInternal } } initialMP[utils.SessionSConnsCfg] = sessionSConns diff --git a/config/kamagentcfg_test.go b/config/kamagentcfg_test.go index 11a4798f4..485090d1a 100644 --- a/config/kamagentcfg_test.go +++ b/config/kamagentcfg_test.go @@ -22,6 +22,7 @@ import ( "testing" "github.com/cgrates/cgrates/utils" + "github.com/cgrates/rpcclient" ) func TestKamAgentCfgloadFromJsonCfg(t *testing.T) { @@ -83,7 +84,7 @@ func TestKamConnCfgloadFromJsonCfg(t *testing.T) { func TestKamAgentCfgAsMapInterface(t *testing.T) { cfgJSONStr := `{ "kamailio_agent": { - "sessions_conns": ["*conn1","*conn2"], + "sessions_conns": ["*birpc_internal", "*conn1","*conn2"], "create_cdr": true, "timezone": "UTC", "evapi_conns":[ @@ -93,7 +94,7 @@ func TestKamAgentCfgAsMapInterface(t *testing.T) { }` eMap := map[string]interface{}{ utils.EnabledCfg: false, - utils.SessionSConnsCfg: []string{"*conn1", "*conn2"}, + utils.SessionSConnsCfg: []string{rpcclient.BiRPCInternal, "*conn1", "*conn2"}, utils.CreateCdrCfg: true, utils.TimezoneCfg: "UTC", utils.EvapiConnsCfg: []map[string]interface{}{ @@ -113,7 +114,7 @@ func TestKamAgentCfgAsMapInterface1(t *testing.T) { }` eMap := map[string]interface{}{ utils.EnabledCfg: false, - utils.SessionSConnsCfg: []string{"*internal"}, + utils.SessionSConnsCfg: []string{rpcclient.BiRPCInternal}, utils.CreateCdrCfg: false, utils.TimezoneCfg: "", utils.EvapiConnsCfg: []map[string]interface{}{ diff --git a/config/radiuscfg_test.go b/config/radiuscfg_test.go index ed6895846..eb394d160 100644 --- a/config/radiuscfg_test.go +++ b/config/radiuscfg_test.go @@ -23,6 +23,7 @@ import ( "time" "github.com/cgrates/cgrates/utils" + "github.com/cgrates/rpcclient" ) func TestRadiusAgentCfgloadFromJsonCfgCase1(t *testing.T) { @@ -154,7 +155,7 @@ func TestRadiusAgentCfgAsMapInterface(t *testing.T) { "client_dictionaries": { "*default": "/usr/share/cgrates/", }, - "sessions_conns": ["*conn1","*conn2"], + "sessions_conns": ["*birpc_internal", "*conn1","*conn2"], "request_processors": [ { "id": "OutboundAUTHDryRun", @@ -180,7 +181,7 @@ func TestRadiusAgentCfgAsMapInterface(t *testing.T) { utils.ClientDictionariesCfg: map[string]string{ utils.MetaDefault: "/usr/share/cgrates/", }, - utils.SessionSConnsCfg: []string{"*conn1", "*conn2"}, + utils.SessionSConnsCfg: []string{rpcclient.BiRPCInternal, "*conn1", "*conn2"}, utils.RequestProcessorsCfg: []map[string]interface{}{ { utils.IDCfg: "OutboundAUTHDryRun", diff --git a/config/rjreader_test.go b/config/rjreader_test.go index b8ef0c3a6..322c6c0ca 100644 --- a/config/rjreader_test.go +++ b/config/rjreader_test.go @@ -485,7 +485,7 @@ func TestGetJSONOffsetLineFuncError(t *testing.T) { rjr.indx = 7 var eLine, eCharacter int64 = 1, 0 if line, character := rjr.getJSONOffsetLine(int64(3)); line != eLine && character != eCharacter { - fmt.Printf("Expected %+v and %+v, received %+v and %+v", eLine, eCharacter, line, character) + t.Errorf("Expected %+v and %+v, received %+v and %+v", eLine, eCharacter, line, character) } } @@ -494,7 +494,7 @@ func TestGetJSONOffsetLineReadStringEOF(t *testing.T) { rjr.indx = 3 var eLine, eCharacter int64 = 1, 0 if line, character := rjr.getJSONOffsetLine(int64(5)); line != eLine && character != eCharacter { - fmt.Printf("Expected %+v and %+v, received %+v and %+v", eLine, eCharacter, line, character) + t.Errorf("Expected %+v and %+v, received %+v and %+v", eLine, eCharacter, line, character) } } @@ -503,7 +503,7 @@ func TestGetJSONOffsetLineReadString1(t *testing.T) { rjr.indx = 0 var eLine, eCharacter int64 = 1, 0 if line, character := rjr.getJSONOffsetLine(int64(5)); line != eLine && character != eCharacter { - fmt.Printf("Expected %+v and %+v, received %+v and %+v", eLine, eCharacter, line, character) + t.Errorf("Expected %+v and %+v, received %+v and %+v", eLine, eCharacter, line, character) } } @@ -514,7 +514,7 @@ func TestGetJSONOffsetLineReadStringNilError(t *testing.T) { rjr.indx = 0 var eLine, eCharacter int64 = 1, 0 if line, character := rjr.getJSONOffsetLine(int64(3)); line != eLine && character != eCharacter { - fmt.Printf("Expected %+v and %+v, received %+v and %+v", eLine, eCharacter, line, character) + t.Errorf("Expected %+v and %+v, received %+v and %+v", eLine, eCharacter, line, character) } } @@ -523,7 +523,7 @@ func TestGetJSONOffsetLineReadLineCommentEOFInvalid(t *testing.T) { rjr.indx = 6 var eLine, eCharacter int64 = 1, 0 if line, character := rjr.getJSONOffsetLine(int64(5)); line != eLine && character != eCharacter { - fmt.Printf("Expected %+v and %+v, received %+v and %+v", eLine, eCharacter, line, character) + t.Errorf("Expected %+v and %+v, received %+v and %+v", eLine, eCharacter, line, character) } } @@ -532,7 +532,7 @@ func TestGetJSONOffsetLineReadLineCommentEOF1(t *testing.T) { rjr.indx = 6 var eLine, eCharacter int64 = 1, 0 if line, character := rjr.getJSONOffsetLine(int64(5)); line != eLine && character != eCharacter { - fmt.Printf("Expected %+v and %+v, received %+v and %+v", eLine, eCharacter, line, character) + t.Errorf("Expected %+v and %+v, received %+v and %+v", eLine, eCharacter, line, character) } } @@ -541,7 +541,7 @@ func TestGetJSONOffsetLineReadCommentEOF(t *testing.T) { rjr.indx = 5 var eLine, eCharacter int64 = 1, 0 if line, character := rjr.getJSONOffsetLine(int64(5)); line != eLine && character != eCharacter { - fmt.Printf("Expected %+v and %+v, received %+v and %+v", eLine, eCharacter, line, character) + t.Errorf("Expected %+v and %+v, received %+v and %+v", eLine, eCharacter, line, character) } } @@ -552,7 +552,7 @@ func TestGetJSONOffsetLineReadCommentInvalidEnding(t *testing.T) { rjr.indx = 5 var eLine, eCharacter int64 = 3, 2 if line, character := rjr.getJSONOffsetLine(int64(5)); line != eLine && character != eCharacter { - fmt.Printf("Expected %+v and %+v, received %+v and %+v", eLine, eCharacter, line, character) + t.Errorf("Expected %+v and %+v, received %+v and %+v", eLine, eCharacter, line, character) } } @@ -562,7 +562,7 @@ func TestGetJSONOffsetLineReadComment(t *testing.T) { rjr.indx = 0 var eLine, eCharacter int64 = 3, 2 if line, character := rjr.getJSONOffsetLine(int64(5)); line != eLine && character != eCharacter { - fmt.Printf("Expected %+v and %+v, received %+v and %+v", eLine, eCharacter, line, character) + t.Errorf("Expected %+v and %+v, received %+v and %+v", eLine, eCharacter, line, character) } } @@ -571,7 +571,7 @@ func TestGetJSONOffsetLineInvalidComment(t *testing.T) { rjr.indx = 0 var eLine, eCharacter int64 = 1, 5 if line, character := rjr.getJSONOffsetLine(int64(5)); line != eLine && character != eCharacter { - fmt.Printf("Expected %+v and %+v, received %+v and %+v", eLine, eCharacter, line, character) + t.Errorf("Expected %+v and %+v, received %+v and %+v", eLine, eCharacter, line, character) } } @@ -580,7 +580,7 @@ func TestGetJSONOffsetLineReadCommentOffset(t *testing.T) { rjr.indx = 0 var eLine, eCharacter int64 = 1, 5 if line, character := rjr.getJSONOffsetLine(int64(3)); line != eLine && character != eCharacter { - fmt.Printf("Expected %+v and %+v, received %+v and %+v", eLine, eCharacter, line, character) + t.Errorf("Expected %+v and %+v, received %+v and %+v", eLine, eCharacter, line, character) } } diff --git a/config/rpcconn_test.go b/config/rpcconn_test.go index 14c7ceaf7..8cc377207 100644 --- a/config/rpcconn_test.go +++ b/config/rpcconn_test.go @@ -23,6 +23,7 @@ import ( "testing" "github.com/cgrates/cgrates/utils" + "github.com/cgrates/rpcclient" ) func TestRPCConnsloadFromJsonCfgCase1(t *testing.T) { @@ -51,6 +52,18 @@ func TestRPCConnsloadFromJsonCfgCase1(t *testing.T) { }, }, }, + rpcclient.BiRPCInternal: { + Strategy: utils.MetaFirst, + PoolSize: 0, + Conns: []*RemoteHost{ + { + Address: rpcclient.BiRPCInternal, + Transport: utils.EmptyString, + Synchronous: false, + TLS: false, + }, + }, + }, utils.MetaLocalHost: { Strategy: utils.MetaFirst, PoolSize: 1, @@ -87,6 +100,18 @@ func TestRPCConnsloadFromJsonCfgCase2(t *testing.T) { }, }, }, + rpcclient.BiRPCInternal: { + Strategy: utils.MetaFirst, + PoolSize: 0, + Conns: []*RemoteHost{ + { + Address: rpcclient.BiRPCInternal, + Transport: utils.EmptyString, + Synchronous: false, + TLS: false, + }, + }, + }, utils.MetaLocalHost: { Strategy: utils.MetaFirst, PoolSize: 0, @@ -140,6 +165,18 @@ func TestRPCConnsAsMapInterface(t *testing.T) { }, }, }, + rpcclient.BiRPCInternal: map[string]interface{}{ + utils.StrategyCfg: utils.MetaFirst, + utils.PoolSize: 0, + utils.Conns: []map[string]interface{}{ + { + utils.AddressCfg: rpcclient.BiRPCInternal, + utils.TransportCfg: utils.EmptyString, + utils.SynchronousCfg: false, + utils.TLS: false, + }, + }, + }, } if cgrCfg, err := NewCGRConfigFromJSONStringWithDefaults(cfgJSONStr); err != nil { t.Error(err) @@ -172,6 +209,18 @@ func TestRpcConnAsMapInterface1(t *testing.T) { utils.PoolSize: 0, utils.StrategyCfg: utils.MetaFirst, }, + rpcclient.BiRPCInternal: map[string]interface{}{ + utils.Conns: []map[string]interface{}{ + { + utils.TLS: false, + utils.AddressCfg: rpcclient.BiRPCInternal, + utils.SynchronousCfg: false, + utils.TransportCfg: utils.EmptyString, + }, + }, + utils.PoolSize: 0, + utils.StrategyCfg: utils.MetaFirst, + }, utils.MetaLocalHost: map[string]interface{}{ utils.Conns: []map[string]interface{}{ { diff --git a/config/sessionscfg.go b/config/sessionscfg.go index b322af0e4..8ea4e2a07 100644 --- a/config/sessionscfg.go +++ b/config/sessionscfg.go @@ -24,6 +24,7 @@ import ( "time" "github.com/cgrates/cgrates/utils" + "github.com/cgrates/rpcclient" ) // NewDfltFsConnConfig returns the first cached default value for a FreeSWITCHAgent connection @@ -572,8 +573,9 @@ func (fscfg *FsAgentCfg) loadFromJSONCfg(jsnCfg *FreeswitchAgentJsonCfg) error { 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) + if connID == utils.MetaInternal || + connID == rpcclient.BiRPCInternal { + fscfg.SessionSConns[idx] = utils.ConcatenatedKey(connID, utils.MetaSessionS) } } } @@ -629,6 +631,8 @@ func (fscfg *FsAgentCfg) AsMapInterface(separator string) (initialMP map[string] sessionSConns[i] = item if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS) { sessionSConns[i] = utils.MetaInternal + } else if item == utils.ConcatenatedKey(rpcclient.BiRPCInternal, utils.MetaSessionS) { + sessionSConns[i] = rpcclient.BiRPCInternal } } initialMP[utils.SessionSConnsCfg] = sessionSConns @@ -767,8 +771,9 @@ func (aCfg *AsteriskAgentCfg) loadFromJSONCfg(jsnCfg *AsteriskAgentJsonCfg) (err 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) + if attrConn == utils.MetaInternal || + attrConn == rpcclient.BiRPCInternal { + aCfg.SessionSConns[idx] = utils.ConcatenatedKey(attrConn, utils.MetaSessionS) } } } @@ -805,6 +810,8 @@ func (aCfg *AsteriskAgentCfg) AsMapInterface() (initialMP map[string]interface{} sessionSConns[i] = item if item == utils.ConcatenatedKey(utils.MetaInternal, utils.MetaSessionS) { sessionSConns[i] = utils.MetaInternal + } else if item == utils.ConcatenatedKey(rpcclient.BiRPCInternal, utils.MetaSessionS) { + sessionSConns[i] = rpcclient.BiRPCInternal } } initialMP[utils.SessionSConnsCfg] = sessionSConns diff --git a/config/sessionscfg_test.go b/config/sessionscfg_test.go index 148832ad5..34ca2cab5 100644 --- a/config/sessionscfg_test.go +++ b/config/sessionscfg_test.go @@ -24,6 +24,7 @@ import ( "time" "github.com/cgrates/cgrates/utils" + "github.com/cgrates/rpcclient" ) func TestFsAgentCfgloadFromJsonCfg1(t *testing.T) { @@ -530,7 +531,7 @@ func TestFsAgentCfgAsMapInterfaceCase1(t *testing.T) { }` eMap := map[string]interface{}{ utils.EnabledCfg: false, - utils.SessionSConnsCfg: []string{"*internal"}, + utils.SessionSConnsCfg: []string{rpcclient.BiRPCInternal}, utils.SubscribeParkCfg: true, utils.CreateCdrCfg: false, utils.ExtraFieldsCfg: "", @@ -553,7 +554,7 @@ func TestFsAgentCfgAsMapInterfaceCase2(t *testing.T) { cfgJSONStr := `{ "freeswitch_agent": { "enabled": true, - "sessions_conns": ["*conn1","*conn2"], + "sessions_conns": ["*birpc_internal", "*conn1","*conn2"], "subscribe_park": false, "create_cdr": true, "max_wait_connection": "7s", @@ -563,7 +564,7 @@ func TestFsAgentCfgAsMapInterfaceCase2(t *testing.T) { }` eMap := map[string]interface{}{ utils.EnabledCfg: true, - utils.SessionSConnsCfg: []string{"*conn1", "*conn2"}, + utils.SessionSConnsCfg: []string{rpcclient.BiRPCInternal, "*conn1", "*conn2"}, utils.SubscribeParkCfg: false, utils.CreateCdrCfg: true, utils.ExtraFieldsCfg: "", @@ -591,7 +592,7 @@ func TestFsAgentCfgAsMapInterfaceCase3(t *testing.T) { }` eMap := map[string]interface{}{ utils.EnabledCfg: false, - utils.SessionSConnsCfg: []string{"*internal"}, + utils.SessionSConnsCfg: []string{rpcclient.BiRPCInternal}, utils.SubscribeParkCfg: true, utils.CreateCdrCfg: false, utils.ExtraFieldsCfg: "randomFields", @@ -709,7 +710,7 @@ func TestAsteriskAgentCfgAsMapInterface(t *testing.T) { }` eMap := map[string]interface{}{ utils.EnabledCfg: false, - utils.SessionSConnsCfg: []string{"*internal"}, + utils.SessionSConnsCfg: []string{rpcclient.BiRPCInternal}, utils.CreateCdrCfg: false, utils.AsteriskConnsCfg: []map[string]interface{}{ {utils.AliasCfg: "", utils.AddressCfg: "127.0.0.1:8088", utils.UserCf: "cgrates", utils.Password: "CGRateS.org", utils.ConnectAttemptsCfg: 3, utils.ReconnectsCfg: 5}, @@ -726,7 +727,7 @@ func TestAsteriskAgentCfgAsMapInterface1(t *testing.T) { cfgJSONStr := `{ "asterisk_agent": { "enabled": true, - "sessions_conns": ["*conn1","*conn2"], + "sessions_conns": ["*birpc_internal", "*conn1","*conn2"], "create_cdr": true, "asterisk_conns":[ {"address": "127.0.0.1:8089","connect_attempts": 5,"reconnects": 8} @@ -735,7 +736,7 @@ func TestAsteriskAgentCfgAsMapInterface1(t *testing.T) { }` eMap := map[string]interface{}{ utils.EnabledCfg: true, - utils.SessionSConnsCfg: []string{"*conn1", "*conn2"}, + utils.SessionSConnsCfg: []string{rpcclient.BiRPCInternal, "*conn1", "*conn2"}, utils.CreateCdrCfg: true, utils.AsteriskConnsCfg: []map[string]interface{}{ {utils.AliasCfg: "", utils.AddressCfg: "127.0.0.1:8089", utils.UserCf: "cgrates", utils.Password: "CGRateS.org", utils.ConnectAttemptsCfg: 5, utils.ReconnectsCfg: 8}, diff --git a/data/conf/samples/diam_tutmysql/cgrates.json b/data/conf/samples/diam_tutmysql/cgrates.json index 42c982929..4d752ff12 100644 --- a/data/conf/samples/diam_tutmysql/cgrates.json +++ b/data/conf/samples/diam_tutmysql/cgrates.json @@ -79,7 +79,7 @@ "diameter_agent": { "enabled": true, "listen": ":3868", - "sessions_conns": ["*internal"], + "sessions_conns": ["*birpc_internal"], }, diff --git a/data/conf/samples/diamsctpagent_internal/cgrates.json b/data/conf/samples/diamsctpagent_internal/cgrates.json index fde270907..fe70facb5 100755 --- a/data/conf/samples/diamsctpagent_internal/cgrates.json +++ b/data/conf/samples/diamsctpagent_internal/cgrates.json @@ -59,7 +59,7 @@ "enabled": true, "listen_net":"sctp", "listen": "127.0.0.1:3869", // address where to listen for diameter requests - "sessions_conns": ["*internal"], + "sessions_conns": ["*birpc_internal"], "rar_template": "*rar", }, diff --git a/data/conf/samples/diamsctpagent_mongo/cgrates.json b/data/conf/samples/diamsctpagent_mongo/cgrates.json index da9cbcb59..f1bdbe0b2 100755 --- a/data/conf/samples/diamsctpagent_mongo/cgrates.json +++ b/data/conf/samples/diamsctpagent_mongo/cgrates.json @@ -63,7 +63,7 @@ "enabled": true, "listen_net":"sctp", "listen": "127.0.0.1:3869", // address where to listen for diameter requests - "sessions_conns": ["*internal"], + "sessions_conns": ["*birpc_internal"], "rar_template": "*rar", }, diff --git a/data/conf/samples/diamsctpagent_mysql/cgrates.json b/data/conf/samples/diamsctpagent_mysql/cgrates.json index 3a8050af5..80ad6529c 100755 --- a/data/conf/samples/diamsctpagent_mysql/cgrates.json +++ b/data/conf/samples/diamsctpagent_mysql/cgrates.json @@ -59,7 +59,7 @@ "enabled": true, "listen_net":"sctp", "listen": "127.0.0.1:3869", // address where to listen for diameter requests - "sessions_conns": ["*internal"], + "sessions_conns": ["*birpc_internal"], "rar_template": "*rar", }, diff --git a/data/tutorial_tests/asterisk_ari/cgrates/etc/cgrates/cgrates.json b/data/tutorial_tests/asterisk_ari/cgrates/etc/cgrates/cgrates.json index 754fa89fd..04384149c 100644 --- a/data/tutorial_tests/asterisk_ari/cgrates/etc/cgrates/cgrates.json +++ b/data/tutorial_tests/asterisk_ari/cgrates/etc/cgrates/cgrates.json @@ -70,7 +70,7 @@ {"address": "127.0.0.1:8088", "user": "cgrates", "password": "CGRateS.org", "connect_attempts": 3,"reconnects": 10} ], - "sessions_conns": ["*internal"], + "sessions_conns": ["*birpc_internal"], "create_cdr": true, }, diff --git a/data/tutorial_tests/fs_evsock/cgrates/etc/cgrates/cgrates.json b/data/tutorial_tests/fs_evsock/cgrates/etc/cgrates/cgrates.json index c8b242a18..0a39d7331 100644 --- a/data/tutorial_tests/fs_evsock/cgrates/etc/cgrates/cgrates.json +++ b/data/tutorial_tests/fs_evsock/cgrates/etc/cgrates/cgrates.json @@ -68,7 +68,7 @@ "event_socket_conns":[ {"address": "127.0.0.1:8021", "password": "ClueCon", "reconnects": -1,"alias":""} ], - "sessions_conns": ["*internal"], + "sessions_conns": ["*birpc_internal"], "create_cdr": true }, diff --git a/data/tutorial_tests/kamevapi/cgrates/etc/cgrates/cgrates.json b/data/tutorial_tests/kamevapi/cgrates/etc/cgrates/cgrates.json index 63bf5737a..ce4cc333e 100644 --- a/data/tutorial_tests/kamevapi/cgrates/etc/cgrates/cgrates.json +++ b/data/tutorial_tests/kamevapi/cgrates/etc/cgrates/cgrates.json @@ -69,7 +69,7 @@ "evapi_conns":[ {"address": "127.0.0.1:8448", "reconnects": 5} ], - "sessions_conns": ["*internal"], + "sessions_conns": ["*birpc_internal"], "create_cdr": true, }, diff --git a/data/tutorials/asterisk_ari/cgrates/etc/cgrates/cgrates.json b/data/tutorials/asterisk_ari/cgrates/etc/cgrates/cgrates.json index 4ca7c50c8..5c0214ea4 100644 --- a/data/tutorials/asterisk_ari/cgrates/etc/cgrates/cgrates.json +++ b/data/tutorials/asterisk_ari/cgrates/etc/cgrates/cgrates.json @@ -69,7 +69,7 @@ {"address": "127.0.0.1:8088", "user": "cgrates", "password": "CGRateS.org", "connect_attempts": 3,"reconnects": 10} ], - "sessions_conns": ["*internal"], + "sessions_conns": ["*birpc_internal"], "create_cdr": true, }, diff --git a/data/tutorials/fs_evsock/cgrates/etc/cgrates/cgrates.json b/data/tutorials/fs_evsock/cgrates/etc/cgrates/cgrates.json index c8b242a18..0a39d7331 100644 --- a/data/tutorials/fs_evsock/cgrates/etc/cgrates/cgrates.json +++ b/data/tutorials/fs_evsock/cgrates/etc/cgrates/cgrates.json @@ -68,7 +68,7 @@ "event_socket_conns":[ {"address": "127.0.0.1:8021", "password": "ClueCon", "reconnects": -1,"alias":""} ], - "sessions_conns": ["*internal"], + "sessions_conns": ["*birpc_internal"], "create_cdr": true }, diff --git a/data/tutorials/kamevapi/cgrates/etc/cgrates/cgrates.json b/data/tutorials/kamevapi/cgrates/etc/cgrates/cgrates.json index 54ee74836..577bb8d1f 100644 --- a/data/tutorials/kamevapi/cgrates/etc/cgrates/cgrates.json +++ b/data/tutorials/kamevapi/cgrates/etc/cgrates/cgrates.json @@ -69,7 +69,7 @@ "evapi_conns":[ {"address": "127.0.0.1:8448", "reconnects": 5} ], - "sessions_conns": ["*internal"], + "sessions_conns": ["*birpc_internal"], "create_cdr": true, }, diff --git a/engine/connmanager.go b/engine/connmanager.go index 63d6b3f54..c54762072 100644 --- a/engine/connmanager.go +++ b/engine/connmanager.go @@ -20,6 +20,7 @@ package engine import ( "fmt" + "strings" "github.com/cgrates/cgrates/config" "github.com/cgrates/cgrates/utils" @@ -52,8 +53,13 @@ func (cM *ConnManager) getConn(connID string, biRPCClient rpcclient.BiRPCConecto // in case we don't find in cache create the connection and add this in cache var intChan chan rpcclient.ClientConnector var isInternalRPC bool - connCfg := cM.cfg.RPCConns()[utils.MetaInternal] - if intChan, isInternalRPC = cM.rpcInternal[connID]; !isInternalRPC { + var connCfg *config.RPCConn + if intChan, isInternalRPC = cM.rpcInternal[connID]; isInternalRPC { + connCfg = cM.cfg.RPCConns()[rpcclient.InternalRPC] + if strings.HasPrefix(connID, rpcclient.BiRPCInternal) { + connCfg = cM.cfg.RPCConns()[rpcclient.BiRPCInternal] + } + } else { connCfg = cM.cfg.RPCConns()[connID] for _, rpcConn := range connCfg.Conns { if rpcConn.Address == utils.MetaInternal { @@ -62,23 +68,7 @@ func (cM *ConnManager) getConn(connID string, biRPCClient rpcclient.BiRPCConecto } } } - switch { - case biRPCClient != nil && isInternalRPC: // special handling for SessionS BiJSONRPCClient - if conn, err = rpcclient.NewRPCClient(utils.EmptyString, utils.EmptyString, false, - utils.EmptyString, utils.EmptyString, utils.EmptyString, - cM.cfg.GeneralCfg().ConnectAttempts, cM.cfg.GeneralCfg().Reconnects, - cM.cfg.GeneralCfg().ConnectTimeout, cM.cfg.GeneralCfg().ReplyTimeout, - rpcclient.BiRPCInternal, intChan, false, biRPCClient); err != nil { - return - } - var rply string - if err = conn.Call(utils.SessionSv1RegisterInternalBiJSONConn, - utils.EmptyString, &rply); err != nil { - utils.Logger.Crit(fmt.Sprintf("<%s> Could not register biRPCClient, error: <%s>", - utils.SessionS, err.Error())) - return - } - case connCfg.Strategy == rpcclient.PoolParallel: + if connCfg.Strategy == rpcclient.PoolParallel { rpcConnCfg := connCfg.Conns[0] // for parrallel we need only the first connection codec := rpcclient.GOBrpc switch { @@ -105,7 +95,7 @@ func (cM *ConnManager) getConn(connID string, biRPCClient rpcclient.BiRPCConecto cM.cfg.GeneralCfg().ReplyTimeout, codec, intChan, int64(cM.cfg.GeneralCfg().MaxParallelConns), false, biRPCClient); err != nil { return } - default: + } else { if conn, err = NewRPCPool(connCfg.Strategy, cM.cfg.TLSCfg().ClientKey, cM.cfg.TLSCfg().ClientCerificate, cM.cfg.TLSCfg().CaCertificate, @@ -115,6 +105,22 @@ func (cM *ConnManager) getConn(connID string, biRPCClient rpcclient.BiRPCConecto return } } + if biRPCClient != nil { + for _, c := range connCfg.Conns { + if c.Transport == rpcclient.BiRPCGOB || + c.Transport == rpcclient.BiRPCJSON || + c.Address == rpcclient.BiRPCInternal { + var rply string + if err = conn.Call(utils.SessionSv1RegisterInternalBiJSONConn, + connID, &rply); err != nil { + utils.Logger.Crit(fmt.Sprintf("<%s> Could not register biRPCClient, error: <%s>", + utils.SessionS, err.Error())) + return + } + break + } + } + } if err = Cache.Set(utils.CacheRPCConnections, connID, conn, nil, true, utils.NonTransactional); err != nil { diff --git a/go.mod b/go.mod index 5bda91a78..277c5e608 100644 --- a/go.mod +++ b/go.mod @@ -14,9 +14,7 @@ require ( github.com/antchfx/xpath v1.1.11 // indirect github.com/aws/aws-sdk-go v1.36.24 github.com/blevesearch/bleve v1.0.14 - github.com/cenk/hub v1.0.1 // indirect - github.com/cenkalti/hub v1.0.1 // indirect - github.com/cenkalti/rpc2 v0.0.0-20210206021708-de76ddb08fa8 + github.com/cenkalti/rpc2 v0.0.0-20210220005819-4a29bc83afe1 github.com/cgrates/aringo v0.0.0-20201113143849-3b299e4e636d github.com/cgrates/baningo v0.0.0-20201105145354-6e3173f6a91b github.com/cgrates/cron v0.0.0-20201022095836-3522d5b72c70 @@ -24,7 +22,7 @@ require ( github.com/cgrates/kamevapi v0.0.0-20191001125829-7dbc3ad58817 github.com/cgrates/ltcache v0.0.0-20181016092649-92fb7fa77cca github.com/cgrates/radigo v0.0.0-20201113143731-162035428d72 - github.com/cgrates/rpcclient v0.0.0-20201120095908-1c0f9f4bb06e + github.com/cgrates/rpcclient v0.0.0-00010101000000-000000000000 github.com/cgrates/sipingo v1.0.1-0.20200514112313-699ebc1cdb8e github.com/cgrates/ugocodec v0.0.0-20201023092048-df93d0123f60 github.com/creack/pty v1.1.11 diff --git a/go.sum b/go.sum index 8298529c8..3cf7e7a27 100644 --- a/go.sum +++ b/go.sum @@ -82,10 +82,12 @@ github.com/cenk/hub v1.0.1 h1:RBwXNOF4a8KjD8BJ08XqN8KbrqaGiQLDrgvUGJSHuPA= github.com/cenk/hub v1.0.1/go.mod h1:rJM1LNAW0ppT8FMMuPK6c2NP/R2nH/UthtuRySSaf6Y= github.com/cenkalti/hub v1.0.1 h1:UMtjc6dHSaOQTO15SVA50MBIR9zQwvsukQupDrkIRtg= github.com/cenkalti/hub v1.0.1/go.mod h1:tcYwtS3a2d9NO/0xDXVJWx3IedurUjYCqFCmpi0lpHs= -github.com/cenkalti/rpc2 v0.0.0-20201118113917-be2cde9a479f h1:A4x+jqy1uTFFQTb6o9oyRmRPHPciBacoDYzALCNyIs0= -github.com/cenkalti/rpc2 v0.0.0-20201118113917-be2cde9a479f/go.mod h1:v2npkhrXyk5BCnkNIiPdRI23Uq6uWPUQGL2hnRcRr/M= +github.com/cenkalti/rpc2 v0.0.0-20210117202628-1bea588996c7 h1:FzmeDLoHQVNEXiH4MY6YtGu+l3oC6D70I2IVFDsNMTQ= +github.com/cenkalti/rpc2 v0.0.0-20210117202628-1bea588996c7/go.mod h1:v2npkhrXyk5BCnkNIiPdRI23Uq6uWPUQGL2hnRcRr/M= github.com/cenkalti/rpc2 v0.0.0-20210206021708-de76ddb08fa8 h1:p9C5lr3/fgr78scg68qXzJ781JPSOPrqNxNQY29MZmA= github.com/cenkalti/rpc2 v0.0.0-20210206021708-de76ddb08fa8/go.mod h1:v2npkhrXyk5BCnkNIiPdRI23Uq6uWPUQGL2hnRcRr/M= +github.com/cenkalti/rpc2 v0.0.0-20210220005819-4a29bc83afe1 h1:aT9Ez2drLmrviqTnVnH87AeXLXLgUrXACJ2g90cTT2w= +github.com/cenkalti/rpc2 v0.0.0-20210220005819-4a29bc83afe1/go.mod h1:v2npkhrXyk5BCnkNIiPdRI23Uq6uWPUQGL2hnRcRr/M= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cgrates/aringo v0.0.0-20201113143849-3b299e4e636d h1:1PLz/t3XZy5KF8EY/ShzBZoVLaY50+tnAbE1wu8rCfg= github.com/cgrates/aringo v0.0.0-20201113143849-3b299e4e636d/go.mod h1:mMAzSIjK11XfRMrOIa7DXYl64REdPldRCbAgzKB47XQ= @@ -101,8 +103,6 @@ github.com/cgrates/ltcache v0.0.0-20181016092649-92fb7fa77cca h1:Ejj4m0Ccl8dMMVn github.com/cgrates/ltcache v0.0.0-20181016092649-92fb7fa77cca/go.mod h1:q7c996DUu8OrJRnewVSQzM+y/bRcxZAHoo+zCD8bFBo= github.com/cgrates/radigo v0.0.0-20201113143731-162035428d72 h1:cTAWQEbab3gKkDSeaxkTaoiP/cNFx+7/kC96wYckk3g= github.com/cgrates/radigo v0.0.0-20201113143731-162035428d72/go.mod h1:3IDSbfIqU5VsYKjrwa3HhuAK1jlI65wa1coHetoaN20= -github.com/cgrates/rpcclient v0.0.0-20201120095908-1c0f9f4bb06e h1:t1oSABmZYacJiB+JrJQVGFqkv+7ekgOo/Jj/KdoM5mI= -github.com/cgrates/rpcclient v0.0.0-20201120095908-1c0f9f4bb06e/go.mod h1:+QZt2Af6g8UScM5NWjAwn0CyvLjgVgkZPJyAJqQgXoQ= github.com/cgrates/sipingo v1.0.1-0.20200514112313-699ebc1cdb8e h1:izFjZB83/XRXInc+gMIssUxdbleGsGIuGCPj2u7RQo0= github.com/cgrates/sipingo v1.0.1-0.20200514112313-699ebc1cdb8e/go.mod h1:0f2+3dq5Iiv3VlcuY83VPJ0QzqRlzDG1Cr8okogQE3g= github.com/cgrates/ugocodec v0.0.0-20201023092048-df93d0123f60 h1:TQDg+HGB17LU8FitLiLvYazYSy62GQ1lO3lGKI3xUrU= diff --git a/sessions/libsessions.go b/sessions/libsessions.go index 136ff8927..bc9f356be 100644 --- a/sessions/libsessions.go +++ b/sessions/libsessions.go @@ -26,6 +26,7 @@ import ( "github.com/cgrates/cgrates/config" "github.com/cgrates/cgrates/engine" "github.com/cgrates/cgrates/utils" + "github.com/cgrates/rpcclient" jwt "github.com/dgrijalva/jwt-go" ) @@ -43,12 +44,18 @@ var authReqs = engine.MapEvent{ // BiRPClient is the interface implemented by Agents which are able to // communicate bidirectionally with SessionS and remote Communication Switch type BiRPClient interface { - Call(serviceMethod string, args interface{}, reply interface{}) error + rpcclient.BiRPCConector V1DisconnectSession(args utils.AttrDisconnectSession, reply *string) (err error) V1GetActiveSessionIDs(ignParam string, sessionIDs *[]*SessionID) (err error) V1ReAuthorize(originID string, reply *string) (err error) V1DisconnectPeer(args *utils.DPRArgs, reply *string) (err error) V1WarnDisconnect(args map[string]interface{}, reply *string) (err error) + + BiRPCv1DisconnectSession(clnt rpcclient.ClientConnector, args utils.AttrDisconnectSession, reply *string) (err error) + BiRPCv1GetActiveSessionIDs(clnt rpcclient.ClientConnector, ignParam string, sessionIDs *[]*SessionID) (err error) + BiRPCv1ReAuthorize(clnt rpcclient.ClientConnector, originID string, reply *string) (err error) + BiRPCv1DisconnectPeer(clnt rpcclient.ClientConnector, args *utils.DPRArgs, reply *string) (err error) + BiRPCv1WarnDisconnect(clnt rpcclient.ClientConnector, args map[string]interface{}, reply *string) (err error) } // GetSetCGRID will populate the CGRID key if not present and return it diff --git a/sessions/sessions.go b/sessions/sessions.go index 00e1af659..b6ebdee75 100644 --- a/sessions/sessions.go +++ b/sessions/sessions.go @@ -126,8 +126,8 @@ func (sS *SessionS) Shutdown() (err error) { // OnBiJSONConnect is called by rpc2.Client on each new connection func (sS *SessionS) OnBiJSONConnect(c *rpc2.Client) { - sS.biJMux.Lock() nodeID := utils.UUIDSha1Prefix() // connection identifier, should be later updated as login procedure + sS.biJMux.Lock() sS.biJClnts[c] = nodeID sS.biJIDs[nodeID] = &biJClient{ conn: c, @@ -146,9 +146,11 @@ func (sS *SessionS) OnBiJSONDisconnect(c *rpc2.Client) { } // RegisterIntBiJConn is called on internal BiJ connection towards SessionS -func (sS *SessionS) RegisterIntBiJConn(c rpcclient.ClientConnector) { +func (sS *SessionS) RegisterIntBiJConn(c rpcclient.ClientConnector, nodeID string) { + if nodeID == utils.EmptyString { + nodeID = sS.cgrCfg.GeneralCfg().NodeID + } sS.biJMux.Lock() - nodeID := sS.cgrCfg.GeneralCfg().NodeID sS.biJClnts[c] = nodeID sS.biJIDs[nodeID] = &biJClient{ conn: c, @@ -1685,7 +1687,7 @@ func (sS *SessionS) CallBiRPC(clnt rpcclient.ClientConnector, var clntVal reflect.Value if clnt == nil { clntVal = reflect.New( - reflect.TypeOf(new(utils.BiRPCInternalClient))).Elem() // Kinda cheat since we make up a type here + reflect.TypeOf(new(rpcclient.BiRPCInternalServer))).Elem() // Kinda cheat since we make up a type here } else { clntVal = reflect.ValueOf(clnt) } @@ -3629,8 +3631,8 @@ func (sS *SessionS) BiRPCv1ForceDisconnect(clnt rpcclient.ClientConnector, // BiRPCv1RegisterInternalBiJSONConn will register the client for a bidirectional comunication func (sS *SessionS) BiRPCv1RegisterInternalBiJSONConn(clnt rpcclient.ClientConnector, - ign string, reply *string) error { - sS.RegisterIntBiJConn(clnt) + connID string, reply *string) error { + sS.RegisterIntBiJConn(clnt, connID) *reply = utils.OK return nil } @@ -4060,3 +4062,39 @@ func (sS *SessionS) BiRPCv1STIRIdentity(clnt rpcclient.ClientConnector, } return } + +// Handlers bidirectional methods following +func (sS *SessionS) Handlers() map[string]interface{} { + return map[string]interface{}{ + utils.SessionSv1GetActiveSessions: sS.BiRPCv1GetActiveSessions, + utils.SessionSv1GetActiveSessionsCount: sS.BiRPCv1GetActiveSessionsCount, + utils.SessionSv1GetPassiveSessions: sS.BiRPCv1GetPassiveSessions, + utils.SessionSv1GetPassiveSessionsCount: sS.BiRPCv1GetPassiveSessionsCount, + + utils.SessionSv1AuthorizeEvent: sS.BiRPCv1AuthorizeEvent, + utils.SessionSv1AuthorizeEventWithDigest: sS.BiRPCv1AuthorizeEventWithDigest, + utils.SessionSv1InitiateSession: sS.BiRPCv1InitiateSession, + utils.SessionSv1InitiateSessionWithDigest: sS.BiRPCv1InitiateSessionWithDigest, + utils.SessionSv1UpdateSession: sS.BiRPCv1UpdateSession, + utils.SessionSv1SyncSessions: sS.BiRPCv1SyncSessions, + utils.SessionSv1TerminateSession: sS.BiRPCv1TerminateSession, + utils.SessionSv1ProcessCDR: sS.BiRPCv1ProcessCDR, + utils.SessionSv1ProcessMessage: sS.BiRPCv1ProcessMessage, + utils.SessionSv1ProcessEvent: sS.BiRPCv1ProcessEvent, + utils.SessionSv1GetCost: sS.BiRPCv1GetCost, + + utils.SessionSv1ForceDisconnect: sS.BiRPCv1ForceDisconnect, + utils.SessionSv1RegisterInternalBiJSONConn: sS.BiRPCv1RegisterInternalBiJSONConn, + + utils.SessionSv1ReplicateSessions: sS.BiRPCv1ReplicateSessions, + utils.SessionSv1SetPassiveSession: sS.BiRPCv1SetPassiveSession, + utils.SessionSv1ActivateSessions: sS.BiRPCv1ActivateSessions, + utils.SessionSv1DeactivateSessions: sS.BiRPCv1DeactivateSessions, + + utils.SessionSv1ReAuthorize: sS.BiRPCv1ReAuthorize, + utils.SessionSv1DisconnectPeer: sS.BiRPCv1DisconnectPeer, + + utils.SessionSv1STIRAuthenticate: sS.BiRPCv1STIRAuthenticate, + utils.SessionSv1STIRIdentity: sS.BiRPCv1STIRIdentity, + } +} diff --git a/sessions/sessions_test.go b/sessions/sessions_test.go index 86604b313..1debc5ff2 100644 --- a/sessions/sessions_test.go +++ b/sessions/sessions_test.go @@ -2485,7 +2485,7 @@ func TestWarnSession(t *testing.T) { sessions := NewSessionS(cfg, dm, nil) sTestMock := &mockConnWarnDisconnect1{} - sessions.RegisterIntBiJConn(sTestMock) + sessions.RegisterIntBiJConn(sTestMock, utils.EmptyString) if err := sessions.warnSession("ClientConnIdtest", nil); err != nil { t.Error(err) @@ -2494,7 +2494,7 @@ func TestWarnSession(t *testing.T) { cfg.GeneralCfg().NodeID = "ClientConnIdtest2" sessions = NewSessionS(cfg, dm, nil) sTestMock2 := &mockConnWarnDisconnect2{} - sessions.RegisterIntBiJConn(sTestMock2) + sessions.RegisterIntBiJConn(sTestMock2, utils.EmptyString) if err := sessions.warnSession("ClientConnIdtest2", nil); err == nil || err != utils.ErrNoActiveSession { t.Errorf("Expected %+v, received %+v", utils.ErrNoActiveSession, err) } @@ -2570,3 +2570,7 @@ func TestInitSession(t *testing.T) { t.Errorf("Expected %v , received: %s", utils.ToJSON(exp), utils.ToJSON(s)) } } + +func TestSessionSAsBiRPC(t *testing.T) { + _ = rpcclient.BiRPCConector(new(SessionS)) +} diff --git a/sessions/sessionscover_it_test.go b/sessions/sessionscover_it_test.go index e6a9279f4..2b08891b8 100644 --- a/sessions/sessionscover_it_test.go +++ b/sessions/sessionscover_it_test.go @@ -418,7 +418,7 @@ func testForceSTerminatorClientCall(t *testing.T) { utils.ConcatenatedKey(utils.MetaInternal, utils.MetaResources): nil, }) sessions := NewSessionS(cfg, dm, connMgr) - sessions.RegisterIntBiJConn(sTestMock) + sessions.RegisterIntBiJConn(sTestMock, utils.EmptyString) ss := &Session{ CGRID: "CGRID", @@ -755,7 +755,7 @@ func testDebitLoopSessionErrorDebiting(t *testing.T) { sessions = NewSessionS(cfg, dm, connMgr) sTestMock := &testMockClientConnDiscSess{} - sessions.RegisterIntBiJConn(sTestMock) + sessions.RegisterIntBiJConn(sTestMock, utils.EmptyString) if _, err = sessions.debitLoopSession(ss, 0, time.Hour); err != nil { t.Error(err) @@ -1025,7 +1025,7 @@ func testDebitLoopSessionDisconnectSession(t *testing.T) { sessions := NewSessionS(cfg, dm, connMgr) sTestMock := &testMockClientConnDiscSess{} - sessions.RegisterIntBiJConn(sTestMock) + sessions.RegisterIntBiJConn(sTestMock, utils.EmptyString) ss := &Session{ CGRID: "CGRID", @@ -1184,10 +1184,10 @@ func testRefundSession(t *testing.T) { }, }, Rating: map[string]*engine.RatingUnit{ - "21a5ab9": &engine.RatingUnit{}, + "21a5ab9": {}, }, Accounting: map[string]*engine.BalanceCharge{ - "44d6c02": &engine.BalanceCharge{}, + "44d6c02": {}, }, } @@ -1313,7 +1313,7 @@ func testDisconnectSession(t *testing.T) { } sTestMock := &testMockClientConn{} - sessions.RegisterIntBiJConn(sTestMock) + sessions.RegisterIntBiJConn(sTestMock, utils.EmptyString) sessions.biJIDs["test"] = &biJClient{ conn: sTestMock, } @@ -1323,7 +1323,7 @@ func testDisconnectSession(t *testing.T) { } sTestMock1 := &mockConnWarnDisconnect1{} - sessions.RegisterIntBiJConn(sTestMock1) + sessions.RegisterIntBiJConn(sTestMock1, utils.EmptyString) sessions.biJIDs["test"] = &biJClient{ conn: sTestMock1, } @@ -1449,7 +1449,7 @@ func testNewSession(t *testing.T) { } sessions.aSessions = map[string]*Session{ - "da39a3ee5e6b4b0d3255bfef95601890afd80709": &Session{}, + "da39a3ee5e6b4b0d3255bfef95601890afd80709": {}, } //sessions already exists if _, err := sessions.newSession(cgrEv, "resourceID", "clientConnID", @@ -1722,7 +1722,7 @@ func testSyncSessions(t *testing.T) { sessions := NewSessionS(cfg, dm, connMgr) sTestMock1 := &testMockClientSyncSessions{} - sessions.RegisterIntBiJConn(sTestMock1) + sessions.RegisterIntBiJConn(sTestMock1, utils.EmptyString) sessions.aSessions = map[string]*Session{ "SESS1": { diff --git a/utils/coreutils.go b/utils/coreutils.go index bc1e3b32f..199c26db0 100644 --- a/utils/coreutils.go +++ b/utils/coreutils.go @@ -823,6 +823,45 @@ func APIerRPCCall(inst interface{}, serviceMethod string, args interface{}, repl return err } +// BiRPCCall is a generic method calling BiRPC on a struct instance +// serviceMethod is assumed to be in the form InstanceV1.Method +// where BiRPCV1Method will become RPC method called on instance +// the subsystem is not checked +func BiRPCCall(inst interface{}, clnt rpcclient.ClientConnector, serviceMethod string, args interface{}, reply interface{}) error { + parts := strings.Split(serviceMethod, ".") + if len(parts) != 2 { + return rpcclient.ErrUnsupporteServiceMethod + } + // get method BiRPCV1.Method + method := reflect.ValueOf(inst).MethodByName( + "BiRPC" + parts[0][len(parts[0])-2:] + parts[1]) // Inherit the version V1 in the method name and add prefix + if !method.IsValid() { + return rpcclient.ErrUnsupporteServiceMethod + } + // construct the params + var clntVal reflect.Value + if clnt == nil { + clntVal = reflect.New( + reflect.TypeOf(new(rpcclient.BiRPCInternalServer))).Elem() // Kinda cheat since we make up a type here + } else { + clntVal = reflect.ValueOf(clnt) + } + params := []reflect.Value{clntVal, reflect.ValueOf(args), + reflect.ValueOf(reply)} + ret := method.Call(params) + if len(ret) != 1 { + return ErrServerError + } + if ret[0].Interface() == nil { + return nil + } + err, ok := ret[0].Interface().(error) + if !ok { + return ErrServerError + } + return err +} + // CachedRPCResponse is used to cache a RPC response type CachedRPCResponse struct { Result interface{}