Implement export for other items

This commit is contained in:
TeoV
2020-03-04 18:04:15 +02:00
committed by Dan Christian Bogos
parent 44438a0884
commit f1029faca0
4 changed files with 826 additions and 295 deletions

View File

@@ -440,6 +440,8 @@ func (apiv1 *APIerSv1) SetRatingProfile(attrs utils.AttrSetRatingProfile, reply
if err := apiv1.DataManager.SetRatingProfile(rpfl, utils.NonTransactional); err != nil {
return utils.NewErrServerError(err)
}
//CacheReload
//generate a loadID for CacheRatingProfiles and store it in database
if err := apiv1.DataManager.SetLoadIDs(map[string]int64{utils.CacheRatingProfiles: time.Now().UnixNano()}); err != nil {
return utils.APIErrorHandler(err)
@@ -1364,8 +1366,8 @@ func (apiv1 *APIerSv1) Ping(ign *utils.CGREvent, reply *string) error {
func (apiV1 *APIerSv1) ExportToFolder(arg *utils.ArgExportToFolder, reply *string) error {
// if items is empy we need to export all items
if len(arg.Items) == 0 {
arg.Items = []string{utils.MetaAttributes, utils.MetaChargers, utils.MetaDispatchers, utils.MetaFilters,
utils.MetaResources, utils.MetaStats, utils.MetaSuppliers, utils.MetaThresholds}
arg.Items = []string{utils.MetaAttributes, utils.MetaChargers, utils.MetaDispatchers, utils.MetaDispatcherHosts,
utils.MetaFilters, utils.MetaResources, utils.MetaStats, utils.MetaSuppliers, utils.MetaThresholds}
}
for _, item := range arg.Items {
switch item {
@@ -1375,7 +1377,6 @@ func (apiV1 *APIerSv1) ExportToFolder(arg *utils.ArgExportToFolder, reply *strin
if err != nil {
return err
}
// take the tenant + id from key
if len(keys) == 0 { // if we don't find items we skip
continue
}
@@ -1388,13 +1389,10 @@ func (apiV1 *APIerSv1) ExportToFolder(arg *utils.ArgExportToFolder, reply *strin
csvWriter := csv.NewWriter(f)
csvWriter.Comma = utils.CSV_SEP
//write the header of the file
// #Tenant,ID,Contexts,FilterIDs,ActivationInterval,AttributeFilterIDs,Path,Type,Value,Blocker,Weight
if err := csvWriter.Write([]string{"#" + utils.Tenant, utils.ID, utils.FilterIDs, utils.ActivationInternal,
utils.AttributeFilterIDs, utils.Path, utils.Type, utils.Value, utils.Blocker, utils.Weight}); err != nil {
if err := csvWriter.Write(engine.TPAttributes{}.CSVHeader()); err != nil {
return err
}
for _, key := range keys {
// take tntID from key
tntID := strings.SplitN(key[len(prfx):], utils.InInFieldSep, 2)
attPrf, err := apiV1.DataManager.GetAttributeProfile(tntID[0], tntID[1],
true, false, utils.NonTransactional)
@@ -1409,7 +1407,196 @@ func (apiV1 *APIerSv1) ExportToFolder(arg *utils.ArgExportToFolder, reply *strin
return err
}
}
}
csvWriter.Flush()
case utils.MetaChargers:
prfx := utils.ChargerProfilePrefix
keys, err := apiV1.DataManager.DataDB().GetKeysForPrefix(prfx)
if err != nil {
return err
}
if len(keys) == 0 { // if we don't find items we skip
continue
}
f, err := os.Create(path.Join(arg.Path, utils.ChargersCsv))
if err != nil {
return err
}
defer f.Close()
csvWriter := csv.NewWriter(f)
csvWriter.Comma = utils.CSV_SEP
//write the header of the file
if err := csvWriter.Write(engine.TPChargers{}.CSVHeader()); err != nil {
return err
}
for _, key := range keys {
tntID := strings.SplitN(key[len(prfx):], utils.InInFieldSep, 2)
chrPrf, err := apiV1.DataManager.GetChargerProfile(tntID[0], tntID[1],
true, false, utils.NonTransactional)
if err != nil {
return err
}
for _, model := range engine.APItoModelTPCharger(
engine.ChargerProfileToAPI(chrPrf)) {
if record, err := engine.CsvDump(model); err != nil {
return err
} else if err := csvWriter.Write(record); err != nil {
return err
}
}
}
csvWriter.Flush()
case utils.MetaDispatchers:
prfx := utils.DispatcherProfilePrefix
keys, err := apiV1.DataManager.DataDB().GetKeysForPrefix(prfx)
if err != nil {
return err
}
if len(keys) == 0 { // if we don't find items we skip
continue
}
f, err := os.Create(path.Join(arg.Path, utils.DispatcherProfilesCsv))
if err != nil {
return err
}
defer f.Close()
csvWriter := csv.NewWriter(f)
csvWriter.Comma = utils.CSV_SEP
//write the header of the file
if err := csvWriter.Write(engine.TPDispatcherProfiles{}.CSVHeader()); err != nil {
return err
}
for _, key := range keys {
tntID := strings.SplitN(key[len(prfx):], utils.InInFieldSep, 2)
dpsPrf, err := apiV1.DataManager.GetDispatcherProfile(tntID[0], tntID[1],
true, false, utils.NonTransactional)
if err != nil {
return err
}
for _, model := range engine.APItoModelTPDispatcherProfile(
engine.DispatcherProfileToAPI(dpsPrf)) {
if record, err := engine.CsvDump(model); err != nil {
return err
} else if err := csvWriter.Write(record); err != nil {
return err
}
}
}
csvWriter.Flush()
case utils.MetaDispatcherHosts:
prfx := utils.DispatcherHostPrefix
keys, err := apiV1.DataManager.DataDB().GetKeysForPrefix(prfx)
if err != nil {
return err
}
if len(keys) == 0 { // if we don't find items we skip
continue
}
f, err := os.Create(path.Join(arg.Path, utils.DispatcherHostsCsv))
if err != nil {
return err
}
defer f.Close()
csvWriter := csv.NewWriter(f)
csvWriter.Comma = utils.CSV_SEP
//write the header of the file
if err := csvWriter.Write(engine.TPDispatcherHosts{}.CSVHeader()); err != nil {
return err
}
for _, key := range keys {
tntID := strings.SplitN(key[len(prfx):], utils.InInFieldSep, 2)
dpsPrf, err := apiV1.DataManager.GetDispatcherHost(tntID[0], tntID[1],
true, false, utils.NonTransactional)
if err != nil {
return err
}
for _, model := range engine.APItoModelTPDispatcherHost(
engine.DispatcherHostToAPI(dpsPrf)) {
if record, err := engine.CsvDump(model); err != nil {
return err
} else if err := csvWriter.Write(record); err != nil {
return err
}
}
}
csvWriter.Flush()
case utils.MetaFilters:
prfx := utils.FilterPrefix
keys, err := apiV1.DataManager.DataDB().GetKeysForPrefix(prfx)
if err != nil {
return err
}
if len(keys) == 0 { // if we don't find items we skip
continue
}
f, err := os.Create(path.Join(arg.Path, utils.FiltersCsv))
if err != nil {
return err
}
defer f.Close()
csvWriter := csv.NewWriter(f)
csvWriter.Comma = utils.CSV_SEP
//write the header of the file
if err := csvWriter.Write(engine.TpFilterS{}.CSVHeader()); err != nil {
return err
}
for _, key := range keys {
tntID := strings.SplitN(key[len(prfx):], utils.InInFieldSep, 2)
fltr, err := engine.GetFilter(apiV1.DataManager, tntID[0], tntID[1],
true, false, utils.NonTransactional)
if err != nil {
return err
}
for _, model := range engine.APItoModelTPFilter(
engine.FilterToTPFilter(fltr)) {
if record, err := engine.CsvDump(model); err != nil {
return err
} else if err := csvWriter.Write(record); err != nil {
return err
}
}
}
csvWriter.Flush()
case utils.MetaResources:
prfx := utils.ResourceProfilesPrefix
keys, err := apiV1.DataManager.DataDB().GetKeysForPrefix(prfx)
if err != nil {
return err
}
if len(keys) == 0 { // if we don't find items we skip
continue
}
f, err := os.Create(path.Join(arg.Path, utils.ResourcesCsv))
if err != nil {
return err
}
defer f.Close()
csvWriter := csv.NewWriter(f)
csvWriter.Comma = utils.CSV_SEP
//write the header of the file
if err := csvWriter.Write(engine.TpResources{}.CSVHeader()); err != nil {
return err
}
for _, key := range keys {
tntID := strings.SplitN(key[len(prfx):], utils.InInFieldSep, 2)
resPrf, err := apiV1.DataManager.GetResourceProfile(tntID[0], tntID[1],
true, false, utils.NonTransactional)
if err != nil {
return err
}
for _, model := range engine.APItoModelResource(
engine.ResourceProfileToAPI(resPrf)) {
if record, err := engine.CsvDump(model); err != nil {
return err
} else if err := csvWriter.Write(record); err != nil {
return err
}
}
}
csvWriter.Flush()
}

View File

@@ -131,48 +131,6 @@ func CsvDump(s interface{}) ([]string, error) {
return result, nil
}
func modelEqual(this interface{}, other interface{}) bool {
var fieldNames []string
st := reflect.TypeOf(this)
stO := reflect.TypeOf(other)
if st != stO {
return false
}
numFields := st.NumField()
for i := 0; i < numFields; i++ {
field := st.Field(i)
index := field.Tag.Get("index")
if index != "" {
fieldNames = append(fieldNames, field.Name)
}
}
thisElem := reflect.ValueOf(this)
otherElem := reflect.ValueOf(other)
for _, fieldName := range fieldNames {
thisField := thisElem.FieldByName(fieldName)
otherField := otherElem.FieldByName(fieldName)
switch thisField.Kind() {
case reflect.Float64:
if thisField.Float() != otherField.Float() {
return false
}
case reflect.Int:
if thisField.Int() != otherField.Int() {
return false
}
case reflect.Bool:
if thisField.Bool() != otherField.Bool() {
return false
}
case reflect.String:
if thisField.String() != otherField.String() {
return false
}
}
}
return true
}
func getColumnCount(s interface{}) int {
st := reflect.TypeOf(s)
numFields := st.NumField()
@@ -1114,6 +1072,13 @@ func APItoModelAccountActions(aas []*utils.TPAccountActions) (result TpAccountAc
type TpResources []*TpResource
// CSVHeader return the header for csv fields as a slice of string
func (tps TpResources) CSVHeader() (result []string) {
return []string{"#" + utils.Tenant, utils.ID, utils.FilterIDs, utils.ActivationIntervalString,
utils.UsageTTL, utils.Limit, utils.AllocationMessage, utils.Blocker, utils.Stored,
utils.Weight, utils.ThresholdIDs}
}
func (tps TpResources) AsTPResources() (result []*utils.TPResourceProfile) {
mrl := make(map[string]*utils.TPResourceProfile)
filterMap := make(map[string]utils.StringMap)
@@ -1296,6 +1261,40 @@ func APItoResource(tpRL *utils.TPResourceProfile, timezone string) (rp *Resource
return rp, nil
}
func ResourceProfileToAPI(rp *ResourceProfile) (tpRL *utils.TPResourceProfile) {
tpRL = &utils.TPResourceProfile{
Tenant: rp.Tenant,
ID: rp.ID,
FilterIDs: make([]string, len(rp.FilterIDs)),
ActivationInterval: new(utils.TPActivationInterval),
Limit: strconv.FormatFloat(rp.Limit, 'f', -1, 64),
AllocationMessage: rp.AllocationMessage,
Blocker: rp.Blocker,
Stored: rp.Stored,
Weight: rp.Weight,
ThresholdIDs: make([]string, len(rp.ThresholdIDs)),
}
if rp.UsageTTL != time.Duration(0) {
tpRL.UsageTTL = rp.UsageTTL.String()
}
for i, fli := range rp.FilterIDs {
tpRL.FilterIDs[i] = fli
}
for i, fli := range rp.ThresholdIDs {
tpRL.ThresholdIDs[i] = fli
}
if rp.ActivationInterval != nil {
if !rp.ActivationInterval.ActivationTime.IsZero() {
tpRL.ActivationInterval.ActivationTime = rp.ActivationInterval.ActivationTime.Format(time.RFC3339)
}
if !rp.ActivationInterval.ExpiryTime.IsZero() {
tpRL.ActivationInterval.ExpiryTime = rp.ActivationInterval.ExpiryTime.Format(time.RFC3339)
}
}
return
}
type TpStats []*TpStat
func (models TpStats) AsTPStats() (result []*utils.TPStatProfile) {
@@ -1672,6 +1671,12 @@ func APItoThresholdProfile(tpTH *utils.TPThresholdProfile, timezone string) (th
type TpFilterS []*TpFilter
// CSVHeader return the header for csv fields as a slice of string
func (tps TpFilterS) CSVHeader() (result []string) {
return []string{"#" + utils.Tenant, utils.ID, utils.Type, utils.Element,
utils.Values, utils.ActivationIntervalString}
}
func (tps TpFilterS) AsTPFilter() (result []*utils.TPFilterProfile) {
mst := make(map[string]*utils.TPFilterProfile)
for _, tp := range tps {
@@ -1769,9 +1774,10 @@ func APItoFilter(tpTH *utils.TPFilterProfile, timezone string) (th *Filter, err
func FilterToTPFilter(f *Filter) (tpFltr *utils.TPFilterProfile) {
tpFltr = &utils.TPFilterProfile{
Tenant: f.Tenant,
ID: f.ID,
Filters: make([]*utils.TPFilter, len(f.Rules)),
Tenant: f.Tenant,
ID: f.ID,
Filters: make([]*utils.TPFilter, len(f.Rules)),
ActivationInterval: new(utils.TPActivationInterval),
}
for i, reqFltr := range f.Rules {
tpFltr.Filters[i] = &utils.TPFilter{
@@ -2011,7 +2017,11 @@ func APItoSupplierProfile(tpSPP *utils.TPSupplierProfile, timezone string) (spp
type TPAttributes []*TPAttribute
// create a function for models that return the CSV header
// CSVHeader return the header for csv fields as a slice of string
func (tps TPAttributes) CSVHeader() (result []string) {
return []string{"#" + utils.Tenant, utils.ID, utils.FilterIDs, utils.ActivationIntervalString,
utils.AttributeFilterIDs, utils.Path, utils.Type, utils.Value, utils.Blocker, utils.Weight}
}
func (tps TPAttributes) AsTPAttributes() (result []*utils.TPAttributeProfile) {
mst := make(map[string]*utils.TPAttributeProfile)
@@ -2179,7 +2189,6 @@ func APItoAttributeProfile(tpAttr *utils.TPAttributeProfile, timezone string) (a
func AttributeProfileToAPI(attrPrf *AttributeProfile) (tpAttr *utils.TPAttributeProfile) {
tpAttr = &utils.TPAttributeProfile{
TPid: utils.EmptyString,
Tenant: attrPrf.Tenant,
ID: attrPrf.ID,
FilterIDs: make([]string, len(attrPrf.FilterIDs)),
@@ -2216,6 +2225,12 @@ func AttributeProfileToAPI(attrPrf *AttributeProfile) (tpAttr *utils.TPAttribute
type TPChargers []*TPCharger
// CSVHeader return the header for csv fields as a slice of string
func (tps TPChargers) CSVHeader() (result []string) {
return []string{"#" + utils.Tenant, utils.ID, utils.FilterIDs, utils.ActivationIntervalString,
utils.RunID, utils.AttributeIDs, utils.Weight}
}
func (tps TPChargers) AsTPChargers() (result []*utils.TPChargerProfile) {
mst := make(map[string]*utils.TPChargerProfile)
filterMap := make(map[string]utils.StringMap)
@@ -2385,8 +2400,42 @@ func APItoChargerProfile(tpCPP *utils.TPChargerProfile, timezone string) (cpp *C
return cpp, nil
}
func ChargerProfileToAPI(chargerPrf *ChargerProfile) (tpCharger *utils.TPChargerProfile) {
tpCharger = &utils.TPChargerProfile{
Tenant: chargerPrf.Tenant,
ID: chargerPrf.ID,
FilterIDs: make([]string, len(chargerPrf.FilterIDs)),
ActivationInterval: new(utils.TPActivationInterval),
RunID: chargerPrf.RunID,
AttributeIDs: make([]string, len(chargerPrf.AttributeIDs)),
Weight: chargerPrf.Weight,
}
for i, fli := range chargerPrf.FilterIDs {
tpCharger.FilterIDs[i] = fli
}
for i, fli := range chargerPrf.AttributeIDs {
tpCharger.AttributeIDs[i] = fli
}
if chargerPrf.ActivationInterval != nil {
if !chargerPrf.ActivationInterval.ActivationTime.IsZero() {
tpCharger.ActivationInterval.ActivationTime = chargerPrf.ActivationInterval.ActivationTime.Format(time.RFC3339)
}
if !chargerPrf.ActivationInterval.ExpiryTime.IsZero() {
tpCharger.ActivationInterval.ExpiryTime = chargerPrf.ActivationInterval.ExpiryTime.Format(time.RFC3339)
}
}
return
}
type TPDispatcherProfiles []*TPDispatcherProfile
// CSVHeader return the header for csv fields as a slice of string
func (tps TPDispatcherProfiles) CSVHeader() (result []string) {
return []string{"#" + utils.Tenant, utils.ID, utils.Subsystems, utils.FilterIDs, utils.ActivationIntervalString,
utils.Strategy, utils.StrategyParameters, utils.ConnID, utils.ConnFilterIDs,
utils.ConnWeight, utils.ConnBlocker, utils.ConnParameters, utils.Weight}
}
func (tps TPDispatcherProfiles) AsTPDispatcherProfiles() (result []*utils.TPDispatcherProfile) {
mst := make(map[string]*utils.TPDispatcherProfile)
filterMap := make(map[string]utils.StringMap)
@@ -2642,9 +2691,73 @@ func APItoDispatcherProfile(tpDPP *utils.TPDispatcherProfile, timezone string) (
return dpp, nil
}
func DispatcherProfileToAPI(dpp *DispatcherProfile) (tpDPP *utils.TPDispatcherProfile) {
tpDPP = &utils.TPDispatcherProfile{
Tenant: dpp.Tenant,
ID: dpp.ID,
Subsystems: make([]string, len(dpp.Subsystems)),
FilterIDs: make([]string, len(dpp.FilterIDs)),
ActivationInterval: new(utils.TPActivationInterval),
Strategy: dpp.Strategy,
StrategyParams: make([]interface{}, len(dpp.StrategyParams)),
Weight: dpp.Weight,
Hosts: make([]*utils.TPDispatcherHostProfile, len(dpp.Hosts)),
}
for i, fli := range dpp.FilterIDs {
tpDPP.FilterIDs[i] = fli
}
for i, sub := range dpp.Subsystems {
tpDPP.Subsystems[i] = sub
}
for key, val := range dpp.StrategyParams {
// here we expect that the key to be an integer because
// according to APItoDispatcherProfile when we convert from TP to obj we use index as key
// so we can ignore error
idx, _ := strconv.Atoi(key)
tpDPP.StrategyParams[idx] = val
}
for i, host := range dpp.Hosts {
tpDPP.Hosts[i] = &utils.TPDispatcherHostProfile{
ID: host.ID,
FilterIDs: make([]string, len(host.FilterIDs)),
Weight: host.Weight,
Params: make([]interface{}, len(host.Params)),
Blocker: host.Blocker,
}
for j, fltr := range host.FilterIDs {
tpDPP.Hosts[i].FilterIDs[j] = fltr
}
idx := 0
for key, val := range host.Params {
paramVal := val
if _, err := strconv.Atoi(key); err != nil {
paramVal = utils.ConcatenatedKey(key, utils.IfaceAsString(val))
}
tpDPP.Hosts[i].Params[idx] = paramVal
idx++
}
}
if dpp.ActivationInterval != nil {
if !dpp.ActivationInterval.ActivationTime.IsZero() {
tpDPP.ActivationInterval.ActivationTime = dpp.ActivationInterval.ActivationTime.Format(time.RFC3339)
}
if !dpp.ActivationInterval.ExpiryTime.IsZero() {
tpDPP.ActivationInterval.ExpiryTime = dpp.ActivationInterval.ExpiryTime.Format(time.RFC3339)
}
}
return
}
// TPHosts
type TPDispatcherHosts []*TPDispatcherHost
// CSVHeader return the header for csv fields as a slice of string
func (tps TPDispatcherHosts) CSVHeader() (result []string) {
return []string{"#" + utils.Tenant, utils.ID, utils.Address, utils.Transport, utils.TLS}
}
func (tps TPDispatcherHosts) AsTPDispatcherHosts() (result []*utils.TPDispatcherHost) {
hostsMap := make(map[string]*utils.TPDispatcherHost)
for _, tp := range tps {
@@ -2718,3 +2831,20 @@ func APItoDispatcherHost(tpDPH *utils.TPDispatcherHost) (dpp *DispatcherHost) {
}
return
}
func DispatcherHostToAPI(dph *DispatcherHost) (tpDPH *utils.TPDispatcherHost) {
tpDPH = &utils.TPDispatcherHost{
Tenant: dph.Tenant,
ID: dph.ID,
Conns: make([]*utils.TPDispatcherHostConn, len(dph.Conns)),
}
for i, conn := range dph.Conns {
tpDPH.Conns[i] = &utils.TPDispatcherHostConn{
Address: conn.Address,
Transport: conn.Transport,
TLS: conn.TLS,
}
}
return
}

View File

@@ -561,6 +561,35 @@ func TestAPItoResource(t *testing.T) {
}
}
func TestResourceProfileToAPI(t *testing.T) {
expected := &utils.TPResourceProfile{
Tenant: "cgrates.org",
ID: "ResGroup1",
FilterIDs: []string{"FLTR_RES_GR_1"},
ActivationInterval: &utils.TPActivationInterval{ActivationTime: "2014-07-29T15:00:00Z"},
Weight: 10,
Limit: "2",
ThresholdIDs: []string{"TRes1"},
AllocationMessage: "asd",
}
rp := &ResourceProfile{
Tenant: "cgrates.org",
ID: "ResGroup1",
ActivationInterval: &utils.ActivationInterval{
ActivationTime: time.Date(2014, 7, 29, 15, 0, 0, 0, time.UTC),
},
Weight: 10,
FilterIDs: []string{"FLTR_RES_GR_1"},
ThresholdIDs: []string{"TRes1"},
AllocationMessage: "asd",
Limit: 2,
}
if rcv := ResourceProfileToAPI(rp); !reflect.DeepEqual(expected, rcv) {
t.Errorf("Expecting: %+v, \n received: %+v", utils.ToJSON(expected), utils.ToJSON(rcv))
}
}
func TestAPItoModelResource(t *testing.T) {
tpRL := &utils.TPResourceProfile{
Tenant: "cgrates.org",
@@ -1366,6 +1395,65 @@ func TestAPItoModelTPAttribute(t *testing.T) {
}
}
func TestCsvDumpForAttributeModels(t *testing.T) {
tpAlsPrf := &utils.TPAttributeProfile{
TPid: "TP1",
Tenant: "cgrates.org",
ID: "ALS1",
Contexts: []string{"con1"},
FilterIDs: []string{"FLTR_ACNT_dan"},
ActivationInterval: &utils.TPActivationInterval{
ActivationTime: "2014-07-14T14:35:00Z",
ExpiryTime: "",
},
Attributes: []*utils.TPAttribute{
&utils.TPAttribute{
Path: utils.MetaReq + utils.NestingSep + "FL1",
Value: "Al1",
},
&utils.TPAttribute{
Path: utils.MetaReq + utils.NestingSep + "FL2",
Value: "Al2",
},
},
Weight: 20,
}
expected := TPAttributes{
&TPAttribute{
Tpid: "TP1",
Tenant: "cgrates.org",
ID: "ALS1",
Contexts: "con1",
FilterIDs: "FLTR_ACNT_dan",
Path: utils.MetaReq + utils.NestingSep + "FL1",
Value: "Al1",
ActivationInterval: "2014-07-14T14:35:00Z",
Weight: 20,
},
&TPAttribute{
Tpid: "TP1",
Tenant: "cgrates.org",
ID: "ALS1",
Path: utils.MetaReq + utils.NestingSep + "FL2",
Value: "Al2",
},
}
rcv := APItoModelTPAttribute(tpAlsPrf)
if !reflect.DeepEqual(expected, rcv) {
t.Errorf("Expecting : %+v,\n received: %+v", utils.ToJSON(expected), utils.ToJSON(rcv))
}
expRecord := []string{"cgrates.org", "ALS1", "con1", "FLTR_ACNT_dan", "2014-07-14T14:35:00Z", "", "*req.FL1", "", "Al1", "false", "20"}
for i, model := range rcv {
if i == 1 {
expRecord = []string{"cgrates.org", "ALS1", "", "", "", "", "*req.FL2", "", "Al2", "false", "0"}
}
if csvRecordRcv, _ := CsvDump(model); !reflect.DeepEqual(expRecord, csvRecordRcv) {
t.Errorf("Expecting : %+v, received: %+v", utils.ToJSON(expRecord), utils.ToJSON(csvRecordRcv))
}
}
}
func TestModelAsTPAttribute(t *testing.T) {
models := TPAttributes{
&TPAttribute{
@@ -1457,6 +1545,38 @@ func TestAPItoChargerProfile(t *testing.T) {
}
}
func TestChargerProfileToAPI(t *testing.T) {
exp := &utils.TPChargerProfile{
Tenant: "cgrates.org",
ID: "Charger1",
FilterIDs: []string{"FLTR_ACNT_dan", "FLTR_DST_DE"},
RunID: "*rated",
ActivationInterval: &utils.TPActivationInterval{
ActivationTime: "2014-07-14T14:35:00Z",
ExpiryTime: "",
},
AttributeIDs: []string{"ATTR1", "ATTR2"},
Weight: 20,
}
chargerPrf := &ChargerProfile{
Tenant: "cgrates.org",
ID: "Charger1",
FilterIDs: []string{"FLTR_ACNT_dan", "FLTR_DST_DE"},
ActivationInterval: &utils.ActivationInterval{
ActivationTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC),
},
RunID: "*rated",
AttributeIDs: []string{"ATTR1", "ATTR2"},
Weight: 20,
}
if rcv := ChargerProfileToAPI(chargerPrf); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(exp, rcv) {
t.Errorf("Expecting : %+v, \n received: %+v", utils.ToJSON(exp), utils.ToJSON(rcv))
}
}
//Number of FilterIDs and AttributeIDs are equal
func TestAPItoModelTPCharger(t *testing.T) {
tpCharger := &utils.TPChargerProfile{
@@ -1766,6 +1886,80 @@ func TestAPItoDispatcherProfile(t *testing.T) {
}
}
func TestDispatcherProfileToAPI(t *testing.T) {
exp := &utils.TPDispatcherProfile{
Tenant: "cgrates.org",
ID: "Dsp",
Subsystems: []string{"*any"},
FilterIDs: []string{"FLTR_ACNT_dan", "FLTR_DST_DE"},
Strategy: utils.MetaFirst,
ActivationInterval: &utils.TPActivationInterval{
ActivationTime: "2014-07-14T14:35:00Z",
ExpiryTime: "",
},
StrategyParams: []interface{}{},
Weight: 20,
Hosts: []*utils.TPDispatcherHostProfile{
&utils.TPDispatcherHostProfile{
ID: "C1",
FilterIDs: []string{},
Weight: 10,
Params: []interface{}{"192.168.54.203", "*ratio:2"},
Blocker: false,
},
},
}
exp2 := &utils.TPDispatcherProfile{
Tenant: "cgrates.org",
ID: "Dsp",
Subsystems: []string{"*any"},
FilterIDs: []string{"FLTR_ACNT_dan", "FLTR_DST_DE"},
Strategy: utils.MetaFirst,
ActivationInterval: &utils.TPActivationInterval{
ActivationTime: "2014-07-14T14:35:00Z",
ExpiryTime: "",
},
StrategyParams: []interface{}{},
Weight: 20,
Hosts: []*utils.TPDispatcherHostProfile{
&utils.TPDispatcherHostProfile{
ID: "C1",
FilterIDs: []string{},
Weight: 10,
Params: []interface{}{"*ratio:2", "192.168.54.203"},
Blocker: false,
},
},
}
dspPrf := &DispatcherProfile{
Tenant: "cgrates.org",
ID: "Dsp",
Subsystems: []string{"*any"},
FilterIDs: []string{"FLTR_ACNT_dan", "FLTR_DST_DE"},
Strategy: utils.MetaFirst,
ActivationInterval: &utils.ActivationInterval{
ActivationTime: time.Date(2014, 7, 14, 14, 35, 0, 0, time.UTC),
},
StrategyParams: map[string]interface{}{},
Weight: 20,
Hosts: DispatcherHostProfiles{
&DispatcherHostProfile{
ID: "C1",
FilterIDs: []string{},
Weight: 10,
Params: map[string]interface{}{"0": "192.168.54.203", utils.MetaRatio: "2"},
Blocker: false,
},
},
}
if rcv := DispatcherProfileToAPI(dspPrf); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(exp, rcv) && !reflect.DeepEqual(exp2, rcv) {
t.Errorf("Expecting : \n %+v \n or \n %+v \n ,\n received: %+v", utils.ToJSON(exp), utils.ToJSON(exp2), utils.ToJSON(rcv))
}
}
func TestAPItoModelTPDispatcher(t *testing.T) {
tpDPP := &utils.TPDispatcherProfile{
TPid: "TP1",

View File

@@ -207,6 +207,7 @@ const (
PDD = "PDD"
SUPPLIER = "Supplier"
RunID = "RunID"
AttributeIDs = "AttributeIDs"
MetaReqRunID = "*req.RunID"
COST = "Cost"
CostDetails = "CostDetails"
@@ -423,247 +424,266 @@ const (
MetaEveryMinute = "*every_minute"
MetaHourly = "*hourly"
ID = "ID"
Thresholds = "Thresholds"
Suppliers = "Suppliers"
Attributes = "Attributes"
Chargers = "Chargers"
Dispatchers = "Dispatchers"
StatS = "Stats"
LoadIDsVrs = "LoadIDs"
RALService = "RALs"
CostSource = "CostSource"
ExtraInfo = "ExtraInfo"
Meta = "*"
MetaSysLog = "*syslog"
MetaStdLog = "*stdout"
EventType = "EventType"
EventSource = "EventSource"
AccountID = "AccountID"
ResourceID = "ResourceID"
TotalUsage = "TotalUsage"
StatID = "StatID"
BalanceType = "BalanceType"
BalanceID = "BalanceID"
BalanceDestinationIds = "BalanceDestinationIds"
BalanceWeight = "BalanceWeight"
BalanceExpirationDate = "BalanceExpirationDate"
BalanceTimingTags = "BalanceTimingTags"
BalanceRatingSubject = "BalanceRatingSubject"
BalanceCategories = "BalanceCategories"
BalanceSharedGroups = "BalanceSharedGroups"
BalanceBlocker = "BalanceBlocker"
BalanceDisabled = "BalanceDisabled"
Units = "Units"
AccountUpdate = "AccountUpdate"
BalanceUpdate = "BalanceUpdate"
StatUpdate = "StatUpdate"
ResourceUpdate = "ResourceUpdate"
CDR = "CDR"
CDRs = "CDRs"
ExpiryTime = "ExpiryTime"
AllowNegative = "AllowNegative"
Disabled = "Disabled"
Action = "Action"
MetaNow = "*now"
SessionSCosts = "SessionSCosts"
Timing = "Timing"
RQF = "RQF"
Resource = "Resource"
User = "User"
Subscribers = "Subscribers"
DerivedChargersV = "DerivedChargers"
Destinations = "Destinations"
ReverseDestinations = "ReverseDestinations"
RatingPlan = "RatingPlan"
RatingProfile = "RatingProfile"
MetaRatingPlans = "*rating_plans"
MetaRatingProfiles = "*rating_profiles"
MetaUsers = "*users"
MetaSubscribers = "*subscribers"
MetaDerivedChargersV = "*derivedchargers"
MetaStorDB = "*stordb"
MetaDataDB = "*datadb"
MetaWeight = "*weight"
MetaLC = "*lc"
MetaHC = "*hc"
MetaQOS = "*qos"
MetaReas = "*reas"
MetaReds = "*reds"
Weight = "Weight"
Cost = "Cost"
DestinationIDs = "DestinationIDs"
RatingSubject = "RatingSubject"
Categories = "Categories"
Blocker = "Blocker"
RatingPlanID = "RatingPlanID"
StartTime = "StartTime"
AccountSummary = "AccountSummary"
RatingFilters = "RatingFilters"
RatingFilter = "RatingFilter"
Accounting = "Accounting"
Rating = "Rating"
Charges = "Charges"
CompressFactor = "CompressFactor"
Increments = "Increments"
Balance = "Balance"
BalanceSummaries = "BalanceSummaries"
Type = "Type"
YearsFieldName = "Years"
MonthsFieldName = "Months"
MonthDaysFieldName = "MonthDays"
WeekDaysFieldName = "WeekDays"
GroupIntervalStart = "GroupIntervalStart"
RateIncrement = "RateIncrement"
RateUnit = "RateUnit"
BalanceUUID = "BalanceUUID"
RatingID = "RatingID"
ExtraChargeID = "ExtraChargeID"
ConnectFee = "ConnectFee"
RoundingMethod = "RoundingMethod"
RoundingDecimals = "RoundingDecimals"
MaxCostStrategy = "MaxCostStrategy"
TimingID = "TimingID"
RatesID = "RatesID"
RatingFiltersID = "RatingFiltersID"
AccountingID = "AccountingID"
MetaSessionS = "*sessions"
MetaDefault = "*default"
Error = "Error"
MetaCgreq = "*cgreq"
MetaCgrep = "*cgrep"
MetaCGRAReq = "*cgrareq"
CGR_ACD = "cgr_acd"
FilterIDs = "FilterIDs"
ActivationInternal = "ActivationInterval"
AttributeFilterIDs = "AttributeFilterIDs"
FieldName = "FieldName"
Path = "Path"
MetaRound = "*round"
Pong = "Pong"
MetaEventCost = "*event_cost"
MetaSuppliersEventCost = "*suppliers_event_cost"
MetaSuppliersIgnoreErrors = "*suppliers_ignore_errors"
Freeswitch = "freeswitch"
Kamailio = "kamailio"
Opensips = "opensips"
Asterisk = "asterisk"
SchedulerS = "SchedulerS"
MetaMultiply = "*multiply"
MetaDivide = "*divide"
MetaUrl = "*url"
MetaXml = "*xml"
ApiKey = "apikey"
MetaReq = "*req"
MetaVars = "*vars"
MetaRep = "*rep"
MetaExp = "*exp"
MetaHdr = "*hdr"
MetaTrl = "*trl"
MetaTmp = "*tmp"
CGROriginHost = "cgr_originhost"
MetaInitiate = "*initiate"
MetaUpdate = "*update"
MetaTerminate = "*terminate"
MetaEvent = "*event"
MetaMessage = "*message"
MetaDryRun = "*dryrun"
Event = "Event"
EmptyString = ""
DynamicDataPrefix = "~"
AttrValueSep = "="
ANDSep = "&"
PipeSep = "|"
MetaApp = "*app"
MetaAppID = "*appid"
MetaCmd = "*cmd"
MetaEnv = "*env:" // use in config for describing enviormant variables
MetaTemplate = "*template"
MetaCCA = "*cca"
MetaErr = "*err"
OriginRealm = "OriginRealm"
ProductName = "ProductName"
IdxStart = "["
IdxEnd = "]"
MetaLog = "*log"
MetaRemoteHost = "*remote_host"
RemoteHost = "RemoteHost"
Local = "local"
TCP = "tcp"
CGRDebitInterval = "CGRDebitInterval"
Version = "Version"
MetaTenant = "*tenant"
ResourceUsage = "ResourceUsage"
MetaDuration = "*duration"
MetaLibPhoneNumber = "*libphonenumber"
MetaIP2Hex = "*ip2hex"
MetaReload = "*reload"
MetaLoad = "*load"
MetaRemove = "*remove"
MetaStore = "*store"
MetaClear = "*clear"
MetaExport = "*export"
LoadIDs = "load_ids"
DNSAgent = "DNSAgent"
TLSNoCaps = "tls"
MetaRouteID = "*route_id"
MetaApiKey = "*api_key"
UsageID = "UsageID"
Rcode = "Rcode"
Replacement = "Replacement"
Regexp = "Regexp"
Order = "Order"
Preference = "Preference"
Flags = "Flags"
Service = "Service"
MetaSuppliersLimit = "*suppliers_limit"
MetaSuppliersOffset = "*suppliers_offset"
ApierV = "ApierV"
MetaApier = "*apier"
MetaAnalyzer = "*analyzer"
CGREventString = "CGREvent"
MetaTextPlain = "*text_plain"
MetaIgnoreErrors = "*ignore_errors"
MetaRelease = "*release"
MetaAllocate = "*allocate"
MetaAuthorize = "*authorize"
MetaInit = "*init"
MetaRatingPlanCost = "*rating_plan_cost"
RatingPlanIDs = "RatingPlanIDs"
ERs = "ERs"
Ratio = "Ratio"
Load = "Load"
Slash = "/"
UUID = "UUID"
ActionsID = "ActionsID"
MetaAct = "*act"
DestinationPrefix = "DestinationPrefix"
DestinationID = "DestinationID"
ExportTemplate = "ExportTemplate"
ExportFormat = "ExportFormat"
Synchronous = "Synchronous"
Attempts = "Attempts"
FieldSeparator = "FieldSeparator"
ExportPath = "ExportPath"
ExportID = "ExportID"
ExportFileName = "ExportFileName"
GroupID = "GroupID"
ThresholdType = "ThresholdType"
ThresholdValue = "ThresholdValue"
Recurrent = "Recurrent"
Executed = "Executed"
MinSleep = "MinSleep"
ActivationDate = "ActivationDate"
ExpirationDate = "ExpirationDate"
MinQueuedItems = "MinQueuedItems"
OrderIDStart = "OrderIDStart"
OrderIDEnd = "OrderIDEnd"
MinCost = "MinCost"
MaxCost = "MaxCost"
MetaLoaders = "*loaders"
TmpSuffix = ".tmp"
MetaDiamreq = "*diamreq"
MetaCost = "*cost"
MetaGroup = "*group"
Address = "Address"
Transport = "Transport"
TLS = "TLS"
Subsystems = "Subsystems"
Strategy = "Strategy"
StrategyParameters = "StrategyParameters"
ConnID = "ConnID"
ConnFilterIDs = "ConnFilterIDs"
ConnWeight = "ConnWeight"
ConnBlocker = "ConnBlocker"
ConnParameters = "ConnParameters"
Thresholds = "Thresholds"
Suppliers = "Suppliers"
Attributes = "Attributes"
Chargers = "Chargers"
Dispatchers = "Dispatchers"
StatS = "Stats"
LoadIDsVrs = "LoadIDs"
RALService = "RALs"
CostSource = "CostSource"
ExtraInfo = "ExtraInfo"
Meta = "*"
MetaSysLog = "*syslog"
MetaStdLog = "*stdout"
EventType = "EventType"
EventSource = "EventSource"
AccountID = "AccountID"
ResourceID = "ResourceID"
TotalUsage = "TotalUsage"
StatID = "StatID"
BalanceType = "BalanceType"
BalanceID = "BalanceID"
BalanceDestinationIds = "BalanceDestinationIds"
BalanceWeight = "BalanceWeight"
BalanceExpirationDate = "BalanceExpirationDate"
BalanceTimingTags = "BalanceTimingTags"
BalanceRatingSubject = "BalanceRatingSubject"
BalanceCategories = "BalanceCategories"
BalanceSharedGroups = "BalanceSharedGroups"
BalanceBlocker = "BalanceBlocker"
BalanceDisabled = "BalanceDisabled"
Units = "Units"
AccountUpdate = "AccountUpdate"
BalanceUpdate = "BalanceUpdate"
StatUpdate = "StatUpdate"
ResourceUpdate = "ResourceUpdate"
CDR = "CDR"
CDRs = "CDRs"
ExpiryTime = "ExpiryTime"
AllowNegative = "AllowNegative"
Disabled = "Disabled"
Action = "Action"
MetaNow = "*now"
SessionSCosts = "SessionSCosts"
Timing = "Timing"
RQF = "RQF"
Resource = "Resource"
User = "User"
Subscribers = "Subscribers"
DerivedChargersV = "DerivedChargers"
Destinations = "Destinations"
ReverseDestinations = "ReverseDestinations"
RatingPlan = "RatingPlan"
RatingProfile = "RatingProfile"
MetaRatingPlans = "*rating_plans"
MetaRatingProfiles = "*rating_profiles"
MetaUsers = "*users"
MetaSubscribers = "*subscribers"
MetaDerivedChargersV = "*derivedchargers"
MetaStorDB = "*stordb"
MetaDataDB = "*datadb"
MetaWeight = "*weight"
MetaLC = "*lc"
MetaHC = "*hc"
MetaQOS = "*qos"
MetaReas = "*reas"
MetaReds = "*reds"
Weight = "Weight"
ThresholdIDs = "ThresholdIDs"
Cost = "Cost"
Limit = "Limit"
UsageTTL = "UsageTTL"
AllocationMessage = "AllocationMessage"
Stored = "Stored"
DestinationIDs = "DestinationIDs"
RatingSubject = "RatingSubject"
Categories = "Categories"
Blocker = "Blocker"
RatingPlanID = "RatingPlanID"
StartTime = "StartTime"
AccountSummary = "AccountSummary"
RatingFilters = "RatingFilters"
RatingFilter = "RatingFilter"
Accounting = "Accounting"
Rating = "Rating"
Charges = "Charges"
CompressFactor = "CompressFactor"
Increments = "Increments"
Balance = "Balance"
BalanceSummaries = "BalanceSummaries"
Type = "Type"
Element = "Element"
Values = "Values"
YearsFieldName = "Years"
MonthsFieldName = "Months"
MonthDaysFieldName = "MonthDays"
WeekDaysFieldName = "WeekDays"
GroupIntervalStart = "GroupIntervalStart"
RateIncrement = "RateIncrement"
RateUnit = "RateUnit"
BalanceUUID = "BalanceUUID"
RatingID = "RatingID"
ExtraChargeID = "ExtraChargeID"
ConnectFee = "ConnectFee"
RoundingMethod = "RoundingMethod"
RoundingDecimals = "RoundingDecimals"
MaxCostStrategy = "MaxCostStrategy"
TimingID = "TimingID"
RatesID = "RatesID"
RatingFiltersID = "RatingFiltersID"
AccountingID = "AccountingID"
MetaSessionS = "*sessions"
MetaDefault = "*default"
Error = "Error"
MetaCgreq = "*cgreq"
MetaCgrep = "*cgrep"
MetaCGRAReq = "*cgrareq"
CGR_ACD = "cgr_acd"
FilterIDs = "FilterIDs"
ActivationIntervalString = "ActivationInterval"
AttributeFilterIDs = "AttributeFilterIDs"
FieldName = "FieldName"
Path = "Path"
MetaRound = "*round"
Pong = "Pong"
MetaEventCost = "*event_cost"
MetaSuppliersEventCost = "*suppliers_event_cost"
MetaSuppliersIgnoreErrors = "*suppliers_ignore_errors"
Freeswitch = "freeswitch"
Kamailio = "kamailio"
Opensips = "opensips"
Asterisk = "asterisk"
SchedulerS = "SchedulerS"
MetaMultiply = "*multiply"
MetaDivide = "*divide"
MetaUrl = "*url"
MetaXml = "*xml"
ApiKey = "apikey"
MetaReq = "*req"
MetaVars = "*vars"
MetaRep = "*rep"
MetaExp = "*exp"
MetaHdr = "*hdr"
MetaTrl = "*trl"
MetaTmp = "*tmp"
CGROriginHost = "cgr_originhost"
MetaInitiate = "*initiate"
MetaUpdate = "*update"
MetaTerminate = "*terminate"
MetaEvent = "*event"
MetaMessage = "*message"
MetaDryRun = "*dryrun"
Event = "Event"
EmptyString = ""
DynamicDataPrefix = "~"
AttrValueSep = "="
ANDSep = "&"
PipeSep = "|"
MetaApp = "*app"
MetaAppID = "*appid"
MetaCmd = "*cmd"
MetaEnv = "*env:" // use in config for describing enviormant variables
MetaTemplate = "*template"
MetaCCA = "*cca"
MetaErr = "*err"
OriginRealm = "OriginRealm"
ProductName = "ProductName"
IdxStart = "["
IdxEnd = "]"
MetaLog = "*log"
MetaRemoteHost = "*remote_host"
RemoteHost = "RemoteHost"
Local = "local"
TCP = "tcp"
CGRDebitInterval = "CGRDebitInterval"
Version = "Version"
MetaTenant = "*tenant"
ResourceUsage = "ResourceUsage"
MetaDuration = "*duration"
MetaLibPhoneNumber = "*libphonenumber"
MetaIP2Hex = "*ip2hex"
MetaReload = "*reload"
MetaLoad = "*load"
MetaRemove = "*remove"
MetaStore = "*store"
MetaClear = "*clear"
MetaExport = "*export"
LoadIDs = "load_ids"
DNSAgent = "DNSAgent"
TLSNoCaps = "tls"
MetaRouteID = "*route_id"
MetaApiKey = "*api_key"
UsageID = "UsageID"
Rcode = "Rcode"
Replacement = "Replacement"
Regexp = "Regexp"
Order = "Order"
Preference = "Preference"
Flags = "Flags"
Service = "Service"
MetaSuppliersLimit = "*suppliers_limit"
MetaSuppliersOffset = "*suppliers_offset"
ApierV = "ApierV"
MetaApier = "*apier"
MetaAnalyzer = "*analyzer"
CGREventString = "CGREvent"
MetaTextPlain = "*text_plain"
MetaIgnoreErrors = "*ignore_errors"
MetaRelease = "*release"
MetaAllocate = "*allocate"
MetaAuthorize = "*authorize"
MetaInit = "*init"
MetaRatingPlanCost = "*rating_plan_cost"
RatingPlanIDs = "RatingPlanIDs"
ERs = "ERs"
Ratio = "Ratio"
Load = "Load"
Slash = "/"
UUID = "UUID"
ActionsID = "ActionsID"
MetaAct = "*act"
DestinationPrefix = "DestinationPrefix"
DestinationID = "DestinationID"
ExportTemplate = "ExportTemplate"
ExportFormat = "ExportFormat"
Synchronous = "Synchronous"
Attempts = "Attempts"
FieldSeparator = "FieldSeparator"
ExportPath = "ExportPath"
ExportID = "ExportID"
ExportFileName = "ExportFileName"
GroupID = "GroupID"
ThresholdType = "ThresholdType"
ThresholdValue = "ThresholdValue"
Recurrent = "Recurrent"
Executed = "Executed"
MinSleep = "MinSleep"
ActivationDate = "ActivationDate"
ExpirationDate = "ExpirationDate"
MinQueuedItems = "MinQueuedItems"
OrderIDStart = "OrderIDStart"
OrderIDEnd = "OrderIDEnd"
MinCost = "MinCost"
MaxCost = "MaxCost"
MetaLoaders = "*loaders"
TmpSuffix = ".tmp"
MetaDiamreq = "*diamreq"
MetaCost = "*cost"
MetaGroup = "*group"
InternalRPCSet = "InternalRPCSet"
)