mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
Add config infrastructure for RateS
This commit is contained in:
committed by
Dan Christian Bogos
parent
ed6647d1f2
commit
4299c56ff4
@@ -181,6 +181,7 @@ func NewDefaultCGRConfig() (cfg *CGRConfig, err error) {
|
||||
cfg.ersCfg = new(ERsCfg)
|
||||
cfg.eesCfg = new(EEsCfg)
|
||||
cfg.eesCfg.Cache = make(map[string]*CacheParamCfg)
|
||||
cfg.rateSCfg = new(RateSCfg)
|
||||
|
||||
cfg.ConfigReloads = make(map[string]chan struct{})
|
||||
cfg.ConfigReloads[utils.CDRE] = make(chan struct{}, 1)
|
||||
@@ -350,7 +351,8 @@ func (cfg *CGRConfig) loadFromJsonCfg(jsnCfg *CgrJsonCfg) (err error) {
|
||||
cfg.loadThresholdSCfg, cfg.loadRouteSCfg, cfg.loadLoaderSCfg,
|
||||
cfg.loadMailerCfg, cfg.loadSureTaxCfg, cfg.loadDispatcherSCfg,
|
||||
cfg.loadLoaderCgrCfg, cfg.loadMigratorCgrCfg, cfg.loadTlsCgrCfg,
|
||||
cfg.loadAnalyzerCgrCfg, cfg.loadApierCfg, cfg.loadErsCfg, cfg.loadEesCfg} {
|
||||
cfg.loadAnalyzerCgrCfg, cfg.loadApierCfg, cfg.loadErsCfg, cfg.loadEesCfg,
|
||||
cfg.loadRateCfg} {
|
||||
if err = loadFunc(jsnCfg); err != nil {
|
||||
return
|
||||
}
|
||||
@@ -741,6 +743,15 @@ func (cfg *CGRConfig) loadEesCfg(jsnCfg *CgrJsonCfg) (err error) {
|
||||
return cfg.eesCfg.loadFromJsonCfg(jsnEEsCfg, cfg.generalCfg.RSRSep, cfg.dfltEvExp)
|
||||
}
|
||||
|
||||
// loadEesCfg loads the Ees section of the configuration
|
||||
func (cfg *CGRConfig) loadRateCfg(jsnCfg *CgrJsonCfg) (err error) {
|
||||
var jsnRateCfg *RateSJsonCfg
|
||||
if jsnRateCfg, err = jsnCfg.RateCfgJson(); err != nil {
|
||||
return
|
||||
}
|
||||
return cfg.rateSCfg.loadFromJsonCfg(jsnRateCfg)
|
||||
}
|
||||
|
||||
// SureTaxCfg use locking to retrieve the configuration, possibility later for runtime reload
|
||||
func (cfg *CGRConfig) SureTaxCfg() *SureTaxCfg {
|
||||
cfg.lks[SURETAX_JSON].Lock()
|
||||
|
||||
@@ -888,4 +888,9 @@ const CGRATES_CFG_JSON = `
|
||||
"attributes_conns": [], // connections to AttributeS for CDRExporter
|
||||
},
|
||||
|
||||
|
||||
"rates": {
|
||||
"enabled": false,
|
||||
},
|
||||
|
||||
}`
|
||||
|
||||
@@ -507,3 +507,15 @@ func (self CgrJsonCfg) ApierCfgJson() (*ApierJsonCfg, error) {
|
||||
}
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
func (self CgrJsonCfg) RateCfgJson() (*RateSJsonCfg, error) {
|
||||
rawCfg, hasKey := self[RateSJson]
|
||||
if !hasKey {
|
||||
return nil, nil
|
||||
}
|
||||
cfg := new(RateSJsonCfg)
|
||||
if err := json.Unmarshal(*rawCfg, cfg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
@@ -1766,6 +1766,15 @@ func TestCgrCfgJSONDefaultApierCfg(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCgrCfgJSONDefaultRateCfg(t *testing.T) {
|
||||
eCfg := &RateSCfg{
|
||||
Enabled: false,
|
||||
}
|
||||
if !reflect.DeepEqual(cgrCfg.rateSCfg, eCfg) {
|
||||
t.Errorf("received: %+v, expecting: %+v", cgrCfg.rateSCfg, eCfg)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCgrCfgV1GetConfigSection(t *testing.T) {
|
||||
JSN_CFG := `
|
||||
{
|
||||
@@ -1872,7 +1881,7 @@ func TestCgrCdfEventExporter(t *testing.T) {
|
||||
Filters: []string{},
|
||||
AttributeSIDs: []string{},
|
||||
Flags: utils.FlagsWithParams{},
|
||||
Fields: []*FCTemplate{
|
||||
ContentFields: []*FCTemplate{
|
||||
{
|
||||
Tag: utils.CGRID,
|
||||
Path: "*exp.CGRID",
|
||||
@@ -1973,11 +1982,13 @@ func TestCgrCdfEventExporter(t *testing.T) {
|
||||
RoundingDecimals: utils.IntPointer(4),
|
||||
},
|
||||
},
|
||||
HeaderFields: []*FCTemplate{},
|
||||
TrailerFields: []*FCTemplate{},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, profile := range eCfg.Exporters {
|
||||
for _, v := range profile.Fields {
|
||||
for _, v := range profile.ContentFields {
|
||||
v.ComputePath()
|
||||
}
|
||||
}
|
||||
@@ -2046,7 +2057,7 @@ func TestCgrCfgEventExporterDefault(t *testing.T) {
|
||||
Timezone: utils.EmptyString,
|
||||
Filters: nil,
|
||||
Flags: utils.FlagsWithParams{},
|
||||
Fields: []*FCTemplate{
|
||||
ContentFields: []*FCTemplate{
|
||||
{
|
||||
Tag: utils.CGRID,
|
||||
Path: "*exp.CGRID",
|
||||
@@ -2147,8 +2158,10 @@ func TestCgrCfgEventExporterDefault(t *testing.T) {
|
||||
RoundingDecimals: utils.IntPointer(4),
|
||||
},
|
||||
},
|
||||
HeaderFields: []*FCTemplate{},
|
||||
TrailerFields: []*FCTemplate{},
|
||||
}
|
||||
for _, v := range eCfg.Fields {
|
||||
for _, v := range eCfg.ContentFields {
|
||||
v.ComputePath()
|
||||
}
|
||||
if !reflect.DeepEqual(cgrCfg.dfltEvExp, eCfg) {
|
||||
|
||||
@@ -188,6 +188,9 @@ func (eeC *EventExporterCfg) loadFromJsonCfg(jsnEec *EventExporterJsonCfg, separ
|
||||
eeC.FieldSep = *jsnEec.Field_separator
|
||||
}
|
||||
if jsnEec.Fields != nil {
|
||||
eeC.HeaderFields = make([]*FCTemplate, 0)
|
||||
eeC.ContentFields = make([]*FCTemplate, 0)
|
||||
eeC.TrailerFields = make([]*FCTemplate, 0)
|
||||
if fields, err := FCTemplatesFromFCTemplatesJsonCfg(*jsnEec.Fields, separator); err != nil {
|
||||
return err
|
||||
} else {
|
||||
@@ -196,14 +199,12 @@ func (eeC *EventExporterCfg) loadFromJsonCfg(jsnEec *EventExporterJsonCfg, separ
|
||||
case utils.MetaHdr:
|
||||
eeC.HeaderFields = append(eeC.HeaderFields, field)
|
||||
case utils.MetaExp:
|
||||
eeC.ContentFields = append(eeC.HeaderFields, field)
|
||||
eeC.ContentFields = append(eeC.ContentFields, field)
|
||||
case utils.MetaTrl:
|
||||
eeC.TrailerFields = append(eeC.HeaderFields, field)
|
||||
eeC.TrailerFields = append(eeC.TrailerFields, field)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -33,24 +33,26 @@ func TestEventExporterClone(t *testing.T) {
|
||||
FieldSep: ",",
|
||||
Filters: []string{"Filter1", "Filter2"},
|
||||
Tenant: NewRSRParsersMustCompile("cgrates.org", true, utils.INFIELD_SEP),
|
||||
Fields: []*FCTemplate{
|
||||
ContentFields: []*FCTemplate{
|
||||
{
|
||||
Tag: "ToR",
|
||||
Path: "ToR",
|
||||
Path: "*exp.ToR",
|
||||
Type: "*composed",
|
||||
Value: NewRSRParsersMustCompile("~*req.2", true, utils.INFIELD_SEP),
|
||||
Mandatory: true,
|
||||
},
|
||||
{
|
||||
Tag: "RandomField",
|
||||
Path: "RandomField",
|
||||
Path: "*exp.RandomField",
|
||||
Type: "*composed",
|
||||
Value: NewRSRParsersMustCompile("Test", true, utils.INFIELD_SEP),
|
||||
Mandatory: true,
|
||||
},
|
||||
},
|
||||
HeaderFields: []*FCTemplate{},
|
||||
TrailerFields: []*FCTemplate{},
|
||||
}
|
||||
for _, v := range orig.Fields {
|
||||
for _, v := range orig.ContentFields {
|
||||
v.ComputePath()
|
||||
}
|
||||
cloned := orig.Clone()
|
||||
@@ -63,31 +65,33 @@ func TestEventExporterClone(t *testing.T) {
|
||||
FieldSep: ",",
|
||||
Filters: []string{"Filter1", "Filter2"},
|
||||
Tenant: NewRSRParsersMustCompile("cgrates.org", true, utils.INFIELD_SEP),
|
||||
Fields: []*FCTemplate{
|
||||
ContentFields: []*FCTemplate{
|
||||
{
|
||||
Tag: "ToR",
|
||||
Path: "ToR",
|
||||
Path: "*exp.ToR",
|
||||
Type: "*composed",
|
||||
Value: NewRSRParsersMustCompile("~*req.2", true, utils.INFIELD_SEP),
|
||||
Mandatory: true,
|
||||
},
|
||||
{
|
||||
Tag: "RandomField",
|
||||
Path: "RandomField",
|
||||
Path: "*exp.RandomField",
|
||||
Type: "*composed",
|
||||
Value: NewRSRParsersMustCompile("Test", true, utils.INFIELD_SEP),
|
||||
Mandatory: true,
|
||||
},
|
||||
},
|
||||
HeaderFields: []*FCTemplate{},
|
||||
TrailerFields: []*FCTemplate{},
|
||||
}
|
||||
for _, v := range initialOrig.Fields {
|
||||
for _, v := range initialOrig.ContentFields {
|
||||
v.ComputePath()
|
||||
}
|
||||
orig.Filters = []string{"SingleFilter"}
|
||||
orig.Fields = []*FCTemplate{
|
||||
orig.ContentFields = []*FCTemplate{
|
||||
{
|
||||
Tag: "ToR",
|
||||
Path: "ToR",
|
||||
Path: "*exp.ToR",
|
||||
Type: "*composed",
|
||||
Value: NewRSRParsersMustCompile("~2", true, utils.INFIELD_SEP),
|
||||
Mandatory: true,
|
||||
@@ -121,7 +125,7 @@ func TestEventExporterSameID(t *testing.T) {
|
||||
Filters: []string{},
|
||||
AttributeSIDs: []string{},
|
||||
Flags: utils.FlagsWithParams{},
|
||||
Fields: []*FCTemplate{
|
||||
ContentFields: []*FCTemplate{
|
||||
{
|
||||
Tag: utils.CGRID,
|
||||
Path: "*exp.CGRID",
|
||||
@@ -222,6 +226,8 @@ func TestEventExporterSameID(t *testing.T) {
|
||||
RoundingDecimals: utils.IntPointer(4),
|
||||
},
|
||||
},
|
||||
HeaderFields: []*FCTemplate{},
|
||||
TrailerFields: []*FCTemplate{},
|
||||
},
|
||||
{
|
||||
ID: "file_exporter1",
|
||||
@@ -233,15 +239,17 @@ func TestEventExporterSameID(t *testing.T) {
|
||||
ExportPath: "/var/spool/cgrates/ees",
|
||||
Attempts: 1,
|
||||
Flags: utils.FlagsWithParams{},
|
||||
Fields: []*FCTemplate{
|
||||
{Tag: "CustomTag2", Path: "CustomPath2", Type: utils.MetaVariable,
|
||||
ContentFields: []*FCTemplate{
|
||||
{Tag: "CustomTag2", Path: "*exp.CustomPath2", Type: utils.MetaVariable,
|
||||
Value: NewRSRParsersMustCompile("CustomValue2", true, utils.INFIELD_SEP), Mandatory: true, Layout: time.RFC3339},
|
||||
},
|
||||
HeaderFields: []*FCTemplate{},
|
||||
TrailerFields: []*FCTemplate{},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, profile := range expectedEEsCfg.Exporters {
|
||||
for _, v := range profile.Fields {
|
||||
for _, v := range profile.ContentFields {
|
||||
v.ComputePath()
|
||||
}
|
||||
}
|
||||
@@ -254,14 +262,14 @@ func TestEventExporterSameID(t *testing.T) {
|
||||
"id": "file_exporter1",
|
||||
"type": "*file_csv",
|
||||
"fields":[
|
||||
{"tag": "CustomTag1", "path": "CustomPath1", "type": "*variable", "value": "CustomValue1", "mandatory": true},
|
||||
{"tag": "CustomTag1", "path": "*exp.CustomPath1", "type": "*variable", "value": "CustomValue1", "mandatory": true},
|
||||
],
|
||||
},
|
||||
{
|
||||
"id": "file_exporter1",
|
||||
"type": "*file_csv",
|
||||
"fields":[
|
||||
{"tag": "CustomTag2", "path": "CustomPath2", "type": "*variable", "value": "CustomValue2", "mandatory": true},
|
||||
{"tag": "CustomTag2", "path": "*exp.CustomPath2", "type": "*variable", "value": "CustomValue2", "mandatory": true},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
@@ -604,3 +604,7 @@ type STIRJsonCfg struct {
|
||||
Publickey_path *string
|
||||
Privatekey_path *string
|
||||
}
|
||||
|
||||
type RateSJsonCfg struct {
|
||||
Enabled *bool
|
||||
}
|
||||
|
||||
@@ -18,6 +18,26 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
package config
|
||||
|
||||
import (
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
type RateSCfg struct {
|
||||
Enabled bool
|
||||
}
|
||||
|
||||
func (rCfg *RateSCfg) loadFromJsonCfg(jsnCfg *RateSJsonCfg) (err error) {
|
||||
if jsnCfg == nil {
|
||||
return
|
||||
}
|
||||
if jsnCfg.Enabled != nil {
|
||||
rCfg.Enabled = *jsnCfg.Enabled
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (rCfg *RateSCfg) AsMapInterface() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
utils.EnabledCfg: rCfg.Enabled,
|
||||
}
|
||||
}
|
||||
|
||||
55
config/ratescfg_test.go
Normal file
55
config/ratescfg_test.go
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
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 ANY 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 <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
package config
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRateSConfigloadFromJsonCfg(t *testing.T) {
|
||||
var rateCfg, expected RateSCfg
|
||||
if err := rateCfg.loadFromJsonCfg(nil); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(rateCfg, expected) {
|
||||
t.Errorf("Expected: %+v ,recived: %+v", expected, rateCfg)
|
||||
}
|
||||
if err := rateCfg.loadFromJsonCfg(new(RateSJsonCfg)); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(rateCfg, expected) {
|
||||
t.Errorf("Expected: %+v ,recived: %+v", expected, rateCfg)
|
||||
}
|
||||
cfgJSONStr := `{
|
||||
"rates": {
|
||||
"enabled": true,
|
||||
},
|
||||
}`
|
||||
expected = RateSCfg{
|
||||
Enabled: true,
|
||||
}
|
||||
if jsnCfg, err := NewCgrJsonCfgFromBytes([]byte(cfgJSONStr)); err != nil {
|
||||
t.Error(err)
|
||||
} else if jsnRateSCfg, err := jsnCfg.RateCfgJson(); err != nil {
|
||||
t.Error(err)
|
||||
} else if err = rateCfg.loadFromJsonCfg(jsnRateSCfg); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(expected, rateCfg) {
|
||||
t.Errorf("Expected: %+v , recived: %+v", expected, rateCfg)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user