diff --git a/config/attributescfg_test.go b/config/attributescfg_test.go index a41ab4c1a..9bc858808 100644 --- a/config/attributescfg_test.go +++ b/config/attributescfg_test.go @@ -28,6 +28,9 @@ func TestAttributeSCfgloadFromJsonCfg(t *testing.T) { jsonCfg := &AttributeSJsonCfg{ Enabled: utils.BoolPointer(true), Indexed_selects: utils.BoolPointer(false), + Resources_conns: &[]string{"*internal", "*conn1"}, + Stats_conns: &[]string{"*internal", "*conn1"}, + Apiers_conns: &[]string{"*internal", "*conn1"}, String_indexed_fields: &[]string{"*req.index1"}, Prefix_indexed_fields: &[]string{"*req.index1", "*req.index2"}, Suffix_indexed_fields: &[]string{"*req.index1"}, @@ -36,9 +39,9 @@ func TestAttributeSCfgloadFromJsonCfg(t *testing.T) { } expected := &AttributeSCfg{ Enabled: true, - ApierSConns: []string{}, - StatSConns: []string{}, - ResourceSConns: []string{}, + ApierSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaApier), "*conn1"}, + StatSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaStats), "*conn1"}, + ResourceSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaResources), "*conn1"}, IndexedSelects: false, StringIndexedFields: &[]string{"*req.index1"}, PrefixIndexedFields: &[]string{"*req.index1", "*req.index2"}, diff --git a/config/loaderscfg.go b/config/loaderscfg.go index 3df06dd46..d37f59a20 100644 --- a/config/loaderscfg.go +++ b/config/loaderscfg.go @@ -157,7 +157,9 @@ func (self *LoaderSCfg) loadFromJsonCfg(jsnCfg *LoaderJsonCfg, msgTemplates map[ data := make([]*LoaderDataType, len(*jsnCfg.Data)) for idx, jsnLoCfg := range *jsnCfg.Data { data[idx] = NewDfltLoaderDataTypeConfig() - data[idx].loadFromJsonCfg(jsnLoCfg, msgTemplates, separator) + if err := data[idx].loadFromJsonCfg(jsnLoCfg, msgTemplates, separator); err != nil { + return err + } } self.Data = data } diff --git a/config/loaderscfg_test.go b/config/loaderscfg_test.go index a3027b7fe..e5875e00c 100644 --- a/config/loaderscfg_test.go +++ b/config/loaderscfg_test.go @@ -25,7 +25,7 @@ import ( "github.com/cgrates/cgrates/utils" ) -func TestLoaderSCfgloadFromJsonCfg(t *testing.T) { +func TestLoaderSCfgloadFromJsonCfgCase1(t *testing.T) { cfgJSONStr := `{ "loaders": [ { @@ -33,7 +33,7 @@ func TestLoaderSCfgloadFromJsonCfg(t *testing.T) { "enabled": true, "tenant": "cgrates.org", "lock_filename": ".cgr.lck", - "caches_conns": ["*internal"], + "caches_conns": ["*internal","*conn1"], "field_separator": ",", "tp_in_dir": "/var/spool/cgrates/loader/in", "tp_out_dir": "/var/spool/cgrates/loader/out", @@ -41,6 +41,7 @@ func TestLoaderSCfgloadFromJsonCfg(t *testing.T) { { "type": "*attributes", "file_name": "Attributes.csv", + "flags": [], "fields": [ {"tag": "TenantID", "path": "Tenant", "type": "*composed", "value": "~req.0", "mandatory": true,"layout": "2006-01-02T15:04:05Z07:00"}, ], @@ -63,7 +64,7 @@ func TestLoaderSCfgloadFromJsonCfg(t *testing.T) { Id: utils.MetaDefault, Tenant: ten, LockFileName: ".cgr.lck", - CacheSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCaches)}, + CacheSConns: []string{utils.ConcatenatedKey(utils.MetaInternal, utils.MetaCaches), "*conn1"}, FieldSeparator: ",", TpInDir: "/var/spool/cgrates/loader/in", TpOutDir: "/var/spool/cgrates/loader/out", @@ -71,6 +72,7 @@ func TestLoaderSCfgloadFromJsonCfg(t *testing.T) { { Type: "*attributes", Filename: "Attributes.csv", + Flags: utils.FlagsWithParams{}, Fields: []*FCTemplate{ { Tag: "TenantID", @@ -99,17 +101,158 @@ func TestLoaderSCfgloadFromJsonCfg(t *testing.T) { } } -func TestLoaderCfgAsMapInterface(t *testing.T) { +func TestLoaderSCfgloadFromJsonCfgCase2(t *testing.T) { + cfgJSON := &LoaderJsonCfg{ + Tenant: utils.StringPointer("a{*"), + } + expected := "invalid converter terminator in rule: " + if jsonCfg, err := NewDefaultCGRConfig(); err != nil { + t.Error(err) + } else if err = jsonCfg.loaderCfg[0].loadFromJsonCfg(nil, jsonCfg.templates, jsonCfg.generalCfg.RSRSep); err != nil { + t.Error(err) + } else if err = jsonCfg.loaderCfg[0].loadFromJsonCfg(cfgJSON, jsonCfg.templates, jsonCfg.generalCfg.RSRSep); err == nil || err.Error() != expected { + t.Errorf("Expected %+v, received %+v", expected, err) + } +} + +func TestLoaderSCfgloadFromJsonCfgCase3(t *testing.T) { + cfgJson := &LoaderJsonCfg{ + Data: &[]*LoaderJsonDataType{ + { + Fields: &[]*FcTemplateJsonCfg{ + { + Value: utils.StringPointer("a{*"), + }, + }, + }, + }, + } + expected := "invalid converter terminator in rule: " + if jsonCfg, err := NewDefaultCGRConfig(); err != nil { + t.Error(err) + } else if err := jsonCfg.loaderCfg[0].loadFromJsonCfg(cfgJson, jsonCfg.templates, jsonCfg.generalCfg.RSRSep); err == nil || err.Error() != expected { + t.Errorf("Expected %+v, received %+v", expected, err) + } +} + +func TestLoaderSCfgloadFromJsonCfgCase4(t *testing.T) { + cfgJson := &LoaderJsonCfg{ + Data: &[]*LoaderJsonDataType{ + { + Fields: &[]*FcTemplateJsonCfg{ + { + Type: utils.StringPointer(utils.MetaTemplate), + }, + }, + }, + }, + } + expected := "no template with id: <>" + if jsonCfg, err := NewDefaultCGRConfig(); err != nil { + t.Error(err) + } else if err = jsonCfg.loaderCfg[0].loadFromJsonCfg(cfgJson, jsonCfg.templates, jsonCfg.generalCfg.RSRSep); err == nil || err.Error() != expected { + t.Errorf("Expected %+v, received %+v", expected, err) + } +} + +func TestLoaderSCfgloadFromJsonCfgCase5(t *testing.T) { + cfgJson := &LoaderJsonCfg{ + Data: &[]*LoaderJsonDataType{ + { + Fields: &[]*FcTemplateJsonCfg{ + { + Tag: utils.StringPointer("randomTag"), + Path: utils.StringPointer("randomPath"), + Type: utils.StringPointer(utils.MetaTemplate), + Value: utils.StringPointer("randomTemplate"), + }, + }, + }, + }, + } + expectedFields := LoaderSCfgs{ + { + Data: []*LoaderDataType{ + { + Fields: []*FCTemplate{ + { + Tag: "TenantID", + Path: "Tenant", + Type: utils.MetaVariable, + Value: NewRSRParsersMustCompile("~*req.0", utils.INFIELD_SEP), + Mandatory: true, + }, + }, + }, + }, + }, + } + msgTemplates := map[string][]*FCTemplate{ + "randomTemplate": { + { + Tag: "TenantID", + Path: "Tenant", + Type: utils.MetaVariable, + Value: NewRSRParsersMustCompile("~*req.0", utils.INFIELD_SEP), + Mandatory: true, + }, + }, + } + if jsonCfg, err := NewDefaultCGRConfig(); err != nil { + t.Error(err) + } else if err = jsonCfg.loaderCfg[0].loadFromJsonCfg(cfgJson, msgTemplates, jsonCfg.generalCfg.RSRSep); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(jsonCfg.loaderCfg[0].Data[0].Fields[0], expectedFields[0].Data[0].Fields[0]) { + t.Errorf("Expected %+v \n, received %+v", utils.ToJSON(expectedFields[0].Data[0].Fields[0]), utils.ToJSON(jsonCfg.loaderCfg[0].Data[0].Fields[0])) + } +} + +func TestLoaderSCfgloadFromJsonCfgCase6(t *testing.T) { + cfgJson := &LoaderJsonCfg{ + Data: &[]*LoaderJsonDataType{nil}, + } + if jsonCfg, err := NewDefaultCGRConfig(); err != nil { + t.Error(err) + } else if err = jsonCfg.loaderCfg[0].loadFromJsonCfg(cfgJson, jsonCfg.templates, jsonCfg.generalCfg.RSRSep); err != nil { + t.Error(err) + } +} + +func TestEnabledCase1(t *testing.T) { + jsonCfg, err := NewDefaultCGRConfig() + if err != nil { + t.Error(err) + } + if enabled := jsonCfg.loaderCfg.Enabled(); enabled { + t.Errorf("Expected %+v", enabled) + } +} +func TestEnabledCase2(t *testing.T) { + cfgJSONStr := `{ + "loaders": [ + { + "enabled": true, + }, + ], +}` + if jsonCfg, err := NewCGRConfigFromJsonStringWithDefaults(cfgJSONStr); err != nil { + t.Error(err) + } else if enabled := jsonCfg.loaderCfg.Enabled(); !enabled { + t.Errorf("Expected %+v", enabled) + } +} + +func TestLoaderCfgAsMapInterfaceCase1(t *testing.T) { cfgJSONStr := `{ "loaders": [ { "id": "*default", "enabled": false, - "tenant": "", + "tenant": "~*req.Destination1", "dry_run": false, "run_delay": 0, "lock_filename": ".cgr.lck", - "caches_conns": ["*internal"], + "caches_conns": ["*internal:*caches"], "field_separator": ",", "tp_in_dir": "/var/spool/cgrates/loader/in", "tp_out_dir": "/var/spool/cgrates/loader/out", @@ -130,11 +273,11 @@ func TestLoaderCfgAsMapInterface(t *testing.T) { { utils.IdCfg: "*default", utils.EnabledCfg: false, - utils.TenantCfg: "", + utils.TenantCfg: "~*req.Destination1", utils.DryRunCfg: false, utils.RunDelayCfg: "0", utils.LockFileNameCfg: ".cgr.lck", - utils.CachesConnsCfg: []string{"*internal"}, + utils.CachesConnsCfg: []string{utils.MetaInternal}, utils.FieldSeparatorCfg: ",", utils.TpInDirCfg: "/var/spool/cgrates/loader/in", utils.TpOutDirCfg: "/var/spool/cgrates/loader/out", @@ -174,11 +317,80 @@ func TestLoaderCfgAsMapInterface(t *testing.T) { t.Errorf("Expected %+v \n, received %+v", utils.ToJSON(eMap[0][utils.DataCfg].([]map[string]interface{})[0][utils.FieldsCfg].([]map[string]interface{})[1]), utils.ToJSON(rcv[0][utils.DataCfg].([]map[string]interface{})[0][utils.FieldsCfg].([]map[string]interface{})[1])) } else if !reflect.DeepEqual(eMap[0][utils.CachesConnsCfg], rcv[0][utils.CachesConnsCfg]) { - t.Errorf("Expecetd %+v, received %+v", eMap[0][utils.CachesConnsCfg], rcv[0][utils.CachesConnsCfg]) + t.Errorf("Expected %+v, received %+v", eMap[0][utils.CachesConnsCfg], rcv[0][utils.CachesConnsCfg]) } else if !reflect.DeepEqual(eMap[0][utils.TpInDirCfg], rcv[0][utils.TpInDirCfg]) { - t.Errorf("Expecetd %+v, received %+v", eMap[0][utils.TpInDirCfg], rcv[0][utils.TpInDirCfg]) + t.Errorf("Expected %+v, received %+v", eMap[0][utils.TpInDirCfg], rcv[0][utils.TpInDirCfg]) } else if !reflect.DeepEqual(eMap[0][utils.LockFileNameCfg], rcv[0][utils.LockFileNameCfg]) { - t.Errorf("Expecetd %+v, received %+v", eMap[0][utils.LockFileNameCfg], rcv[0][utils.LockFileNameCfg]) + t.Errorf("Expected %+v, received %+v", eMap[0][utils.LockFileNameCfg], rcv[0][utils.LockFileNameCfg]) } } } + +func TestLoaderCfgAsMapInterfaceCase2(t *testing.T) { + cfgJSONStr := `{ + "loaders": [ + { + "id": "*default", + "enabled": false, + "tenant": "~*req.Destination1", + "dry_run": false, + "run_delay": 1, + "lock_filename": ".cgr.lck", + "caches_conns": ["*conn1"], + "field_separator": ",", + "tp_in_dir": "/var/spool/cgrates/loader/in", + "tp_out_dir": "/var/spool/cgrates/loader/out", + "data":[ + { + "type": "*attributes", + "file_name": "Attributes.csv", + "fields": [ + {"tag": "TenantID", "path": "Tenant", "type": "*variable", "value": "~req.0", "mandatory": true}, + {"tag": "ProfileID", "path": "ID", "type": "*variable", "value": "~*req.1", "mandatory": true}, + ], + }, + ], + }, + ], +}` + eMap := []map[string]interface{}{ + { + utils.IdCfg: "*default", + utils.EnabledCfg: false, + utils.TenantCfg: "~*req.Destination1", + utils.DryRunCfg: false, + utils.RunDelayCfg: "0", + utils.LockFileNameCfg: ".cgr.lck", + utils.CachesConnsCfg: []string{"*conn1"}, + utils.FieldSeparatorCfg: ",", + utils.TpInDirCfg: "/var/spool/cgrates/loader/in", + utils.TpOutDirCfg: "/var/spool/cgrates/loader/out", + utils.DataCfg: []map[string]interface{}{ + { + utils.TypeCfg: "*attributes", + utils.FilenameCfg: "Attributes.csv", + utils.FieldsCfg: []map[string]interface{}{ + { + utils.TagCfg: "TenantID", + utils.PathCfg: "Tenant", + utils.TypeCfg: "*variable", + utils.ValueCfg: "~*req.0", + utils.MandatoryCfg: true, + }, { + utils.TagCfg: "ProfileID", + utils.PathCfg: "ID", + utils.TypeCfg: "*variable", + utils.ValueCfg: "~*req.1", + utils.MandatoryCfg: true, + }, + }, + }, + }, + }, + } + if jsonCfg, err := NewCGRConfigFromJsonStringWithDefaults(cfgJSONStr); err != nil { + t.Error(err) + } else if rcv := jsonCfg.loaderCfg.AsMapInterface(jsonCfg.generalCfg.RSRSep); !reflect.DeepEqual(rcv[0][utils.Tenant], eMap[0][utils.Tenant]) { + t.Errorf("Expected %+v, received %+v", rcv[0][utils.Tenant], eMap[0][utils.Tenant]) + } +}