mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-14 20:59:53 +05:00
Add Charger in LoaderS
This commit is contained in:
committed by
Dan Christian Bogos
parent
94138f156c
commit
93b849bd8e
@@ -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"},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
@@ -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")},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -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
44
dispatcher/chargers.go
Executable 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)
|
||||
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user