mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
new v2 SetAccount API
This commit is contained in:
@@ -543,16 +543,16 @@ type AttrSetBalance struct {
|
||||
Tenant string
|
||||
Account string
|
||||
BalanceType string
|
||||
BalanceUuid *string
|
||||
BalanceId *string
|
||||
Directions *string
|
||||
BalanceUUID *string
|
||||
BalanceID *string
|
||||
Directions *[]string
|
||||
Value *float64
|
||||
ExpiryTime *string
|
||||
RatingSubject *string
|
||||
Categories *string
|
||||
DestinationIds *string
|
||||
SharedGroups *string
|
||||
TimingIds *string
|
||||
Categories *[]string
|
||||
DestinationIDs *[]string
|
||||
SharedGroups *[]string
|
||||
TimingIDs *[]string
|
||||
Weight *float64
|
||||
Blocker *bool
|
||||
Disabled *bool
|
||||
@@ -561,7 +561,7 @@ type AttrSetBalance struct {
|
||||
|
||||
func (attr *AttrSetBalance) SetBalance(b *engine.Balance) {
|
||||
if attr.Directions != nil {
|
||||
b.Directions = utils.ParseStringMap(*attr.Directions)
|
||||
b.Directions = utils.StringMapFromSlice(*attr.Directions)
|
||||
}
|
||||
if attr.Value != nil {
|
||||
b.Value = *attr.Value
|
||||
@@ -573,16 +573,16 @@ func (attr *AttrSetBalance) SetBalance(b *engine.Balance) {
|
||||
b.RatingSubject = *attr.RatingSubject
|
||||
}
|
||||
if attr.Categories != nil {
|
||||
b.Categories = utils.ParseStringMap(*attr.Categories)
|
||||
b.Categories = utils.StringMapFromSlice(*attr.Categories)
|
||||
}
|
||||
if attr.DestinationIds != nil {
|
||||
b.DestinationIds = utils.ParseStringMap(*attr.DestinationIds)
|
||||
if attr.DestinationIDs != nil {
|
||||
b.DestinationIds = utils.StringMapFromSlice(*attr.DestinationIDs)
|
||||
}
|
||||
if attr.SharedGroups != nil {
|
||||
b.SharedGroups = utils.ParseStringMap(*attr.SharedGroups)
|
||||
b.SharedGroups = utils.StringMapFromSlice(*attr.SharedGroups)
|
||||
}
|
||||
if attr.TimingIds != nil {
|
||||
b.TimingIDs = utils.ParseStringMap(*attr.TimingIds)
|
||||
if attr.TimingIDs != nil {
|
||||
b.TimingIDs = utils.StringMapFromSlice(*attr.TimingIDs)
|
||||
}
|
||||
if attr.Weight != nil {
|
||||
b.Weight = *attr.Weight
|
||||
@@ -602,8 +602,8 @@ func (self *ApierV1) SetBalance(attr *AttrAddBalance, reply *string) error {
|
||||
if missing := utils.MissingStructFields(attr, []string{"Tenant", "Account", "BalanceType"}); len(missing) != 0 {
|
||||
return utils.NewErrMandatoryIeMissing(missing...)
|
||||
}
|
||||
if attr.BalanceId == "" && attr.BalanceUuid == "" {
|
||||
return utils.NewErrMandatoryIeMissing("BalanceId", "or", "BalanceUuid")
|
||||
if attr.BalanceID == "" && attr.BalanceUUID == "" {
|
||||
return utils.NewErrMandatoryIeMissing("BalanceID", "or", "BalanceUUID")
|
||||
}
|
||||
expTime, err := utils.ParseTimeDetectLayout(attr.ExpiryTime, self.Config.DefaultTimezone)
|
||||
if err != nil {
|
||||
@@ -623,17 +623,17 @@ func (self *ApierV1) SetBalance(attr *AttrAddBalance, reply *string) error {
|
||||
ActionType: engine.SET_BALANCE,
|
||||
BalanceType: attr.BalanceType,
|
||||
Balance: &engine.Balance{
|
||||
Uuid: attr.BalanceUuid,
|
||||
Id: attr.BalanceId,
|
||||
Uuuid: attr.BalanceUUID,
|
||||
ID: attr.BalanceID,
|
||||
Value: attr.Value,
|
||||
ExpirationDate: expTime,
|
||||
RatingSubject: attr.RatingSubject,
|
||||
Directions: utils.ParseStringMap(attr.Directions),
|
||||
DestinationIds: utils.ParseStringMap(attr.DestinationIds),
|
||||
DestinationIDs: utils.ParseStringMap(attr.DestinationIDs),
|
||||
Categories: utils.ParseStringMap(attr.Categories),
|
||||
Weight: attr.Weight,
|
||||
SharedGroups: utils.ParseStringMap(attr.SharedGroups),
|
||||
TimingIDs: utils.ParseStringMap(attr.TimingIds),
|
||||
TimingIDs: utils.ParseStringMap(attr.TimingIDs),
|
||||
Blocker: true,
|
||||
Disabled: attr.Disabled,
|
||||
},
|
||||
@@ -652,9 +652,9 @@ func (self *ApierV1) SetBalance(attr *AttrSetBalance, reply *string) error {
|
||||
if missing := utils.MissingStructFields(attr, []string{"Tenant", "Account", "BalanceType"}); len(missing) != 0 {
|
||||
return utils.NewErrMandatoryIeMissing(missing...)
|
||||
}
|
||||
if (attr.BalanceId == nil || *attr.BalanceId == "") &&
|
||||
(attr.BalanceUuid == nil || *attr.BalanceUuid == "") {
|
||||
return utils.NewErrMandatoryIeMissing("BalanceId", "or", "BalanceUuid")
|
||||
if (attr.BalanceID == nil || *attr.BalanceID == "") &&
|
||||
(attr.BalanceUUID == nil || *attr.BalanceUUID == "") {
|
||||
return utils.NewErrMandatoryIeMissing("BalanceID", "or", "BalanceUUID")
|
||||
}
|
||||
var err error
|
||||
if attr.ExpiryTime != nil {
|
||||
@@ -681,8 +681,8 @@ func (self *ApierV1) SetBalance(attr *AttrSetBalance, reply *string) error {
|
||||
if b.IsExpired() {
|
||||
continue
|
||||
}
|
||||
if (attr.BalanceUuid != nil && b.Uuid == *attr.BalanceUuid) ||
|
||||
(attr.BalanceId != nil && b.Id == *attr.BalanceId) {
|
||||
if (attr.BalanceUUID != nil && b.Uuid == *attr.BalanceUUID) ||
|
||||
(attr.BalanceID != nil && b.Id == *attr.BalanceID) {
|
||||
previousSharedGroups = b.SharedGroups
|
||||
balance = b
|
||||
found = true
|
||||
@@ -697,7 +697,7 @@ func (self *ApierV1) SetBalance(attr *AttrSetBalance, reply *string) error {
|
||||
account.BalanceMap[attr.BalanceType] = append(account.BalanceMap[attr.BalanceType], balance)
|
||||
}
|
||||
|
||||
if attr.BalanceId != nil && *attr.BalanceId == utils.META_DEFAULT {
|
||||
if attr.BalanceID != nil && *attr.BalanceID == utils.META_DEFAULT {
|
||||
balance.Id = utils.META_DEFAULT
|
||||
if attr.Value != nil {
|
||||
balance.Value = *attr.Value
|
||||
@@ -708,12 +708,12 @@ func (self *ApierV1) SetBalance(attr *AttrSetBalance, reply *string) error {
|
||||
|
||||
if !found || !previousSharedGroups.Equal(balance.SharedGroups) {
|
||||
_, err = engine.Guardian.Guard(func() (interface{}, error) {
|
||||
for sgId := range balance.SharedGroups {
|
||||
for sgID := range balance.SharedGroups {
|
||||
// add shared group member
|
||||
sg, err := self.RatingDb.GetSharedGroup(sgId, false)
|
||||
sg, err := self.RatingDb.GetSharedGroup(sgID, false)
|
||||
if err != nil || sg == nil {
|
||||
//than is problem
|
||||
utils.Logger.Warning(fmt.Sprintf("Could not get shared group: %v", sgId))
|
||||
utils.Logger.Warning(fmt.Sprintf("Could not get shared group: %v", sgID))
|
||||
} else {
|
||||
if _, found := sg.MemberIds[account.Id]; !found {
|
||||
// add member and save
|
||||
|
||||
@@ -81,9 +81,9 @@ func (self *ApierV2) GetAccount(attr *utils.AttrGetAccount, reply *engine.Accoun
|
||||
type AttrSetAccount struct {
|
||||
Tenant string
|
||||
Account string
|
||||
ActionPlanIds string
|
||||
ActionPlanIds *[]string
|
||||
ActionPlansOverwrite bool
|
||||
ActionTriggersIds string
|
||||
ActionTriggersIds *[]string
|
||||
ActionTriggerOverwrite bool
|
||||
AllowNegative *bool
|
||||
Disabled *bool
|
||||
@@ -94,7 +94,7 @@ func (self *ApierV2) SetAccount(attr AttrSetAccount, reply *string) error {
|
||||
if missing := utils.MissingStructFields(&attr, []string{"Tenant", "Account"}); len(missing) != 0 {
|
||||
return utils.NewErrMandatoryIeMissing(missing...)
|
||||
}
|
||||
var schedulerReloadNeeded = false
|
||||
dirtyActionPlans := make(map[string]*engine.ActionPlan)
|
||||
accID := utils.AccountKey(attr.Tenant, attr.Account)
|
||||
var ub *engine.Account
|
||||
_, err := engine.Guardian.Guard(func() (interface{}, error) {
|
||||
@@ -105,38 +105,55 @@ func (self *ApierV2) SetAccount(attr AttrSetAccount, reply *string) error {
|
||||
Id: accID,
|
||||
}
|
||||
}
|
||||
if len(attr.ActionPlanIds) != 0 {
|
||||
if attr.ActionPlanIds != nil {
|
||||
_, err := engine.Guardian.Guard(func() (interface{}, error) {
|
||||
var ap *engine.ActionPlan
|
||||
var err error
|
||||
ap, err = self.RatingDb.GetActionPlan(attr.ActionPlanIds, false)
|
||||
actionPlansMap, err := self.RatingDb.GetAllActionPlans()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if _, exists := ap.AccountIDs[accID]; !exists {
|
||||
if ap.AccountIDs == nil {
|
||||
ap.AccountIDs = make(utils.StringMap)
|
||||
if attr.ActionPlansOverwrite {
|
||||
// clean previous action plans
|
||||
for actionPlanID, ap := range actionPlansMap {
|
||||
if _, exists := ap.AccountIDs[accID]; exists {
|
||||
delete(ap.AccountIDs, accID)
|
||||
dirtyActionPlans[actionPlanID] = ap
|
||||
}
|
||||
}
|
||||
ap.AccountIDs[accID] = true
|
||||
schedulerReloadNeeded = true
|
||||
// create tasks
|
||||
for _, at := range ap.ActionTimings {
|
||||
if at.IsASAP() {
|
||||
t := &engine.Task{
|
||||
Uuid: utils.GenUUID(),
|
||||
AccountID: accID,
|
||||
ActionsID: at.ActionsID,
|
||||
}
|
||||
if err = self.RatingDb.PushTask(t); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
for _, actionPlanID := range *attr.ActionPlanIds {
|
||||
ap, ok := actionPlansMap[actionPlanID]
|
||||
if !ok {
|
||||
return 0, utils.ErrNotFound
|
||||
}
|
||||
|
||||
if _, exists := ap.AccountIDs[accID]; !exists {
|
||||
if ap.AccountIDs == nil {
|
||||
ap.AccountIDs = make(utils.StringMap)
|
||||
}
|
||||
ap.AccountIDs[accID] = true
|
||||
dirtyActionPlans[actionPlanID] = ap
|
||||
// create tasks
|
||||
for _, at := range ap.ActionTimings {
|
||||
if at.IsASAP() {
|
||||
t := &engine.Task{
|
||||
Uuid: utils.GenUUID(),
|
||||
AccountID: accID,
|
||||
ActionsID: at.ActionsID,
|
||||
}
|
||||
if err = self.RatingDb.PushTask(t); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if err := self.RatingDb.SetActionPlan(attr.ActionPlanIds, ap); err != nil {
|
||||
}
|
||||
for actionPlanID, ap := range dirtyActionPlans {
|
||||
if err := self.RatingDb.SetActionPlan(actionPlanID, ap); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
// update cache
|
||||
self.RatingDb.CacheRatingPrefixValues(map[string][]string{utils.ACTION_PLAN_PREFIX: []string{utils.ACTION_PLAN_PREFIX + attr.ActionPlanIds}})
|
||||
self.RatingDb.CacheRatingPrefixValues(map[string][]string{utils.ACTION_PLAN_PREFIX: []string{utils.ACTION_PLAN_PREFIX + actionPlanID}})
|
||||
}
|
||||
return 0, nil
|
||||
}, 0, utils.ACTION_PLAN_PREFIX)
|
||||
@@ -145,14 +162,30 @@ func (self *ApierV2) SetAccount(attr AttrSetAccount, reply *string) error {
|
||||
}
|
||||
}
|
||||
|
||||
if len(attr.ActionTriggersIds) != 0 {
|
||||
atrs, err := self.RatingDb.GetActionTriggers(attr.ActionTriggersIds)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
if attr.ActionTriggersIds != nil {
|
||||
if attr.ActionTriggerOverwrite {
|
||||
ub.ActionTriggers = make(engine.ActionTriggers, 0)
|
||||
}
|
||||
for _, actionTriggerID := range *attr.ActionTriggersIds {
|
||||
atrs, err := self.RatingDb.GetActionTriggers(actionTriggerID)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
for _, at := range atrs {
|
||||
var found bool
|
||||
for _, existingAt := range ub.ActionTriggers {
|
||||
if existingAt.Equals(at) {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
ub.ActionTriggers = append(ub.ActionTriggers, at)
|
||||
}
|
||||
}
|
||||
}
|
||||
ub.ActionTriggers = atrs
|
||||
ub.InitCounters()
|
||||
}
|
||||
ub.InitCounters()
|
||||
if attr.AllowNegative != nil {
|
||||
ub.AllowNegative = *attr.AllowNegative
|
||||
}
|
||||
@@ -168,7 +201,7 @@ func (self *ApierV2) SetAccount(attr AttrSetAccount, reply *string) error {
|
||||
if err != nil {
|
||||
return utils.NewErrServerError(err)
|
||||
}
|
||||
if attr.ReloadScheduler && schedulerReloadNeeded {
|
||||
if attr.ReloadScheduler && len(dirtyActionPlans) > 0 {
|
||||
// reload scheduler
|
||||
if self.Sched != nil {
|
||||
self.Sched.Reload(true)
|
||||
|
||||
@@ -18,12 +18,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
package console
|
||||
|
||||
import "github.com/cgrates/cgrates/utils"
|
||||
import "github.com/cgrates/cgrates/apier/v2"
|
||||
|
||||
func init() {
|
||||
c := &CmdAddAccount{
|
||||
name: "account_set",
|
||||
rpcMethod: "ApierV1.SetAccount",
|
||||
rpcMethod: "ApierV2.SetAccount",
|
||||
}
|
||||
commands[c.Name()] = c
|
||||
c.CommandExecuter = &CommandExecuter{c}
|
||||
@@ -33,7 +33,7 @@ func init() {
|
||||
type CmdAddAccount struct {
|
||||
name string
|
||||
rpcMethod string
|
||||
rpcParams *utils.AttrSetAccount
|
||||
rpcParams *v2.AttrSetAccount
|
||||
*CommandExecuter
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ func (self *CmdAddAccount) RpcMethod() string {
|
||||
|
||||
func (self *CmdAddAccount) RpcParams(reset bool) interface{} {
|
||||
if reset || self.rpcParams == nil {
|
||||
self.rpcParams = &utils.AttrSetAccount{}
|
||||
self.rpcParams = &v2.AttrSetAccount{}
|
||||
}
|
||||
return self.rpcParams
|
||||
}
|
||||
|
||||
@@ -183,6 +183,11 @@ func (at *ActionTrigger) CreateBalance() *Balance {
|
||||
}
|
||||
}
|
||||
|
||||
func (at *ActionTrigger) Equals(oat *ActionTrigger) bool {
|
||||
// ids only
|
||||
return at.ID == oat.ID && at.UniqueID == oat.UniqueID
|
||||
}
|
||||
|
||||
// Structure to store actions according to weight
|
||||
type ActionTriggers []*ActionTrigger
|
||||
|
||||
|
||||
@@ -1833,7 +1833,7 @@ func TestActionCSVFilter(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error("error getting actions: ", err)
|
||||
}
|
||||
if len(act) != 1 || act[0].Filter != `{"Type":"*voice","Value":{"*gte":100}}` {
|
||||
if len(act) != 1 || act[0].Filter != `{"*and":[{"Value":{"*lt":0}},{"Id":{"*eq":"*default"}}]}` {
|
||||
t.Error("Error loading actions: ", act[0].Filter)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,7 +174,7 @@ DEFEE,*cdrlog,"{""Category"":""^ddi"",""MediationRunId"":""^did_run""}",,,,,,,,,
|
||||
NEG,*allow_negative,,,,*monetary,*out,,,,,*unlimited,,0,10,false,false,10
|
||||
BLOCK,*topup,,,bblocker,*monetary,*out,,NAT,,,*unlimited,,10,20,true,false,20
|
||||
BLOCK,*topup,,,bfree,*monetary,*out,,,,,*unlimited,,20,10,false,false,10
|
||||
FILTER,*topup,,"{""Type"":""*voice"",""Value"":{""*gte"":100}}",bfree,*monetary,*out,,,,,*unlimited,,20,10,false,false,10
|
||||
FILTER,*topup,,"{""*and"":[{""Value"":{""*lt"":0}},{""Id"":{""*eq"":""*default""}}]}",bfree,*monetary,*out,,,,,*unlimited,,20,10,false,false,10
|
||||
`
|
||||
actionPlans = `
|
||||
MORE_MINUTES,MINI,ONE_TIME_RUN,10
|
||||
|
||||
21
utils/map.go
21
utils/map.go
@@ -74,15 +74,7 @@ func NewStringMap(s ...string) StringMap {
|
||||
}
|
||||
|
||||
func ParseStringMap(s string) StringMap {
|
||||
slice := strings.Split(s, INFIELD_SEP)
|
||||
result := make(StringMap)
|
||||
for _, v := range slice {
|
||||
v = strings.TrimSpace(v)
|
||||
if v != "" {
|
||||
result[v] = true
|
||||
}
|
||||
}
|
||||
return result
|
||||
return StringMapFromSlice(strings.Split(s, INFIELD_SEP))
|
||||
}
|
||||
|
||||
func (sm StringMap) Equal(om StringMap) bool {
|
||||
@@ -130,6 +122,17 @@ func (sm StringMap) Slice() []string {
|
||||
return result
|
||||
}
|
||||
|
||||
func StringMapFromSlice(s []string) StringMap {
|
||||
result := make(StringMap)
|
||||
for _, v := range s {
|
||||
v = strings.TrimSpace(v)
|
||||
if v != "" {
|
||||
result[v] = true
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (sm StringMap) Copy(o StringMap) {
|
||||
for k, v := range o {
|
||||
sm[k] = v
|
||||
|
||||
Reference in New Issue
Block a user