Add infrastructure for ActionProfile for Replicator Dispatcher and LoaderS

This commit is contained in:
TeoV
2020-12-08 13:00:44 +02:00
committed by Dan Christian Bogos
parent a717fc4f3d
commit 28c59978b9
7 changed files with 318 additions and 15 deletions

View File

@@ -286,6 +286,15 @@ func (rplSv1 *ReplicatorSv1) GetRateProfile(tntID *utils.TenantIDWithOpts, reply
return nil
}
func (rplSv1 *ReplicatorSv1) GetActionProfile(tntID *utils.TenantIDWithOpts, reply *engine.ActionProfile) error {
if rcv, err := rplSv1.dm.DataDB().GetActionProfileDrv(tntID.Tenant, tntID.ID); err != nil {
return err
} else {
*reply = *rcv
}
return nil
}
//GetResourceProfile
func (rplSv1 *ReplicatorSv1) GetItemLoadIDs(itemID *utils.StringWithOpts, reply *map[string]int64) error {
if rcv, err := rplSv1.dm.DataDB().GetItemLoadIDsDrv(itemID.Arg); err != nil {
@@ -511,6 +520,14 @@ func (rplSv1 *ReplicatorSv1) SetRateProfile(dpp *engine.RateProfileWithOpts, rep
return nil
}
func (rplSv1 *ReplicatorSv1) SetActionProfile(acp *engine.ActionProfileWithOpts, reply *string) error {
if err := rplSv1.dm.DataDB().SetActionProfileDrv(acp.ActionProfile); err != nil {
return err
}
*reply = utils.OK
return nil
}
// RemoveThreshold
func (rplSv1 *ReplicatorSv1) RemoveThreshold(args *utils.TenantIDWithOpts, reply *string) error {
if err := rplSv1.dm.DataDB().RemoveThresholdDrv(args.Tenant, args.ID); err != nil {
@@ -706,6 +723,14 @@ func (rplSv1 *ReplicatorSv1) RemoveRateProfile(args *utils.TenantIDWithOpts, rep
return nil
}
func (rplSv1 *ReplicatorSv1) RemoveActionProfile(args *utils.TenantIDWithOpts, reply *string) error {
if err := rplSv1.dm.DataDB().RemoveActionProfileDrv(args.Tenant, args.ID); err != nil {
return err
}
*reply = utils.OK
return nil
}
func (rplSv1 *ReplicatorSv1) RemoveDispatcherHost(args *utils.TenantIDWithOpts, reply *string) error {
if err := rplSv1.dm.DataDB().RemoveDispatcherHostDrv(args.Tenant, args.ID); err != nil {
return err

View File

@@ -813,7 +813,27 @@ const CGRATES_CFG_JSON = `
{"tag": "RateValue", "path": "RateValue", "type": "*variable", "value": "~*req.17"},
{"tag": "RateUnit", "path": "RateUnit", "type": "*variable", "value": "~*req.18"},
{"tag": "RateIncrement", "path": "RateIncrement", "type": "*variable", "value": "~*req.19"},
],
},
{
"type": "*action_profiles", // data source type
"file_name": "ActionProfiles.csv", // file name in the tp_in_dir
"fields": [
{"tag": "Tenant", "path": "Tenant", "type": "*variable", "value": "~*req.0", "mandatory": true},
{"tag": "ID", "path": "ID", "type": "*variable", "value": "~*req.1", "mandatory": true},
{"tag": "FilterIDs", "path": "FilterIDs", "type": "*variable", "value": "~*req.2"},
{"tag": "ActivationInterval", "path": "ActivationInterval", "type": "*variable", "value": "~*req.3"},
{"tag": "Weight", "path": "Weight", "type": "*variable", "value": "~*req.4"},
{"tag": "Schedule", "path": "Schedule", "type": "*variable", "value": "~*req.5"},
{"tag": "AccountIDs", "path": "AccountIDs", "type": "*variable", "value": "~*req.6"},
{"tag": "ActionID", "path": "ActionID", "type": "*variable", "value": "~*req.7"},
{"tag": "ActionFilterIDs", "path": "ActionFilterIDs", "type": "*variable", "value": "~*req.8"},
{"tag": "ActionBlocker", "path": "ActionBlocker", "type": "*variable", "value": "~*req.9"},
{"tag": "ActionTTL", "path": "ActionTTL", "type": "*variable", "value": "~*req.10"},
{"tag": "ActionType", "path": "ActionType", "type": "*variable", "value": "~*req.11"},
{"tag": "ActionOpts", "path": "ActionOpts", "type": "*variable", "value": "~*req.12"},
{"tag": "ActionPath", "path": "ActionPath", "type": "*variable", "value": "~*req.13"},
{"tag": "ActionValue", "path": "ActionValue", "type": "*variable", "value": "~*req.14"},
],
},
],

View File

@@ -1616,6 +1616,74 @@ func TestDfLoaderJsonCfg(t *testing.T) {
Value: utils.StringPointer("~*req.19")},
},
},
{
Type: utils.StringPointer(utils.MetaActionProfiles),
File_name: utils.StringPointer(utils.ActionProfilesCsv),
Fields: &[]*FcTemplateJsonCfg{
{Tag: utils.StringPointer(utils.Tenant),
Path: utils.StringPointer(utils.Tenant),
Type: utils.StringPointer(utils.MetaVariable),
Value: utils.StringPointer("~*req.0"),
Mandatory: utils.BoolPointer(true)},
{Tag: utils.StringPointer(utils.ID),
Path: utils.StringPointer(utils.ID),
Type: utils.StringPointer(utils.MetaVariable),
Value: utils.StringPointer("~*req.1"),
Mandatory: utils.BoolPointer(true)},
{Tag: utils.StringPointer("FilterIDs"),
Path: utils.StringPointer("FilterIDs"),
Type: utils.StringPointer(utils.MetaVariable),
Value: utils.StringPointer("~*req.2")},
{Tag: utils.StringPointer("ActivationInterval"),
Path: utils.StringPointer("ActivationInterval"),
Type: utils.StringPointer(utils.MetaVariable),
Value: utils.StringPointer("~*req.3")},
{Tag: utils.StringPointer("Weight"),
Path: utils.StringPointer("Weight"),
Type: utils.StringPointer(utils.MetaVariable),
Value: utils.StringPointer("~*req.4")},
{Tag: utils.StringPointer("Schedule"),
Path: utils.StringPointer("Schedule"),
Type: utils.StringPointer(utils.MetaVariable),
Value: utils.StringPointer("~*req.5")},
{Tag: utils.StringPointer("AccountIDs"),
Path: utils.StringPointer("AccountIDs"),
Type: utils.StringPointer(utils.MetaVariable),
Value: utils.StringPointer("~*req.6")},
{Tag: utils.StringPointer("ActionID"),
Path: utils.StringPointer("ActionID"),
Type: utils.StringPointer(utils.MetaVariable),
Value: utils.StringPointer("~*req.7")},
{Tag: utils.StringPointer("ActionFilterIDs"),
Path: utils.StringPointer("ActionFilterIDs"),
Type: utils.StringPointer(utils.MetaVariable),
Value: utils.StringPointer("~*req.8")},
{Tag: utils.StringPointer("ActionBlocker"),
Path: utils.StringPointer("ActionBlocker"),
Type: utils.StringPointer(utils.MetaVariable),
Value: utils.StringPointer("~*req.9")},
{Tag: utils.StringPointer("ActionTTL"),
Path: utils.StringPointer("ActionTTL"),
Type: utils.StringPointer(utils.MetaVariable),
Value: utils.StringPointer("~*req.10")},
{Tag: utils.StringPointer("ActionType"),
Path: utils.StringPointer("ActionType"),
Type: utils.StringPointer(utils.MetaVariable),
Value: utils.StringPointer("~*req.11")},
{Tag: utils.StringPointer("ActionOpts"),
Path: utils.StringPointer("ActionOpts"),
Type: utils.StringPointer(utils.MetaVariable),
Value: utils.StringPointer("~*req.12")},
{Tag: utils.StringPointer("ActionPath"),
Path: utils.StringPointer("ActionPath"),
Type: utils.StringPointer(utils.MetaVariable),
Value: utils.StringPointer("~*req.13")},
{Tag: utils.StringPointer("ActionValue"),
Path: utils.StringPointer("ActionValue"),
Type: utils.StringPointer(utils.MetaVariable),
Value: utils.StringPointer("~*req.14")},
},
},
},
},
}

File diff suppressed because one or more lines are too long

View File

@@ -527,6 +527,26 @@ func (dS *DispatcherService) ReplicatorSv1GetRateProfile(args *utils.TenantIDWit
}, utils.MetaReplicator, utils.ReplicatorSv1GetRateProfile, args, reply)
}
func (dS *DispatcherService) ReplicatorSv1GetActionProfile(args *utils.TenantIDWithOpts, reply *engine.ActionProfile) (err error) {
tnt := dS.cfg.GeneralCfg().DefaultTenant
if args.TenantID != nil && args.TenantID.Tenant != utils.EmptyString {
tnt = args.TenantID.Tenant
}
if len(dS.cfg.DispatcherSCfg().AttributeSConns) != 0 {
if err = dS.authorize(utils.ReplicatorSv1GetActionProfile, tnt,
utils.IfaceAsString(args.Opts[utils.OptsAPIKey]), utils.TimePointer(time.Now())); err != nil {
return
}
}
return dS.Dispatch(&utils.CGREventWithOpts{
CGREvent: &utils.CGREvent{
Tenant: tnt,
ID: args.ID,
},
Opts: args.Opts,
}, utils.MetaReplicator, utils.ReplicatorSv1GetActionProfile, args, reply)
}
func (dS *DispatcherService) ReplicatorSv1GetItemLoadIDs(args *utils.StringWithOpts, rpl *map[string]int64) (err error) {
if args == nil {
args = new(utils.StringWithOpts)
@@ -945,6 +965,25 @@ func (dS *DispatcherService) ReplicatorSv1SetRateProfile(args *engine.RateProfil
}, utils.MetaReplicator, utils.ReplicatorSv1SetRateProfile, args, rpl)
}
func (dS *DispatcherService) ReplicatorSv1SetActionProfile(args *engine.ActionProfileWithOpts, rpl *string) (err error) {
if args == nil {
args = &engine.ActionProfileWithOpts{}
}
args.Tenant = utils.FirstNonEmpty(args.Tenant, dS.cfg.GeneralCfg().DefaultTenant)
if len(dS.cfg.DispatcherSCfg().AttributeSConns) != 0 {
if err = dS.authorize(utils.ReplicatorSv1SetActionProfile, args.Tenant,
utils.IfaceAsString(args.Opts[utils.OptsAPIKey]), utils.TimePointer(time.Now())); err != nil {
return
}
}
return dS.Dispatch(&utils.CGREventWithOpts{
CGREvent: &utils.CGREvent{
Tenant: args.Tenant,
},
Opts: args.Opts,
}, utils.MetaReplicator, utils.ReplicatorSv1SetActionProfile, args, rpl)
}
func (dS *DispatcherService) ReplicatorSv1SetActionPlan(args *engine.SetActionPlanArgWithOpts, rpl *string) (err error) {
if args == nil {
args = &engine.SetActionPlanArgWithOpts{}
@@ -1458,6 +1497,25 @@ func (dS *DispatcherService) ReplicatorSv1RemoveRateProfile(args *utils.TenantID
}, utils.MetaReplicator, utils.ReplicatorSv1RemoveRateProfile, args, rpl)
}
func (dS *DispatcherService) ReplicatorSv1RemoveActionProfile(args *utils.TenantIDWithOpts, rpl *string) (err error) {
if args == nil {
args = &utils.TenantIDWithOpts{}
}
args.Tenant = utils.FirstNonEmpty(args.Tenant, dS.cfg.GeneralCfg().DefaultTenant)
if len(dS.cfg.DispatcherSCfg().AttributeSConns) != 0 {
if err = dS.authorize(utils.ReplicatorSv1RemoveActionProfile, args.Tenant,
utils.IfaceAsString(args.Opts[utils.OptsAPIKey]), utils.TimePointer(time.Now())); err != nil {
return
}
}
return dS.Dispatch(&utils.CGREventWithOpts{
CGREvent: &utils.CGREvent{
Tenant: args.Tenant,
},
Opts: args.Opts,
}, utils.MetaReplicator, utils.ReplicatorSv1RemoveActionProfile, args, rpl)
}
// ReplicatorSv1GetIndexes .
func (dS *DispatcherService) ReplicatorSv1GetIndexes(args *utils.GetIndexesArg, reply *map[string]utils.StringSet) (err error) {
if args == nil {

View File

@@ -606,6 +606,36 @@ func (ldr *Loader) storeLoadedData(loaderType string,
cacheArgs[utils.RateProfileIDs] = ids
}
}
case utils.MetaActionProfiles:
cacheIDs = []string{utils.CacheActionProfilesFilterIndexes}
for _, lDataSet := range lds {
acpsModels := make(engine.ActionProfileMdls, len(lDataSet))
for i, ld := range lDataSet {
acpsModels[i] = new(engine.ActionProfileMdl)
if err = utils.UpdateStructWithIfaceMap(acpsModels[i], ld); err != nil {
return
}
}
for _, tpAcp := range acpsModels.AsTPActionProfile() {
acp, err := engine.APItoActionProfile(tpAcp, ldr.timezone)
if err != nil {
return err
}
if ldr.dryRun {
utils.Logger.Info(
fmt.Sprintf("<%s-%s> DRY_RUN: ActionProfile: %s",
utils.LoaderS, ldr.ldrID, utils.ToJSON(acp)))
continue
}
// get IDs so we can reload in cache
ids = append(ids, acp.TenantID())
if err := ldr.dm.SetActionProfile(acp, true); err != nil {
return err
}
cacheArgs[utils.ActionProfileIDs] = ids
}
}
}
if len(ldr.cacheConns) != 0 {
@@ -928,6 +958,24 @@ func (ldr *Loader) removeLoadedData(loaderType string, lds map[string][]LoaderDa
cacheArgs[utils.RateProfileIDs] = ids
}
}
case utils.MetaActionProfiles:
cacheIDs = []string{utils.CacheActionProfiles, utils.CacheActionProfilesFilterIndexes}
for tntID := range lds {
if ldr.dryRun {
utils.Logger.Info(
fmt.Sprintf("<%s-%s> DRY_RUN: ActionProfileID: %s",
utils.LoaderS, ldr.ldrID, tntID))
} else {
tntIDStruct := utils.NewTenantID(tntID)
// get IDs so we can reload in cache
ids = append(ids, tntID)
if err := ldr.dm.RemoveActionProfile(tntIDStruct.Tenant,
tntIDStruct.ID, utils.NonTransactional, true); err != nil {
return err
}
cacheArgs[utils.ActionProfileIDs] = ids
}
}
}
if len(ldr.cacheConns) != 0 {

View File

@@ -2027,18 +2027,19 @@ func TestNewLoaderWithMultiFiles(t *testing.T) {
}
}
expected := utils.StringSet{
"Attributes.csv": {},
"Chargers.csv": {},
"DispatcherHosts.csv": {},
"DispatcherProfiles.csv": {},
"File1.csv": {},
"File2.csv": {},
"Filters.csv": {},
"RateProfiles.csv": {},
"Resources.csv": {},
"Routes.csv": {},
"Stats.csv": {},
"Thresholds.csv": {},
utils.AttributesCsv: {},
utils.ChargersCsv: {},
utils.DispatcherHostsCsv: {},
utils.DispatcherProfilesCsv: {},
"File1.csv": {},
"File2.csv": {},
utils.FiltersCsv: {},
utils.RateProfilesCsv: {},
utils.ResourcesCsv: {},
utils.RoutesCsv: {},
utils.StatsCsv: {},
utils.ThresholdsCsv: {},
utils.ActionProfilesCsv: {},
}
if !reflect.DeepEqual(expected, openRdrs) {
t.Errorf("Expected %s,received %s", utils.ToJSON(expected), utils.ToJSON(openRdrs))