diff --git a/apier/v1/replicator.go b/apier/v1/replicator.go index be807cd9a..1d3ad22a3 100644 --- a/apier/v1/replicator.go +++ b/apier/v1/replicator.go @@ -39,6 +39,7 @@ func (rplSv1 *ReplicatorSv1) Call(serviceMethod string, args interface{}, reply //GetAccount func (rplSv1 *ReplicatorSv1) GetAccount(args *utils.StringWithOpts, reply *engine.Account) error { + engine.SetReplicateHost(utils.AccountPrefix, args.Arg, utils.IfaceAsString(args.Opts[utils.RemoteHostOpt])) if rcv, err := rplSv1.dm.GetAccount(args.Arg); err != nil { return err } else { @@ -49,6 +50,7 @@ func (rplSv1 *ReplicatorSv1) GetAccount(args *utils.StringWithOpts, reply *engin //GetDestination func (rplSv1 *ReplicatorSv1) GetDestination(key *utils.StringWithOpts, reply *engine.Destination) error { + engine.SetReplicateHost(utils.DestinationPrefix, key.Arg, utils.IfaceAsString(key.Opts[utils.RemoteHostOpt])) if rcv, err := rplSv1.dm.DataDB().GetDestinationDrv(key.Arg, utils.NonTransactional); err != nil { return err } else { @@ -59,6 +61,7 @@ func (rplSv1 *ReplicatorSv1) GetDestination(key *utils.StringWithOpts, reply *en //GetDestination func (rplSv1 *ReplicatorSv1) GetReverseDestination(key *utils.StringWithOpts, reply *[]string) error { + engine.SetReplicateHost(utils.ReverseDestinationPrefix, key.Arg, utils.IfaceAsString(key.Opts[utils.RemoteHostOpt])) if rcv, err := rplSv1.dm.DataDB().GetReverseDestinationDrv(key.Arg, utils.NonTransactional); err != nil { return err } else { @@ -69,6 +72,7 @@ func (rplSv1 *ReplicatorSv1) GetReverseDestination(key *utils.StringWithOpts, re //GetStatQueue func (rplSv1 *ReplicatorSv1) GetStatQueue(tntID *utils.TenantIDWithOpts, reply *engine.StatQueue) error { + engine.SetReplicateHost(utils.StatQueuePrefix, tntID.TenantID.TenantID(), utils.IfaceAsString(tntID.Opts[utils.RemoteHostOpt])) if rcv, err := rplSv1.dm.DataDB().GetStatQueueDrv(tntID.Tenant, tntID.ID); err != nil { return err } else { @@ -79,6 +83,7 @@ func (rplSv1 *ReplicatorSv1) GetStatQueue(tntID *utils.TenantIDWithOpts, reply * //GetFilter func (rplSv1 *ReplicatorSv1) GetFilter(tntID *utils.TenantIDWithOpts, reply *engine.Filter) error { + engine.SetReplicateHost(utils.FilterPrefix, tntID.TenantID.TenantID(), utils.IfaceAsString(tntID.Opts[utils.RemoteHostOpt])) if rcv, err := rplSv1.dm.DataDB().GetFilterDrv(tntID.Tenant, tntID.ID); err != nil { return err } else { @@ -89,6 +94,7 @@ func (rplSv1 *ReplicatorSv1) GetFilter(tntID *utils.TenantIDWithOpts, reply *eng //GetThreshold func (rplSv1 *ReplicatorSv1) GetThreshold(tntID *utils.TenantIDWithOpts, reply *engine.Threshold) error { + engine.SetReplicateHost(utils.ThresholdPrefix, tntID.TenantID.TenantID(), utils.IfaceAsString(tntID.Opts[utils.RemoteHostOpt])) if rcv, err := rplSv1.dm.DataDB().GetThresholdDrv(tntID.Tenant, tntID.ID); err != nil { return err } else { @@ -99,6 +105,7 @@ func (rplSv1 *ReplicatorSv1) GetThreshold(tntID *utils.TenantIDWithOpts, reply * //GetThresholdProfile func (rplSv1 *ReplicatorSv1) GetThresholdProfile(tntID *utils.TenantIDWithOpts, reply *engine.ThresholdProfile) error { + engine.SetReplicateHost(utils.ThresholdProfilePrefix, tntID.TenantID.TenantID(), utils.IfaceAsString(tntID.Opts[utils.RemoteHostOpt])) if rcv, err := rplSv1.dm.DataDB().GetThresholdProfileDrv(tntID.Tenant, tntID.ID); err != nil { return err } else { @@ -109,6 +116,7 @@ func (rplSv1 *ReplicatorSv1) GetThresholdProfile(tntID *utils.TenantIDWithOpts, //GetStatQueueProfile func (rplSv1 *ReplicatorSv1) GetStatQueueProfile(tntID *utils.TenantIDWithOpts, reply *engine.StatQueueProfile) error { + engine.SetReplicateHost(utils.StatQueueProfilePrefix, tntID.TenantID.TenantID(), utils.IfaceAsString(tntID.Opts[utils.RemoteHostOpt])) if rcv, err := rplSv1.dm.DataDB().GetStatQueueProfileDrv(tntID.Tenant, tntID.ID); err != nil { return err } else { @@ -119,6 +127,7 @@ func (rplSv1 *ReplicatorSv1) GetStatQueueProfile(tntID *utils.TenantIDWithOpts, //GetTiming func (rplSv1 *ReplicatorSv1) GetTiming(id *utils.StringWithOpts, reply *utils.TPTiming) error { + engine.SetReplicateHost(utils.TimingsPrefix, id.Arg, utils.IfaceAsString(id.Opts[utils.RemoteHostOpt])) if rcv, err := rplSv1.dm.DataDB().GetTimingDrv(id.Arg); err != nil { return err } else { @@ -129,6 +138,7 @@ func (rplSv1 *ReplicatorSv1) GetTiming(id *utils.StringWithOpts, reply *utils.TP //GetResource func (rplSv1 *ReplicatorSv1) GetResource(tntID *utils.TenantIDWithOpts, reply *engine.Resource) error { + engine.SetReplicateHost(utils.ResourcesPrefix, tntID.TenantID.TenantID(), utils.IfaceAsString(tntID.Opts[utils.RemoteHostOpt])) if rcv, err := rplSv1.dm.DataDB().GetResourceDrv(tntID.Tenant, tntID.ID); err != nil { return err } else { @@ -139,6 +149,7 @@ func (rplSv1 *ReplicatorSv1) GetResource(tntID *utils.TenantIDWithOpts, reply *e //GetResourceProfile func (rplSv1 *ReplicatorSv1) GetResourceProfile(tntID *utils.TenantIDWithOpts, reply *engine.ResourceProfile) error { + engine.SetReplicateHost(utils.ResourceProfilesPrefix, tntID.TenantID.TenantID(), utils.IfaceAsString(tntID.Opts[utils.RemoteHostOpt])) if rcv, err := rplSv1.dm.DataDB().GetResourceProfileDrv(tntID.Tenant, tntID.ID); err != nil { return err } else { @@ -149,6 +160,7 @@ func (rplSv1 *ReplicatorSv1) GetResourceProfile(tntID *utils.TenantIDWithOpts, r //GetActionTriggers func (rplSv1 *ReplicatorSv1) GetActionTriggers(id *utils.StringWithOpts, reply *engine.ActionTriggers) error { + engine.SetReplicateHost(utils.ActionTriggerPrefix, id.Arg, utils.IfaceAsString(id.Opts[utils.RemoteHostOpt])) if rcv, err := rplSv1.dm.DataDB().GetActionTriggersDrv(id.Arg); err != nil { return err } else { @@ -159,6 +171,7 @@ func (rplSv1 *ReplicatorSv1) GetActionTriggers(id *utils.StringWithOpts, reply * //GetSharedGroup func (rplSv1 *ReplicatorSv1) GetSharedGroup(id *utils.StringWithOpts, reply *engine.SharedGroup) error { + engine.SetReplicateHost(utils.SharedGroupPrefix, id.Arg, utils.IfaceAsString(id.Opts[utils.RemoteHostOpt])) if rcv, err := rplSv1.dm.DataDB().GetSharedGroupDrv(id.Arg); err != nil { return err } else { @@ -169,6 +182,7 @@ func (rplSv1 *ReplicatorSv1) GetSharedGroup(id *utils.StringWithOpts, reply *eng //GetActions func (rplSv1 *ReplicatorSv1) GetActions(id *utils.StringWithOpts, reply *engine.Actions) error { + engine.SetReplicateHost(utils.ActionPrefix, id.Arg, utils.IfaceAsString(id.Opts[utils.RemoteHostOpt])) if rcv, err := rplSv1.dm.DataDB().GetActionsDrv(id.Arg); err != nil { return err } else { @@ -179,6 +193,7 @@ func (rplSv1 *ReplicatorSv1) GetActions(id *utils.StringWithOpts, reply *engine. //GetActions func (rplSv1 *ReplicatorSv1) GetActionPlan(id *utils.StringWithOpts, reply *engine.ActionPlan) error { + engine.SetReplicateHost(utils.ActionPlanPrefix, id.Arg, utils.IfaceAsString(id.Opts[utils.RemoteHostOpt])) if rcv, err := rplSv1.dm.DataDB().GetActionPlanDrv(id.Arg, true, utils.NonTransactional); err != nil { return err } else { @@ -188,10 +203,13 @@ func (rplSv1 *ReplicatorSv1) GetActionPlan(id *utils.StringWithOpts, reply *engi } //GetAllActionPlans -func (rplSv1 *ReplicatorSv1) GetAllActionPlans(_ *utils.StringWithOpts, reply *map[string]*engine.ActionPlan) error { +func (rplSv1 *ReplicatorSv1) GetAllActionPlans(id *utils.StringWithOpts, reply *map[string]*engine.ActionPlan) error { if rcv, err := rplSv1.dm.DataDB().GetAllActionPlansDrv(); err != nil { return err } else { + for _, ap := range rcv { + engine.SetReplicateHost(utils.ActionPlanPrefix, ap.Id, utils.IfaceAsString(id.Opts[utils.RemoteHostOpt])) + } *reply = rcv } return nil @@ -199,6 +217,7 @@ func (rplSv1 *ReplicatorSv1) GetAllActionPlans(_ *utils.StringWithOpts, reply *m //GetAccountActionPlans func (rplSv1 *ReplicatorSv1) GetAccountActionPlans(id *utils.StringWithOpts, reply *[]string) error { + engine.SetReplicateHost(utils.AccountActionPlansPrefix, id.Arg, utils.IfaceAsString(id.Opts[utils.RemoteHostOpt])) if rcv, err := rplSv1.dm.DataDB().GetAccountActionPlansDrv(id.Arg, false, utils.NonTransactional); err != nil { return err } else { @@ -209,6 +228,7 @@ func (rplSv1 *ReplicatorSv1) GetAccountActionPlans(id *utils.StringWithOpts, rep //GetAllActionPlans func (rplSv1 *ReplicatorSv1) GetRatingPlan(id *utils.StringWithOpts, reply *engine.RatingPlan) error { + engine.SetReplicateHost(utils.RatingPlanPrefix, id.Arg, utils.IfaceAsString(id.Opts[utils.RemoteHostOpt])) if rcv, err := rplSv1.dm.DataDB().GetRatingPlanDrv(id.Arg); err != nil { return err } else { @@ -219,6 +239,7 @@ func (rplSv1 *ReplicatorSv1) GetRatingPlan(id *utils.StringWithOpts, reply *engi //GetAllActionPlans func (rplSv1 *ReplicatorSv1) GetRatingProfile(id *utils.StringWithOpts, reply *engine.RatingProfile) error { + engine.SetReplicateHost(utils.RatingProfilePrefix, id.Arg, utils.IfaceAsString(id.Opts[utils.RemoteHostOpt])) if rcv, err := rplSv1.dm.DataDB().GetRatingProfileDrv(id.Arg); err != nil { return err } else { @@ -229,6 +250,7 @@ func (rplSv1 *ReplicatorSv1) GetRatingProfile(id *utils.StringWithOpts, reply *e //GetResourceProfile func (rplSv1 *ReplicatorSv1) GetRouteProfile(tntID *utils.TenantIDWithOpts, reply *engine.RouteProfile) error { + engine.SetReplicateHost(utils.RouteProfilePrefix, tntID.TenantID.TenantID(), utils.IfaceAsString(tntID.Opts[utils.RemoteHostOpt])) if rcv, err := rplSv1.dm.DataDB().GetRouteProfileDrv(tntID.Tenant, tntID.ID); err != nil { return err } else { @@ -239,6 +261,7 @@ func (rplSv1 *ReplicatorSv1) GetRouteProfile(tntID *utils.TenantIDWithOpts, repl //GetResourceProfile func (rplSv1 *ReplicatorSv1) GetAttributeProfile(tntID *utils.TenantIDWithOpts, reply *engine.AttributeProfile) error { + engine.SetReplicateHost(utils.AttributeProfilePrefix, tntID.TenantID.TenantID(), utils.IfaceAsString(tntID.Opts[utils.RemoteHostOpt])) if rcv, err := rplSv1.dm.DataDB().GetAttributeProfileDrv(tntID.Tenant, tntID.ID); err != nil { return err } else { @@ -249,6 +272,7 @@ func (rplSv1 *ReplicatorSv1) GetAttributeProfile(tntID *utils.TenantIDWithOpts, //GetResourceProfile func (rplSv1 *ReplicatorSv1) GetChargerProfile(tntID *utils.TenantIDWithOpts, reply *engine.ChargerProfile) error { + engine.SetReplicateHost(utils.ChargerProfilePrefix, tntID.TenantID.TenantID(), utils.IfaceAsString(tntID.Opts[utils.RemoteHostOpt])) if rcv, err := rplSv1.dm.DataDB().GetChargerProfileDrv(tntID.Tenant, tntID.ID); err != nil { return err } else { @@ -259,6 +283,7 @@ func (rplSv1 *ReplicatorSv1) GetChargerProfile(tntID *utils.TenantIDWithOpts, re //GetResourceProfile func (rplSv1 *ReplicatorSv1) GetDispatcherProfile(tntID *utils.TenantIDWithOpts, reply *engine.DispatcherProfile) error { + engine.SetReplicateHost(utils.DispatcherProfilePrefix, tntID.TenantID.TenantID(), utils.IfaceAsString(tntID.Opts[utils.RemoteHostOpt])) if rcv, err := rplSv1.dm.DataDB().GetDispatcherProfileDrv(tntID.Tenant, tntID.ID); err != nil { return err } else { @@ -269,6 +294,7 @@ func (rplSv1 *ReplicatorSv1) GetDispatcherProfile(tntID *utils.TenantIDWithOpts, //GetResourceProfile func (rplSv1 *ReplicatorSv1) GetDispatcherHost(tntID *utils.TenantIDWithOpts, reply *engine.DispatcherHost) error { + engine.SetReplicateHost(utils.DispatcherHostPrefix, tntID.TenantID.TenantID(), utils.IfaceAsString(tntID.Opts[utils.RemoteHostOpt])) if rcv, err := rplSv1.dm.DataDB().GetDispatcherHostDrv(tntID.Tenant, tntID.ID); err != nil { return err } else { @@ -278,6 +304,7 @@ func (rplSv1 *ReplicatorSv1) GetDispatcherHost(tntID *utils.TenantIDWithOpts, re } func (rplSv1 *ReplicatorSv1) GetRateProfile(tntID *utils.TenantIDWithOpts, reply *engine.RateProfile) error { + engine.SetReplicateHost(utils.RateProfilePrefix, tntID.TenantID.TenantID(), utils.IfaceAsString(tntID.Opts[utils.RemoteHostOpt])) if rcv, err := rplSv1.dm.DataDB().GetRateProfileDrv(tntID.Tenant, tntID.ID); err != nil { return err } else { @@ -287,6 +314,7 @@ func (rplSv1 *ReplicatorSv1) GetRateProfile(tntID *utils.TenantIDWithOpts, reply } func (rplSv1 *ReplicatorSv1) GetActionProfile(tntID *utils.TenantIDWithOpts, reply *engine.ActionProfile) error { + engine.SetReplicateHost(utils.ActionProfilePrefix, tntID.TenantID.TenantID(), utils.IfaceAsString(tntID.Opts[utils.RemoteHostOpt])) if rcv, err := rplSv1.dm.DataDB().GetActionProfileDrv(tntID.Tenant, tntID.ID); err != nil { return err } else { @@ -296,6 +324,7 @@ func (rplSv1 *ReplicatorSv1) GetActionProfile(tntID *utils.TenantIDWithOpts, rep } func (rplSv1 *ReplicatorSv1) GetAccountProfile(tntID *utils.TenantIDWithOpts, reply *utils.AccountProfile) error { + engine.SetReplicateHost(utils.AccountProfilePrefix, tntID.TenantID.TenantID(), utils.IfaceAsString(tntID.Opts[utils.RemoteHostOpt])) if rcv, err := rplSv1.dm.DataDB().GetAccountProfileDrv(tntID.Tenant, tntID.ID); err != nil { return err } else { @@ -306,6 +335,7 @@ func (rplSv1 *ReplicatorSv1) GetAccountProfile(tntID *utils.TenantIDWithOpts, re //GetResourceProfile func (rplSv1 *ReplicatorSv1) GetItemLoadIDs(itemID *utils.StringWithOpts, reply *map[string]int64) error { + engine.SetReplicateHost(utils.LoadIDPrefix, itemID.Arg, utils.IfaceAsString(itemID.Opts[utils.RemoteHostOpt])) if rcv, err := rplSv1.dm.DataDB().GetItemLoadIDsDrv(itemID.Arg); err != nil { return err } else { @@ -771,6 +801,7 @@ func (rplSv1 *ReplicatorSv1) Ping(ign *utils.CGREvent, reply *string) error { // GetIndexes . func (rplSv1 *ReplicatorSv1) GetIndexes(args *utils.GetIndexesArg, reply *map[string]utils.StringSet) error { + engine.SetReplicateHost(utils.CacheInstanceToPrefix[args.IdxItmType], args.TntCtx, utils.IfaceAsString(args.Opts[utils.RemoteHostOpt])) indx, err := rplSv1.dm.DataDB().GetIndexesDrv(args.IdxItmType, args.TntCtx, args.IdxKey) if err != nil { return err diff --git a/cmd/cgr-engine/cgr-engine.go b/cmd/cgr-engine/cgr-engine.go index 54c56e296..494a75535 100644 --- a/cmd/cgr-engine/cgr-engine.go +++ b/cmd/cgr-engine/cgr-engine.go @@ -630,7 +630,7 @@ func main() { initGuardianSv1(internalGuardianSChan, server, anz) // Start ServiceManager - srvManager := servmanager.NewServiceManager(cfg, shdChan, shdWg) + srvManager := servmanager.NewServiceManager(cfg, shdChan, shdWg, connManager) attrS := services.NewAttributeService(cfg, dmService, cacheS, filterSChan, server, internalAttributeSChan, anz, srvDep) dspS := services.NewDispatcherService(cfg, dmService, cacheS, filterSChan, server, internalDispatcherSChan, connManager, anz, srvDep) dspH := services.NewRegistrarCService(cfg, server, connManager, anz, srvDep) diff --git a/config/config_defaults.go b/config/config_defaults.go index 9ab02f7d3..055e245fe 100644 --- a/config/config_defaults.go +++ b/config/config_defaults.go @@ -80,6 +80,8 @@ const CGRATES_CFG_JSON = ` "db_password": "", // password to use when connecting to data_db "remote_conns":[], "replication_conns":[], + "filtered_replication": false, // if this is enabled the replication will be made only to the conns that received a get + "remote_conn_id": "", // the ID to be sent to remote_conns to identify the connection "items":{ "*accounts":{"remote":false, "replicate":false}, "*reverse_destinations": {"remote":false, "replicate":false}, @@ -285,6 +287,7 @@ const CGRATES_CFG_JSON = ` "*stir": {"limit": -1, "ttl": "3h", "static_ttl": false, "replicate": false}, // stirShaken cache keys "*apiban":{"limit": -1, "ttl": "2m", "static_ttl": false, "replicate": false}, "*caps_events": {"limit": -1, "ttl": "", "static_ttl": false, "replicate": false}, // caps cached samples + "*replication_hosts": {"limit": 0, "ttl": "", "static_ttl": false, "replicate": false}, // the replication hosts cache(used when filtered_replication is enbled) // only for *internal database "*versions": {"limit": -1, "ttl": "", "static_ttl": false, "replicate": false}, // for version storing diff --git a/config/datadbcfg.go b/config/datadbcfg.go index 2a61f4399..ed800c746 100644 --- a/config/datadbcfg.go +++ b/config/datadbcfg.go @@ -28,16 +28,18 @@ import ( // DataDbCfg Database config type DataDbCfg struct { - DataDbType string - DataDbHost string // The host to connect to. Values that start with / are for UNIX domain sockets. - DataDbPort string // The port to bind to. - DataDbName string // The name of the database to connect to. - DataDbUser string // The user to sign in as. - DataDbPass string // The user's password. - RmtConns []string // Remote DataDB connIDs - RplConns []string // Replication connIDs - Items map[string]*ItemOpt - Opts map[string]interface{} + DataDbType string + DataDbHost string // The host to connect to. Values that start with / are for UNIX domain sockets. + DataDbPort string // The port to bind to. + DataDbName string // The name of the database to connect to. + DataDbUser string // The user to sign in as. + DataDbPass string // The user's password. + RmtConns []string // Remote DataDB connIDs + RplConns []string // Replication connIDs + RplFiltered bool + RmtConnID string + Items map[string]*ItemOpt + Opts map[string]interface{} } // loadFromJSONCfg loads Database config from JsonCfg @@ -102,20 +104,28 @@ func (dbcfg *DataDbCfg) loadFromJSONCfg(jsnDbCfg *DbJsonCfg) (err error) { dbcfg.Opts[k] = v } } - return nil + if jsnDbCfg.Filtered_replication != nil { + dbcfg.RplFiltered = *jsnDbCfg.Filtered_replication + } + if jsnDbCfg.Remote_conn_id != nil { + dbcfg.RmtConnID = *jsnDbCfg.Remote_conn_id + } + return } // Clone returns the cloned object func (dbcfg *DataDbCfg) Clone() (cln *DataDbCfg) { cln = &DataDbCfg{ - DataDbType: dbcfg.DataDbType, - DataDbHost: dbcfg.DataDbHost, - DataDbPort: dbcfg.DataDbPort, - DataDbName: dbcfg.DataDbName, - DataDbUser: dbcfg.DataDbUser, - DataDbPass: dbcfg.DataDbPass, - Items: make(map[string]*ItemOpt), - Opts: make(map[string]interface{}), + DataDbType: dbcfg.DataDbType, + DataDbHost: dbcfg.DataDbHost, + DataDbPort: dbcfg.DataDbPort, + DataDbName: dbcfg.DataDbName, + DataDbUser: dbcfg.DataDbUser, + DataDbPass: dbcfg.DataDbPass, + RplFiltered: dbcfg.RplFiltered, + RmtConnID: dbcfg.RmtConnID, + Items: make(map[string]*ItemOpt), + Opts: make(map[string]interface{}), } for k, itm := range dbcfg.Items { cln.Items[k] = itm.Clone() @@ -142,13 +152,15 @@ func (dbcfg *DataDbCfg) Clone() (cln *DataDbCfg) { // AsMapInterface returns the config as a map[string]interface{} func (dbcfg *DataDbCfg) AsMapInterface() (initialMP map[string]interface{}) { initialMP = map[string]interface{}{ - utils.DataDbTypeCfg: utils.Meta + dbcfg.DataDbType, - utils.DataDbHostCfg: dbcfg.DataDbHost, - utils.DataDbNameCfg: dbcfg.DataDbName, - utils.DataDbUserCfg: dbcfg.DataDbUser, - utils.DataDbPassCfg: dbcfg.DataDbPass, - utils.RmtConnsCfg: dbcfg.RmtConns, - utils.RplConnsCfg: dbcfg.RplConns, + utils.DataDbTypeCfg: utils.Meta + dbcfg.DataDbType, + utils.DataDbHostCfg: dbcfg.DataDbHost, + utils.DataDbNameCfg: dbcfg.DataDbName, + utils.DataDbUserCfg: dbcfg.DataDbUser, + utils.DataDbPassCfg: dbcfg.DataDbPass, + utils.RmtConnsCfg: dbcfg.RmtConns, + utils.RplConnsCfg: dbcfg.RplConns, + utils.FilteredReplicationCfg: dbcfg.RplFiltered, + utils.RemoteConnIDCfg: dbcfg.RmtConnID, } opts := make(map[string]interface{}) for k, v := range dbcfg.Opts { diff --git a/config/libconfig_json.go b/config/libconfig_json.go index 541c8c687..28502cc23 100644 --- a/config/libconfig_json.go +++ b/config/libconfig_json.go @@ -93,6 +93,8 @@ type DbJsonCfg struct { Prefix_indexed_fields *[]string Remote_conns *[]string Replication_conns *[]string + Filtered_replication *bool + Remote_conn_id *string Items *map[string]*ItemOptJson Opts map[string]interface{} } diff --git a/engine/connmanager.go b/engine/connmanager.go index ecf180148..c2f9b7532 100644 --- a/engine/connmanager.go +++ b/engine/connmanager.go @@ -24,12 +24,17 @@ import ( "github.com/cgrates/cgrates/config" "github.com/cgrates/cgrates/utils" + "github.com/cgrates/ltcache" "github.com/cgrates/rpcclient" ) // NewConnManager returns the Connection Manager func NewConnManager(cfg *config.CGRConfig, rpcInternal map[string]chan rpcclient.ClientConnector) (cM *ConnManager) { - cM = &ConnManager{cfg: cfg, rpcInternal: rpcInternal} + cM = &ConnManager{ + cfg: cfg, + rpcInternal: rpcInternal, + connCache: ltcache.NewCache(-1, 0, true, nil), + } SetConnManager(cM) return } @@ -38,6 +43,7 @@ func NewConnManager(cfg *config.CGRConfig, rpcInternal map[string]chan rpcclient type ConnManager struct { cfg *config.CGRConfig rpcInternal map[string]chan rpcclient.ClientConnector + connCache *ltcache.Cache } // getConn is used to retrieve a connection from cache @@ -68,6 +74,17 @@ func (cM *ConnManager) getConn(connID string, biRPCClient rpcclient.BiRPCConecto } } } + if conn, err = cM.getConnWithConfig(connID, connCfg, biRPCClient, intChan, isInternalRPC); err != nil { + return + } + err = Cache.Set(utils.CacheRPCConnections, connID, conn, nil, + true, utils.NonTransactional) + return +} + +func (cM *ConnManager) getConnWithConfig(connID string, connCfg *config.RPCConn, + biRPCClient rpcclient.BiRPCConector, intChan chan rpcclient.ClientConnector, + isInternalRPC bool) (conn rpcclient.ClientConnector, err error) { if connCfg.Strategy == rpcclient.PoolParallel { rpcConnCfg := connCfg.Conns[0] // for parrallel we need only the first connection codec := rpcclient.GOBrpc @@ -101,7 +118,7 @@ func (cM *ConnManager) getConn(connID string, biRPCClient rpcclient.BiRPCConecto cM.cfg.TLSCfg().ClientCerificate, cM.cfg.TLSCfg().CaCertificate, cM.cfg.GeneralCfg().ConnectAttempts, cM.cfg.GeneralCfg().Reconnects, cM.cfg.GeneralCfg().ConnectTimeout, cM.cfg.GeneralCfg().ReplyTimeout, - connCfg.Conns, intChan, false, biRPCClient); err != nil { + connCfg.Conns, intChan, false, biRPCClient, connID, cM.connCache); err != nil { return } } @@ -119,11 +136,6 @@ func (cM *ConnManager) getConn(connID string, biRPCClient rpcclient.BiRPCConecto } } } - - if err = Cache.Set(utils.CacheRPCConnections, connID, conn, nil, - true, utils.NonTransactional); err != nil { - return - } return } @@ -138,11 +150,55 @@ func (cM *ConnManager) Call(connIDs []string, biRPCClient rpcclient.BiRPCConecto if conn, err = cM.getConn(connID, biRPCClient); err != nil { continue } - if err = conn.Call(method, arg, reply); rpcclient.IsNetworkError(err) { - continue - } else { + if err = conn.Call(method, arg, reply); !rpcclient.IsNetworkError(err) { return } } return } + +// CallWithConnIDs will call the method only on specified rpcconns +func (cM *ConnManager) CallWithConnIDs(connIDs []string, subsHostIDs utils.StringSet, method string, arg, reply interface{}) (err error) { + if len(connIDs) == 0 { + return utils.NewErrMandatoryIeMissing("connIDs") + } + // no connection for this id exit here + if subsHostIDs.Size() == 0 { + return + } + var conn rpcclient.ClientConnector + for _, connID := range connIDs { + // recreate the config with only conns that are needed + connCfg := cM.cfg.RPCConns()[connID] + newCfg := &config.RPCConn{ + Strategy: connCfg.Strategy, + PoolSize: connCfg.PoolSize, + // alloc for all connection in order to not increase the size later + Conns: make([]*config.RemoteHost, 0, len(connCfg.Conns)), + } + for _, conn := range connCfg.Conns { + if conn.ID != utils.EmptyString && + subsHostIDs.Has(conn.ID) { + newCfg.Conns = append(newCfg.Conns, conn) // the slice will never grow + } + } + if len(newCfg.Conns) == 0 { + // skip this pool if no connection matches + continue + } + if conn, err = cM.getConnWithConfig(connID, newCfg, nil, nil, false); err != nil { + continue + } + if err = conn.Call(method, arg, reply); !rpcclient.IsNetworkError(err) { + return + } + } + return +} + +// Reload will clear all RPC related caches +func (cM *ConnManager) Reload() { + Cache.Clear([]string{utils.CacheRPCConnections}) + Cache.Clear([]string{utils.CacheReplicationHosts}) + cM.connCache.Clear() +} diff --git a/engine/datamanager.go b/engine/datamanager.go index 446bb720f..6adabc099 100644 --- a/engine/datamanager.go +++ b/engine/datamanager.go @@ -112,8 +112,7 @@ func (dm *DataManager) DataDB() DataDB { func (dm *DataManager) LoadDataDBCache(attr map[string][]string) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } if dm.DataDB().GetStorageType() == utils.INTERNAL { return // all the data is in cache already @@ -389,8 +388,9 @@ func (dm *DataManager) GetDestination(key string, cacheRead, cacheWrite bool, tr Arg: key, Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, Opts: map[string]interface{}{ - utils.OptsAPIKey: itm.APIKey, - utils.OptsRouteID: itm.RouteID, + utils.OptsAPIKey: itm.APIKey, + utils.OptsRouteID: itm.RouteID, + utils.RemoteHostOpt: utils.FirstNonEmpty(config.CgrConfig().DataDbCfg().RmtConnID, config.CgrConfig().GeneralCfg().NodeID), }, }, &dest); err == nil { err = dm.dataDB.SetDestinationDrv(dest, utils.NonTransactional) @@ -418,15 +418,15 @@ func (dm *DataManager) GetDestination(key string, cacheRead, cacheWrite bool, tr func (dm *DataManager) SetDestination(dest *Destination, transactionID string) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } if err = dm.dataDB.SetDestinationDrv(dest, transactionID); err != nil { return } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaDestinations]; itm.Replicate { - var reply string - if err = dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, + err = replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.DestinationPrefix, dest.Id, // this are used to get the host IDs from cache utils.ReplicatorSv1SetDestination, &DestinationWithOpts{ Destination: dest, @@ -434,18 +434,14 @@ func (dm *DataManager) SetDestination(dest *Destination, transactionID string) ( Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply); err != nil { - err = utils.CastRPCErr(err) - return - } + }}) } return } func (dm *DataManager) RemoveDestination(destID string, transactionID string) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } var oldDst *Destination @@ -472,23 +468,24 @@ func (dm *DataManager) RemoveDestination(destID string, transactionID string) (e } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaDestinations]; itm.Replicate { - var reply string - dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, utils.ReplicatorSv1RemoveDestination, + replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.DestinationPrefix, destID, // this are used to get the host IDs from cache + utils.ReplicatorSv1RemoveDestination, &utils.StringWithOpts{ Arg: destID, Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply) + }}) } return } func (dm *DataManager) SetReverseDestination(destID string, prefixes []string, transactionID string) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } if err = dm.dataDB.SetReverseDestinationDrv(destID, prefixes, transactionID); err != nil { return @@ -526,8 +523,9 @@ func (dm *DataManager) GetReverseDestination(prefix string, Arg: prefix, Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, Opts: map[string]interface{}{ - utils.OptsAPIKey: itm.APIKey, - utils.OptsRouteID: itm.RouteID, + utils.OptsAPIKey: itm.APIKey, + utils.OptsRouteID: itm.RouteID, + utils.RemoteHostOpt: utils.FirstNonEmpty(config.CgrConfig().DataDbCfg().RmtConnID, config.CgrConfig().GeneralCfg().NodeID), }, }, &ids); err == nil { err = dm.dataDB.SetReverseDestinationDrv(prefix, ids, transactionID) @@ -614,8 +612,9 @@ func (dm *DataManager) GetAccount(id string) (acc *Account, err error) { Arg: id, Tenant: tenant, Opts: map[string]interface{}{ - utils.OptsAPIKey: itm.APIKey, - utils.OptsRouteID: itm.RouteID, + utils.OptsAPIKey: itm.APIKey, + utils.OptsRouteID: itm.RouteID, + utils.RemoteHostOpt: utils.FirstNonEmpty(config.CgrConfig().DataDbCfg().RmtConnID, config.CgrConfig().GeneralCfg().NodeID), }, }, &acc); err == nil { err = dm.dataDB.SetAccountDrv(acc) @@ -631,40 +630,37 @@ func (dm *DataManager) GetAccount(id string) (acc *Account, err error) { func (dm *DataManager) SetAccount(acc *Account) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } if err = dm.dataDB.SetAccountDrv(acc); err != nil { return } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaAccounts]; itm.Replicate { - var reply string - if err = dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, + err = replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.AccountPrefix, acc.ID, // this are used to get the host IDs from cache utils.ReplicatorSv1SetAccount, &AccountWithOpts{ Account: acc, Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply); err != nil { - err = utils.CastRPCErr(err) - return - } + }}) } return } func (dm *DataManager) RemoveAccount(id string) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } if err = dm.dataDB.RemoveAccountDrv(id); err != nil { return } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaAccounts]; itm.Replicate { - var reply string - dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, + replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.AccountPrefix, id, // this are used to get the host IDs from cache utils.ReplicatorSv1RemoveAccount, &utils.StringWithOpts{ Arg: id, @@ -672,7 +668,7 @@ func (dm *DataManager) RemoveAccount(id string) (err error) { Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply) + }}) } return } @@ -701,8 +697,9 @@ func (dm *DataManager) GetStatQueue(tenant, id string, &utils.TenantIDWithOpts{ TenantID: &utils.TenantID{Tenant: tenant, ID: id}, Opts: map[string]interface{}{ - utils.OptsAPIKey: itm.APIKey, - utils.OptsRouteID: itm.RouteID, + utils.OptsAPIKey: itm.APIKey, + utils.OptsRouteID: itm.RouteID, + utils.RemoteHostOpt: utils.FirstNonEmpty(config.CgrConfig().DataDbCfg().RmtConnID, config.CgrConfig().GeneralCfg().NodeID), }}, &sq); err == nil { var ssq *StoredStatQueue if dm.dataDB.GetStorageType() != utils.MetaInternal { @@ -738,8 +735,7 @@ func (dm *DataManager) GetStatQueue(tenant, id string, func (dm *DataManager) SetStatQueue(sq *StatQueue, metrics []*MetricWithFilters, minItems int, ttl *time.Duration, queueLength int, simpleSet bool) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } if !simpleSet { tnt := sq.Tenant // save the tenant @@ -811,18 +807,16 @@ func (dm *DataManager) SetStatQueue(sq *StatQueue, metrics []*MetricWithFilters, return } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaStatQueues]; itm.Replicate { - var reply string - if err = dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, + err = replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.StatQueuePrefix, sq.TenantID(), // this are used to get the host IDs from cache utils.ReplicatorSv1SetStatQueue, &StoredStatQueueWithOpts{ StoredStatQueue: ssq, Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply); err != nil { - err = utils.CastRPCErr(err) - return - } + }}) } return } @@ -830,22 +824,22 @@ func (dm *DataManager) SetStatQueue(sq *StatQueue, metrics []*MetricWithFilters, // RemoveStatQueue removes the StoredStatQueue func (dm *DataManager) RemoveStatQueue(tenant, id string, transactionID string) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } if err = dm.dataDB.RemStatQueueDrv(tenant, id); err != nil { return } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaStatQueues]; itm.Replicate { - var reply string - dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, + replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.StatQueuePrefix, utils.ConcatenatedKey(tenant, id), // this are used to get the host IDs from cache utils.ReplicatorSv1RemoveStatQueue, &utils.TenantIDWithOpts{ TenantID: &utils.TenantID{Tenant: tenant, ID: id}, Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply) + }}) } return } @@ -877,8 +871,9 @@ func (dm *DataManager) GetFilter(tenant, id string, cacheRead, cacheWrite bool, &utils.TenantIDWithOpts{ TenantID: &utils.TenantID{Tenant: tenant, ID: id}, Opts: map[string]interface{}{ - utils.OptsAPIKey: itm.APIKey, - utils.OptsRouteID: itm.RouteID, + utils.OptsAPIKey: itm.APIKey, + utils.OptsRouteID: itm.RouteID, + utils.RemoteHostOpt: utils.FirstNonEmpty(config.CgrConfig().DataDbCfg().RmtConnID, config.CgrConfig().GeneralCfg().NodeID), }}, &fltr); err == nil { err = dm.dataDB.SetFilterDrv(fltr) } @@ -909,8 +904,7 @@ func (dm *DataManager) GetFilter(tenant, id string, cacheRead, cacheWrite bool, func (dm *DataManager) SetFilter(fltr *Filter, withIndex bool) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } var oldFlt *Filter if oldFlt, err = dm.GetFilter(fltr.Tenant, fltr.ID, true, false, @@ -926,26 +920,23 @@ func (dm *DataManager) SetFilter(fltr *Filter, withIndex bool) (err error) { } } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaFilters]; itm.Replicate { - var reply string - if err = dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, + err = replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.FilterPrefix, fltr.TenantID(), // this are used to get the host IDs from cache utils.ReplicatorSv1SetFilter, &FilterWithOpts{ Filter: fltr, Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply); err != nil { - err = utils.CastRPCErr(err) - return - } + }}) } return } func (dm *DataManager) RemoveFilter(tenant, id, transactionID string, withIndex bool) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } var oldFlt *Filter if oldFlt, err = dm.GetFilter(tenant, id, true, false, @@ -974,15 +965,16 @@ func (dm *DataManager) RemoveFilter(tenant, id, transactionID string, withIndex return utils.ErrNotFound } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaFilters]; itm.Replicate { - var reply string - dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, + replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.FilterPrefix, utils.ConcatenatedKey(tenant, id), // this are used to get the host IDs from cache utils.ReplicatorSv1RemoveFilter, &utils.TenantIDWithOpts{ TenantID: &utils.TenantID{Tenant: tenant, ID: id}, Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply) + }}) } return } @@ -1009,8 +1001,9 @@ func (dm *DataManager) GetThreshold(tenant, id string, utils.ReplicatorSv1GetThreshold, &utils.TenantIDWithOpts{ TenantID: &utils.TenantID{Tenant: tenant, ID: id}, Opts: map[string]interface{}{ - utils.OptsAPIKey: itm.APIKey, - utils.OptsRouteID: itm.RouteID, + utils.OptsAPIKey: itm.APIKey, + utils.OptsRouteID: itm.RouteID, + utils.RemoteHostOpt: utils.FirstNonEmpty(config.CgrConfig().DataDbCfg().RmtConnID, config.CgrConfig().GeneralCfg().NodeID), }}, &th); err == nil { err = dm.dataDB.SetThresholdDrv(th) } @@ -1037,8 +1030,7 @@ func (dm *DataManager) GetThreshold(tenant, id string, func (dm *DataManager) SetThreshold(th *Threshold, snooze time.Duration, simpleSet bool) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } if !simpleSet { tnt := th.Tenant // save the tenant @@ -1062,39 +1054,38 @@ func (dm *DataManager) SetThreshold(th *Threshold, snooze time.Duration, simpleS return } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaThresholds]; itm.Replicate { - var reply string - if err = dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, + err = replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.ThresholdPrefix, th.TenantID(), // this are used to get the host IDs from cache utils.ReplicatorSv1SetThreshold, &ThresholdWithOpts{ Threshold: th, Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply); err != nil { - err = utils.CastRPCErr(err) - return - } + }}) } return } func (dm *DataManager) RemoveThreshold(tenant, id, transactionID string) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } if err = dm.DataDB().RemoveThresholdDrv(tenant, id); err != nil { return } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaThresholds]; itm.Replicate { - var reply string - dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, utils.ReplicatorSv1RemoveThreshold, + replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.ThresholdPrefix, utils.ConcatenatedKey(tenant, id), // this are used to get the host IDs from cache + utils.ReplicatorSv1RemoveThreshold, &utils.TenantIDWithOpts{ TenantID: &utils.TenantID{Tenant: tenant, ID: id}, Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply) + }}) } return } @@ -1122,8 +1113,9 @@ func (dm *DataManager) GetThresholdProfile(tenant, id string, cacheRead, cacheWr &utils.TenantIDWithOpts{ TenantID: &utils.TenantID{Tenant: tenant, ID: id}, Opts: map[string]interface{}{ - utils.OptsAPIKey: itm.APIKey, - utils.OptsRouteID: itm.RouteID, + utils.OptsAPIKey: itm.APIKey, + utils.OptsRouteID: itm.RouteID, + utils.RemoteHostOpt: utils.FirstNonEmpty(config.CgrConfig().DataDbCfg().RmtConnID, config.CgrConfig().GeneralCfg().NodeID), }}, &th); err == nil { err = dm.dataDB.SetThresholdProfileDrv(th) } @@ -1151,8 +1143,7 @@ func (dm *DataManager) GetThresholdProfile(tenant, id string, cacheRead, cacheWr func (dm *DataManager) SetThresholdProfile(th *ThresholdProfile, withIndex bool) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } if withIndex { if brokenReference := dm.checkFilters(th.Tenant, th.FilterIDs); len(brokenReference) != 0 { @@ -1179,19 +1170,16 @@ func (dm *DataManager) SetThresholdProfile(th *ThresholdProfile, withIndex bool) } } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaThresholdProfiles]; itm.Replicate { - var reply string - if err = dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, + err = replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.ThresholdProfilePrefix, th.TenantID(), // this are used to get the host IDs from cache utils.ReplicatorSv1SetThresholdProfile, &ThresholdProfileWithOpts{ ThresholdProfile: th, Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }, - }, &reply); err != nil { - err = utils.CastRPCErr(err) - return - } + }}) } return } @@ -1199,8 +1187,7 @@ func (dm *DataManager) SetThresholdProfile(th *ThresholdProfile, withIndex bool) func (dm *DataManager) RemoveThresholdProfile(tenant, id, transactionID string, withIndex bool) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } oldTh, err := dm.GetThresholdProfile(tenant, id, true, false, utils.NonTransactional) if err != nil && err != utils.ErrNotFound { @@ -1222,14 +1209,16 @@ func (dm *DataManager) RemoveThresholdProfile(tenant, id, } } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaThresholdProfiles]; itm.Replicate { - var reply string - dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, utils.ReplicatorSv1RemoveThresholdProfile, + replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.ThresholdProfilePrefix, utils.ConcatenatedKey(tenant, id), // this are used to get the host IDs from cache + utils.ReplicatorSv1RemoveThresholdProfile, &utils.TenantIDWithOpts{ TenantID: &utils.TenantID{Tenant: tenant, ID: id}, Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply) + }}) } return } @@ -1257,8 +1246,9 @@ func (dm *DataManager) GetStatQueueProfile(tenant, id string, cacheRead, cacheWr &utils.TenantIDWithOpts{ TenantID: &utils.TenantID{Tenant: tenant, ID: id}, Opts: map[string]interface{}{ - utils.OptsAPIKey: itm.APIKey, - utils.OptsRouteID: itm.RouteID, + utils.OptsAPIKey: itm.APIKey, + utils.OptsRouteID: itm.RouteID, + utils.RemoteHostOpt: utils.FirstNonEmpty(config.CgrConfig().DataDbCfg().RmtConnID, config.CgrConfig().GeneralCfg().NodeID), }}, &sqp); err == nil { err = dm.dataDB.SetStatQueueProfileDrv(sqp) } @@ -1286,8 +1276,7 @@ func (dm *DataManager) GetStatQueueProfile(tenant, id string, cacheRead, cacheWr func (dm *DataManager) SetStatQueueProfile(sqp *StatQueueProfile, withIndex bool) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } if withIndex { if brokenReference := dm.checkFilters(sqp.Tenant, sqp.FilterIDs); len(brokenReference) != 0 { @@ -1314,18 +1303,16 @@ func (dm *DataManager) SetStatQueueProfile(sqp *StatQueueProfile, withIndex bool } } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaStatQueueProfiles]; itm.Replicate { - var reply string - if err = dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, + err = replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.StatQueueProfilePrefix, sqp.TenantID(), // this are used to get the host IDs from cache utils.ReplicatorSv1SetStatQueueProfile, &StatQueueProfileWithOpts{ StatQueueProfile: sqp, Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply); err != nil { - err = utils.CastRPCErr(err) - return - } + }}) } return } @@ -1333,8 +1320,7 @@ func (dm *DataManager) SetStatQueueProfile(sqp *StatQueueProfile, withIndex bool func (dm *DataManager) RemoveStatQueueProfile(tenant, id, transactionID string, withIndex bool) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } oldSts, err := dm.GetStatQueueProfile(tenant, id, true, false, utils.NonTransactional) if err != nil && err != utils.ErrNotFound { @@ -1356,14 +1342,16 @@ func (dm *DataManager) RemoveStatQueueProfile(tenant, id, } } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaStatQueueProfiles]; itm.Replicate { - var reply string - dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, utils.ReplicatorSv1RemoveStatQueueProfile, + replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.StatQueueProfilePrefix, utils.ConcatenatedKey(tenant, id), // this are used to get the host IDs from cache + utils.ReplicatorSv1RemoveStatQueueProfile, &utils.TenantIDWithOpts{ TenantID: &utils.TenantID{Tenant: tenant, ID: id}, Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply) + }}) } return } @@ -1390,8 +1378,9 @@ func (dm *DataManager) GetTiming(id string, skipCache bool, Arg: id, Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, Opts: map[string]interface{}{ - utils.OptsAPIKey: itm.APIKey, - utils.OptsRouteID: itm.RouteID, + utils.OptsAPIKey: itm.APIKey, + utils.OptsRouteID: itm.RouteID, + utils.RemoteHostOpt: utils.FirstNonEmpty(config.CgrConfig().DataDbCfg().RmtConnID, config.CgrConfig().GeneralCfg().NodeID), }, }, &t); err == nil { err = dm.dataDB.SetTimingDrv(t) @@ -1418,8 +1407,7 @@ func (dm *DataManager) GetTiming(id string, skipCache bool, func (dm *DataManager) SetTiming(t *utils.TPTiming) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } if err = dm.DataDB().SetTimingDrv(t); err != nil { return @@ -1428,26 +1416,23 @@ func (dm *DataManager) SetTiming(t *utils.TPTiming) (err error) { return } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaTimings]; itm.Replicate { - var reply string - if err = dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, + err = replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.TimingsPrefix, t.ID, // this are used to get the host IDs from cache utils.ReplicatorSv1SetTiming, &utils.TPTimingWithOpts{ TPTiming: t, Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply); err != nil { - err = utils.CastRPCErr(err) - return - } + }}) } return } func (dm *DataManager) RemoveTiming(id, transactionID string) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } if err = dm.DataDB().RemoveTimingDrv(id); err != nil { return @@ -1487,8 +1472,9 @@ func (dm *DataManager) GetResource(tenant, id string, cacheRead, cacheWrite bool &utils.TenantIDWithOpts{ TenantID: &utils.TenantID{Tenant: tenant, ID: id}, Opts: map[string]interface{}{ - utils.OptsAPIKey: itm.APIKey, - utils.OptsRouteID: itm.RouteID, + utils.OptsAPIKey: itm.APIKey, + utils.OptsRouteID: itm.RouteID, + utils.RemoteHostOpt: utils.FirstNonEmpty(config.CgrConfig().DataDbCfg().RmtConnID, config.CgrConfig().GeneralCfg().NodeID), }}, &rs); err == nil { err = dm.dataDB.SetResourceDrv(rs) } @@ -1516,8 +1502,7 @@ func (dm *DataManager) GetResource(tenant, id string, cacheRead, cacheWrite bool func (dm *DataManager) SetResource(rs *Resource, ttl *time.Duration, usageLimit float64, simpleSet bool) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } if !simpleSet { // do stuff @@ -1549,40 +1534,38 @@ func (dm *DataManager) SetResource(rs *Resource, ttl *time.Duration, usageLimit return } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaResources]; itm.Replicate { - var reply string - if err = dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, + err = replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.ResourcesPrefix, rs.TenantID(), // this are used to get the host IDs from cache utils.ReplicatorSv1SetResource, &ResourceWithOpts{ Resource: rs, Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply); err != nil { - err = utils.CastRPCErr(err) - return - } + }}) } return } func (dm *DataManager) RemoveResource(tenant, id, transactionID string) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } if err = dm.DataDB().RemoveResourceDrv(tenant, id); err != nil { return } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaResources]; itm.Replicate { - var reply string - dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, + replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.ResourcesPrefix, utils.ConcatenatedKey(tenant, id), // this are used to get the host IDs from cache utils.ReplicatorSv1RemoveResource, &utils.TenantIDWithOpts{ TenantID: &utils.TenantID{Tenant: tenant, ID: id}, Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply) + }}) } return } @@ -1609,8 +1592,9 @@ func (dm *DataManager) GetResourceProfile(tenant, id string, cacheRead, cacheWri utils.ReplicatorSv1GetResourceProfile, &utils.TenantIDWithOpts{ TenantID: &utils.TenantID{Tenant: tenant, ID: id}, Opts: map[string]interface{}{ - utils.OptsAPIKey: itm.APIKey, - utils.OptsRouteID: itm.RouteID, + utils.OptsAPIKey: itm.APIKey, + utils.OptsRouteID: itm.RouteID, + utils.RemoteHostOpt: utils.FirstNonEmpty(config.CgrConfig().DataDbCfg().RmtConnID, config.CgrConfig().GeneralCfg().NodeID), }}, &rp); err == nil { err = dm.dataDB.SetResourceProfileDrv(rp) } @@ -1638,8 +1622,7 @@ func (dm *DataManager) GetResourceProfile(tenant, id string, cacheRead, cacheWri func (dm *DataManager) SetResourceProfile(rp *ResourceProfile, withIndex bool) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } if withIndex { if brokenReference := dm.checkFilters(rp.Tenant, rp.FilterIDs); len(brokenReference) != 0 { @@ -1667,26 +1650,23 @@ func (dm *DataManager) SetResourceProfile(rp *ResourceProfile, withIndex bool) ( Cache.Clear([]string{utils.CacheEventResources}) } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaResourceProfile]; itm.Replicate { - var reply string - if err = dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, + err = replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.ResourceProfilesPrefix, rp.TenantID(), // this are used to get the host IDs from cache utils.ReplicatorSv1SetResourceProfile, &ResourceProfileWithOpts{ ResourceProfile: rp, Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply); err != nil { - err = utils.CastRPCErr(err) - return - } + }}) } return } func (dm *DataManager) RemoveResourceProfile(tenant, id, transactionID string, withIndex bool) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } oldRes, err := dm.GetResourceProfile(tenant, id, true, false, utils.NonTransactional) if err != nil && err != utils.ErrNotFound { @@ -1708,14 +1688,16 @@ func (dm *DataManager) RemoveResourceProfile(tenant, id, transactionID string, w } } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaResourceProfile]; itm.Replicate { - var reply string - dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, - utils.ReplicatorSv1RemoveResourceProfile, &utils.TenantIDWithOpts{ + replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.ResourceProfilesPrefix, utils.ConcatenatedKey(tenant, id), // this are used to get the host IDs from cache + utils.ReplicatorSv1RemoveResourceProfile, + &utils.TenantIDWithOpts{ TenantID: &utils.TenantID{Tenant: tenant, ID: id}, Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply) + }}) } return } @@ -1742,8 +1724,9 @@ func (dm *DataManager) GetActionTriggers(id string, skipCache bool, Arg: id, Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, Opts: map[string]interface{}{ - utils.OptsAPIKey: itm.APIKey, - utils.OptsRouteID: itm.RouteID, + utils.OptsAPIKey: itm.APIKey, + utils.OptsRouteID: itm.RouteID, + utils.RemoteHostOpt: utils.FirstNonEmpty(config.CgrConfig().DataDbCfg().RmtConnID, config.CgrConfig().GeneralCfg().NodeID), }, }, attrs); err == nil { err = dm.dataDB.SetActionTriggersDrv(id, attrs) @@ -1769,8 +1752,7 @@ func (dm *DataManager) GetActionTriggers(id string, skipCache bool, func (dm *DataManager) RemoveActionTriggers(id, transactionID string) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } if err = dm.DataDB().RemoveActionTriggersDrv(id); err != nil { return @@ -1780,8 +1762,9 @@ func (dm *DataManager) RemoveActionTriggers(id, transactionID string) (err error return errCh } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaActionTriggers]; itm.Replicate { - var reply string - dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, + replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.ActionTriggerPrefix, id, // this are used to get the host IDs from cache utils.ReplicatorSv1RemoveActionTriggers, &utils.StringWithOpts{ Arg: id, @@ -1789,7 +1772,7 @@ func (dm *DataManager) RemoveActionTriggers(id, transactionID string) (err error Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply) + }}) } return } @@ -1805,8 +1788,7 @@ type SetActionTriggersArgWithOpts struct { func (dm *DataManager) SetActionTriggers(key string, attr ActionTriggers, transactionID string) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } if err = dm.DataDB().SetActionTriggersDrv(key, attr); err != nil { return @@ -1815,19 +1797,18 @@ func (dm *DataManager) SetActionTriggers(key string, attr ActionTriggers, return } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaActionTriggers]; itm.Replicate { - var reply string - if err = dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, utils.ReplicatorSv1SetActionTriggers, + err = replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.ActionTriggerPrefix, key, // this are used to get the host IDs from cache + utils.ReplicatorSv1SetActionTriggers, &SetActionTriggersArgWithOpts{ - Attrs: attr, Key: key, + Attrs: attr, + Key: key, + Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }, - Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, - }, &reply); err != nil { - err = utils.CastRPCErr(err) - return - } + }}) } return } @@ -1854,8 +1835,9 @@ func (dm *DataManager) GetSharedGroup(key string, skipCache bool, Arg: key, Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, Opts: map[string]interface{}{ - utils.OptsAPIKey: itm.APIKey, - utils.OptsRouteID: itm.RouteID, + utils.OptsAPIKey: itm.APIKey, + utils.OptsRouteID: itm.RouteID, + utils.RemoteHostOpt: utils.FirstNonEmpty(config.CgrConfig().DataDbCfg().RmtConnID, config.CgrConfig().GeneralCfg().NodeID), }, }, &sg); err == nil { err = dm.dataDB.SetSharedGroupDrv(sg) @@ -1882,8 +1864,7 @@ func (dm *DataManager) GetSharedGroup(key string, skipCache bool, func (dm *DataManager) SetSharedGroup(sg *SharedGroup, transactionID string) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } if err = dm.DataDB().SetSharedGroupDrv(sg); err != nil { return @@ -1893,8 +1874,9 @@ func (dm *DataManager) SetSharedGroup(sg *SharedGroup, return } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaSharedGroups]; itm.Replicate { - var reply string - if err = dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, + err = replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.SharedGroupPrefix, sg.Id, // this are used to get the host IDs from cache utils.ReplicatorSv1SetSharedGroup, &SharedGroupWithOpts{ SharedGroup: sg, @@ -1902,18 +1884,14 @@ func (dm *DataManager) SetSharedGroup(sg *SharedGroup, Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply); err != nil { - err = utils.CastRPCErr(err) - return - } + }}) } return } func (dm *DataManager) RemoveSharedGroup(id, transactionID string) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } if err = dm.DataDB().RemoveSharedGroupDrv(id); err != nil { return @@ -1923,8 +1901,9 @@ func (dm *DataManager) RemoveSharedGroup(id, transactionID string) (err error) { return errCh } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaSharedGroups]; itm.Replicate { - var reply string - dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, + replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.SharedGroupPrefix, id, // this are used to get the host IDs from cache utils.ReplicatorSv1RemoveSharedGroup, &utils.StringWithOpts{ Arg: id, @@ -1932,7 +1911,7 @@ func (dm *DataManager) RemoveSharedGroup(id, transactionID string) (err error) { Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply) + }}) } return } @@ -1961,8 +1940,9 @@ func (dm *DataManager) GetActions(key string, skipCache bool, transactionID stri Arg: key, Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, Opts: map[string]interface{}{ - utils.OptsAPIKey: itm.APIKey, - utils.OptsRouteID: itm.RouteID, + utils.OptsAPIKey: itm.APIKey, + utils.OptsRouteID: itm.RouteID, + utils.RemoteHostOpt: utils.FirstNonEmpty(config.CgrConfig().DataDbCfg().RmtConnID, config.CgrConfig().GeneralCfg().NodeID), }, }, &as); err == nil { err = dm.dataDB.SetActionsDrv(key, as) @@ -1996,47 +1976,47 @@ type SetActionsArgsWithOpts struct { func (dm *DataManager) SetActions(key string, as Actions, transactionID string) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } if err = dm.DataDB().SetActionsDrv(key, as); err != nil { return } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaActions]; itm.Replicate { - var reply string - if err = dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, utils.ReplicatorSv1SetActions, + err = replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.ActionPrefix, key, // this are used to get the host IDs from cache + utils.ReplicatorSv1SetActions, &SetActionsArgsWithOpts{ - Key: key, Acs: as, + Key: key, + Acs: as, Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply); err != nil { - err = utils.CastRPCErr(err) - return - } + }}) } return } func (dm *DataManager) RemoveActions(key, transactionID string) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } if err = dm.DataDB().RemoveActionsDrv(key); err != nil { return } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaActions]; itm.Replicate { - var reply string - dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, - utils.ReplicatorSv1RemoveActions, &utils.StringWithOpts{ + replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.ActionPrefix, key, // this are used to get the host IDs from cache + utils.ReplicatorSv1RemoveActions, + &utils.StringWithOpts{ Arg: key, Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply) + }}) } return } @@ -2053,8 +2033,9 @@ func (dm *DataManager) GetActionPlan(key string, skipCache bool, transactionID s Arg: key, Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, Opts: map[string]interface{}{ - utils.OptsAPIKey: itm.APIKey, - utils.OptsRouteID: itm.RouteID, + utils.OptsAPIKey: itm.APIKey, + utils.OptsRouteID: itm.RouteID, + utils.RemoteHostOpt: utils.FirstNonEmpty(config.CgrConfig().DataDbCfg().RmtConnID, config.CgrConfig().GeneralCfg().NodeID), }, }, &ats); err == nil { err = dm.dataDB.SetActionPlanDrv(key, ats, true, utils.NonTransactional) @@ -2079,16 +2060,17 @@ type SetActionPlanArgWithOpts struct { func (dm *DataManager) SetActionPlan(key string, ats *ActionPlan, overwrite bool, transactionID string) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } if err = dm.dataDB.SetActionPlanDrv(key, ats, overwrite, transactionID); err != nil { return } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaActionPlans]; itm.Replicate { - var reply string - if err = dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, - utils.ReplicatorSv1SetActionPlan, &SetActionPlanArgWithOpts{ + err = replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.ActionPlanPrefix, key, // this are used to get the host IDs from cache + utils.ReplicatorSv1SetActionPlan, + &SetActionPlanArgWithOpts{ Key: key, Ats: ats, Overwrite: overwrite, @@ -2096,10 +2078,7 @@ func (dm *DataManager) SetActionPlan(key string, ats *ActionPlan, Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply); err != nil { - err = utils.CastRPCErr(err) - return - } + }}) } return } @@ -2117,8 +2096,9 @@ func (dm *DataManager) GetAllActionPlans() (ats map[string]*ActionPlan, err erro Arg: utils.EmptyString, Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, Opts: map[string]interface{}{ - utils.OptsAPIKey: itm.APIKey, - utils.OptsRouteID: itm.RouteID, + utils.OptsAPIKey: itm.APIKey, + utils.OptsRouteID: itm.RouteID, + utils.RemoteHostOpt: utils.FirstNonEmpty(config.CgrConfig().DataDbCfg().RmtConnID, config.CgrConfig().GeneralCfg().NodeID), }, }, &ats) } @@ -2131,15 +2111,15 @@ func (dm *DataManager) GetAllActionPlans() (ats map[string]*ActionPlan, err erro func (dm *DataManager) RemoveActionPlan(key string, transactionID string) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } if err = dm.dataDB.RemoveActionPlanDrv(key, transactionID); err != nil { return } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaActionPlans]; itm.Replicate { - var reply string - dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, + replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.ActionPlanPrefix, key, // this are used to get the host IDs from cache utils.ReplicatorSv1RemoveActionPlan, &utils.StringWithOpts{ Arg: key, @@ -2147,7 +2127,7 @@ func (dm *DataManager) RemoveActionPlan(key string, transactionID string) (err e Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply) + }}) } return } @@ -2165,8 +2145,9 @@ func (dm *DataManager) GetAccountActionPlans(acntID string, Arg: acntID, Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, Opts: map[string]interface{}{ - utils.OptsAPIKey: itm.APIKey, - utils.OptsRouteID: itm.RouteID, + utils.OptsAPIKey: itm.APIKey, + utils.OptsRouteID: itm.RouteID, + utils.RemoteHostOpt: utils.FirstNonEmpty(config.CgrConfig().DataDbCfg().RmtConnID, config.CgrConfig().GeneralCfg().NodeID), }, }, &apIDs); err == nil { err = dm.dataDB.SetAccountActionPlansDrv(acntID, apIDs, true) @@ -2190,16 +2171,17 @@ type SetAccountActionPlansArgWithOpts struct { func (dm *DataManager) SetAccountActionPlans(acntID string, aPlIDs []string, overwrite bool) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } if err = dm.dataDB.SetAccountActionPlansDrv(acntID, aPlIDs, overwrite); err != nil { return } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaAccountActionPlans]; itm.Replicate { - var reply string - if err = dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, - utils.ReplicatorSv1SetAccountActionPlans, &SetAccountActionPlansArgWithOpts{ + err = replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.AccountActionPlansPrefix, acntID, // this are used to get the host IDs from cache + utils.ReplicatorSv1SetAccountActionPlans, + &SetAccountActionPlansArgWithOpts{ AcntID: acntID, AplIDs: aPlIDs, Overwrite: overwrite, @@ -2207,10 +2189,7 @@ func (dm *DataManager) SetAccountActionPlans(acntID string, aPlIDs []string, ove Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply); err != nil { - err = utils.CastRPCErr(err) - return - } + }}) } return } @@ -2225,23 +2204,24 @@ type RemAccountActionPlansArgsWithOpts struct { func (dm *DataManager) RemAccountActionPlans(acntID string, apIDs []string) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } if err = dm.dataDB.RemAccountActionPlansDrv(acntID, apIDs); err != nil { return } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaAccountActionPlans]; itm.Replicate { - var reply string - dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, + replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.AccountActionPlansPrefix, acntID, // this are used to get the host IDs from cache utils.ReplicatorSv1RemAccountActionPlans, &RemAccountActionPlansArgsWithOpts{ - AcntID: acntID, ApIDs: apIDs, + AcntID: acntID, + ApIDs: apIDs, Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply) + }}) } return } @@ -2269,8 +2249,9 @@ func (dm *DataManager) GetRatingPlan(key string, skipCache bool, Arg: key, Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, Opts: map[string]interface{}{ - utils.OptsAPIKey: itm.APIKey, - utils.OptsRouteID: itm.RouteID, + utils.OptsAPIKey: itm.APIKey, + utils.OptsRouteID: itm.RouteID, + utils.RemoteHostOpt: utils.FirstNonEmpty(config.CgrConfig().DataDbCfg().RmtConnID, config.CgrConfig().GeneralCfg().NodeID), }, }, &rp); err == nil { err = dm.dataDB.SetRatingPlanDrv(rp) @@ -2296,8 +2277,7 @@ func (dm *DataManager) GetRatingPlan(key string, skipCache bool, func (dm *DataManager) SetRatingPlan(rp *RatingPlan, transactionID string) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } if err = dm.DataDB().SetRatingPlanDrv(rp); err != nil { return @@ -2306,8 +2286,9 @@ func (dm *DataManager) SetRatingPlan(rp *RatingPlan, transactionID string) (err return } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaRatingPlans]; itm.Replicate { - var reply string - if err = dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, + err = replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.RatingPlanPrefix, rp.Id, // this are used to get the host IDs from cache utils.ReplicatorSv1SetRatingPlan, &RatingPlanWithOpts{ RatingPlan: rp, @@ -2315,18 +2296,14 @@ func (dm *DataManager) SetRatingPlan(rp *RatingPlan, transactionID string) (err Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply); err != nil { - err = utils.CastRPCErr(err) - return - } + }}) } return } func (dm *DataManager) RemoveRatingPlan(key string, transactionID string) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } if err = dm.DataDB().RemoveRatingPlanDrv(key); err != nil { return @@ -2336,8 +2313,9 @@ func (dm *DataManager) RemoveRatingPlan(key string, transactionID string) (err e return errCh } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaRatingPlans]; itm.Replicate { - var reply string - dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, + replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.RatingPlanPrefix, key, // this are used to get the host IDs from cache utils.ReplicatorSv1RemoveRatingPlan, &utils.StringWithOpts{ Arg: key, @@ -2345,7 +2323,7 @@ func (dm *DataManager) RemoveRatingPlan(key string, transactionID string) (err e Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply) + }}) } return } @@ -2376,8 +2354,9 @@ func (dm *DataManager) GetRatingProfile(key string, skipCache bool, Arg: key, Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, Opts: map[string]interface{}{ - utils.OptsAPIKey: itm.APIKey, - utils.OptsRouteID: itm.RouteID, + utils.OptsAPIKey: itm.APIKey, + utils.OptsRouteID: itm.RouteID, + utils.RemoteHostOpt: utils.FirstNonEmpty(config.CgrConfig().DataDbCfg().RmtConnID, config.CgrConfig().GeneralCfg().NodeID), }, }, &rpf); err == nil { err = dm.dataDB.SetRatingProfileDrv(rpf) @@ -2404,15 +2383,15 @@ func (dm *DataManager) GetRatingProfile(key string, skipCache bool, func (dm *DataManager) SetRatingProfile(rpf *RatingProfile, transactionID string) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } if err = dm.DataDB().SetRatingProfileDrv(rpf); err != nil { return } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaRatingProfiles]; itm.Replicate { - var reply string - if err = dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, + err = replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.RatingProfilePrefix, rpf.Id, // this are used to get the host IDs from cache utils.ReplicatorSv1SetRatingProfile, &RatingProfileWithOpts{ RatingProfile: rpf, @@ -2420,10 +2399,7 @@ func (dm *DataManager) SetRatingProfile(rpf *RatingProfile, Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply); err != nil { - err = utils.CastRPCErr(err) - return - } + }}) } return } @@ -2431,15 +2407,15 @@ func (dm *DataManager) SetRatingProfile(rpf *RatingProfile, func (dm *DataManager) RemoveRatingProfile(key string, transactionID string) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } if err = dm.DataDB().RemoveRatingProfileDrv(key); err != nil { return } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaRatingProfiles]; itm.Replicate { - var reply string - dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, + replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.RatingProfilePrefix, key, // this are used to get the host IDs from cache utils.ReplicatorSv1RemoveRatingProfile, &utils.StringWithOpts{ Arg: key, @@ -2447,7 +2423,7 @@ func (dm *DataManager) RemoveRatingProfile(key string, Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply) + }}) } return } @@ -2482,8 +2458,9 @@ func (dm *DataManager) GetRouteProfile(tenant, id string, cacheRead, cacheWrite &utils.TenantIDWithOpts{ TenantID: &utils.TenantID{Tenant: tenant, ID: id}, Opts: map[string]interface{}{ - utils.OptsAPIKey: itm.APIKey, - utils.OptsRouteID: itm.RouteID, + utils.OptsAPIKey: itm.APIKey, + utils.OptsRouteID: itm.RouteID, + utils.RemoteHostOpt: utils.FirstNonEmpty(config.CgrConfig().DataDbCfg().RmtConnID, config.CgrConfig().GeneralCfg().NodeID), }}, &rpp); err == nil { err = dm.dataDB.SetRouteProfileDrv(rpp) } @@ -2515,8 +2492,7 @@ func (dm *DataManager) GetRouteProfile(tenant, id string, cacheRead, cacheWrite func (dm *DataManager) SetRouteProfile(rpp *RouteProfile, withIndex bool) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } if withIndex { if brokenReference := dm.checkFilters(rpp.Tenant, rpp.FilterIDs); len(brokenReference) != 0 { @@ -2543,26 +2519,23 @@ func (dm *DataManager) SetRouteProfile(rpp *RouteProfile, withIndex bool) (err e } } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaRouteProfiles]; itm.Replicate { - var reply string - if err = dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, + err = replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.RouteProfilePrefix, rpp.TenantID(), // this are used to get the host IDs from cache utils.ReplicatorSv1SetRouteProfile, &RouteProfileWithOpts{ RouteProfile: rpp, Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply); err != nil { - err = utils.CastRPCErr(err) - return - } + }}) } return } func (dm *DataManager) RemoveRouteProfile(tenant, id, transactionID string, withIndex bool) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } oldRpp, err := dm.GetRouteProfile(tenant, id, true, false, utils.NonTransactional) if err != nil && err != utils.ErrNotFound { @@ -2584,15 +2557,16 @@ func (dm *DataManager) RemoveRouteProfile(tenant, id, transactionID string, with } } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaRouteProfiles]; itm.Replicate { - var reply string - dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, + replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.RouteProfilePrefix, utils.ConcatenatedKey(tenant, id), // this are used to get the host IDs from cache utils.ReplicatorSv1RemoveRouteProfile, &utils.TenantIDWithOpts{ TenantID: &utils.TenantID{Tenant: tenant, ID: id}, Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply) + }}) } return } @@ -2623,8 +2597,9 @@ func (dm *DataManager) GetAttributeProfile(tenant, id string, cacheRead, cacheWr &utils.TenantIDWithOpts{ TenantID: &utils.TenantID{Tenant: tenant, ID: id}, Opts: map[string]interface{}{ - utils.OptsAPIKey: itm.APIKey, - utils.OptsRouteID: itm.RouteID, + utils.OptsAPIKey: itm.APIKey, + utils.OptsRouteID: itm.RouteID, + utils.RemoteHostOpt: utils.FirstNonEmpty(config.CgrConfig().DataDbCfg().RmtConnID, config.CgrConfig().GeneralCfg().NodeID), }}, &attrPrfl); err == nil { err = dm.dataDB.SetAttributeProfileDrv(attrPrfl) } @@ -2656,8 +2631,7 @@ func (dm *DataManager) GetAttributeProfile(tenant, id string, cacheRead, cacheWr func (dm *DataManager) SetAttributeProfile(ap *AttributeProfile, withIndex bool) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } if withIndex { if brokenReference := dm.checkFilters(ap.Tenant, ap.FilterIDs); len(brokenReference) != 0 { @@ -2686,26 +2660,23 @@ func (dm *DataManager) SetAttributeProfile(ap *AttributeProfile, withIndex bool) } } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaAttributeProfiles]; itm.Replicate { - var reply string - if err = dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, + err = replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.AttributeProfilePrefix, ap.TenantID(), // this are used to get the host IDs from cache utils.ReplicatorSv1SetAttributeProfile, &AttributeProfileWithOpts{ AttributeProfile: ap, Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply); err != nil { - err = utils.CastRPCErr(err) - return - } + }}) } return } func (dm *DataManager) RemoveAttributeProfile(tenant, id string, transactionID string, withIndex bool) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } oldAttr, err := dm.GetAttributeProfile(tenant, id, true, false, utils.NonTransactional) if err != nil { @@ -2729,15 +2700,16 @@ func (dm *DataManager) RemoveAttributeProfile(tenant, id string, transactionID s } } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaAttributeProfiles]; itm.Replicate { - var reply string - dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, + replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.AttributeProfilePrefix, utils.ConcatenatedKey(tenant, id), // this are used to get the host IDs from cache utils.ReplicatorSv1RemoveAttributeProfile, &utils.TenantIDWithOpts{ TenantID: &utils.TenantID{Tenant: tenant, ID: id}, Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply) + }}) } return } @@ -2765,8 +2737,9 @@ func (dm *DataManager) GetChargerProfile(tenant, id string, cacheRead, cacheWrit &utils.TenantIDWithOpts{ TenantID: &utils.TenantID{Tenant: tenant, ID: id}, Opts: map[string]interface{}{ - utils.OptsAPIKey: itm.APIKey, - utils.OptsRouteID: itm.RouteID, + utils.OptsAPIKey: itm.APIKey, + utils.OptsRouteID: itm.RouteID, + utils.RemoteHostOpt: utils.FirstNonEmpty(config.CgrConfig().DataDbCfg().RmtConnID, config.CgrConfig().GeneralCfg().NodeID), }}, &cpp); err == nil { err = dm.dataDB.SetChargerProfileDrv(cpp) } @@ -2794,8 +2767,7 @@ func (dm *DataManager) GetChargerProfile(tenant, id string, cacheRead, cacheWrit func (dm *DataManager) SetChargerProfile(cpp *ChargerProfile, withIndex bool) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } if withIndex { if brokenReference := dm.checkFilters(cpp.Tenant, cpp.FilterIDs); len(brokenReference) != 0 { @@ -2822,18 +2794,16 @@ func (dm *DataManager) SetChargerProfile(cpp *ChargerProfile, withIndex bool) (e } } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaChargerProfiles]; itm.Replicate { - var reply string - if err = dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, + err = replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.ChargerProfilePrefix, cpp.TenantID(), // this are used to get the host IDs from cache utils.ReplicatorSv1SetChargerProfile, &ChargerProfileWithOpts{ ChargerProfile: cpp, Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply); err != nil { - err = utils.CastRPCErr(err) - return - } + }}) } return } @@ -2841,8 +2811,7 @@ func (dm *DataManager) SetChargerProfile(cpp *ChargerProfile, withIndex bool) (e func (dm *DataManager) RemoveChargerProfile(tenant, id string, transactionID string, withIndex bool) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } oldCpp, err := dm.GetChargerProfile(tenant, id, true, false, utils.NonTransactional) if err != nil && err != utils.ErrNotFound { @@ -2864,15 +2833,16 @@ func (dm *DataManager) RemoveChargerProfile(tenant, id string, } } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaChargerProfiles]; itm.Replicate { - var reply string - dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, + replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.ChargerProfilePrefix, utils.ConcatenatedKey(tenant, id), // this are used to get the host IDs from cache utils.ReplicatorSv1RemoveChargerProfile, &utils.TenantIDWithOpts{ TenantID: &utils.TenantID{Tenant: tenant, ID: id}, Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply) + }}) } return } @@ -2900,8 +2870,9 @@ func (dm *DataManager) GetDispatcherProfile(tenant, id string, cacheRead, cacheW &utils.TenantIDWithOpts{ TenantID: &utils.TenantID{Tenant: tenant, ID: id}, Opts: map[string]interface{}{ - utils.OptsAPIKey: itm.APIKey, - utils.OptsRouteID: itm.RouteID, + utils.OptsAPIKey: itm.APIKey, + utils.OptsRouteID: itm.RouteID, + utils.RemoteHostOpt: utils.FirstNonEmpty(config.CgrConfig().DataDbCfg().RmtConnID, config.CgrConfig().GeneralCfg().NodeID), }}, &dpp); err == nil { err = dm.dataDB.SetDispatcherProfileDrv(dpp) } @@ -2929,8 +2900,7 @@ func (dm *DataManager) GetDispatcherProfile(tenant, id string, cacheRead, cacheW func (dm *DataManager) SetDispatcherProfile(dpp *DispatcherProfile, withIndex bool) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } if withIndex { if brokenReference := dm.checkFilters(dpp.Tenant, dpp.FilterIDs); len(brokenReference) != 0 { @@ -2959,18 +2929,16 @@ func (dm *DataManager) SetDispatcherProfile(dpp *DispatcherProfile, withIndex bo } } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaDispatcherProfiles]; itm.Replicate { - var reply string - if err = dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, + err = replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.DispatcherProfilePrefix, dpp.TenantID(), // this are used to get the host IDs from cache utils.ReplicatorSv1SetDispatcherProfile, &DispatcherProfileWithOpts{ DispatcherProfile: dpp, Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply); err != nil { - err = utils.CastRPCErr(err) - return - } + }}) } return } @@ -2978,8 +2946,7 @@ func (dm *DataManager) SetDispatcherProfile(dpp *DispatcherProfile, withIndex bo func (dm *DataManager) RemoveDispatcherProfile(tenant, id string, transactionID string, withIndex bool) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } oldDpp, err := dm.GetDispatcherProfile(tenant, id, true, false, utils.NonTransactional) if err != nil && err != utils.ErrNotFound { @@ -3003,15 +2970,16 @@ func (dm *DataManager) RemoveDispatcherProfile(tenant, id string, } } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaDispatcherProfiles]; itm.Replicate { - var reply string - dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, + replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.DispatcherProfilePrefix, utils.ConcatenatedKey(tenant, id), // this are used to get the host IDs from cache utils.ReplicatorSv1RemoveDispatcherProfile, &utils.TenantIDWithOpts{ TenantID: &utils.TenantID{Tenant: tenant, ID: id}, Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply) + }}) } return } @@ -3039,8 +3007,9 @@ func (dm *DataManager) GetDispatcherHost(tenant, id string, cacheRead, cacheWrit &utils.TenantIDWithOpts{ TenantID: &utils.TenantID{Tenant: tenant, ID: id}, Opts: map[string]interface{}{ - utils.OptsAPIKey: itm.APIKey, - utils.OptsRouteID: itm.RouteID, + utils.OptsAPIKey: itm.APIKey, + utils.OptsRouteID: itm.RouteID, + utils.RemoteHostOpt: utils.FirstNonEmpty(config.CgrConfig().DataDbCfg().RmtConnID, config.CgrConfig().GeneralCfg().NodeID), }}, &dH); err == nil { err = dm.dataDB.SetDispatcherHostDrv(dH) } @@ -3068,25 +3037,22 @@ func (dm *DataManager) GetDispatcherHost(tenant, id string, cacheRead, cacheWrit func (dm *DataManager) SetDispatcherHost(dpp *DispatcherHost) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } if err = dm.DataDB().SetDispatcherHostDrv(dpp); err != nil { return } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaDispatcherHosts]; itm.Replicate { - var reply string - if err = dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, + err = replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.DispatcherHostPrefix, dpp.TenantID(), // this are used to get the host IDs from cache utils.ReplicatorSv1SetDispatcherHost, &DispatcherHostWithOpts{ DispatcherHost: dpp, Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply); err != nil { - err = utils.CastRPCErr(err) - return - } + }}) } return } @@ -3094,8 +3060,7 @@ func (dm *DataManager) SetDispatcherHost(dpp *DispatcherHost) (err error) { func (dm *DataManager) RemoveDispatcherHost(tenant, id string, transactionID string) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } oldDpp, err := dm.GetDispatcherHost(tenant, id, true, false, utils.NonTransactional) if err != nil && err != utils.ErrNotFound { @@ -3108,15 +3073,16 @@ func (dm *DataManager) RemoveDispatcherHost(tenant, id string, return utils.ErrNotFound } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaDispatcherHosts]; itm.Replicate { - var reply string - dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, + replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.DispatcherHostPrefix, utils.ConcatenatedKey(tenant, id), // this are used to get the host IDs from cache utils.ReplicatorSv1RemoveDispatcherHost, &utils.TenantIDWithOpts{ TenantID: &utils.TenantID{Tenant: tenant, ID: id}, Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply) + }}) } return } @@ -3135,8 +3101,9 @@ func (dm *DataManager) GetItemLoadIDs(itemIDPrefix string, cacheWrite bool) (loa Arg: itemIDPrefix, Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, Opts: map[string]interface{}{ - utils.OptsAPIKey: itm.APIKey, - utils.OptsRouteID: itm.RouteID, + utils.OptsAPIKey: itm.APIKey, + utils.OptsRouteID: itm.RouteID, + utils.RemoteHostOpt: utils.FirstNonEmpty(config.CgrConfig().DataDbCfg().RmtConnID, config.CgrConfig().GeneralCfg().NodeID), }, }, &loadIDs); err == nil { err = dm.dataDB.SetLoadIDsDrv(loadIDs) @@ -3167,17 +3134,22 @@ func (dm *DataManager) GetItemLoadIDs(itemIDPrefix string, cacheWrite bool) (loa return } +// SetLoadIDs sets the loadIDs in the DB func (dm *DataManager) SetLoadIDs(loadIDs map[string]int64) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } if err = dm.DataDB().SetLoadIDsDrv(loadIDs); err != nil { return } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaLoadIDs]; itm.Replicate { - var reply string - if err = dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, + objIDs := make([]string, 0, len(loadIDs)) + for k := range loadIDs { + objIDs = append(objIDs, k) + } + err = replicateMultipleIDs(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.LoadIDPrefix, objIDs, // this are used to get the host IDs from cache utils.ReplicatorSv1SetLoadIDs, &utils.LoadIDsWithOpts{ LoadIDs: loadIDs, @@ -3185,10 +3157,7 @@ func (dm *DataManager) SetLoadIDs(loadIDs map[string]int64) (err error) { Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply); err != nil { - err = utils.CastRPCErr(err) - return - } + }}) } return } @@ -3216,8 +3185,9 @@ func (dm *DataManager) GetRateProfile(tenant, id string, cacheRead, cacheWrite b &utils.TenantIDWithOpts{ TenantID: &utils.TenantID{Tenant: tenant, ID: id}, Opts: map[string]interface{}{ - utils.OptsAPIKey: itm.APIKey, - utils.OptsRouteID: itm.RouteID, + utils.OptsAPIKey: itm.APIKey, + utils.OptsRouteID: itm.RouteID, + utils.RemoteHostOpt: utils.FirstNonEmpty(config.CgrConfig().DataDbCfg().RmtConnID, config.CgrConfig().GeneralCfg().NodeID), }}, &rpp); err == nil { rpp.Sort() err = dm.dataDB.SetRateProfileDrv(rpp) @@ -3249,8 +3219,7 @@ func (dm *DataManager) GetRateProfile(tenant, id string, cacheRead, cacheWrite b func (dm *DataManager) SetRateProfile(rpp *RateProfile, withIndex bool) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } if withIndex { if brokenReference := dm.checkFilters(rpp.Tenant, rpp.FilterIDs); len(brokenReference) != 0 { @@ -3305,18 +3274,16 @@ func (dm *DataManager) SetRateProfile(rpp *RateProfile, withIndex bool) (err err } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaRateProfiles]; itm.Replicate { - var reply string - if err = dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, + err = replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.RateProfilePrefix, rpp.TenantID(), // this are used to get the host IDs from cache utils.ReplicatorSv1SetRateProfile, &RateProfileWithOpts{ RateProfile: rpp, Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply); err != nil { - err = utils.CastRPCErr(err) - return - } + }}) } return } @@ -3324,8 +3291,7 @@ func (dm *DataManager) SetRateProfile(rpp *RateProfile, withIndex bool) (err err func (dm *DataManager) RemoveRateProfile(tenant, id string, transactionID string, withIndex bool) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } oldRpp, err := dm.GetRateProfile(tenant, id, true, false, utils.NonTransactional) if err != nil && err != utils.ErrNotFound { @@ -3350,23 +3316,23 @@ func (dm *DataManager) RemoveRateProfile(tenant, id string, } } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaRateProfiles]; itm.Replicate { - var reply string - dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, + replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.RateProfilePrefix, utils.ConcatenatedKey(tenant, id), // this are used to get the host IDs from cache utils.ReplicatorSv1RemoveRateProfile, &utils.TenantIDWithOpts{ TenantID: &utils.TenantID{Tenant: tenant, ID: id}, Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply) + }}) } return } func (dm *DataManager) RemoveRateProfileRates(tenant, id string, rateIDs []string, withIndex bool) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } oldRpp, err := dm.GetRateProfile(tenant, id, true, false, utils.NonTransactional) if err != nil { @@ -3402,26 +3368,23 @@ func (dm *DataManager) RemoveRateProfileRates(tenant, id string, rateIDs []strin } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaRateProfiles]; itm.Replicate { - var reply string - if err = dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, + err = replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.RateProfilePrefix, oldRpp.TenantID(), // this are used to get the host IDs from cache utils.ReplicatorSv1SetRateProfile, &RateProfileWithOpts{ RateProfile: oldRpp, Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply); err != nil { - err = utils.CastRPCErr(err) - return - } + }}) } return } func (dm *DataManager) SetRateProfileRates(rpp *RateProfile, withIndex bool) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } if withIndex { for _, rate := range rpp.Rates { @@ -3457,18 +3420,16 @@ func (dm *DataManager) SetRateProfileRates(rpp *RateProfile, withIndex bool) (er } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaRateProfiles]; itm.Replicate { - var reply string - if err = dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, + err = replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.RateProfilePrefix, oldRpp.TenantID(), // this are used to get the host IDs from cache utils.ReplicatorSv1SetRateProfile, &RateProfileWithOpts{ RateProfile: oldRpp, Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply); err != nil { - err = utils.CastRPCErr(err) - return - } + }}) } return } @@ -3496,8 +3457,9 @@ func (dm *DataManager) GetActionProfile(tenant, id string, cacheRead, cacheWrite &utils.TenantIDWithOpts{ TenantID: &utils.TenantID{Tenant: tenant, ID: id}, Opts: map[string]interface{}{ - utils.OptsAPIKey: itm.APIKey, - utils.OptsRouteID: itm.RouteID, + utils.OptsAPIKey: itm.APIKey, + utils.OptsRouteID: itm.RouteID, + utils.RemoteHostOpt: utils.FirstNonEmpty(config.CgrConfig().DataDbCfg().RmtConnID, config.CgrConfig().GeneralCfg().NodeID), }}, &ap); err == nil { err = dm.dataDB.SetActionProfileDrv(ap) } @@ -3525,8 +3487,7 @@ func (dm *DataManager) GetActionProfile(tenant, id string, cacheRead, cacheWrite func (dm *DataManager) SetActionProfile(ap *ActionProfile, withIndex bool) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } if withIndex { if brokenReference := dm.checkFilters(ap.Tenant, ap.FilterIDs); len(brokenReference) != 0 { @@ -3553,18 +3514,16 @@ func (dm *DataManager) SetActionProfile(ap *ActionProfile, withIndex bool) (err } } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaActionProfiles]; itm.Replicate { - var reply string - if err = dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, + err = replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.ActionProfilePrefix, ap.TenantID(), // this are used to get the host IDs from cache utils.ReplicatorSv1SetActionProfile, &ActionProfileWithOpts{ ActionProfile: ap, Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply); err != nil { - err = utils.CastRPCErr(err) - return - } + }}) } return } @@ -3572,8 +3531,7 @@ func (dm *DataManager) SetActionProfile(ap *ActionProfile, withIndex bool) (err func (dm *DataManager) RemoveActionProfile(tenant, id string, transactionID string, withIndex bool) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } oldRpp, err := dm.GetActionProfile(tenant, id, true, false, utils.NonTransactional) if err != nil && err != utils.ErrNotFound { @@ -3592,15 +3550,16 @@ func (dm *DataManager) RemoveActionProfile(tenant, id string, } } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaActionProfiles]; itm.Replicate { - var reply string - dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, + replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.ActionProfilePrefix, utils.ConcatenatedKey(tenant, id), // this are used to get the host IDs from cache utils.ReplicatorSv1RemoveActionProfile, &utils.TenantIDWithOpts{ TenantID: &utils.TenantID{Tenant: tenant, ID: id}, Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply) + }}) } return } @@ -3645,8 +3604,9 @@ func (dm *DataManager) GetIndexes(idxItmType, tntCtx, idxKey string, IdxKey: idxKey, Tenant: config.CgrConfig().GeneralCfg().DefaultTenant, Opts: map[string]interface{}{ - utils.OptsAPIKey: itm.APIKey, - utils.OptsRouteID: itm.RouteID, + utils.OptsAPIKey: itm.APIKey, + utils.OptsRouteID: itm.RouteID, + utils.RemoteHostOpt: utils.FirstNonEmpty(config.CgrConfig().DataDbCfg().RmtConnID, config.CgrConfig().GeneralCfg().NodeID), }, }, &indexes); err == nil { err = dm.dataDB.SetIndexesDrv(idxItmType, tntCtx, indexes, true, utils.NonTransactional) @@ -3680,16 +3640,16 @@ func (dm *DataManager) GetIndexes(idxItmType, tntCtx, idxKey string, func (dm *DataManager) SetIndexes(idxItmType, tntCtx string, indexes map[string]utils.StringSet, commit bool, transactionID string) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } if err = dm.DataDB().SetIndexesDrv(idxItmType, tntCtx, indexes, commit, transactionID); err != nil { return } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaIndexes]; itm.Replicate { - var reply string - if err = dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, + err = replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.CacheInstanceToPrefix[idxItmType], tntCtx, // this are used to get the host IDs from cache utils.ReplicatorSv1SetIndexes, &utils.SetIndexesArg{ IdxItmType: idxItmType, @@ -3699,25 +3659,22 @@ func (dm *DataManager) SetIndexes(idxItmType, tntCtx string, Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }, - }, &reply); err != nil { - err = utils.CastRPCErr(err) - } + }}) } return } func (dm *DataManager) RemoveIndexes(idxItmType, tntCtx, idxKey string) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } if err = dm.DataDB().RemoveIndexesDrv(idxItmType, tntCtx, idxKey); err != nil { return } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaIndexes]; itm.Replicate { - var reply string - if err = dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, + replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.CacheInstanceToPrefix[idxItmType], tntCtx, // this are used to get the host IDs from cache utils.ReplicatorSv1RemoveIndexes, &utils.GetIndexesArg{ IdxItmType: idxItmType, @@ -3727,10 +3684,7 @@ func (dm *DataManager) RemoveIndexes(idxItmType, tntCtx, idxKey string) (err err Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }, - }, &reply); err != nil { - err = utils.CastRPCErr(err) - } + }}) } return } @@ -3796,8 +3750,9 @@ func (dm *DataManager) checkFilters(tenant string, ids []string) (brokenReferenc &utils.TenantIDWithOpts{ TenantID: &utils.TenantID{Tenant: tenant, ID: id}, Opts: map[string]interface{}{ - utils.OptsAPIKey: itm.APIKey, - utils.OptsRouteID: itm.RouteID, + utils.OptsAPIKey: itm.APIKey, + utils.OptsRouteID: itm.RouteID, + utils.RemoteHostOpt: utils.FirstNonEmpty(config.CgrConfig().DataDbCfg().RmtConnID, config.CgrConfig().GeneralCfg().NodeID), }}, &fltr) has = fltr == nil } @@ -3823,8 +3778,9 @@ func (dm *DataManager) GetAccountProfile(tenant, id string) (ap *utils.AccountPr &utils.TenantIDWithOpts{ TenantID: &utils.TenantID{Tenant: tenant, ID: id}, Opts: map[string]interface{}{ - utils.OptsAPIKey: itm.APIKey, - utils.OptsRouteID: itm.RouteID, + utils.OptsAPIKey: itm.APIKey, + utils.OptsRouteID: itm.RouteID, + utils.RemoteHostOpt: utils.FirstNonEmpty(config.CgrConfig().DataDbCfg().RmtConnID, config.CgrConfig().GeneralCfg().NodeID), }}, &ap); err == nil { err = dm.dataDB.SetAccountProfileDrv(ap) } @@ -3838,8 +3794,7 @@ func (dm *DataManager) GetAccountProfile(tenant, id string) (ap *utils.AccountPr func (dm *DataManager) SetAccountProfile(ap *utils.AccountProfile, withIndex bool) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } if withIndex { if brokenReference := dm.checkFilters(ap.Tenant, ap.FilterIDs); len(brokenReference) != 0 { @@ -3866,18 +3821,16 @@ func (dm *DataManager) SetAccountProfile(ap *utils.AccountProfile, withIndex boo } } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaAccountProfiles]; itm.Replicate { - var reply string - if err = dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, + err = replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.AccountProfilePrefix, ap.TenantID(), // this are used to get the host IDs from cache utils.ReplicatorSv1SetAccountProfile, &utils.AccountProfileWithOpts{ AccountProfile: ap, Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply); err != nil { - err = utils.CastRPCErr(err) - return - } + }}) } return } @@ -3885,8 +3838,7 @@ func (dm *DataManager) SetAccountProfile(ap *utils.AccountProfile, withIndex boo func (dm *DataManager) RemoveAccountProfile(tenant, id string, transactionID string, withIndex bool) (err error) { if dm == nil { - err = utils.ErrNoDatabaseConn - return + return utils.ErrNoDatabaseConn } oldRpp, err := dm.GetAccountProfile(tenant, id) if err != nil && err != utils.ErrNotFound { @@ -3905,15 +3857,16 @@ func (dm *DataManager) RemoveAccountProfile(tenant, id string, } } if itm := config.CgrConfig().DataDbCfg().Items[utils.MetaAccountProfiles]; itm.Replicate { - var reply string - dm.connMgr.Call(config.CgrConfig().DataDbCfg().RplConns, nil, + replicate(dm.connMgr, config.CgrConfig().DataDbCfg().RplConns, + config.CgrConfig().DataDbCfg().RplFiltered, + utils.AccountProfilePrefix, utils.ConcatenatedKey(tenant, id), // this are used to get the host IDs from cache utils.ReplicatorSv1RemoveAccountProfile, &utils.TenantIDWithOpts{ TenantID: &utils.TenantID{Tenant: tenant, ID: id}, Opts: map[string]interface{}{ utils.OptsAPIKey: itm.APIKey, utils.OptsRouteID: itm.RouteID, - }}, &reply) + }}) } return } diff --git a/engine/dispatcherprfl.go b/engine/dispatcherprfl.go index 055d2fa02..7784a92d8 100644 --- a/engine/dispatcherprfl.go +++ b/engine/dispatcherprfl.go @@ -159,7 +159,8 @@ func (dH *DispatcherHost) Call(serviceMethod string, args interface{}, reply int cfg.TLSCfg().ClientCerificate, cfg.TLSCfg().CaCertificate, cfg.GeneralCfg().ConnectAttempts, cfg.GeneralCfg().Reconnects, cfg.GeneralCfg().ConnectTimeout, cfg.GeneralCfg().ReplyTimeout, - IntRPC.GetInternalChanel(), false, nil); err != nil { + IntRPC.GetInternalChanel(), false, nil, + utils.EmptyString, utils.EmptyString, nil); err != nil { return } diff --git a/engine/libengine.go b/engine/libengine.go index b9c1f2b5a..826ac5c38 100644 --- a/engine/libengine.go +++ b/engine/libengine.go @@ -25,6 +25,7 @@ import ( "github.com/cgrates/cgrates/config" "github.com/cgrates/cgrates/utils" + "github.com/cgrates/ltcache" "github.com/cgrates/rpcclient" ) @@ -32,7 +33,7 @@ import ( func NewRPCPool(dispatchStrategy string, keyPath, certPath, caPath string, connAttempts, reconnects int, connectTimeout, replyTimeout time.Duration, rpcConnCfgs []*config.RemoteHost, internalConnChan chan rpcclient.ClientConnector, lazyConnect bool, - biRPCClient rpcclient.BiRPCConector) (rpcPool *rpcclient.RPCPool, err error) { + biRPCClient rpcclient.BiRPCConector, poolID string, connCache *ltcache.Cache) (rpcPool *rpcclient.RPCPool, err error) { var rpcClient rpcclient.ClientConnector var atLestOneConnected bool // If one connected we don't longer return errors rpcPool = rpcclient.NewRPCPool(dispatchStrategy, replyTimeout) @@ -43,9 +44,9 @@ func NewRPCPool(dispatchStrategy string, keyPath, certPath, caPath string, connA err = rpcclient.ErrDisconnected continue } - rpcClient, err = NewRPCConnection(rpcConnCfg, keyPath, certPath, caPath, connAttempts, reconnects, - connectTimeout, replyTimeout, internalConnChan, lazyConnect, biRPCClient) - if err == rpcclient.ErrUnsupportedCodec { + if rpcClient, err = NewRPCConnection(rpcConnCfg, keyPath, certPath, caPath, connAttempts, reconnects, + connectTimeout, replyTimeout, internalConnChan, lazyConnect, biRPCClient, + poolID, rpcConnCfg.ID, connCache); err == rpcclient.ErrUnsupportedCodec { return nil, fmt.Errorf("Unsupported transport: <%s>", rpcConnCfg.Transport) } if err == nil { @@ -60,17 +61,31 @@ func NewRPCPool(dispatchStrategy string, keyPath, certPath, caPath string, connA } // NewRPCConnection creates a new connection based on the RemoteHost structure +// connCache is used to cache the connection with ID func NewRPCConnection(cfg *config.RemoteHost, keyPath, certPath, caPath string, connAttempts, reconnects int, connectTimeout, replyTimeout time.Duration, internalConnChan chan rpcclient.ClientConnector, lazyConnect bool, - biRPCClient rpcclient.BiRPCConector) (client rpcclient.ClientConnector, err error) { + biRPCClient rpcclient.BiRPCConector, poolID, connID string, connCache *ltcache.Cache) (client rpcclient.ClientConnector, err error) { + var id string + if connID != utils.EmptyString { + id = poolID + utils.ConcatenatedKeySep + connID + if x, ok := connCache.Get(id); ok && x != nil { + return x.(rpcclient.ClientConnector), nil + } + } if cfg.Address == rpcclient.InternalRPC || cfg.Address == rpcclient.BiRPCInternal { - return rpcclient.NewRPCClient("", "", cfg.TLS, keyPath, certPath, caPath, connAttempts, + client, err = rpcclient.NewRPCClient("", "", cfg.TLS, keyPath, certPath, caPath, connAttempts, reconnects, connectTimeout, replyTimeout, cfg.Address, internalConnChan, lazyConnect, biRPCClient) + } else { + client, err = rpcclient.NewRPCClient(utils.TCP, cfg.Address, cfg.TLS, keyPath, certPath, caPath, + connAttempts, reconnects, connectTimeout, replyTimeout, + utils.FirstNonEmpty(cfg.Transport, rpcclient.GOBrpc), nil, lazyConnect, biRPCClient) } - return rpcclient.NewRPCClient(utils.TCP, cfg.Address, cfg.TLS, keyPath, certPath, caPath, - connAttempts, reconnects, connectTimeout, replyTimeout, - utils.FirstNonEmpty(cfg.Transport, rpcclient.GOBrpc), nil, lazyConnect, biRPCClient) + if connID != utils.EmptyString && + err == nil { + connCache.Set(id, client, nil) + } + return } // IntRPC is the global variable that is used to comunicate with all the subsystems internally diff --git a/engine/libtest.go b/engine/libtest.go index e23b16b9e..65f3cc185 100644 --- a/engine/libtest.go +++ b/engine/libtest.go @@ -562,6 +562,7 @@ func GetDefaultEmptyCacheStats() map[string]*ltcache.CacheStats { utils.CacheActionProfilesFilterIndexes: {}, utils.CacheAccountProfiles: {}, utils.CacheAccountProfilesFilterIndexes: {}, + utils.CacheReplicationHosts: {}, utils.CacheAccounts: {}, utils.CacheVersions: {}, diff --git a/engine/remoterepl.go b/engine/remoterepl.go new file mode 100644 index 000000000..706efd9bc --- /dev/null +++ b/engine/remoterepl.go @@ -0,0 +1,78 @@ +/* +Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments +Copyright (C) ITsysCOM GmbH + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT MetaAny WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see +*/ + +package engine + +import ( + "github.com/cgrates/cgrates/utils" +) + +// SetReplicateHost will set the connID in cache +func SetReplicateHost(objType, objID, connID string) { + if connID == utils.EmptyString { + return + } + Cache.SetWithoutReplicate(utils.CacheReplicationHosts, objType+objID+utils.ConcatenatedKeySep+connID, connID, []string{objType + objID}, + true, utils.NonTransactional) +} + +// replicate will call Set/Remove APIs on ReplicatorSv1 +func replicate(connMgr *ConnManager, connIDs []string, filtered bool, objType, objID, method string, args interface{}) (err error) { + // the reply is string for Set/Remove APIs + // ignored in favor of the error + var reply string + if !filtered { + // is not partial so send to all defined connections + return utils.CastRPCErr(connMgr.Call(connIDs, nil, method, args, &reply)) + } + // is partial so get all the replicationHosts from cache based on object Type and ID + // alp_cgrates.org:ATTR1 + rplcHostIDsIfaces := Cache.tCache.GetGroupItems(utils.CacheReplicationHosts, objType+objID) + rplcHostIDs := make(utils.StringSet) + for _, hostID := range rplcHostIDsIfaces { + rplcHostIDs.Add(hostID.(string)) + } + // using the replication hosts call the method + return utils.CastRPCErr(connMgr.CallWithConnIDs(connIDs, rplcHostIDs, + method, args, &reply)) +} + +// replicateMultipleIDs will do the same thing as replicate but uses multiple objectIDs +// used when setting the LoadIDs +func replicateMultipleIDs(connMgr *ConnManager, connIDs []string, filtered bool, objType string, objIDs []string, method string, args interface{}) (err error) { + // the reply is string for Set/Remove APIs + // ignored in favor of the error + var reply string + if !filtered { + // is not partial so send to all defined connections + return utils.CastRPCErr(connMgr.Call(connIDs, nil, method, args, &reply)) + } + // is partial so get all the replicationHosts from cache based on object Type and ID + // combine all hosts in a single set so if we receive a get with one ID in list + // send all list to that hos + rplcHostIDs := make(utils.StringSet) + for _, objID := range objIDs { + rplcHostIDsIfaces := Cache.tCache.GetGroupItems(utils.CacheReplicationHosts, objType+objID) + for _, hostID := range rplcHostIDsIfaces { + rplcHostIDs.Add(hostID.(string)) + } + } + // using the replication hosts call the method + return utils.CastRPCErr(connMgr.CallWithConnIDs(connIDs, rplcHostIDs, + method, args, &reply)) +} diff --git a/services/accounts_it_test.go b/services/accounts_it_test.go index ec6b98c0b..eb9ed1a8a 100644 --- a/services/accounts_it_test.go +++ b/services/accounts_it_test.go @@ -48,7 +48,7 @@ func TestAccountSReload(t *testing.T) { close(chS.GetPrecacheChannel(utils.CacheAccountProfiles)) close(chS.GetPrecacheChannel(utils.CacheAccountProfilesFilterIndexes)) server := cores.NewServer(nil) - srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg) + srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg, nil) srvDep := map[string]*sync.WaitGroup{utils.DataDB: new(sync.WaitGroup)} db := NewDataDBService(cfg, nil, srvDep) acctRPC := make(chan rpcclient.ClientConnector, 1) diff --git a/services/actions_it_test.go b/services/actions_it_test.go index c0d8418da..3a4219c0f 100644 --- a/services/actions_it_test.go +++ b/services/actions_it_test.go @@ -48,7 +48,7 @@ func TestActionSReload(t *testing.T) { close(chS.GetPrecacheChannel(utils.CacheActionProfiles)) close(chS.GetPrecacheChannel(utils.CacheActionProfilesFilterIndexes)) server := cores.NewServer(nil) - srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg) + srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg, nil) srvDep := map[string]*sync.WaitGroup{utils.DataDB: new(sync.WaitGroup)} db := NewDataDBService(cfg, nil, srvDep) actRPC := make(chan rpcclient.ClientConnector, 1) diff --git a/services/analyzers_it_test.go b/services/analyzers_it_test.go index f1d528301..5deec7099 100644 --- a/services/analyzers_it_test.go +++ b/services/analyzers_it_test.go @@ -48,7 +48,7 @@ func TestAnalyzerSReload(t *testing.T) { filterSChan := make(chan *engine.FilterS, 1) filterSChan <- nil server := cores.NewServer(nil) - srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg) + srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg, nil) srvDep := map[string]*sync.WaitGroup{utils.DataDB: new(sync.WaitGroup)} db := NewDataDBService(cfg, nil, srvDep) anzRPC := make(chan rpcclient.ClientConnector, 1) diff --git a/services/apiers_it_test.go b/services/apiers_it_test.go index a42280adc..c2e3f8a84 100644 --- a/services/apiers_it_test.go +++ b/services/apiers_it_test.go @@ -54,7 +54,7 @@ func TestApiersReload(t *testing.T) { cfg.ThresholdSCfg().Enabled = true cfg.SchedulerCfg().Enabled = true server := cores.NewServer(nil) - srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg) + srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg, nil) srvDep := map[string]*sync.WaitGroup{utils.DataDB: new(sync.WaitGroup)} db := NewDataDBService(cfg, nil, srvDep) cfg.StorDbCfg().Type = utils.INTERNAL diff --git a/services/asteriskagent_it_test.go b/services/asteriskagent_it_test.go index 45e5ee5db..c196da763 100644 --- a/services/asteriskagent_it_test.go +++ b/services/asteriskagent_it_test.go @@ -53,7 +53,7 @@ func TestAsteriskAgentReload(t *testing.T) { cacheSChan <- chS server := cores.NewServer(nil) - srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg) + srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg, nil) srvDep := map[string]*sync.WaitGroup{utils.DataDB: new(sync.WaitGroup)} db := NewDataDBService(cfg, nil, srvDep) anz := NewAnalyzerService(cfg, server, filterSChan, shdChan, make(chan rpcclient.ClientConnector, 1), srvDep) @@ -119,7 +119,7 @@ func TestAsteriskAgentReload2(t *testing.T) { cacheSChan <- chS server := cores.NewServer(nil) - srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg) + srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg, nil) srvDep := map[string]*sync.WaitGroup{utils.DataDB: new(sync.WaitGroup)} db := NewDataDBService(cfg, nil, srvDep) anz := NewAnalyzerService(cfg, server, filterSChan, shdChan, make(chan rpcclient.ClientConnector, 1), srvDep) diff --git a/services/attributes_it_test.go b/services/attributes_it_test.go index a564b06cb..7df6b7e3e 100644 --- a/services/attributes_it_test.go +++ b/services/attributes_it_test.go @@ -48,7 +48,7 @@ func TestAttributeSReload(t *testing.T) { close(chS.GetPrecacheChannel(utils.CacheAttributeProfiles)) close(chS.GetPrecacheChannel(utils.CacheAttributeFilterIndexes)) server := cores.NewServer(nil) - srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg) + srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg, nil) srvDep := map[string]*sync.WaitGroup{utils.DataDB: new(sync.WaitGroup)} db := NewDataDBService(cfg, nil, srvDep) attrRPC := make(chan rpcclient.ClientConnector, 1) diff --git a/services/cdrs_it_test.go b/services/cdrs_it_test.go index 094d14c03..300bc3776 100644 --- a/services/cdrs_it_test.go +++ b/services/cdrs_it_test.go @@ -60,7 +60,7 @@ func TestCdrsReload(t *testing.T) { cfg.ChargerSCfg().Enabled = true server := cores.NewServer(nil) - srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg) + srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg, nil) srvDep := map[string]*sync.WaitGroup{utils.DataDB: new(sync.WaitGroup)} db := NewDataDBService(cfg, nil, srvDep) cfg.StorDbCfg().Type = utils.INTERNAL diff --git a/services/chargers_it_test.go b/services/chargers_it_test.go index 4bc0786cd..bc216424f 100644 --- a/services/chargers_it_test.go +++ b/services/chargers_it_test.go @@ -51,7 +51,7 @@ func TestChargerSReload(t *testing.T) { filterSChan <- nil srvDep := map[string]*sync.WaitGroup{utils.DataDB: new(sync.WaitGroup)} server := cores.NewServer(nil) - srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg) + srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg, nil) db := NewDataDBService(cfg, nil, srvDep) anz := NewAnalyzerService(cfg, server, filterSChan, shdChan, make(chan rpcclient.ClientConnector, 1), srvDep) attrS := NewAttributeService(cfg, db, chS, filterSChan, server, make(chan rpcclient.ClientConnector, 1), anz, srvDep) diff --git a/services/cores_it_test.go b/services/cores_it_test.go index 162be2520..5a8942748 100644 --- a/services/cores_it_test.go +++ b/services/cores_it_test.go @@ -45,7 +45,7 @@ func TestCoreSReload(t *testing.T) { filterSChan := make(chan *engine.FilterS, 1) filterSChan <- nil server := cores.NewServer(nil) - srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg) + srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg, nil) srvDep := map[string]*sync.WaitGroup{utils.DataDB: new(sync.WaitGroup)} db := NewDataDBService(cfg, nil, srvDep) coreRPC := make(chan rpcclient.ClientConnector, 1) diff --git a/services/datadb_it_test.go b/services/datadb_it_test.go index 0b945ad6e..3b78c1ec8 100644 --- a/services/datadb_it_test.go +++ b/services/datadb_it_test.go @@ -50,7 +50,7 @@ func TestDataDBReload(t *testing.T) { close(chS.GetPrecacheChannel(utils.CacheAttributeFilterIndexes)) server := cores.NewServer(nil) srvDep := map[string]*sync.WaitGroup{utils.DataDB: new(sync.WaitGroup)} - srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg) + srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg, nil) cM := engine.NewConnManager(cfg, nil) db := NewDataDBService(cfg, cM, srvDep) anz := NewAnalyzerService(cfg, server, filterSChan, shdChan, make(chan rpcclient.ClientConnector, 1), srvDep) diff --git a/services/diameteragent_it_test.go b/services/diameteragent_it_test.go index 562a09b20..62f8c1dfd 100644 --- a/services/diameteragent_it_test.go +++ b/services/diameteragent_it_test.go @@ -48,7 +48,7 @@ func TestDiameterAgentReload1(t *testing.T) { cacheSChan <- chS server := cores.NewServer(nil) srvDep := map[string]*sync.WaitGroup{utils.DataDB: new(sync.WaitGroup)} - srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg) + srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg, nil) db := NewDataDBService(cfg, nil, srvDep) anz := NewAnalyzerService(cfg, server, filterSChan, shdChan, make(chan rpcclient.ClientConnector, 1), srvDep) sS := NewSessionService(cfg, db, server, make(chan rpcclient.ClientConnector, 1), diff --git a/services/dispatchers_it_test.go b/services/dispatchers_it_test.go index a5e8f435f..87d6374c0 100644 --- a/services/dispatchers_it_test.go +++ b/services/dispatchers_it_test.go @@ -51,7 +51,7 @@ func TestDispatcherSReload(t *testing.T) { filterSChan := make(chan *engine.FilterS, 1) filterSChan <- nil server := cores.NewServer(nil) - srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg) + srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg, nil) srvDep := map[string]*sync.WaitGroup{utils.DataDB: new(sync.WaitGroup)} db := NewDataDBService(cfg, nil, srvDep) anz := NewAnalyzerService(cfg, server, filterSChan, shdChan, make(chan rpcclient.ClientConnector, 1), srvDep) diff --git a/services/dnsagent_it_test.go b/services/dnsagent_it_test.go index 920868317..e2c9f23b1 100644 --- a/services/dnsagent_it_test.go +++ b/services/dnsagent_it_test.go @@ -55,7 +55,7 @@ func TestDNSAgentReload(t *testing.T) { cacheSChan <- chS server := cores.NewServer(nil) - srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg) + srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg, nil) srvDep := map[string]*sync.WaitGroup{utils.DataDB: new(sync.WaitGroup)} db := NewDataDBService(cfg, nil, srvDep) anz := NewAnalyzerService(cfg, server, filterSChan, shdChan, make(chan rpcclient.ClientConnector, 1), srvDep) diff --git a/services/ees_it_test.go b/services/ees_it_test.go index ab86c0c39..307c07fd7 100644 --- a/services/ees_it_test.go +++ b/services/ees_it_test.go @@ -55,7 +55,7 @@ func TestEventExporterSReload(t *testing.T) { shdChan := utils.NewSyncedChan() shdWg := new(sync.WaitGroup) server := cores.NewServer(nil) - srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg) + srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg, nil) srvDep := map[string]*sync.WaitGroup{utils.DataDB: new(sync.WaitGroup)} db := NewDataDBService(cfg, nil, srvDep) chS := engine.NewCacheS(cfg, nil, nil) diff --git a/services/ers_it_test.go b/services/ers_it_test.go index 8ecc634a4..426ae1d5a 100644 --- a/services/ers_it_test.go +++ b/services/ers_it_test.go @@ -60,7 +60,7 @@ func TestEventReaderSReload(t *testing.T) { }() shdWg := new(sync.WaitGroup) server := cores.NewServer(nil) - srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg) + srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg, nil) srvDep := map[string]*sync.WaitGroup{utils.DataDB: new(sync.WaitGroup)} anz := NewAnalyzerService(cfg, server, filterSChan, shdChan, make(chan rpcclient.ClientConnector, 1), srvDep) db := NewDataDBService(cfg, nil, srvDep) diff --git a/services/freeswitchagent_it_test.go b/services/freeswitchagent_it_test.go index cef5b9078..1d097f90e 100644 --- a/services/freeswitchagent_it_test.go +++ b/services/freeswitchagent_it_test.go @@ -54,7 +54,7 @@ func TestFreeSwitchAgentReload(t *testing.T) { cacheSChan <- chS server := cores.NewServer(nil) - srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg) + srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg, nil) srvDep := map[string]*sync.WaitGroup{utils.DataDB: new(sync.WaitGroup)} db := NewDataDBService(cfg, nil, srvDep) anz := NewAnalyzerService(cfg, server, filterSChan, shdChan, make(chan rpcclient.ClientConnector, 1), srvDep) diff --git a/services/httpagent_it_test.go b/services/httpagent_it_test.go index d21739b9b..168af3ac2 100644 --- a/services/httpagent_it_test.go +++ b/services/httpagent_it_test.go @@ -52,7 +52,7 @@ func TestHTTPAgentReload(t *testing.T) { cacheSChan := make(chan rpcclient.ClientConnector, 1) cacheSChan <- chS server := cores.NewServer(nil) - srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg) + srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg, nil) srvDep := map[string]*sync.WaitGroup{utils.DataDB: new(sync.WaitGroup)} db := NewDataDBService(cfg, nil, srvDep) anz := NewAnalyzerService(cfg, server, filterSChan, shdChan, make(chan rpcclient.ClientConnector, 1), srvDep) diff --git a/services/kamailioagent_it_test.go b/services/kamailioagent_it_test.go index 09679e487..34b2531c4 100644 --- a/services/kamailioagent_it_test.go +++ b/services/kamailioagent_it_test.go @@ -53,7 +53,7 @@ func TestKamailioAgentReload(t *testing.T) { cacheSChan <- chS server := cores.NewServer(nil) - srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg) + srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg, nil) srvDep := map[string]*sync.WaitGroup{utils.DataDB: new(sync.WaitGroup)} db := NewDataDBService(cfg, nil, srvDep) anz := NewAnalyzerService(cfg, server, filterSChan, shdChan, make(chan rpcclient.ClientConnector, 1), srvDep) diff --git a/services/loaders_it_test.go b/services/loaders_it_test.go index 6cb3551cd..fafbdc8e8 100644 --- a/services/loaders_it_test.go +++ b/services/loaders_it_test.go @@ -69,7 +69,7 @@ func TestLoaderSReload(t *testing.T) { filterSChan := make(chan *engine.FilterS, 1) filterSChan <- nil server := cores.NewServer(nil) - srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg) + srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg, nil) srvDep := map[string]*sync.WaitGroup{utils.DataDB: new(sync.WaitGroup)} db := NewDataDBService(cfg, nil, srvDep) anz := NewAnalyzerService(cfg, server, filterSChan, shdChan, make(chan rpcclient.ClientConnector, 1), srvDep) diff --git a/services/radiusagent_it_test.go b/services/radiusagent_it_test.go index 08282722e..68e421890 100644 --- a/services/radiusagent_it_test.go +++ b/services/radiusagent_it_test.go @@ -56,7 +56,7 @@ func TestRadiusAgentReload(t *testing.T) { cacheSChan <- chS server := cores.NewServer(nil) - srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg) + srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg, nil) srvDep := map[string]*sync.WaitGroup{utils.DataDB: new(sync.WaitGroup)} db := NewDataDBService(cfg, nil, srvDep) anz := NewAnalyzerService(cfg, server, filterSChan, shdChan, make(chan rpcclient.ClientConnector, 1), srvDep) @@ -124,7 +124,7 @@ func TestRadiusAgentReload2(t *testing.T) { cacheSChan <- chS server := cores.NewServer(nil) - srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg) + srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg, nil) srvDep := map[string]*sync.WaitGroup{utils.DataDB: new(sync.WaitGroup)} db := NewDataDBService(cfg, nil, srvDep) anz := NewAnalyzerService(cfg, server, filterSChan, shdChan, make(chan rpcclient.ClientConnector, 1), srvDep) diff --git a/services/rals_it_test.go b/services/rals_it_test.go index 35016decc..ae714809c 100644 --- a/services/rals_it_test.go +++ b/services/rals_it_test.go @@ -60,7 +60,7 @@ func TestRalsReload(t *testing.T) { cfg.ThresholdSCfg().Enabled = true server := cores.NewServer(nil) - srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg) + srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg, nil) srvDep := map[string]*sync.WaitGroup{utils.DataDB: new(sync.WaitGroup)} db := NewDataDBService(cfg, nil, srvDep) cfg.StorDbCfg().Type = utils.INTERNAL diff --git a/services/rates_it_test.go b/services/rates_it_test.go index e2a5c2d8e..52f7e38f2 100644 --- a/services/rates_it_test.go +++ b/services/rates_it_test.go @@ -44,7 +44,7 @@ func TestRateSReload(t *testing.T) { shdChan := utils.NewSyncedChan() shdWg := new(sync.WaitGroup) server := cores.NewServer(nil) - srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg) + srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg, nil) srvDep := map[string]*sync.WaitGroup{utils.DataDB: new(sync.WaitGroup)} db := NewDataDBService(cfg, nil, srvDep) chS := engine.NewCacheS(cfg, nil, nil) diff --git a/services/registrarc_it_test.go b/services/registrarc_it_test.go index 71b2cc258..11965b12e 100644 --- a/services/registrarc_it_test.go +++ b/services/registrarc_it_test.go @@ -50,7 +50,7 @@ func TestDispatcherHReload(t *testing.T) { filterSChan := make(chan *engine.FilterS, 1) filterSChan <- nil server := cores.NewServer(nil) - srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg) + srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg, nil) srvDep := map[string]*sync.WaitGroup{utils.DataDB: new(sync.WaitGroup)} db := NewDataDBService(cfg, nil, srvDep) anz := NewAnalyzerService(cfg, server, filterSChan, shdChan, make(chan rpcclient.ClientConnector, 1), srvDep) diff --git a/services/resources_it_test.go b/services/resources_it_test.go index 64d5028a1..b88118ed5 100644 --- a/services/resources_it_test.go +++ b/services/resources_it_test.go @@ -53,7 +53,7 @@ func TestResourceSReload(t *testing.T) { close(chS.GetPrecacheChannel(utils.CacheResources)) close(chS.GetPrecacheChannel(utils.CacheResourceFilterIndexes)) server := cores.NewServer(nil) - srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg) + srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg, nil) srvDep := map[string]*sync.WaitGroup{utils.DataDB: new(sync.WaitGroup)} anz := NewAnalyzerService(cfg, server, filterSChan, shdChan, make(chan rpcclient.ClientConnector, 1), srvDep) db := NewDataDBService(cfg, nil, srvDep) diff --git a/services/routes_it_test.go b/services/routes_it_test.go index e3a0269b9..6b7ea84e7 100644 --- a/services/routes_it_test.go +++ b/services/routes_it_test.go @@ -47,7 +47,7 @@ func TestRouteSReload(t *testing.T) { close(chS.GetPrecacheChannel(utils.CacheRouteProfiles)) close(chS.GetPrecacheChannel(utils.CacheRouteFilterIndexes)) server := cores.NewServer(nil) - srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg) + srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg, nil) srvDep := map[string]*sync.WaitGroup{utils.DataDB: new(sync.WaitGroup)} anz := NewAnalyzerService(cfg, server, filterSChan, shdChan, make(chan rpcclient.ClientConnector, 1), srvDep) db := NewDataDBService(cfg, nil, srvDep) diff --git a/services/schedulers_it_test.go b/services/schedulers_it_test.go index 2d0129cdb..d1e2d0d34 100644 --- a/services/schedulers_it_test.go +++ b/services/schedulers_it_test.go @@ -46,7 +46,7 @@ func TestSchedulerSReload(t *testing.T) { filterSChan <- nil close(chS.GetPrecacheChannel(utils.CacheActionPlans)) server := cores.NewServer(nil) - srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg) + srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg, nil) srvDep := map[string]*sync.WaitGroup{utils.DataDB: new(sync.WaitGroup)} db := NewDataDBService(cfg, nil, srvDep) anz := NewAnalyzerService(cfg, server, filterSChan, shdChan, make(chan rpcclient.ClientConnector, 1), srvDep) diff --git a/services/sipagent_it_test.go b/services/sipagent_it_test.go index 95827f517..1de2b9f70 100644 --- a/services/sipagent_it_test.go +++ b/services/sipagent_it_test.go @@ -51,7 +51,7 @@ func TestSIPAgentReload(t *testing.T) { cacheSChan <- chS server := cores.NewServer(nil) - srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg) + srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg, nil) srvDep := map[string]*sync.WaitGroup{utils.DataDB: new(sync.WaitGroup)} db := NewDataDBService(cfg, nil, srvDep) anz := NewAnalyzerService(cfg, server, filterSChan, shdChan, make(chan rpcclient.ClientConnector, 1), srvDep) diff --git a/services/stats_it_test.go b/services/stats_it_test.go index 1070ee05b..6ac70235d 100644 --- a/services/stats_it_test.go +++ b/services/stats_it_test.go @@ -53,7 +53,7 @@ func TestStatSReload(t *testing.T) { close(chS.GetPrecacheChannel(utils.CacheStatQueues)) close(chS.GetPrecacheChannel(utils.CacheStatFilterIndexes)) server := cores.NewServer(nil) - srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg) + srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg, nil) srvDep := map[string]*sync.WaitGroup{utils.DataDB: new(sync.WaitGroup)} anz := NewAnalyzerService(cfg, server, filterSChan, shdChan, make(chan rpcclient.ClientConnector, 1), srvDep) db := NewDataDBService(cfg, nil, srvDep) diff --git a/services/stordb_it_test.go b/services/stordb_it_test.go index 0effc30d1..367fd1a50 100644 --- a/services/stordb_it_test.go +++ b/services/stordb_it_test.go @@ -44,7 +44,7 @@ func TestStorDBReload(t *testing.T) { chS := engine.NewCacheS(cfg, nil, nil) cfg.ChargerSCfg().Enabled = true server := cores.NewServer(nil) - srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg) + srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg, nil) srvDep := map[string]*sync.WaitGroup{utils.DataDB: new(sync.WaitGroup)} db := NewDataDBService(cfg, nil, srvDep) cfg.StorDbCfg().Password = "CGRateS.org" diff --git a/services/thresholds_it_test.go b/services/thresholds_it_test.go index b568bf5af..5dca015fa 100644 --- a/services/thresholds_it_test.go +++ b/services/thresholds_it_test.go @@ -49,7 +49,7 @@ func TestThresholdSReload(t *testing.T) { close(chS.GetPrecacheChannel(utils.CacheThresholds)) close(chS.GetPrecacheChannel(utils.CacheThresholdFilterIndexes)) server := cores.NewServer(nil) - srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg) + srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg, nil) srvDep := map[string]*sync.WaitGroup{utils.DataDB: new(sync.WaitGroup)} anz := NewAnalyzerService(cfg, server, filterSChan, shdChan, make(chan rpcclient.ClientConnector, 1), srvDep) db := NewDataDBService(cfg, nil, srvDep) @@ -117,7 +117,7 @@ func TestThresholdSReload2(t *testing.T) { close(chS.GetPrecacheChannel(utils.CacheThresholds)) close(chS.GetPrecacheChannel(utils.CacheThresholdFilterIndexes)) server := cores.NewServer(nil) - srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg) + srvMngr := servmanager.NewServiceManager(cfg, shdChan, shdWg, nil) srvDep := map[string]*sync.WaitGroup{utils.DataDB: new(sync.WaitGroup)} anz := NewAnalyzerService(cfg, server, filterSChan, shdChan, make(chan rpcclient.ClientConnector, 1), srvDep) db := NewDataDBService(cfg, nil, srvDep) diff --git a/servmanager/servmanager.go b/servmanager/servmanager.go index a14effa7d..93bef4fde 100644 --- a/servmanager/servmanager.go +++ b/servmanager/servmanager.go @@ -32,12 +32,13 @@ import ( ) // NewServiceManager returns a service manager -func NewServiceManager(cfg *config.CGRConfig, shdChan *utils.SyncedChan, shdWg *sync.WaitGroup) *ServiceManager { +func NewServiceManager(cfg *config.CGRConfig, shdChan *utils.SyncedChan, shdWg *sync.WaitGroup, connMgr *engine.ConnManager) *ServiceManager { sm := &ServiceManager{ cfg: cfg, subsystems: make(map[string]Service), shdChan: shdChan, shdWg: shdWg, + connMgr: connMgr, } return sm } @@ -50,6 +51,7 @@ type ServiceManager struct { shdChan *utils.SyncedChan shdWg *sync.WaitGroup + connMgr *engine.ConnManager } // Call . @@ -240,7 +242,7 @@ func (srvMngr *ServiceManager) handleReload() { case <-srvMngr.GetConfig().GetReloadChan(config.RateSJson): go srvMngr.reloadService(utils.RateS) case <-srvMngr.GetConfig().GetReloadChan(config.RPCConnsJsonName): - engine.Cache.Clear([]string{utils.CacheRPCConnections}) + go srvMngr.connMgr.Reload() case <-srvMngr.GetConfig().GetReloadChan(config.SIPAgentJson): go srvMngr.reloadService(utils.SIPAgent) case <-srvMngr.GetConfig().GetReloadChan(config.RegistrarCJson): diff --git a/utils/consts.go b/utils/consts.go index c44eea8fa..3d9d4ab4b 100755 --- a/utils/consts.go +++ b/utils/consts.go @@ -45,7 +45,7 @@ var ( extraDBPartition = NewStringSet([]string{CacheDispatchers, CacheDispatcherRoutes, CacheDispatcherLoads, CacheDiameterMessages, CacheRPCResponses, CacheClosedSessions, CacheCDRIDs, CacheRPCConnections, CacheUCH, CacheSTIR, CacheEventCharges, MetaAPIBan, - CacheCapsEvents, CacheVersions}) + CacheCapsEvents, CacheVersions, CacheReplicationHosts}) dataDBPartition = NewStringSet([]string{CacheDestinations, CacheReverseDestinations, CacheRatingPlans, CacheRatingProfiles, CacheActions, CacheActionTriggers, CacheSharedGroups, CacheTimings, @@ -1974,6 +1974,7 @@ const ( CacheAccounts = "*accounts" CacheVersions = "*versions" CacheCapsEvents = "*caps_events" + CacheReplicationHosts = "*replication_hosts" // storDB CacheTBLTPTimings = "*tp_timings" @@ -2112,6 +2113,8 @@ const ( RedisClientCertificate = "redis_client_certificate" RedisClientKey = "redis_client_key" RedisCACertificate = "redis_ca_certificate" + FilteredReplicationCfg = "filtered_replication" + RemoteConnIDCfg = "remote_conn_id" ) // ItemOpt @@ -2605,6 +2608,8 @@ const ( MetaEventType = "*eventType" EventType = "EventType" SchedulerInit = "SchedulerInit" + + RemoteHostOpt = "*rmtHost" ) // Event Flags diff --git a/utils/coreutils.go b/utils/coreutils.go index be4df8185..77ca7a0c5 100644 --- a/utils/coreutils.go +++ b/utils/coreutils.go @@ -928,8 +928,10 @@ type StringWithOpts struct { } func CastRPCErr(err error) error { - if _, has := ErrMap[err.Error()]; has { - return ErrMap[err.Error()] + if err != nil { + if _, has := ErrMap[err.Error()]; has { + return ErrMap[err.Error()] + } } return err }