Add action type *dynamic_action_trigger

This commit is contained in:
arberkatellari
2025-06-12 17:31:30 +02:00
committed by Dan Christian Bogos
parent 0e15a7826f
commit 990f001465
12 changed files with 601 additions and 162 deletions

View File

@@ -1061,7 +1061,7 @@ func testApierGetActionTrigger(t *testing.T) {
//set an ActionTrigger in database
var reply string
if err := rater.Call(context.Background(), utils.APIerSv1SetActionTrigger,
AttrSetActionTrigger{
engine.AttrSetActionTrigger{
GroupID: "TEST_ID1",
UniqueID: "TEST_ID2",
}, &reply); err != nil {
@@ -1394,7 +1394,7 @@ func testApierSetAccountActionTriggers(t *testing.T) {
setReq := AttrSetAccountActionTriggers{
Tenant: "cgrates.org",
Account: "dan2",
AttrSetActionTrigger: AttrSetActionTrigger{
AttrSetActionTrigger: engine.AttrSetActionTrigger{
UniqueID: reply[0].UniqueID,
ActionTrigger: map[string]any{
utils.ActivationDate: "2016-02-05T18:00:00Z",

View File

@@ -1131,7 +1131,7 @@ func testInternalReplicateITActionTrigger(t *testing.T) {
}
// set
var reply string
attrSet := AttrSetActionTrigger{
attrSet := engine.AttrSetActionTrigger{
GroupID: "TestATR",
UniqueID: "UniqueID",
ActionTrigger: map[string]any{

View File

@@ -19,7 +19,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
package v1
import (
"errors"
"strings"
"time"
@@ -204,151 +203,7 @@ func (apierSv1 *APIerSv1) ResetAccountActionTriggers(ctx *context.Context, attr
type AttrSetAccountActionTriggers struct {
Tenant string
Account string
AttrSetActionTrigger
}
type AttrSetActionTrigger struct {
GroupID string
UniqueID string
ActionTrigger map[string]any
}
// UpdateActionTrigger updates the ActionTrigger if is matching
func (attr *AttrSetActionTrigger) UpdateActionTrigger(at *engine.ActionTrigger, timezone string) (updated bool, err error) {
if at == nil {
return false, errors.New("Empty ActionTrigger")
}
if at.ID == utils.EmptyString { // New AT, update it's data
if attr.GroupID == utils.EmptyString {
return false, utils.NewErrMandatoryIeMissing(utils.GroupID)
}
if missing := utils.MissingMapFields(attr.ActionTrigger, []string{"ThresholdType", "ThresholdValue"}); len(missing) != 0 {
return false, utils.NewErrMandatoryIeMissing(missing...)
}
at.ID = attr.GroupID
if attr.UniqueID != utils.EmptyString {
at.UniqueID = attr.UniqueID
}
}
if attr.GroupID != utils.EmptyString && attr.GroupID != at.ID {
return
}
if attr.UniqueID != utils.EmptyString && attr.UniqueID != at.UniqueID {
return
}
// at matches
updated = true
if thr, has := attr.ActionTrigger[utils.ThresholdType]; has {
at.ThresholdType = utils.IfaceAsString(thr)
}
if thr, has := attr.ActionTrigger[utils.ThresholdValue]; has {
if at.ThresholdValue, err = utils.IfaceAsFloat64(thr); err != nil {
return
}
}
if rec, has := attr.ActionTrigger[utils.Recurrent]; has {
if at.Recurrent, err = utils.IfaceAsBool(rec); err != nil {
return
}
}
if exec, has := attr.ActionTrigger[utils.Executed]; has {
if at.Executed, err = utils.IfaceAsBool(exec); err != nil {
return
}
}
if minS, has := attr.ActionTrigger[utils.MinSleep]; has {
if at.MinSleep, err = utils.IfaceAsDuration(minS); err != nil {
return
}
}
if exp, has := attr.ActionTrigger[utils.ExpirationDate]; has {
if at.ExpirationDate, err = utils.IfaceAsTime(exp, timezone); err != nil {
return
}
}
if act, has := attr.ActionTrigger[utils.ActivationDate]; has {
if at.ActivationDate, err = utils.IfaceAsTime(act, timezone); err != nil {
return
}
}
if at.Balance == nil {
at.Balance = &engine.BalanceFilter{}
}
if bid, has := attr.ActionTrigger[utils.BalanceID]; has {
at.Balance.ID = utils.StringPointer(utils.IfaceAsString(bid))
}
if btype, has := attr.ActionTrigger[utils.BalanceType]; has {
at.Balance.Type = utils.StringPointer(utils.IfaceAsString(btype))
}
if bdest, has := attr.ActionTrigger[utils.BalanceDestinationIds]; has {
var bdIds []string
if bdIds, err = utils.IfaceAsSliceString(bdest); err != nil {
return
}
at.Balance.DestinationIDs = utils.StringMapPointer(utils.NewStringMap(bdIds...))
}
if bweight, has := attr.ActionTrigger[utils.BalanceWeight]; has {
var bw float64
if bw, err = utils.IfaceAsFloat64(bweight); err != nil {
return
}
at.Balance.Weight = utils.Float64Pointer(bw)
}
if exp, has := attr.ActionTrigger[utils.BalanceExpirationDate]; has {
var balanceExpTime time.Time
if balanceExpTime, err = utils.IfaceAsTime(exp, timezone); err != nil {
return
}
at.Balance.ExpirationDate = utils.TimePointer(balanceExpTime)
}
if bTimeTag, has := attr.ActionTrigger[utils.BalanceTimingTags]; has {
var timeTag []string
if timeTag, err = utils.IfaceAsSliceString(bTimeTag); err != nil {
return
}
at.Balance.TimingIDs = utils.StringMapPointer(utils.NewStringMap(timeTag...))
}
if brs, has := attr.ActionTrigger[utils.BalanceRatingSubject]; has {
at.Balance.RatingSubject = utils.StringPointer(utils.IfaceAsString(brs))
}
if bcat, has := attr.ActionTrigger[utils.BalanceCategories]; has {
var cat []string
if cat, err = utils.IfaceAsSliceString(bcat); err != nil {
return
}
at.Balance.Categories = utils.StringMapPointer(utils.NewStringMap(cat...))
}
if bsg, has := attr.ActionTrigger[utils.BalanceSharedGroups]; has {
var shrgrps []string
if shrgrps, err = utils.IfaceAsSliceString(bsg); err != nil {
return
}
at.Balance.SharedGroups = utils.StringMapPointer(utils.NewStringMap(shrgrps...))
}
if bb, has := attr.ActionTrigger[utils.BalanceBlocker]; has {
var bBlocker bool
if bBlocker, err = utils.IfaceAsBool(bb); err != nil {
return
}
at.Balance.Blocker = utils.BoolPointer(bBlocker)
}
if bd, has := attr.ActionTrigger[utils.BalanceDisabled]; has {
var bDis bool
if bDis, err = utils.IfaceAsBool(bd); err != nil {
return
}
at.Balance.Disabled = utils.BoolPointer(bDis)
}
if minQ, has := attr.ActionTrigger[utils.MinQueuedItems]; has {
var mQ int64
if mQ, err = utils.IfaceAsTInt64(minQ); err != nil {
return
}
at.MinQueuedItems = int(mQ)
}
if accID, has := attr.ActionTrigger[utils.ActionsID]; has {
at.ActionsID = utils.IfaceAsString(accID)
}
return
engine.AttrSetActionTrigger
}
// SetAccountActionTriggers updates or creates if not present the ActionTrigger for an Account
@@ -444,7 +299,7 @@ func (apierSv1 *APIerSv1) RemoveActionTrigger(ctx *context.Context, attr *AttrRe
}
// SetActionTrigger updates a ActionTrigger
func (apierSv1 *APIerSv1) SetActionTrigger(ctx *context.Context, attr *AttrSetActionTrigger, reply *string) (err error) {
func (apierSv1 *APIerSv1) SetActionTrigger(ctx *context.Context, attr *engine.AttrSetActionTrigger, reply *string) (err error) {
if missing := utils.MissingStructFields(attr, []string{"GroupID"}); len(missing) != 0 {
return utils.NewErrMandatoryIeMissing(missing...)
}

View File

@@ -28,7 +28,7 @@ import (
)
func TestAttrSetActionTriggerUpdateActionTrigger(t *testing.T) {
ast := AttrSetActionTrigger{}
ast := engine.AttrSetActionTrigger{}
if _, err := ast.UpdateActionTrigger(nil, ""); err == nil || err.Error() != "Empty ActionTrigger" {
t.Errorf("Expected error \"Empty ActionTrigger\", received: %v", err)
}
@@ -43,7 +43,7 @@ func TestAttrSetActionTriggerUpdateActionTrigger(t *testing.T) {
t.Errorf("Expected error %s , received: %v", expErr, err)
}
tNow := time.Now()
ast = AttrSetActionTrigger{
ast = engine.AttrSetActionTrigger{
GroupID: "GroupID",
UniqueID: "ID",
ActionTrigger: map[string]any{
@@ -182,7 +182,7 @@ func TestAttrSetActionTriggerUpdateActionTrigger(t *testing.T) {
ID: "GroupID2",
UniqueID: "ID2",
}
ast = AttrSetActionTrigger{
ast = engine.AttrSetActionTrigger{
GroupID: "GroupID",
UniqueID: "ID",
}
@@ -195,7 +195,7 @@ func TestAttrSetActionTriggerUpdateActionTrigger(t *testing.T) {
ID: "GroupID",
UniqueID: "ID2",
}
ast = AttrSetActionTrigger{
ast = engine.AttrSetActionTrigger{
GroupID: "GroupID",
UniqueID: "ID",
}

View File

@@ -174,7 +174,7 @@ func testAPIerSv2itSetAccountActionTriggers(t *testing.T) {
attrs := v1.AttrSetAccountActionTriggers{
Tenant: "cgrates.org",
Account: "dan",
AttrSetActionTrigger: v1.AttrSetActionTrigger{
AttrSetActionTrigger: engine.AttrSetActionTrigger{
GroupID: "MONITOR_MAX_BALANCE",
ActionTrigger: map[string]any{
utils.ThresholdType: utils.TriggerMaxBalance,