Add Charger in LoaderS

This commit is contained in:
TeoV
2018-07-10 10:24:41 -04:00
committed by Dan Christian Bogos
parent 94138f156c
commit 93b849bd8e
8 changed files with 255 additions and 1 deletions

View File

@@ -595,6 +595,19 @@ const CGRATES_CFG_JSON = `
{"tag": "Weight", "field_id": "Weight", "type": "*composed", "value": "15"},
],
},
{
"type": "*chargers", // data source type
"file_name": "Chargers.csv", // file name in the tp_in_dir
"fields": [
{"tag": "Tenant", "field_id": "Tenant", "type": "*composed", "value": "0", "mandatory": true},
{"tag": "ID", "field_id": "ID", "type": "*composed", "value": "1", "mandatory": true},
{"tag": "FilterIDs", "field_id": "FilterIDs", "type": "*composed", "value": "2"},
{"tag": "ActivationInterval", "field_id": "ActivationInterval", "type": "*composed", "value": "3"},
{"tag": "RunID", "field_id": "RunID", "type": "*composed", "value": "4"},
{"tag": "AttributeIDs", "field_id": "AttributeIDs", "type": "*composed", "value": "5"},
{"tag": "Weight", "field_id": "Weight", "type": "*composed", "value": "6"},
],
},
],
},
],

View File

@@ -1133,6 +1133,42 @@ func TestDfLoaderJsonCfg(t *testing.T) {
Value: utils.StringPointer("15")},
},
},
&LoaderJsonDataType{
Type: utils.StringPointer(utils.MetaChargers),
File_name: utils.StringPointer(utils.ChargersCsv),
Fields: &[]*CdrFieldJsonCfg{
&CdrFieldJsonCfg{Tag: utils.StringPointer(utils.Tenant),
Field_id: utils.StringPointer(utils.Tenant),
Type: utils.StringPointer(utils.META_COMPOSED),
Value: utils.StringPointer("0"),
Mandatory: utils.BoolPointer(true)},
&CdrFieldJsonCfg{Tag: utils.StringPointer(utils.ID),
Field_id: utils.StringPointer(utils.ID),
Type: utils.StringPointer(utils.META_COMPOSED),
Value: utils.StringPointer("1"),
Mandatory: utils.BoolPointer(true)},
&CdrFieldJsonCfg{Tag: utils.StringPointer("FilterIDs"),
Field_id: utils.StringPointer("FilterIDs"),
Type: utils.StringPointer(utils.META_COMPOSED),
Value: utils.StringPointer("2")},
&CdrFieldJsonCfg{Tag: utils.StringPointer("ActivationInterval"),
Field_id: utils.StringPointer("ActivationInterval"),
Type: utils.StringPointer(utils.META_COMPOSED),
Value: utils.StringPointer("3")},
&CdrFieldJsonCfg{Tag: utils.StringPointer("RunID"),
Field_id: utils.StringPointer("RunID"),
Type: utils.StringPointer(utils.META_COMPOSED),
Value: utils.StringPointer("4")},
&CdrFieldJsonCfg{Tag: utils.StringPointer("AttributeIDs"),
Field_id: utils.StringPointer("AttributeIDs"),
Type: utils.StringPointer(utils.META_COMPOSED),
Value: utils.StringPointer("5")},
&CdrFieldJsonCfg{Tag: utils.StringPointer("Weight"),
Field_id: utils.StringPointer("Weight"),
Type: utils.StringPointer(utils.META_COMPOSED),
Value: utils.StringPointer("6")},
},
},
},
},
}

View File

@@ -1418,6 +1418,42 @@ func TestCgrLoaderCfgITDefaults(t *testing.T) {
Value: utils.ParseRSRFieldsMustCompile("15", utils.INFIELD_SEP)},
},
},
&LoaderDataType{
Type: utils.MetaChargers,
Filename: utils.ChargersCsv,
Fields: []*CfgCdrField{
&CfgCdrField{Tag: "Tenant",
FieldId: "Tenant",
Type: utils.META_COMPOSED,
Value: utils.ParseRSRFieldsMustCompile("0", utils.INFIELD_SEP),
Mandatory: true},
&CfgCdrField{Tag: "ID",
FieldId: "ID",
Type: utils.META_COMPOSED,
Value: utils.ParseRSRFieldsMustCompile("1", utils.INFIELD_SEP),
Mandatory: true},
&CfgCdrField{Tag: "FilterIDs",
FieldId: "FilterIDs",
Type: utils.META_COMPOSED,
Value: utils.ParseRSRFieldsMustCompile("2", utils.INFIELD_SEP)},
&CfgCdrField{Tag: "ActivationInterval",
FieldId: "ActivationInterval",
Type: utils.META_COMPOSED,
Value: utils.ParseRSRFieldsMustCompile("3", utils.INFIELD_SEP)},
&CfgCdrField{Tag: "RunID",
FieldId: "RunID",
Type: utils.META_COMPOSED,
Value: utils.ParseRSRFieldsMustCompile("4", utils.INFIELD_SEP)},
&CfgCdrField{Tag: "AttributeIDs",
FieldId: "AttributeIDs",
Type: utils.META_COMPOSED,
Value: utils.ParseRSRFieldsMustCompile("5", utils.INFIELD_SEP)},
&CfgCdrField{Tag: "Weight",
FieldId: "Weight",
Type: utils.META_COMPOSED,
Value: utils.ParseRSRFieldsMustCompile("6", utils.INFIELD_SEP)},
},
},
},
},
}

44
dispatcher/chargers.go Executable file
View File

@@ -0,0 +1,44 @@
/*
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 dispatcher
import (
"github.com/cgrates/cgrates/engine"
"github.com/cgrates/cgrates/utils"
)
func (dS *DispatcherService) ChargerSv1Ping(ign string, reply *string) error {
if dS.chargerS == nil {
return utils.NewErrNotConnected(utils.AttributeS)
}
return dS.chargerS.Call(utils.ChargerSv1Ping, ign, reply)
}
func (dS *DispatcherService) ChargerSv1GetChargersForEvent(args *ArgsAttrProcessEventWithApiKey,
reply *engine.AttributeProfile) (err error) {
if dS.attrS == nil {
return utils.NewErrNotConnected(utils.AttributeS)
}
if err = dS.authorize(utils.AttributeSv1GetAttributeForEvent, args.AttrArgsProcessEvent.CGREvent.Tenant,
args.APIKey, args.AttrArgsProcessEvent.CGREvent.Time); err != nil {
return
}
return dS.attrS.Call(utils.AttributeSv1GetAttributeForEvent, args.AttrArgsProcessEvent, reply)
}

View File

@@ -72,6 +72,7 @@ type DispatcherService struct {
splS rpcclient.RpcClientConnection // SupplierS connections
attrS rpcclient.RpcClientConnection // AttributeS connections
sessionS rpcclient.RpcClientConnection // SessionS server connections
chargerS rpcclient.RpcClientConnection // ChargerS server connections
}
// ListenAndServe will initialize the service

View File

@@ -398,6 +398,32 @@ func (ldr *Loader) storeLoadedData(loaderType string,
}
}
}
case utils.MetaChargers:
for _, lDataSet := range lds {
cppModels := make(engine.TPChargers, len(lDataSet))
for i, ld := range lDataSet {
cppModels[i] = new(engine.TPCharger)
if err = utils.UpdateStructWithIfaceMap(cppModels[i], ld); err != nil {
return
}
}
for _, tpCPP := range cppModels.AsTPChargers() {
cpp, err := engine.APItoChargerProfile(tpCPP, ldr.timezone)
if err != nil {
return err
}
if ldr.dryRun {
utils.Logger.Info(
fmt.Sprintf("<%s-%s> DRY_RUN: ChargerProfile: %s",
utils.LoaderS, ldr.ldrID, utils.ToJSON(cpp)))
continue
}
if err := ldr.dm.SetChargerProfile(cpp, true); err != nil {
return err
}
}
}
}
return
}

View File

@@ -928,3 +928,101 @@ cgrates.org,SPL_LEASTCOST_1,,,,,supplier2,,,RP_RETAIL1,resource_spl2,,20,,,
utils.ToJSON(eSp3), utils.ToJSON(aps))
}
}
func TestLoaderProcessChargers(t *testing.T) {
chargerCSV := `
#Tenant[0],Id[1],FilterIDs[2],ActivationInterval[3],RunID[4],AttributeIDs[5],Weight[6]
cgrates.org,Charge1,*string:Account:1001;*string:Account:1002,2014-07-29T15:00:00Z,*rated,Attr1;Attr2,20
cgrates.org,Charge2,*string:Account:1003,2014-07-29T15:00:00Z,*default,Attr3,10
`
data, _ := engine.NewMapStorage()
ldr := &Loader{
ldrID: "TestLoaderProcessContent",
bufLoaderData: make(map[string][]LoaderData),
dm: engine.NewDataManager(data),
timezone: "UTC",
}
ldr.dataTpls = map[string][]*config.CfgCdrField{
utils.MetaChargers: []*config.CfgCdrField{
&config.CfgCdrField{Tag: "TenantID",
FieldId: "Tenant",
Type: utils.META_COMPOSED,
Value: utils.ParseRSRFieldsMustCompile("0", utils.INFIELD_SEP),
Mandatory: true},
&config.CfgCdrField{Tag: "ProfileID",
FieldId: "ID",
Type: utils.META_COMPOSED,
Value: utils.ParseRSRFieldsMustCompile("1", utils.INFIELD_SEP),
Mandatory: true},
&config.CfgCdrField{Tag: "FilterIDs",
FieldId: "FilterIDs",
Type: utils.META_COMPOSED,
Value: utils.ParseRSRFieldsMustCompile("2", utils.INFIELD_SEP)},
&config.CfgCdrField{Tag: "ActivationInterval",
FieldId: "ActivationInterval",
Type: utils.META_COMPOSED,
Value: utils.ParseRSRFieldsMustCompile("3", utils.INFIELD_SEP)},
&config.CfgCdrField{Tag: "RunID",
FieldId: "RunID",
Type: utils.META_COMPOSED,
Value: utils.ParseRSRFieldsMustCompile("4", utils.INFIELD_SEP)},
&config.CfgCdrField{Tag: "AttributeIDs",
FieldId: "AttributeIDs",
Type: utils.META_COMPOSED,
Value: utils.ParseRSRFieldsMustCompile("5", utils.INFIELD_SEP)},
&config.CfgCdrField{Tag: "Weight",
FieldId: "Weight",
Type: utils.META_COMPOSED,
Value: utils.ParseRSRFieldsMustCompile("6", utils.INFIELD_SEP)},
},
}
rdr := ioutil.NopCloser(strings.NewReader(chargerCSV))
csvRdr := csv.NewReader(rdr)
csvRdr.Comment = '#'
ldr.rdrs = map[string]map[string]*openedCSVFile{
utils.MetaChargers: map[string]*openedCSVFile{
utils.ChargersCsv: &openedCSVFile{fileName: utils.ChargersCsv,
rdr: rdr, csvRdr: csvRdr}},
}
if err := ldr.processContent(utils.MetaChargers); err != nil {
t.Error(err)
}
if len(ldr.bufLoaderData) != 0 {
t.Errorf("wrong buffer content: %+v", ldr.bufLoaderData)
}
eCharger1 := &engine.ChargerProfile{
Tenant: "cgrates.org",
ID: "Charge1",
FilterIDs: []string{"*string:Account:1001", "*string:Account:1002"},
ActivationInterval: &utils.ActivationInterval{
ActivationTime: time.Date(2014, 7, 29, 15, 00, 0, 0, time.UTC),
},
RunID: "*rated",
AttributeIDs: []string{"Attr1", "Attr2"},
Weight: 20,
}
eCharger2 := &engine.ChargerProfile{
Tenant: "cgrates.org",
ID: "Charge2",
FilterIDs: []string{"*string:Account:1003"},
ActivationInterval: &utils.ActivationInterval{
ActivationTime: time.Date(2014, 7, 29, 15, 00, 0, 0, time.UTC),
},
RunID: "*default",
AttributeIDs: []string{"Attr3"},
Weight: 10,
}
if rcv, err := ldr.dm.GetChargerProfile("cgrates.org", "Charge1",
false, utils.NonTransactional); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(eCharger1, rcv) {
t.Errorf("expecting: %s, received: %s", utils.ToJSON(eCharger1), utils.ToJSON(rcv))
}
if rcv, err := ldr.dm.GetChargerProfile("cgrates.org", "Charge2",
false, utils.NonTransactional); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(eCharger2, rcv) {
t.Errorf("expecting: %s, received: %s", eCharger2, rcv)
}
}

View File

@@ -592,6 +592,7 @@ const (
ThresholdS = "ThresholdS"
DispatcherS = "DispatcherS"
LoaderS = "LoaderS"
ChargerS = "ChargerS"
)
// Lower service names
@@ -661,7 +662,6 @@ const (
APIKey = "APIKey"
APIMethods = "APIMethods"
NestingSep = "."
ChargerS = "ChargerS"
)
// MetaFilterIndexesAPIs