diff --git a/apier/v1/config.go b/apier/v1/config.go index f7b0c4421..7b3584760 100644 --- a/apier/v1/config.go +++ b/apier/v1/config.go @@ -23,23 +23,31 @@ import ( "github.com/cgrates/cgrates/utils" ) +// NewConfigSv1 returns a new ConfigSv1 func NewConfigSv1(cfg *config.CGRConfig) *ConfigSv1 { return &ConfigSv1{cfg: cfg} } -// Exports RPC from ConfigSv1 +// ConfigSv1 exports RPC for config type ConfigSv1 struct { cfg *config.CGRConfig } +// GetJSONSection will retrieve from CGRConfig a section func (cSv1 *ConfigSv1) GetJSONSection(section *config.StringWithArgDispatcher, reply *map[string]interface{}) (err error) { return cSv1.cfg.V1GetConfigSection(section, reply) } +// ReloadConfig reloads the configuration func (cSv1 *ConfigSv1) ReloadConfig(args *config.ConfigReloadWithArgDispatcher, reply *string) (err error) { return cSv1.cfg.V1ReloadConfig(args, reply) } +// ReloadSections reloads the sections of configz +func (cSv1 *ConfigSv1) ReloadSections(args map[string]interface{}, reply *string) (err error) { + return cSv1.cfg.V1ReloadSections(args, reply) +} + // Call implements rpcclient.ClientConnector interface for internal RPC func (cSv1 *ConfigSv1) Call(serviceMethod string, args interface{}, reply interface{}) error { diff --git a/config/config.go b/config/config.go index 76ae2639a..3128f0701 100755 --- a/config/config.go +++ b/config/config.go @@ -19,6 +19,7 @@ along with this program. If not, see package config import ( + "bytes" "encoding/json" "errors" "fmt" @@ -345,8 +346,8 @@ func (cfg *CGRConfig) loadFromJsonCfg(jsnCfg *CgrJsonCfg) (err error) { // loadRPCConns loads the RPCConns section of the configuration func (cfg *CGRConfig) loadRPCConns(jsnCfg *CgrJsonCfg) (err error) { - var jsnRpcConns map[string]*RPCConnsJson - if jsnRpcConns, err = jsnCfg.RPCConnJsonCfg(); err != nil { + var jsnRPCConns map[string]*RPCConnsJson + if jsnRPCConns, err = jsnCfg.RPCConnJsonCfg(); err != nil { return } // hardoded the *internal connection @@ -359,7 +360,7 @@ func (cfg *CGRConfig) loadRPCConns(jsnCfg *CgrJsonCfg) (err error) { }, }, } - for key, val := range jsnRpcConns { + for key, val := range jsnRPCConns { cfg.rpcConns[key] = NewDfltRPCConn() if err = cfg.rpcConns[key].loadFromJsonCfg(val); err != nil { return @@ -625,7 +626,7 @@ func (cfg *CGRConfig) loadDiameterAgentCfg(jsnCfg *CgrJsonCfg) (err error) { if jsnDACfg, err = jsnCfg.DiameterAgentJsonCfg(); err != nil { return } - return cfg.diameterAgentCfg.loadFromJsonCfg(jsnDACfg, cfg.GeneralCfg().RSRSep) + return cfg.diameterAgentCfg.loadFromJsonCfg(jsnDACfg, cfg.generalCfg.RSRSep) } // loadRadiusAgentCfg loads the RadiusAgent section of the configuration @@ -634,7 +635,7 @@ func (cfg *CGRConfig) loadRadiusAgentCfg(jsnCfg *CgrJsonCfg) (err error) { if jsnRACfg, err = jsnCfg.RadiusAgentJsonCfg(); err != nil { return } - return cfg.radiusAgentCfg.loadFromJsonCfg(jsnRACfg, cfg.GeneralCfg().RSRSep) + return cfg.radiusAgentCfg.loadFromJsonCfg(jsnRACfg, cfg.generalCfg.RSRSep) } // loadDNSAgentCfg loads the DNSAgent section of the configuration @@ -643,7 +644,7 @@ func (cfg *CGRConfig) loadDNSAgentCfg(jsnCfg *CgrJsonCfg) (err error) { if jsnDNSCfg, err = jsnCfg.DNSAgentJsonCfg(); err != nil { return } - return cfg.dnsAgentCfg.loadFromJsonCfg(jsnDNSCfg, cfg.GeneralCfg().RSRSep) + return cfg.dnsAgentCfg.loadFromJsonCfg(jsnDNSCfg, cfg.generalCfg.RSRSep) } // loadHttpAgentCfg loads the HttpAgent section of the configuration @@ -652,7 +653,7 @@ func (cfg *CGRConfig) loadHttpAgentCfg(jsnCfg *CgrJsonCfg) (err error) { if jsnHttpAgntCfg, err = jsnCfg.HttpAgentJsonCfg(); err != nil { return } - return cfg.httpAgentCfg.loadFromJsonCfg(jsnHttpAgntCfg, cfg.GeneralCfg().RSRSep) + return cfg.httpAgentCfg.loadFromJsonCfg(jsnHttpAgntCfg, cfg.generalCfg.RSRSep) } // loadAttributeSCfg loads the AttributeS section of the configuration @@ -719,7 +720,7 @@ func (cfg *CGRConfig) loadLoaderSCfg(jsnCfg *CgrJsonCfg) (err error) { // cfg.loaderCfg = make(LoaderSCfgs, len(jsnLoaderCfg)) for _, profile := range jsnLoaderCfg { loadSCfgp := NewDfltLoaderSCfg() - loadSCfgp.loadFromJsonCfg(profile, cfg.GeneralCfg().RSRSep) + loadSCfgp.loadFromJsonCfg(profile, cfg.generalCfg.RSRSep) cfg.loaderCfg = append(cfg.loaderCfg, loadSCfgp) // use apend so the loaderS profile to be loaded from multiple files } } @@ -804,7 +805,7 @@ func (cfg *CGRConfig) loadErsCfg(jsnCfg *CgrJsonCfg) (err error) { if jsnERsCfg, err = jsnCfg.ERsJsonCfg(); err != nil { return } - return cfg.ersCfg.loadFromJsonCfg(jsnERsCfg, cfg.GeneralCfg().RSRSep, cfg.dfltEvRdr) + return cfg.ersCfg.loadFromJsonCfg(jsnERsCfg, cfg.generalCfg.RSRSep, cfg.dfltEvRdr) } // SureTaxCfg use locking to retrieve the configuration, possibility later for runtime reload @@ -1861,3 +1862,48 @@ func (cfg *CGRConfig) initChanels() { cfg.rldChans[section] = make(chan struct{}, 1) } } + +// V1ReloadSections reloads the sections of configz +func (cfg *CGRConfig) V1ReloadSections(args map[string]interface{}, reply *string) (err error) { + if len(args) == 0 { + *reply = utils.OK + return + } + var b []byte + if b, err = json.Marshal(args); err != nil { + return + } + fmt.Println(string(b)) + // lock all sections + cfg.lockSections() + fmt.Println("lock") + + if err = cfg.loadConfigFromReader(bytes.NewBuffer(b), []func(*CgrJsonCfg) error{cfg.loadFromJsonCfg}); err != nil { + cfg.unlockSections() // unlock before exiting function + return + } + + fmt.Println("before checkConfigSanity") + err = cfg.checkConfigSanity() + fmt.Println("after checkConfigSanity") + + cfg.unlockSections() // unlock before checking the error + fmt.Println("after unlock") + + if err != nil { + return + } + + section := utils.MetaAll + if len(args) == 1 { + for k := range args { + section = k + break + } + } + if err = cfg.reloadSection(section); err != nil { + return + } + *reply = utils.OK + return +} diff --git a/config/config_it_test.go b/config/config_it_test.go index baa3f7342..0c5b940c0 100644 --- a/config/config_it_test.go +++ b/config/config_it_test.go @@ -876,3 +876,90 @@ func TestCgrCfgV1ReloadConfigSection(t *testing.T) { } } } + +func TestCGRConfigReloadSectionsSessionS(t *testing.T) { + cfg, err := NewDefaultCGRConfig() + if err != nil { + t.Fatal(err) + } + cfg.RalsCfg().Enabled = true + cfg.ChargerSCfg().Enabled = true + cfg.CdrsCfg().Enabled = true + var reply string + if err = cfg.V1ReloadSections(map[string]interface{}{ + "sessions": map[string]interface{}{ + "enabled": true, + "resources_conns": []string{"*localhost"}, + "suppliers_conns": []string{"*localhost"}, + "attributes_conns": []string{"*localhost"}, + "rals_conns": []string{"*internal"}, + "cdrs_conns": []string{"*internal"}, + "chargers_conns": []string{"*internal"}, + }, + }, &reply); err != nil { + t.Error(err) + } else if reply != utils.OK { + t.Errorf("Expected OK received: %s", reply) + } + expAttr := &SessionSCfg{ + Enabled: true, + ListenBijson: "127.0.0.1:2014", + ChargerSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaChargers)}, + RALsConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaResponder)}, + ResSConns: []string{utils.MetaLocalHost}, + ThreshSConns: []string{}, + StatSConns: []string{}, + SupplSConns: []string{utils.MetaLocalHost}, + AttrSConns: []string{utils.MetaLocalHost}, + CDRsConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCDRs)}, + + ReplicationConns: []*RemoteHost{}, + MaxCallDuration: 3 * time.Hour, + SessionIndexes: utils.NewStringMap(), + ClientProtocol: 1, + TerminateAttempts: 5, + } + if !reflect.DeepEqual(expAttr, cfg.SessionSCfg()) { + t.Errorf("Expected %s , received: %s ", utils.ToJSON(expAttr), utils.ToJSON(cfg.SessionSCfg())) + } +} + +func TestCGRConfigReloadAll(t *testing.T) { + cfg, err := NewDefaultCGRConfig() + if err != nil { + t.Fatal(err) + } + cfg.RalsCfg().Enabled = true + cfg.ChargerSCfg().Enabled = true + cfg.CdrsCfg().Enabled = true + var reply string + if err = cfg.V1ReloadConfig(&ConfigReloadWithArgDispatcher{ + Path: path.Join("/usr", "share", "cgrates", "conf", "samples", "tutmongo2"), + Section: utils.MetaAll, + }, &reply); err != nil { + t.Error(err) + } else if reply != utils.OK { + t.Errorf("Expected OK received: %s", reply) + } + expAttr := &SessionSCfg{ + Enabled: true, + ListenBijson: "127.0.0.1:2014", + ChargerSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaChargers)}, + RALsConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaResponder)}, + ResSConns: []string{utils.MetaLocalHost}, + ThreshSConns: []string{}, + StatSConns: []string{}, + SupplSConns: []string{utils.MetaLocalHost}, + AttrSConns: []string{utils.MetaLocalHost}, + CDRsConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCDRs)}, + + ReplicationConns: []*RemoteHost{}, + MaxCallDuration: 3 * time.Hour, + SessionIndexes: utils.NewStringMap(), + ClientProtocol: 1, + TerminateAttempts: 5, + } + if !reflect.DeepEqual(expAttr, cfg.SessionSCfg()) { + t.Errorf("Expected %s , received: %s ", utils.ToJSON(expAttr), utils.ToJSON(cfg.SessionSCfg())) + } +} diff --git a/config/multifiles_it_test.go b/config/multifiles_it_test.go index deb368920..a31e37750 100644 --- a/config/multifiles_it_test.go +++ b/config/multifiles_it_test.go @@ -115,6 +115,7 @@ func TestMfEnvReaderITRead(t *testing.T) { DigestSeparator: ",", DigestEqual: ":", RSRSep: ";", + MaxParralelConns: 100, } if !reflect.DeepEqual(expected, *mfCgrCfg.generalCfg) { t.Errorf("Expected: %+v\n, recived: %+v", utils.ToJSON(expected), utils.ToJSON(*mfCgrCfg.generalCfg))