diff --git a/cmd/cgr-engine/cgr-engine.go b/cmd/cgr-engine/cgr-engine.go index 0188a59ee..cee8738ae 100644 --- a/cmd/cgr-engine/cgr-engine.go +++ b/cmd/cgr-engine/cgr-engine.go @@ -338,10 +338,7 @@ func singnalHandler(shdWg *sync.WaitGroup, shdChan *utils.SyncedChan) { go func() { var reply string if err := config.CgrConfig().V1ReloadConfig(context.Background(), - &config.ReloadArgs{ - Section: utils.EmptyString, - Path: config.CgrConfig().ConfigPath, // use the same path - }, &reply); err != nil { + new(config.ReloadArgs), &reply); err != nil { utils.Logger.Warning( fmt.Sprintf("Error reloading configuration: <%s>", err)) } diff --git a/config/apis.go b/config/apis.go index 0fa54161c..e238d2052 100644 --- a/config/apis.go +++ b/config/apis.go @@ -127,39 +127,32 @@ func (cfg *CGRConfig) getSectionAsMap(section string) (mp interface{}, err error type ReloadArgs struct { APIOpts map[string]interface{} Tenant string - Path string Section string DryRun bool } // V1ReloadConfig reloads the configuration func (cfg *CGRConfig) V1ReloadConfig(ctx *context.Context, args *ReloadArgs, reply *string) (err error) { - updateDB := cfg.db != nil - if !updateDB && - args.Path == utils.EmptyString { - return utils.NewErrMandatoryIeMissing("Path") - } else if updateDB && - args.Path != utils.EmptyString { - return fmt.Errorf("Reload from the path is disabled when the configDB is enabled") - } cfgV := cfg if args.DryRun { cfgV = cfg.Clone() } cfgV.reloadDPCache(args.Section) - if updateDB { - sections := []string{args.Section} - if args.Section == utils.MetaEmpty || - args.Section == utils.MetaAll { - sections = sortedCfgSections[:len(sortedCfgSections)-1] // all exept the configDB section - } - err = cfgV.loadCfgFromDB(cfg.db, sections) - } else { - err = cfgV.loadCfgWithLocks(args.Path, args.Section) - } - if err != nil { + if err = cfgV.loadCfgWithLocks(cfg.ConfigPath, args.Section); err != nil { return } + if cfg.db != nil { + sections := []string{args.Section} + allSections := args.Section == utils.MetaEmpty || + args.Section == utils.MetaAll + if allSections { + sections = sortedCfgSections + } + if err = cfgV.loadCfgFromDB(cfg.db, sections, allSections); err != nil { + return + } + } + // lock all sections cfgV.rLockSections() @@ -388,19 +381,24 @@ func (cfg *CGRConfig) LoadFromDB(jsnCfg ConfigDB) (err error) { return cfg.checkConfigSanity() } -func (cfg *CGRConfig) loadCfgFromDB(db ConfigDB, sections []string) (err error) { +func (cfg *CGRConfig) loadCfgFromDB(db ConfigDB, sections []string, ignoreConfigDB bool) (err error) { loadMap := cfg.getLoadFunctions() for _, section := range sections { - if fnct, has := loadMap[section]; !has || - section == ConfigDBJSON { - return fmt.Errorf("Invalid section: <%s> ", section) - } else { - cfg.lks[section].Lock() - err = fnct(db) - cfg.lks[section].Unlock() - if err != nil { - return + if section == ConfigDBJSON { + if ignoreConfigDB { + continue } + return fmt.Errorf("Invalid section: <%s> ", section) + } + fnct, has := loadMap[section] + if !has { + return fmt.Errorf("Invalid section: <%s> ", section) + } + cfg.lks[section].Lock() + err = fnct(db) + cfg.lks[section].Unlock() + if err != nil { + return } } return diff --git a/config/config_it_test.go b/config/config_it_test.go index 13f2cdc59..d9048bdf0 100644 --- a/config/config_it_test.go +++ b/config/config_it_test.go @@ -42,6 +42,7 @@ var ( testNewCgrJsonCfgFromHttp, testNewCGRConfigFromPath, testCGRConfigReloadAttributeS, + testCGRConfigReloadAttributeSWithDB, testCGRConfigReloadChargerSDryRun, testCGRConfigReloadChargerS, testCGRConfigReloadThresholdS, @@ -136,8 +137,8 @@ func testCGRConfigReloadAttributeS(t *testing.T) { cfg.rldChans[section] = make(chan struct{}, 1) } var reply string + cfg.ConfigPath = path.Join("/usr", "share", "cgrates", "conf", "samples", "tutmongo2") if err = cfg.V1ReloadConfig(context.Background(), &ReloadArgs{ - Path: path.Join("/usr", "share", "cgrates", "conf", "samples", "tutmongo2"), Section: AttributeSJSON, }, &reply); err != nil { t.Error(err) @@ -161,14 +162,51 @@ func testCGRConfigReloadAttributeS(t *testing.T) { } } +func testCGRConfigReloadAttributeSWithDB(t *testing.T) { + cfg := NewDefaultCGRConfig() + for _, section := range sortedCfgSections { + cfg.rldChans[section] = make(chan struct{}, 1) + } + cfg.db = make(CgrJsonCfg) + if err := cfg.db.SetSection(context.Background(), AttributeSJSON, &AttributeSJsonCfg{ + Stats_conns: &[]string{utils.MetaLocalHost}, + }); err != nil { + t.Fatal(err) + } + var reply string + cfg.ConfigPath = path.Join("/usr", "share", "cgrates", "conf", "samples", "tutmongo2") + if err = cfg.V1ReloadConfig(context.Background(), &ReloadArgs{ + Section: AttributeSJSON, + }, &reply); err != nil { + t.Error(err) + } else if reply != utils.OK { + t.Errorf("Expected OK received: %s", reply) + } + expAttr := &AttributeSCfg{ + Enabled: true, + ApierSConns: []string{}, + ResourceSConns: []string{}, + StatSConns: []string{utils.MetaLocalHost}, + StringIndexedFields: &[]string{utils.MetaReq + utils.NestingSep + utils.AccountField}, + PrefixIndexedFields: &[]string{}, + SuffixIndexedFields: &[]string{}, + IndexedSelects: true, + ProcessRuns: 1, + AnyContext: true, + } + if !reflect.DeepEqual(expAttr, cfg.AttributeSCfg()) { + t.Errorf("Expected %s , received: %s ", utils.ToJSON(expAttr), utils.ToJSON(cfg.AttributeSCfg())) + } +} + func testCGRConfigReloadChargerSDryRun(t *testing.T) { cfg := NewDefaultCGRConfig() for _, section := range sortedCfgSections { cfg.rldChans[section] = make(chan struct{}, 1) } var reply string + cfg.ConfigPath = path.Join("/usr", "share", "cgrates", "conf", "samples", "tutmongo2") if err = cfg.V1ReloadConfig(context.Background(), &ReloadArgs{ - Path: path.Join("/usr", "share", "cgrates", "conf", "samples", "tutmongo2"), Section: ChargerSJSON, DryRun: true, }, &reply); err != nil { @@ -189,8 +227,8 @@ func testCGRConfigReloadChargerS(t *testing.T) { cfg.rldChans[section] = make(chan struct{}, 1) } var reply string + cfg.ConfigPath = path.Join("/usr", "share", "cgrates", "conf", "samples", "tutmongo2") if err = cfg.V1ReloadConfig(context.Background(), &ReloadArgs{ - Path: path.Join("/usr", "share", "cgrates", "conf", "samples", "tutmongo2"), Section: ChargerSJSON, }, &reply); err != nil { t.Error(err) @@ -216,10 +254,8 @@ func testCGRConfigReloadThresholdS(t *testing.T) { cfg.rldChans[section] = make(chan struct{}, 1) } var reply string - if err = cfg.V1ReloadConfig(context.Background(), &ReloadArgs{ - Path: path.Join("/usr", "share", "cgrates", "conf", "samples", "tutmongo2"), - Section: ThresholdSJSON, - }, &reply); err != nil { + cfg.ConfigPath = path.Join("/usr", "share", "cgrates", "conf", "samples", "tutmongo2") + if err = cfg.V1ReloadConfig(context.Background(), &ReloadArgs{Section: ThresholdSJSON}, &reply); err != nil { t.Error(err) } else if reply != utils.OK { t.Errorf("Expected OK received: %s", reply) @@ -243,8 +279,8 @@ func testCGRConfigReloadStatS(t *testing.T) { cfg.rldChans[section] = make(chan struct{}, 1) } var reply string + cfg.ConfigPath = path.Join("/usr", "share", "cgrates", "conf", "samples", "tutmongo2") if err = cfg.V1ReloadConfig(context.Background(), &ReloadArgs{ - Path: path.Join("/usr", "share", "cgrates", "conf", "samples", "tutmongo2"), Section: StatSJSON, }, &reply); err != nil { t.Error(err) @@ -270,8 +306,8 @@ func testCGRConfigReloadResourceS(t *testing.T) { cfg.rldChans[section] = make(chan struct{}, 1) } var reply string + cfg.ConfigPath = path.Join("/usr", "share", "cgrates", "conf", "samples", "tutmongo2") if err = cfg.V1ReloadConfig(context.Background(), &ReloadArgs{ - Path: path.Join("/usr", "share", "cgrates", "conf", "samples", "tutmongo2"), Section: ResourceSJSON, }, &reply); err != nil { t.Error(err) @@ -297,8 +333,8 @@ func testCGRConfigReloadSupplierS(t *testing.T) { cfg.rldChans[section] = make(chan struct{}, 1) } var reply string + cfg.ConfigPath = path.Join("/usr", "share", "cgrates", "conf", "samples", "tutmongo2") if err = cfg.V1ReloadConfig(context.Background(), &ReloadArgs{ - Path: path.Join("/usr", "share", "cgrates", "conf", "samples", "tutmongo2"), Section: RouteSJSON, }, &reply); err != nil { t.Error(err) @@ -328,19 +364,12 @@ func testCGRConfigV1ReloadConfigFromPathInvalidSection(t *testing.T) { } expectedErr := "Invalid section: " var reply string + cfg.ConfigPath = path.Join("/usr", "share", "cgrates", "conf", "samples", "tutmongo2") if err := cfg.V1ReloadConfig(context.Background(), &ReloadArgs{ - Path: path.Join("/usr", "share", "cgrates", "conf", "samples", "tutmongo2"), Section: "InvalidSection", }, &reply); err == nil || err.Error() != expectedErr { t.Errorf("Expected %q. received %q", expectedErr, err.Error()) } - - expectedErr = utils.NewErrMandatoryIeMissing("Path").Error() - if err := cfg.V1ReloadConfig(context.Background(), &ReloadArgs{ - Section: "InvalidSection", - }, &reply); err == nil || err.Error() != expectedErr { - t.Errorf("Expected %+v. received %+v", expectedErr, err) - } } func testV1ReloadConfigFromPathConfigSanity(t *testing.T) { @@ -350,8 +379,8 @@ func testV1ReloadConfigFromPathConfigSanity(t *testing.T) { for _, section := range sortedCfgSections { cfg.rldChans[section] = make(chan struct{}, 1) } + cfg.ConfigPath = path.Join("/usr", "share", "cgrates", "conf", "samples", "tutinternal") if err := cfg.V1ReloadConfig(context.Background(), &ReloadArgs{ - Path: path.Join("/usr", "share", "cgrates", "conf", "samples", "tutinternal"), Section: ChargerSJSON}, &reply); err == nil || err.Error() != expectedErr { t.Errorf("Expected %+v, received %+v", expectedErr, err) } @@ -382,8 +411,8 @@ func testCGRConfigReloadERs(t *testing.T) { } cfg.SessionSCfg().Enabled = true var reply string + cfg.ConfigPath = path.Join("/usr", "share", "cgrates", "conf", "samples", "ers_example") if err = cfg.V1ReloadConfig(context.Background(), &ReloadArgs{ - Path: path.Join("/usr", "share", "cgrates", "conf", "samples", "ers_example"), Section: ERsJSON, }, &reply); err != nil { t.Error(err) @@ -468,8 +497,8 @@ func testCGRConfigReloadDNSAgent(t *testing.T) { } cfg.SessionSCfg().Enabled = true var reply string + cfg.ConfigPath = path.Join("/usr", "share", "cgrates", "conf", "samples", "dnsagent_reload") if err = cfg.V1ReloadConfig(context.Background(), &ReloadArgs{ - Path: path.Join("/usr", "share", "cgrates", "conf", "samples", "dnsagent_reload"), Section: DNSAgentJSON, }, &reply); err != nil { t.Error(err) @@ -496,8 +525,8 @@ func testCGRConfigReloadFreeswitchAgent(t *testing.T) { } cfg.SessionSCfg().Enabled = true var reply string + cfg.ConfigPath = path.Join("/usr", "share", "cgrates", "conf", "samples", "freeswitch_reload") if err = cfg.V1ReloadConfig(context.Background(), &ReloadArgs{ - Path: path.Join("/usr", "share", "cgrates", "conf", "samples", "freeswitch_reload"), Section: FreeSWITCHAgentJSON, }, &reply); err != nil { t.Error(err) @@ -675,8 +704,8 @@ func testCgrCfgV1ReloadConfigSection(t *testing.T) { var reply string var rcv map[string]interface{} + cfg.ConfigPath = "/usr/share/cgrates/conf/samples/ers_example" if err := cfg.V1ReloadConfig(context.Background(), &ReloadArgs{ - Path: "/usr/share/cgrates/conf/samples/ers_example", Section: ERsJSON, }, &reply); err != nil { t.Fatal(err) @@ -829,8 +858,8 @@ func testCGRConfigReloadAll(t *testing.T) { cfg.ChargerSCfg().Enabled = true cfg.CdrsCfg().Enabled = true var reply string + cfg.ConfigPath = path.Join("/usr", "share", "cgrates", "conf", "samples", "tutmongo2") if err = cfg.V1ReloadConfig(context.Background(), &ReloadArgs{ - Path: path.Join("/usr", "share", "cgrates", "conf", "samples", "tutmongo2"), Section: utils.MetaAll, }, &reply); err != nil { t.Error(err)