diff --git a/config/config.go b/config/config.go
index 187ce4bbb..0bc365efe 100755
--- a/config/config.go
+++ b/config/config.go
@@ -37,7 +37,7 @@ var (
dfltKamConnConfig *KamConnConfig // Default Kamailio Connection configuration
dfltHaPoolConfig *HaPoolConfig
dfltAstConnCfg *AsteriskConnCfg
- dfltLoaderConfig *LoaderSConfig
+ dfltLoaderConfig *LoaderSCfg
dfltLoaderDataTypeConfig *LoaderDataType
)
@@ -256,6 +256,7 @@ type CGRConfig struct {
MaxCallDuration time.Duration // The maximum call duration (used by responder when querying DerivedCharging) // ToDo: export it in configuration file
CdreProfiles map[string]*CdreCfg
+ loaderCfg []*LoaderSCfg // configuration for Loader
CdrcProfiles map[string][]*CdrcConfig // Number of CDRC instances running imports, format map[dirPath][]{Configs}
sessionSCfg *SessionSCfg
@@ -276,7 +277,6 @@ type CGRConfig struct {
statsCfg *StatSCfg // Configuration for StatS
thresholdSCfg *ThresholdSCfg // configuration for ThresholdS
supplierSCfg *SupplierSCfg // configuration for SupplierS
- loaderCfg []*LoaderSConfig // configuration for Loader
dispatcherSCfg *DispatcherSCfg // configuration for Dispatcher
MailerServer string // The server to use when sending emails out
MailerAuthUser string // Authenticate to email server using this user
@@ -954,9 +954,9 @@ func (self *CGRConfig) loadFromJsonCfg(jsnCfg *CgrJsonCfg) (err error) {
}
if jsnLoaderCfg != nil {
- self.loaderCfg = make([]*LoaderSConfig, len(jsnLoaderCfg))
+ self.loaderCfg = make([]*LoaderSCfg, len(jsnLoaderCfg))
for idx, profile := range jsnLoaderCfg {
- self.loaderCfg[idx] = NewDfltLoaderSConfig()
+ self.loaderCfg[idx] = NewDfltLoaderSCfg()
self.loaderCfg[idx].loadFromJsonCfg(profile)
}
}
@@ -1252,7 +1252,7 @@ func (cfg *CGRConfig) CacheCfg() CacheCfg {
return cfg.cacheCfg
}
-func (cfg *CGRConfig) LoaderCfg() []*LoaderSConfig {
+func (cfg *CGRConfig) LoaderCfg() []*LoaderSCfg {
return cfg.loaderCfg
}
diff --git a/config/config_test.go b/config/config_test.go
index 16c906b4a..5cef20a7c 100755
--- a/config/config_test.go
+++ b/config/config_test.go
@@ -1079,7 +1079,7 @@ func TestDbDefaults(t *testing.T) {
}
func TestCgrLoaderCfgITDefaults(t *testing.T) {
- eCfg := []*LoaderSConfig{
+ eCfg := []*LoaderSCfg{
{
Id: utils.META_DEFAULT,
Enabled: false,
diff --git a/config/loadercfg.go b/config/loadercgrcfg.go
similarity index 100%
rename from config/loadercfg.go
rename to config/loadercgrcfg.go
diff --git a/config/loadersconfig.go b/config/loaderscfg.go
similarity index 93%
rename from config/loadersconfig.go
rename to config/loaderscfg.go
index fe94d0c9b..b7e496ba7 100644
--- a/config/loadersconfig.go
+++ b/config/loaderscfg.go
@@ -22,15 +22,15 @@ import (
"time"
)
-func NewDfltLoaderSConfig() *LoaderSConfig {
+func NewDfltLoaderSCfg() *LoaderSCfg {
if dfltLoaderConfig == nil {
- return new(LoaderSConfig)
+ return new(LoaderSCfg)
}
dfltVal := *dfltLoaderConfig
return &dfltVal
}
-type LoaderSConfig struct { // rename to LoaderSConfig
+type LoaderSCfg struct {
Id string
Enabled bool
Tenant RSRParsers
@@ -76,7 +76,7 @@ func (self *LoaderDataType) loadFromJsonCfg(jsnCfg *LoaderJsonDataType) (err err
return nil
}
-func (self *LoaderSConfig) loadFromJsonCfg(jsnCfg *LoaderJsonCfg) (err error) {
+func (self *LoaderSCfg) loadFromJsonCfg(jsnCfg *LoaderJsonCfg) (err error) {
if jsnCfg == nil {
return nil
}
@@ -130,8 +130,8 @@ func (self *LoaderSConfig) loadFromJsonCfg(jsnCfg *LoaderJsonCfg) (err error) {
}
// Clone itself into a new LoadersConfig
-func (self *LoaderSConfig) Clone() *LoaderSConfig {
- clnLoader := new(LoaderSConfig)
+func (self *LoaderSCfg) Clone() *LoaderSCfg {
+ clnLoader := new(LoaderSCfg)
clnLoader.Id = self.Id
clnLoader.Enabled = self.Enabled
clnLoader.Tenant = self.Tenant
diff --git a/config/loaderscfg_test.go b/config/loaderscfg_test.go
new file mode 100644
index 000000000..1232eaa49
--- /dev/null
+++ b/config/loaderscfg_test.go
@@ -0,0 +1,107 @@
+/*
+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
+*/
+package config
+
+import (
+ "reflect"
+ "strings"
+ "testing"
+
+ "github.com/cgrates/cgrates/utils"
+)
+
+func TestLoaderSCfgloadFromJsonCfg(t *testing.T) {
+ var loadscfg, expected LoaderSCfg
+ if err := loadscfg.loadFromJsonCfg(nil); err != nil {
+ t.Error(err)
+ } else if !reflect.DeepEqual(loadscfg, expected) {
+ t.Errorf("Expected: %+v ,recived: %+v", expected, loadscfg)
+ }
+ if err := loadscfg.loadFromJsonCfg(new(LoaderJsonCfg)); err != nil {
+ t.Error(err)
+ } else if !reflect.DeepEqual(loadscfg, expected) {
+ t.Errorf("Expected: %+v ,recived: %+v", expected, loadscfg)
+ }
+ cfgJSONStr := `{
+"loaders": [
+ {
+ "id": "*default", // identifier of the Loader
+ "enabled": false, // starts as service: .
+ "tenant": "cgrates.org", // tenant used in filterS.Pass
+ "dry_run": false, // do not send the CDRs to CDRS, just parse them
+ "run_delay": 0, // sleep interval in seconds between consecutive runs, 0 to use automation via inotify
+ "lock_filename": ".cgr.lck", // Filename containing concurrency lock in case of delayed processing
+ "caches_conns": [
+ {"address": "*internal"}, // address where to reach the CacheS for data reload, empty for no reloads <""|*internal|x.y.z.y:1234>
+ ],
+ "field_separator": ",", // separator used in case of csv files
+ "tp_in_dir": "/var/spool/cgrates/loader/in", // absolute path towards the directory where the CDRs are stored
+ "tp_out_dir": "/var/spool/cgrates/loader/out", // absolute path towards the directory where processed CDRs will be moved
+ "data":[ // data profiles to load
+ {
+ "type": "*attributes", // data source type
+ "file_name": "Attributes.csv", // file name in the tp_in_dir
+ "fields": [
+ {"tag": "TenantID", "field_id": "Tenant", "type": "*composed", "value": "~0", "mandatory": true},
+ ],
+ },]
+ }
+ ]
+}`
+ val, err := NewRSRParsers("~0", true)
+ if err != nil {
+ t.Error(err)
+ }
+ ten, err := NewRSRParsers("cgrates.org", true)
+ if err != nil {
+ t.Error(err)
+ }
+ expected = LoaderSCfg{
+ Id: "*default",
+ Tenant: ten,
+ LockFileName: ".cgr.lck",
+ CacheSConns: []*HaPoolConfig{{Address: utils.MetaInternal}},
+ FieldSeparator: ",",
+ TpInDir: "/var/spool/cgrates/loader/in",
+ TpOutDir: "/var/spool/cgrates/loader/out",
+ Data: []*LoaderDataType{
+ {
+ Type: "*attributes",
+ Filename: "Attributes.csv",
+ Fields: []*FCTemplate{
+ {
+ Tag: "TenantID",
+ FieldId: "Tenant",
+ Type: "*composed",
+ Value: val,
+ Mandatory: true,
+ },
+ },
+ },
+ },
+ }
+ if jsnCfg, err := NewCgrJsonCfgFromReader(strings.NewReader(cfgJSONStr)); err != nil {
+ t.Error(err)
+ } else if jsnLoadersCfg, err := jsnCfg.LoaderJsonCfg(); err != nil {
+ t.Error(err)
+ } else if err = loadscfg.loadFromJsonCfg(jsnLoadersCfg[0]); err != nil {
+ t.Error(err)
+ } else if !reflect.DeepEqual(expected, loadscfg) {
+ t.Errorf("Expected: %+v , recived: %+v", utils.ToJSON(expected), utils.ToJSON(loadscfg))
+ }
+}
diff --git a/loaders/loader.go b/loaders/loader.go
index a84cceef5..65bc19fd7 100644
--- a/loaders/loader.go
+++ b/loaders/loader.go
@@ -38,7 +38,7 @@ type openedCSVFile struct {
csvRdr *csv.Reader
}
-func NewLoader(dm *engine.DataManager, cfg *config.LoaderSConfig,
+func NewLoader(dm *engine.DataManager, cfg *config.LoaderSCfg,
timezone string, filterS *engine.FilterS) (ldr *Loader) {
ldr = &Loader{
enabled: cfg.Enabled,
diff --git a/loaders/loaders.go b/loaders/loaders.go
index b98263a08..1f9557859 100644
--- a/loaders/loaders.go
+++ b/loaders/loaders.go
@@ -27,7 +27,7 @@ import (
"github.com/cgrates/cgrates/utils"
)
-func NewLoaderService(dm *engine.DataManager, ldrsCfg []*config.LoaderSConfig,
+func NewLoaderService(dm *engine.DataManager, ldrsCfg []*config.LoaderSCfg,
timezone string, filterS *engine.FilterS) (ldrS *LoaderService) {
ldrS = &LoaderService{ldrs: make(map[string]*Loader)}
for _, ldrCfg := range ldrsCfg {