Add config infrastructure for RateS

This commit is contained in:
TeoV
2020-05-14 15:08:15 +03:00
committed by Dan Christian Bogos
parent ed6647d1f2
commit 4299c56ff4
9 changed files with 154 additions and 25 deletions

View File

@@ -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()

View File

@@ -888,4 +888,9 @@ const CGRATES_CFG_JSON = `
"attributes_conns": [], // connections to AttributeS for CDRExporter
},
"rates": {
"enabled": false,
},
}`

View File

@@ -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
}

View File

@@ -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) {

View File

@@ -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
}

View File

@@ -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},
],
},
],

View File

@@ -604,3 +604,7 @@ type STIRJsonCfg struct {
Publickey_path *string
Privatekey_path *string
}
type RateSJsonCfg struct {
Enabled *bool
}

View File

@@ -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
View 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)
}
}