Example #1
0
// Removes an ActionTimings or parts of it depending on filters being set
func (self *ApierV1) RemActionTiming(attrs AttrRemActionTiming, reply *string) error {
	if missing := utils.MissingStructFields(&attrs, []string{"ActionPlanId"}); len(missing) != 0 { // Only mandatory ActionPlanId
		return utils.NewErrMandatoryIeMissing(missing...)
	}
	if len(attrs.Account) != 0 { // Presence of Account requires complete account details to be provided
		if missing := utils.MissingStructFields(&attrs, []string{"Tenant", "Account"}); len(missing) != 0 {
			return utils.NewErrMandatoryIeMissing(missing...)
		}
	}
	_, err := engine.Guardian.Guard(func() (interface{}, error) {
		ats, err := self.RatingDb.GetActionPlans(attrs.ActionPlanId, false)
		if err != nil {
			return 0, err
		} else if len(ats) == 0 {
			return 0, utils.ErrNotFound
		}
		ats = engine.RemActionPlan(ats, attrs.ActionTimingId, utils.AccountKey(attrs.Tenant, attrs.Account))
		if err := self.RatingDb.SetActionPlans(attrs.ActionPlanId, ats); err != nil {
			return 0, err
		}
		if len(ats) > 0 { // update cache
			self.RatingDb.CacheRatingPrefixValues(map[string][]string{utils.ACTION_PLAN_PREFIX: []string{utils.ACTION_PLAN_PREFIX + attrs.ActionPlanId}})
		}
		return 0, nil
	}, 0, utils.ACTION_PLAN_PREFIX)
	if err != nil {
		return utils.NewErrServerError(err)
	}
	if attrs.ReloadScheduler && self.Sched != nil {
		self.Sched.LoadActionPlans(self.RatingDb)
		self.Sched.Restart()
	}
	*reply = OK
	return nil
}
Example #2
0
// Removes an ActionTimings or parts of it depending on filters being set
func (self *ApierV1) RemActionTiming(attrs AttrRemActionTiming, reply *string) error {
	if missing := utils.MissingStructFields(&attrs, []string{"ActionPlanId"}); len(missing) != 0 { // Only mandatory ActionPlanId
		return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing)
	}
	if len(attrs.Account) != 0 { // Presence of Account requires complete account details to be provided
		if missing := utils.MissingStructFields(&attrs, []string{"Tenant", "Account", "Direction"}); len(missing) != 0 {
			return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing)
		}
	}
	_, err := engine.AccLock.Guard(engine.ACTION_TIMING_PREFIX, func() (float64, error) {
		ats, err := self.AccountDb.GetActionTimings(attrs.ActionPlanId)
		if err != nil {
			return 0, err
		} else if len(ats) == 0 {
			return 0, errors.New(utils.ERR_NOT_FOUND)
		}
		ats = engine.RemActionTiming(ats, attrs.ActionTimingId, utils.AccountKey(attrs.Tenant, attrs.Account, attrs.Direction))
		if err := self.AccountDb.SetActionTimings(attrs.ActionPlanId, ats); err != nil {
			return 0, err
		}
		return 0, nil
	})
	if err != nil {
		return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error())
	}
	if attrs.ReloadScheduler && self.Sched != nil {
		self.Sched.LoadActionTimings(self.AccountDb)
		self.Sched.Restart()
	}
	*reply = OK
	return nil
}
Example #3
0
// Removes an ActionTimings or parts of it depending on filters being set
func (self *ApierV1) RemActionTiming(attrs AttrRemActionTiming, reply *string) error {
	if missing := utils.MissingStructFields(&attrs, []string{"ActionPlanId"}); len(missing) != 0 { // Only mandatory ActionPlanId
		return utils.NewErrMandatoryIeMissing(missing...)
	}
	if len(attrs.Account) != 0 { // Presence of Account requires complete account details to be provided
		if missing := utils.MissingStructFields(&attrs, []string{"Tenant", "Account"}); len(missing) != 0 {
			return utils.NewErrMandatoryIeMissing(missing...)
		}
	}
	_, err := engine.Guardian.Guard(func() (interface{}, error) {
		ap, err := self.RatingDb.GetActionPlan(attrs.ActionPlanId, false)
		if err != nil {
			return 0, err
		} else if ap == nil {
			return 0, utils.ErrNotFound
		}

		if attrs.Tenant != "" && attrs.Account != "" {
			accID := utils.AccountKey(attrs.Tenant, attrs.Account)
			delete(ap.AccountIDs, accID)
			err = self.RatingDb.SetActionPlan(ap.Id, ap, true)
			goto UPDATE
		}

		if attrs.ActionTimingId != "" { // delete only a action timing from action plan
			for i, at := range ap.ActionTimings {
				if at.Uuid == attrs.ActionTimingId {
					ap.ActionTimings[i] = ap.ActionTimings[len(ap.ActionTimings)-1]
					ap.ActionTimings = ap.ActionTimings[:len(ap.ActionTimings)-1]
					break
				}
			}
			err = self.RatingDb.SetActionPlan(ap.Id, ap, true)
			goto UPDATE
		}

		if attrs.ActionPlanId != "" { // delete the entire action plan
			ap.ActionTimings = nil // will delete the action plan
			err = self.RatingDb.SetActionPlan(ap.Id, ap, true)
			goto UPDATE
		}
	UPDATE:
		if err != nil {
			return 0, err
		}
		// update cache
		self.RatingDb.CacheRatingPrefixValues("AttrRemActionTimingAPI", map[string][]string{utils.ACTION_PLAN_PREFIX: []string{utils.ACTION_PLAN_PREFIX + attrs.ActionPlanId}})
		return 0, nil
	}, 0, utils.ACTION_PLAN_PREFIX)
	if err != nil {
		*reply = err.Error()
		return utils.NewErrServerError(err)
	}
	if attrs.ReloadScheduler && self.Sched != nil {
		self.Sched.Reload(true)
	}
	*reply = OK
	return nil
}
Example #4
0
func (self *ApierV1) SetActionPlan(attrs AttrSetActionPlan, reply *string) (err error) {
	if missing := utils.MissingStructFields(&attrs, []string{"Id", "ActionPlan"}); len(missing) != 0 {
		return utils.NewErrMandatoryIeMissing(missing...)
	}
	for _, at := range attrs.ActionPlan {
		requiredFields := []string{"ActionsId", "Time", "Weight"}
		if missing := utils.MissingStructFields(at, requiredFields); len(missing) != 0 {
			return fmt.Errorf("%s:Action:%s:%v", utils.ErrMandatoryIeMissing.Error(), at.ActionsId, missing)
		}
	}
	if !attrs.Overwrite {
		if exists, err := self.RatingDb.HasData(utils.ACTION_PLAN_PREFIX, attrs.Id); err != nil {
			return utils.NewErrServerError(err)
		} else if exists {
			return utils.ErrExists
		}
	}
	ap := &engine.ActionPlan{
		Id: attrs.Id,
	}
	for _, apiAtm := range attrs.ActionPlan {
		if exists, err := self.RatingDb.HasData(utils.ACTION_PREFIX, apiAtm.ActionsId); err != nil {
			return utils.NewErrServerError(err)
		} else if !exists {
			return fmt.Errorf("%s:%s", utils.ErrBrokenReference.Error(), apiAtm.ActionsId)
		}
		timing := new(engine.RITiming)
		timing.Years.Parse(apiAtm.Years, ";")
		timing.Months.Parse(apiAtm.Months, ";")
		timing.MonthDays.Parse(apiAtm.MonthDays, ";")
		timing.WeekDays.Parse(apiAtm.WeekDays, ";")
		timing.StartTime = apiAtm.Time
		ap.ActionTimings = append(ap.ActionTimings, &engine.ActionTiming{
			Uuid:      utils.GenUUID(),
			Weight:    apiAtm.Weight,
			Timing:    &engine.RateInterval{Timing: timing},
			ActionsID: apiAtm.ActionsId,
		})
	}
	if err := self.RatingDb.SetActionPlan(ap.Id, ap, true, utils.NonTransactional); err != nil {
		return utils.NewErrServerError(err)
	}
	if err = self.RatingDb.CacheDataFromDB(utils.ACTION_PLAN_PREFIX, []string{ap.Id}, true); err != nil {
		return utils.NewErrServerError(err)
	}
	if attrs.ReloadScheduler {
		sched := self.ServManager.GetScheduler()
		if sched == nil {
			return errors.New(utils.SchedulerNotRunningCaps)
		}
		sched.Reload()
	}
	*reply = OK
	return nil
}
Example #5
0
func (self *ApierV1) SetActionPlan(attrs AttrSetActionPlan, reply *string) error {
	if missing := utils.MissingStructFields(&attrs, []string{"Id", "ActionPlan"}); len(missing) != 0 {
		return utils.NewErrMandatoryIeMissing(missing...)
	}
	for _, at := range attrs.ActionPlan {
		requiredFields := []string{"ActionsId", "Time", "Weight"}
		if missing := utils.MissingStructFields(at, requiredFields); len(missing) != 0 {
			return fmt.Errorf("%s:Action:%s:%v", utils.ErrMandatoryIeMissing.Error(), at.ActionsId, missing)
		}
	}
	if !attrs.Overwrite {
		if exists, err := self.RatingDb.HasData(utils.ACTION_PLAN_PREFIX, attrs.Id); err != nil {
			return utils.NewErrServerError(err)
		} else if exists {
			return utils.ErrExists
		}
	}
	storeAtms := make(engine.ActionPlans, len(attrs.ActionPlan))
	for idx, apiAtm := range attrs.ActionPlan {
		if exists, err := self.RatingDb.HasData(utils.ACTION_PREFIX, apiAtm.ActionsId); err != nil {
			return utils.NewErrServerError(err)
		} else if !exists {
			return fmt.Errorf("%s:%s", utils.ErrBrokenReference.Error(), apiAtm.ActionsId)
		}
		timing := new(engine.RITiming)
		timing.Years.Parse(apiAtm.Years, ";")
		timing.Months.Parse(apiAtm.Months, ";")
		timing.MonthDays.Parse(apiAtm.MonthDays, ";")
		timing.WeekDays.Parse(apiAtm.WeekDays, ";")
		timing.StartTime = apiAtm.Time
		at := &engine.ActionPlan{
			Uuid:      utils.GenUUID(),
			Id:        attrs.Id,
			Weight:    apiAtm.Weight,
			Timing:    &engine.RateInterval{Timing: timing},
			ActionsId: apiAtm.ActionsId,
		}
		storeAtms[idx] = at
	}
	if err := self.RatingDb.SetActionPlans(attrs.Id, storeAtms); err != nil {
		return utils.NewErrServerError(err)
	}
	self.RatingDb.CacheRatingPrefixValues(map[string][]string{utils.ACTION_PLAN_PREFIX: []string{utils.ACTION_PLAN_PREFIX + attrs.Id}})
	if attrs.ReloadScheduler {
		if self.Sched == nil {
			return errors.New("SCHEDULER_NOT_ENABLED")
		}
		self.Sched.LoadActionPlans(self.RatingDb)
		self.Sched.Restart()
	}
	*reply = OK
	return nil
}
Example #6
0
func (self *ApierV1) SetActions(attrs V1AttrSetActions, reply *string) (err error) {
	if missing := utils.MissingStructFields(&attrs, []string{"ActionsId", "Actions"}); len(missing) != 0 {
		return utils.NewErrMandatoryIeMissing(missing...)
	}
	for _, action := range attrs.Actions {
		requiredFields := []string{"Identifier", "Weight"}
		if action.BalanceType != "" { // Add some inter-dependent parameters - if balanceType then we are not talking about simply calling actions
			requiredFields = append(requiredFields, "Direction", "Units")
		}
		if missing := utils.MissingStructFields(action, requiredFields); len(missing) != 0 {
			return fmt.Errorf("%s:Action:%s:%v", utils.ErrMandatoryIeMissing.Error(), action.Identifier, missing)
		}
	}
	if !attrs.Overwrite {
		if exists, err := self.RatingDb.HasData(utils.ACTION_PREFIX, attrs.ActionsId); err != nil {
			return utils.NewErrServerError(err)
		} else if exists {
			return utils.ErrExists
		}
	}
	storeActions := make(engine.Actions, len(attrs.Actions))
	for idx, apiAct := range attrs.Actions {
		a := &engine.Action{
			Id:               attrs.ActionsId,
			ActionType:       apiAct.Identifier,
			Weight:           apiAct.Weight,
			ExpirationString: apiAct.ExpiryTime,
			ExtraParameters:  apiAct.ExtraParameters,
			Filter:           apiAct.Filter,
			Balance: &engine.BalanceFilter{ // TODO: update this part
				Uuid:           utils.StringPointer(apiAct.BalanceUuid),
				ID:             utils.StringPointer(apiAct.BalanceId),
				Type:           utils.StringPointer(apiAct.BalanceType),
				Value:          &utils.ValueFormula{Static: apiAct.Units},
				Weight:         apiAct.BalanceWeight,
				Directions:     utils.StringMapPointer(utils.ParseStringMap(apiAct.Directions)),
				DestinationIDs: utils.StringMapPointer(utils.ParseStringMap(apiAct.DestinationIds)),
				RatingSubject:  utils.StringPointer(apiAct.RatingSubject),
				SharedGroups:   utils.StringMapPointer(utils.ParseStringMap(apiAct.SharedGroups)),
			},
		}
		storeActions[idx] = a
	}
	if err := self.RatingDb.SetActions(attrs.ActionsId, storeActions, utils.NonTransactional); err != nil {
		return utils.NewErrServerError(err)
	}
	if err = self.RatingDb.CacheDataFromDB(utils.ACTION_PREFIX, []string{attrs.ActionsId}, true); err != nil {
		utils.NewErrServerError(err)
	}
	*reply = OK
	return nil
}
Example #7
0
func (self *ApierV1) SetActionPlan(attrs AttrSetActionPlan, reply *string) error {
	if missing := utils.MissingStructFields(&attrs, []string{"Id", "ActionPlan"}); len(missing) != 0 {
		return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing)
	}
	for _, at := range attrs.ActionPlan {
		requiredFields := []string{"ActionsId", "Time", "Weight"}
		if missing := utils.MissingStructFields(at, requiredFields); len(missing) != 0 {
			return fmt.Errorf("%s:Action:%s:%v", utils.ERR_MANDATORY_IE_MISSING, at.ActionsId, missing)
		}
	}
	if !attrs.Overwrite {
		if exists, err := self.AccountDb.HasData(engine.ACTION_TIMING_PREFIX, attrs.Id); err != nil {
			return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error())
		} else if exists {
			return errors.New(utils.ERR_EXISTS)
		}
	}
	storeAtms := make(engine.ActionPlan, len(attrs.ActionPlan))
	for idx, apiAtm := range attrs.ActionPlan {
		if exists, err := self.AccountDb.HasData(engine.ACTION_PREFIX, apiAtm.ActionsId); err != nil {
			return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error())
		} else if !exists {
			return fmt.Errorf("%s:%s", utils.ERR_BROKEN_REFERENCE, err.Error())
		}
		timing := new(engine.RITiming)
		timing.Years.Parse(apiAtm.Years, ";")
		timing.Months.Parse(apiAtm.Months, ";")
		timing.MonthDays.Parse(apiAtm.MonthDays, ";")
		timing.WeekDays.Parse(apiAtm.WeekDays, ";")
		timing.StartTime = apiAtm.Time
		at := &engine.ActionTiming{
			Uuid:      utils.GenUUID(),
			Id:        attrs.Id,
			Weight:    apiAtm.Weight,
			Timing:    &engine.RateInterval{Timing: timing},
			ActionsId: apiAtm.ActionsId,
		}
		storeAtms[idx] = at
	}
	if err := self.AccountDb.SetActionTimings(attrs.Id, storeAtms); err != nil {
		return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error())
	}
	if attrs.ReloadScheduler {
		if self.Sched == nil {
			return errors.New("SCHEDULER_NOT_ENABLED")
		}
		self.Sched.LoadActionTimings(self.AccountDb)
		self.Sched.Restart()
	}
	*reply = OK
	return nil
}
Example #8
0
func (self *ApierV1) SetActions(attrs utils.AttrSetActions, reply *string) error {
	if missing := utils.MissingStructFields(&attrs, []string{"ActionsId", "Actions"}); len(missing) != 0 {
		return utils.NewErrMandatoryIeMissing(missing...)
	}
	for _, action := range attrs.Actions {
		requiredFields := []string{"Identifier", "Weight"}
		if action.BalanceType != "" { // Add some inter-dependent parameters - if balanceType then we are not talking about simply calling actions
			requiredFields = append(requiredFields, "Direction", "Units")
		}
		if missing := utils.MissingStructFields(action, requiredFields); len(missing) != 0 {
			return fmt.Errorf("%s:Action:%s:%v", utils.ErrMandatoryIeMissing.Error(), action.Identifier, missing)
		}
	}
	if !attrs.Overwrite {
		if exists, err := self.RatingDb.HasData(utils.ACTION_PREFIX, attrs.ActionsId); err != nil {
			return utils.NewErrServerError(err)
		} else if exists {
			return utils.ErrExists
		}
	}
	storeActions := make(engine.Actions, len(attrs.Actions))
	for idx, apiAct := range attrs.Actions {
		a := &engine.Action{
			Id:               utils.GenUUID(),
			ActionType:       apiAct.Identifier,
			BalanceType:      apiAct.BalanceType,
			Weight:           apiAct.Weight,
			ExpirationString: apiAct.ExpiryTime,
			ExtraParameters:  apiAct.ExtraParameters,
			Filter:           apiAct.Filter,
			Balance: &engine.Balance{
				Uuid:           utils.GenUUID(),
				Id:             apiAct.BalanceId,
				Value:          apiAct.Units,
				Weight:         apiAct.BalanceWeight,
				Directions:     utils.ParseStringMap(apiAct.Directions),
				DestinationIds: utils.ParseStringMap(apiAct.DestinationIds),
				RatingSubject:  apiAct.RatingSubject,
				SharedGroups:   utils.ParseStringMap(apiAct.SharedGroups),
			},
		}
		storeActions[idx] = a
	}
	if err := self.RatingDb.SetActions(attrs.ActionsId, storeActions); err != nil {
		return utils.NewErrServerError(err)
	}
	self.RatingDb.CacheRatingPrefixValues(map[string][]string{utils.ACTION_PREFIX: []string{utils.ACTION_PREFIX + attrs.ActionsId}})
	*reply = OK
	return nil
}
Example #9
0
// Sets a specific rating profile working with data directly in the RatingDb without involving storDb
func (self *ApierV1) SetRatingProfile(attrs AttrSetRatingProfile, reply *string) error {
	if missing := utils.MissingStructFields(&attrs, []string{"Tenant", "TOR", "Direction", "Subject", "RatingPlanActivations"}); len(missing) != 0 {
		return utils.NewErrMandatoryIeMissing(missing...)
	}
	for _, rpa := range attrs.RatingPlanActivations {
		if missing := utils.MissingStructFields(rpa, []string{"ActivationTime", "RatingPlanId"}); len(missing) != 0 {
			return fmt.Errorf("%s:RatingPlanActivation:%v", utils.ErrMandatoryIeMissing.Error(), missing)
		}
	}
	tpRpf := utils.TPRatingProfile{Tenant: attrs.Tenant, Category: attrs.Category, Direction: attrs.Direction, Subject: attrs.Subject}
	keyId := tpRpf.KeyId()
	var rpfl *engine.RatingProfile
	if !attrs.Overwrite {
		if exists, err := self.RatingDb.HasData(utils.RATING_PROFILE_PREFIX, keyId); err != nil {
			return utils.NewErrServerError(err)
		} else if exists {
			var err error
			if rpfl, err = self.RatingDb.GetRatingProfile(keyId, false); err != nil {
				return utils.NewErrServerError(err)
			}
		}
	}
	if rpfl == nil {
		rpfl = &engine.RatingProfile{Id: keyId, RatingPlanActivations: make(engine.RatingPlanActivations, 0)}
	}
	for _, ra := range attrs.RatingPlanActivations {
		at, err := utils.ParseTimeDetectLayout(ra.ActivationTime, self.Config.DefaultTimezone)
		if err != nil {
			return fmt.Errorf(fmt.Sprintf("%s:Cannot parse activation time from %v", utils.ErrServerError.Error(), ra.ActivationTime))
		}
		if exists, err := self.RatingDb.HasData(utils.RATING_PLAN_PREFIX, ra.RatingPlanId); err != nil {
			return utils.NewErrServerError(err)
		} else if !exists {
			return fmt.Errorf(fmt.Sprintf("%s:RatingPlanId:%s", utils.ErrNotFound.Error(), ra.RatingPlanId))
		}
		rpfl.RatingPlanActivations = append(rpfl.RatingPlanActivations, &engine.RatingPlanActivation{ActivationTime: at, RatingPlanId: ra.RatingPlanId,
			FallbackKeys: utils.FallbackSubjKeys(tpRpf.Direction, tpRpf.Tenant, tpRpf.Category, ra.FallbackSubjects)})
	}
	if err := self.RatingDb.SetRatingProfile(rpfl); err != nil {
		return utils.NewErrServerError(err)
	}
	//Automatic cache of the newly inserted rating profile
	if err := self.RatingDb.CacheRatingPrefixValues(map[string][]string{
		utils.RATING_PROFILE_PREFIX: []string{utils.RATING_PROFILE_PREFIX + keyId},
	}); err != nil {
		return err
	}
	*reply = OK
	return nil
}
Example #10
0
func (self *ApierV1) SetActions(attrs AttrSetActions, reply *string) error {
	if missing := utils.MissingStructFields(&attrs, []string{"ActionsId", "Actions"}); len(missing) != 0 {
		return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing)
	}
	for _, action := range attrs.Actions {
		requiredFields := []string{"Identifier", "Weight"}
		if action.BalanceType != "" { // Add some inter-dependent parameters - if balanceType then we are not talking about simply calling actions
			requiredFields = append(requiredFields, "Direction", "Units")
		}
		if missing := utils.MissingStructFields(action, requiredFields); len(missing) != 0 {
			return fmt.Errorf("%s:Action:%s:%v", utils.ERR_MANDATORY_IE_MISSING, action.Identifier, missing)
		}
	}
	if !attrs.Overwrite {
		if exists, err := self.AccountDb.HasData(engine.ACTION_PREFIX, attrs.ActionsId); err != nil {
			return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error())
		} else if exists {
			return errors.New(utils.ERR_EXISTS)
		}
	}
	storeActions := make(engine.Actions, len(attrs.Actions))
	for idx, apiAct := range attrs.Actions {
		a := &engine.Action{
			Id:               utils.GenUUID(),
			ActionType:       apiAct.Identifier,
			BalanceType:      apiAct.BalanceType,
			Direction:        apiAct.Direction,
			Weight:           apiAct.Weight,
			ExpirationString: apiAct.ExpiryTime,
			ExtraParameters:  apiAct.ExtraParameters,
			Balance: &engine.Balance{
				Uuid:          utils.GenUUID(),
				Value:         apiAct.Units,
				Weight:        apiAct.BalanceWeight,
				DestinationId: apiAct.DestinationId,
				RatingSubject: apiAct.RatingSubject,
				SharedGroup:   apiAct.SharedGroup,
			},
		}
		storeActions[idx] = a
	}
	if err := self.AccountDb.SetActions(attrs.ActionsId, storeActions); err != nil {
		return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error())
	}
	didNotChange := []string{}
	self.AccountDb.CacheAccounting(nil, didNotChange, didNotChange, didNotChange)
	*reply = OK
	return nil
}
Example #11
0
// Queries specific AccountActions profile on tariff plan
func (self *ApierV1) GetTPAccountActionsByLoadId(attrs utils.TPAccountActions, reply *[]*utils.TPAccountActions) error {
	mndtryFlds := []string{"TPid", "LoadId"}
	if len(attrs.Account) != 0 { // If account provided as filter, make all related fields mandatory
		mndtryFlds = append(mndtryFlds, "Tenant", "Account", "Direction")
	}
	if missing := utils.MissingStructFields(&attrs, mndtryFlds); len(missing) != 0 { //Params missing
		return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing)
	}
	if aa, err := self.StorDb.GetTpAccountActions(&attrs); err != nil {
		return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error())
	} else if len(aa) == 0 {
		return errors.New(utils.ERR_NOT_FOUND)
	} else {
		var acts []*utils.TPAccountActions
		if len(attrs.Account) != 0 {
			acts = []*utils.TPAccountActions{aa[attrs.KeyId()]}
		} else {
			for _, actLst := range aa {
				acts = append(acts, actLst)
			}
		}
		*reply = acts
	}
	return nil
}
Example #12
0
// Returns a list of ActionTriggers on an account
func (self *ApierV1) RemAccountActionTriggers(attrs AttrRemAcntActionTriggers, reply *string) error {
	if missing := utils.MissingStructFields(&attrs, []string{"Tenant", "Account", "Direction"}); len(missing) != 0 {
		return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing)
	}
	balanceId := utils.AccountKey(attrs.Tenant, attrs.Account, attrs.Direction)
	_, err := engine.AccLock.Guard(balanceId, func() (float64, error) {
		ub, err := self.AccountDb.GetAccount(balanceId)
		if err != nil {
			return 0, err
		}
		for idx, actr := range ub.ActionTriggers {
			if len(attrs.ActionTriggerId) != 0 && actr.Id != attrs.ActionTriggerId { // Empty actionTriggerId will match always
				continue
			}
			if len(ub.ActionTriggers) != 1 { // Remove by index
				ub.ActionTriggers[idx], ub.ActionTriggers = ub.ActionTriggers[len(ub.ActionTriggers)-1], ub.ActionTriggers[:len(ub.ActionTriggers)-1]
			} else { // For last item, simply reinit the slice
				ub.ActionTriggers = make(engine.ActionTriggerPriotityList, 0)
			}
		}
		if err := self.AccountDb.SetAccount(ub); err != nil {
			return 0, err
		}
		return 0, nil
	})
	if err != nil {
		return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error())
	}
	*reply = OK
	return nil
}
Example #13
0
// Queries specific DerivedCharge on tariff plan
func (self *ApierV1) GetTPAccountActions(attrs AttrGetTPAccountActions, reply *utils.TPAccountActions) error {
	if missing := utils.MissingStructFields(&attrs, []string{"TPid", "AccountActionsId"}); len(missing) != 0 { //Params missing
		return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing)
	}
	tmpAa := &utils.TPAccountActions{TPid: attrs.TPid}
	if err := tmpAa.SetAccountActionsId(attrs.AccountActionsId); err != nil {
		return err
	}
	if aas, err := self.StorDb.GetTpAccountActions(tmpAa); err != nil {
		return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error())
	} else if len(aas) == 0 {
		return errors.New(utils.ERR_NOT_FOUND)
	} else {
		aa := aas[tmpAa.KeyId()]
		tpdc := utils.TPAccountActions{
			TPid:             attrs.TPid,
			ActionPlanId:     aa.ActionPlanId,
			ActionTriggersId: aa.ActionTriggersId,
		}
		if err := tpdc.SetAccountActionsId(attrs.AccountActionsId); err != nil {
			return err
		}
		*reply = tpdc
	}
	return nil
}
Example #14
0
func (self *ApierV1) GetAccountActionPlan(attrs AttrAcntAction, reply *[]*AccountActionTiming) error {
	if missing := utils.MissingStructFields(&attrs, []string{"Tenant", "Account"}); len(missing) != 0 {
		return utils.NewErrMandatoryIeMissing(strings.Join(missing, ","), "")
	}
	accountATs := make([]*AccountActionTiming, 0) // needs to be initialized if remains empty
	allAPs, err := self.RatingDb.GetAllActionPlans()
	if err != nil {
		return utils.NewErrServerError(err)
	}
	accID := utils.AccountKey(attrs.Tenant, attrs.Account)
	for _, ap := range allAPs {
		if ap == nil {
			continue
		}
		if _, exists := ap.AccountIDs[accID]; exists {
			for _, at := range ap.ActionTimings {
				accountATs = append(accountATs, &AccountActionTiming{
					ActionPlanId: ap.Id,
					Uuid:         at.Uuid,
					ActionsId:    at.ActionsID,
					NextExecTime: at.GetNextStartTime(time.Now()),
				})
			}
		}

	}
	*reply = accountATs
	return nil
}
Example #15
0
// Queries specific DerivedCharge on tariff plan
func (self *ApierV1) GetTPAccountActions(attrs AttrGetTPAccountActions, reply *utils.TPAccountActions) error {
	if missing := utils.MissingStructFields(&attrs, []string{"TPid", "AccountActionsId"}); len(missing) != 0 { //Params missing
		return utils.NewErrMandatoryIeMissing(missing...)
	}
	tmpAa := &utils.TPAccountActions{TPid: attrs.TPid}
	if err := tmpAa.SetAccountActionsId(attrs.AccountActionsId); err != nil {
		return err
	}
	tmpAaa := engine.APItoModelAccountAction(tmpAa)
	if aas, err := self.StorDb.GetTpAccountActions(tmpAaa); err != nil {
		return utils.NewErrServerError(err)
	} else if len(aas) == 0 {
		return utils.ErrNotFound
	} else {
		tpAaa, err := engine.TpAccountActions(aas).GetAccountActions()
		if err != nil {
			return err
		}
		aa := tpAaa[tmpAa.KeyId()]
		tpdc := utils.TPAccountActions{
			TPid:             attrs.TPid,
			ActionPlanId:     aa.ActionPlanId,
			ActionTriggersId: aa.ActionTriggersId,
		}
		if err := tpdc.SetAccountActionsId(attrs.AccountActionsId); err != nil {
			return err
		}
		*reply = tpdc
	}
	return nil
}
Example #16
0
// Queries specific AccountActions profile on tariff plan
func (self *ApierV1) GetTPAccountActionsByLoadId(attrs utils.TPAccountActions, reply *[]*utils.TPAccountActions) error {
	mndtryFlds := []string{"TPid", "LoadId"}
	if len(attrs.Account) != 0 { // If account provided as filter, make all related fields mandatory
		mndtryFlds = append(mndtryFlds, "Tenant", "Account")
	}
	if missing := utils.MissingStructFields(&attrs, mndtryFlds); len(missing) != 0 { //Params missing
		return utils.NewErrMandatoryIeMissing(missing...)
	}
	aas := engine.APItoModelAccountAction(&attrs)
	if aa, err := self.StorDb.GetTpAccountActions(aas); err != nil {
		return utils.NewErrServerError(err)
	} else if len(aa) == 0 {
		return utils.ErrNotFound
	} else {

		tpAa, err := engine.TpAccountActions(aa).GetAccountActions()
		if err != nil {
			return err
		}
		var acts []*utils.TPAccountActions
		if len(attrs.Account) != 0 {
			acts = []*utils.TPAccountActions{tpAa[attrs.KeyId()]}
		} else {
			for _, actLst := range tpAa {
				acts = append(acts, actLst)
			}
		}
		*reply = acts
	}
	return nil
}
Example #17
0
// Queries specific RatingProfile on tariff plan
func (self *ApierV1) GetTPRatingProfile(attrs AttrGetTPRatingProfile, reply *utils.TPRatingProfile) error {
	if missing := utils.MissingStructFields(&attrs, []string{"TPid", "RatingProfileId"}); len(missing) != 0 { //Params missing
		return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing)
	}
	tmpRpf := &utils.TPRatingProfile{TPid: attrs.TPid}
	if err := tmpRpf.SetRatingProfilesId(attrs.RatingProfileId); err != nil {
		return err
	}
	if rpfs, err := self.StorDb.GetTpRatingProfiles(tmpRpf); err != nil {
		return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error())
	} else if len(rpfs) == 0 {
		return errors.New(utils.ERR_NOT_FOUND)
	} else {
		rpf := rpfs[tmpRpf.KeyId()]
		tpdc := utils.TPRatingProfile{
			TPid: attrs.TPid,
			RatingPlanActivations: rpf.RatingPlanActivations,
		}
		if err := tpdc.SetRatingProfilesId(attrs.RatingProfileId); err != nil {
			return err
		}
		*reply = tpdc
	}
	return nil
}
Example #18
0
// Creates a new ActionTimings profile within a tariff plan
func (self *ApierV1) SetTPActionPlan(attrs utils.TPActionPlan, reply *string) error {
	if missing := utils.MissingStructFields(&attrs, []string{"TPid", "Id", "ActionPlan"}); len(missing) != 0 {
		return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing)
	}
	for _, at := range attrs.ActionPlan {
		requiredFields := []string{"ActionsId", "TimingId", "Weight"}
		if missing := utils.MissingStructFields(at, requiredFields); len(missing) != 0 {
			return fmt.Errorf("%s:Action:%s:%v", utils.ERR_MANDATORY_IE_MISSING, at.ActionsId, missing)
		}
	}
	if err := self.StorDb.SetTPActionTimings(attrs.TPid, map[string][]*utils.TPActionTiming{attrs.Id: attrs.ActionPlan}); err != nil {
		return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error())
	}
	*reply = "OK"
	return nil
}
Example #19
0
// Returns a list of ActionTriggers on an account
func (self *ApierV1) RemAccountActionTriggers(attrs AttrRemAcntActionTriggers, reply *string) error {
	if missing := utils.MissingStructFields(&attrs, []string{"Tenant", "Account"}); len(missing) != 0 {
		return utils.NewErrMandatoryIeMissing(missing...)
	}
	balanceId := utils.AccountKey(attrs.Tenant, attrs.Account)
	_, err := engine.Guardian.Guard(func() (interface{}, error) {
		ub, err := self.AccountDb.GetAccount(balanceId)
		if err != nil {
			return 0, err
		}
		nactrs := make(engine.ActionTriggers, 0)
		for _, actr := range ub.ActionTriggers {
			match, _ := regexp.MatchString(attrs.ActionTriggersId, actr.Id)
			if len(attrs.ActionTriggersId) != 0 && !match {
				nactrs = append(nactrs, actr)
			}
		}
		ub.ActionTriggers = nactrs
		if err := self.AccountDb.SetAccount(ub); err != nil {
			return 0, err
		}
		return 0, nil
	}, 0, balanceId)
	if err != nil {
		return utils.NewErrServerError(err)
	}
	*reply = OK
	return nil
}
Example #20
0
func (self *ApierV1) RemoveAccount(attr utils.AttrRemoveAccount, reply *string) error {
	if missing := utils.MissingStructFields(&attr, []string{"Tenant", "Account"}); len(missing) != 0 {
		return utils.NewErrMandatoryIeMissing(missing...)
	}
	dirtyActionPlans := make(map[string]*engine.ActionPlan)
	accID := utils.AccountKey(attr.Tenant, attr.Account)
	_, err := engine.Guardian.Guard(func() (interface{}, error) {
		// remove it from all action plans
		_, err := engine.Guardian.Guard(func() (interface{}, error) {
			actionPlansMap, err := self.RatingDb.GetAllActionPlans()
			if err == utils.ErrNotFound {
				// no action plans
				return 0, nil
			}
			if err != nil {
				return 0, err
			}

			for actionPlanID, ap := range actionPlansMap {
				if _, exists := ap.AccountIDs[accID]; exists {
					delete(ap.AccountIDs, accID)
					dirtyActionPlans[actionPlanID] = ap
				}
			}

			var actionPlansCacheIds []string
			for actionPlanID, ap := range dirtyActionPlans {
				if err := self.RatingDb.SetActionPlan(actionPlanID, ap, true); err != nil {
					return 0, err
				}
				actionPlansCacheIds = append(actionPlansCacheIds, utils.ACTION_PLAN_PREFIX+actionPlanID)
			}
			if len(actionPlansCacheIds) > 0 {
				// update cache
				self.RatingDb.CacheRatingPrefixValues("RemoveAccountAPI", map[string][]string{
					utils.ACTION_PLAN_PREFIX: actionPlansCacheIds})
			}
			return 0, nil
		}, 0, utils.ACTION_PLAN_PREFIX)
		if err != nil {
			return 0, err
		}

		if err := self.AccountDb.RemoveAccount(accID); err != nil {
			return 0, err
		}
		return 0, nil
	}, 0, accID)
	if err != nil {
		return utils.NewErrServerError(err)
	}
	if attr.ReloadScheduler && len(dirtyActionPlans) > 0 {
		// reload scheduler
		if self.Sched != nil {
			self.Sched.Reload(true)
		}
	}
	*reply = OK
	return nil
}
Example #21
0
// Remove aliases configured for a rating profile subject
func (self *ApierV1) RemRatingSubjectAliases(tenantRatingSubject engine.TenantRatingSubject, reply *string) error {
	if missing := utils.MissingStructFields(&tenantRatingSubject, []string{"Tenant", "Subject"}); len(missing) != 0 {
		return utils.NewErrMandatoryIeMissing(missing...)
	}
	aliases := engine.GetAliasService()
	if aliases == nil {
		return errors.New("ALIASES_NOT_ENABLED")
	}
	var reverseAliases map[string][]*engine.Alias
	if err := aliases.Call("AliasesV1.GetReverseAlias", &engine.AttrReverseAlias{Target: "Subject", Alias: tenantRatingSubject.Subject, Context: utils.ALIAS_CONTEXT_RATING}, &reverseAliases); err != nil {
		return utils.NewErrServerError(err)
	}
	var ignr string
	for _, aliass := range reverseAliases {
		for _, alias := range aliass {
			if alias.Tenant != tenantRatingSubject.Tenant {
				continue // From another tenant
			}
			if err := aliases.Call("AliasesV1.RemoveAlias", alias, &ignr); err != nil {
				return utils.NewErrServerError(err)
			}
		}
	}
	*reply = utils.OK
	return nil
}
Example #22
0
func (self *ApierV1) SetDestination(attrs utils.AttrSetDestination, reply *string) (err error) {
	if missing := utils.MissingStructFields(&attrs, []string{"Id", "Prefixes"}); len(missing) != 0 {
		return utils.NewErrMandatoryIeMissing(missing...)
	}
	dest := &engine.Destination{Id: attrs.Id, Prefixes: attrs.Prefixes}
	var oldDest *engine.Destination
	if oldDest, err = self.RatingDb.GetDestination(attrs.Id, false, utils.NonTransactional); err != nil {
		if err != utils.ErrNotFound {
			return utils.NewErrServerError(err)
		}
	} else if !attrs.Overwrite {
		return utils.ErrExists
	}
	if err := self.RatingDb.SetDestination(dest, utils.NonTransactional); err != nil {
		return utils.NewErrServerError(err)
	}
	if err = self.RatingDb.CacheDataFromDB(utils.DESTINATION_PREFIX, []string{attrs.Id}, true); err != nil {
		return
	}
	if err = self.RatingDb.UpdateReverseDestination(oldDest, dest, utils.NonTransactional); err != nil {
		return
	}
	if err = self.RatingDb.CacheDataFromDB(utils.REVERSE_DESTINATION_PREFIX, dest.Prefixes, true); err != nil {
		return
	}
	*reply = OK
	return nil
}
Example #23
0
func (self *ApierV1) ImportTariffPlanFromFolder(attrs utils.AttrImportTPFromFolder, reply *string) error {
	if missing := utils.MissingStructFields(&attrs, []string{"TPid", "FolderPath"}); len(missing) != 0 {
		return utils.NewErrMandatoryIeMissing(missing...)
	}
	if len(attrs.CsvSeparator) == 0 {
		attrs.CsvSeparator = ","
	}
	if fi, err := os.Stat(attrs.FolderPath); err != nil {
		if strings.HasSuffix(err.Error(), "no such file or directory") {
			return utils.ErrInvalidPath
		}
		return utils.NewErrServerError(err)
	} else if !fi.IsDir() {
		return utils.ErrInvalidPath
	}
	csvImporter := engine.TPCSVImporter{
		TPid:     attrs.TPid,
		StorDb:   self.StorDb,
		DirPath:  attrs.FolderPath,
		Sep:      rune(attrs.CsvSeparator[0]),
		Verbose:  false,
		ImportId: attrs.RunId,
	}
	if err := csvImporter.Run(); err != nil {
		return utils.NewErrServerError(err)
	}
	*reply = utils.OK
	return nil
}
Example #24
0
// Load derived chargers from storDb into dataDb.
func (self *ApierV1) LoadDerivedChargers(attrs utils.TPDerivedChargers, reply *string) error {
	if missing := utils.MissingStructFields(&attrs, []string{"TPid", "LoadId", "Tenant", "Category", "Direction", "Account", "Subject"}); len(missing) != 0 {
		return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing)
	}
	if attrs.Loadid == utils.EMPTY {
		attrs.Loadid = ""
	}
	if attrs.Tenant == utils.EMPTY {
		attrs.Tenant = ""
	}
	if attrs.Category == utils.EMPTY {
		attrs.Category = ""
	}
	if attrs.Direction == utils.EMPTY {
		attrs.Direction = ""
	}
	if attrs.Account == utils.EMPTY {
		attrs.Account = ""
	}
	if attrs.Subject == utils.EMPTY {
		attrs.Subject = ""
	}
	dbReader := engine.NewDbReader(self.StorDb, self.RatingDb, self.AccountDb, attrs.TPid)
	if err := dbReader.LoadDerivedChargersFiltered(&attrs); err != nil {
		return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error())
	}
	//Automatic cache of the newly inserted rating plan
	didNotChange := []string{}
	if err := self.AccountDb.CacheAccounting(didNotChange, didNotChange, didNotChange, nil); err != nil {
		return err
	}
	*reply = OK
	return nil
}
Example #25
0
func (self *ApierV1) RemoveActionTrigger(attr AttrRemoveActionTrigger, reply *string) error {
	if missing := utils.MissingStructFields(&attr, []string{"GroupID"}); len(missing) != 0 {
		return utils.NewErrMandatoryIeMissing(missing...)
	}
	if attr.UniqueID == "" {
		err := self.RatingDb.RemoveActionTriggers(attr.GroupID, utils.NonTransactional)
		if err != nil {
			*reply = err.Error()
		} else {
			*reply = utils.OK
		}
		return err
	} else {
		atrs, err := self.RatingDb.GetActionTriggers(attr.GroupID, false, utils.NonTransactional)
		if err != nil {
			*reply = err.Error()
			return err
		}
		var remainingAtrs engine.ActionTriggers
		for _, atr := range atrs {
			if atr.UniqueID == attr.UniqueID {
				continue
			}
			remainingAtrs = append(remainingAtrs, atr)
		}
		// set the cleared list back
		err = self.RatingDb.SetActionTriggers(attr.GroupID, remainingAtrs, utils.NonTransactional)
		if err != nil {
			*reply = err.Error()
		} else {
			*reply = utils.OK
		}
		return err
	}
}
Example #26
0
// Queries specific RatingProfile on tariff plan
func (self *ApierV1) GetTPRatingProfilesByLoadId(attrs utils.TPRatingProfile, reply *[]*utils.TPRatingProfile) error {
	mndtryFlds := []string{"TPid", "LoadId"}
	if len(attrs.Subject) != 0 { // If Subject provided as filter, make all related fields mandatory
		mndtryFlds = append(mndtryFlds, "Tenant", "TOR", "Direction", "Subject")
	}
	if missing := utils.MissingStructFields(&attrs, mndtryFlds); len(missing) != 0 { //Params missing
		return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing)
	}
	if dr, err := self.StorDb.GetTpRatingProfiles(&attrs); err != nil {
		return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error())
	} else if dr == nil {
		return errors.New(utils.ERR_NOT_FOUND)
	} else {
		var rpfs []*utils.TPRatingProfile
		if len(attrs.Subject) != 0 {
			rpfs = []*utils.TPRatingProfile{dr[attrs.KeyId()]}
		} else {
			for _, rpfLst := range dr {
				rpfs = append(rpfs, rpfLst)
			}
		}
		*reply = rpfs
	}
	return nil
}
Example #27
0
func (self *ApierV1) RemoveAccountActionTriggers(attr AttrRemoveAccountActionTriggers, reply *string) error {
	if missing := utils.MissingStructFields(&attr, []string{"Tenant", "Account"}); len(missing) != 0 {
		return utils.NewErrMandatoryIeMissing(missing...)
	}
	accID := utils.AccountKey(attr.Tenant, attr.Account)
	_, err := engine.Guardian.Guard(func() (interface{}, error) {
		var account *engine.Account
		if acc, err := self.AccountDb.GetAccount(accID); err == nil {
			account = acc
		} else {
			return 0, err
		}
		var newActionTriggers engine.ActionTriggers
		for _, at := range account.ActionTriggers {
			if (attr.UniqueID == "" || at.UniqueID == attr.UniqueID) &&
				(attr.GroupID == "" || at.ID == attr.GroupID) {
				// remove action trigger
				continue
			}
			newActionTriggers = append(newActionTriggers, at)
		}
		account.ActionTriggers = newActionTriggers
		account.InitCounters()
		if err := self.AccountDb.SetAccount(account); err != nil {
			return 0, err
		}
		return 0, nil
	}, 0, accID)
	if err != nil {
		*reply = err.Error()
		return err
	}
	*reply = utils.OK
	return nil
}
Example #28
0
// Queries specific RatingProfile on tariff plan
func (self *ApierV1) GetTPRatingProfile(attrs AttrGetTPRatingProfile, reply *utils.TPRatingProfile) error {
	if missing := utils.MissingStructFields(&attrs, []string{"TPid", "RatingProfileId"}); len(missing) != 0 { //Params missing
		return utils.NewErrMandatoryIeMissing(missing...)
	}
	tmpRpf := &utils.TPRatingProfile{TPid: attrs.TPid}
	if err := tmpRpf.SetRatingProfilesId(attrs.RatingProfileId); err != nil {
		return err
	}
	rpf := engine.APItoModelRatingProfile(tmpRpf)
	if rpfs, err := self.StorDb.GetTpRatingProfiles(&rpf[0]); err != nil {
		return utils.NewErrServerError(err)
	} else if len(rpfs) == 0 {
		return utils.ErrNotFound
	} else {
		rpfMap, err := engine.TpRatingProfiles(rpfs).GetRatingProfiles()
		if err != nil {
			return err
		}
		rpf := rpfMap[tmpRpf.KeyId()]
		tpdc := utils.TPRatingProfile{
			TPid: attrs.TPid,
			RatingPlanActivations: rpf.RatingPlanActivations,
		}
		if err := tpdc.SetRatingProfilesId(attrs.RatingProfileId); err != nil {
			return err
		}
		*reply = tpdc
	}
	return nil
}
Example #29
0
// Queries specific RatingProfile on tariff plan
func (self *ApierV1) GetTPRatingProfilesByLoadId(attrs utils.TPRatingProfile, reply *[]*utils.TPRatingProfile) error {
	mndtryFlds := []string{"TPid", "LoadId"}
	if len(attrs.Subject) != 0 { // If Subject provided as filter, make all related fields mandatory
		mndtryFlds = append(mndtryFlds, "Tenant", "TOR", "Direction", "Subject")
	}
	if missing := utils.MissingStructFields(&attrs, mndtryFlds); len(missing) != 0 { //Params missing
		return utils.NewErrMandatoryIeMissing(missing...)
	}
	rpf := engine.APItoModelRatingProfile(&attrs)
	if dr, err := self.StorDb.GetTpRatingProfiles(&rpf[0]); err != nil {
		return utils.NewErrServerError(err)
	} else if dr == nil {
		return utils.ErrNotFound
	} else {
		rpfMap, err := engine.TpRatingProfiles(dr).GetRatingProfiles()
		if err != nil {
			return err
		}
		var rpfs []*utils.TPRatingProfile
		if len(attrs.Subject) != 0 {
			rpfs = []*utils.TPRatingProfile{rpfMap[attrs.KeyId()]}
		} else {
			for _, rpfLst := range rpfMap {
				rpfs = append(rpfs, rpfLst)
			}
		}
		*reply = rpfs
	}
	return nil
}
Example #30
0
// Ads a new account into dataDb. If already defined, returns success.
func (self *ApierV1) SetAccount(attr utils.AttrSetAccount, reply *string) error {
	if missing := utils.MissingStructFields(&attr, []string{"Tenant", "Direction", "Account"}); len(missing) != 0 {
		return utils.NewErrMandatoryIeMissing(missing...)
	}
	balanceId := utils.AccountKey(attr.Tenant, attr.Account, attr.Direction)
	var ub *engine.Account
	var ats engine.ActionPlans
	_, err := engine.Guardian.Guard(func() (interface{}, error) {
		if bal, _ := self.AccountDb.GetAccount(balanceId); bal != nil {
			ub = bal
		} else { // Not found in db, create it here
			ub = &engine.Account{
				Id: balanceId,
			}
		}

		if len(attr.ActionPlanId) != 0 {
			var err error
			ats, err = self.RatingDb.GetActionPlans(attr.ActionPlanId)
			if err != nil {
				return 0, err
			}
			for _, at := range ats {
				at.AccountIds = append(at.AccountIds, balanceId)
			}
		}
		if attr.AllowNegative != nil {
			ub.AllowNegative = *attr.AllowNegative
		}
		if attr.Disabled != nil {
			ub.Disabled = *attr.Disabled
		}
		// All prepared, save account
		if err := self.AccountDb.SetAccount(ub); err != nil {
			return 0, err
		}
		return 0, nil
	}, 0, balanceId)
	if err != nil {
		return utils.NewErrServerError(err)
	}
	if len(ats) != 0 {
		_, err := engine.Guardian.Guard(func() (interface{}, error) { // ToDo: Try locking it above on read somehow
			if err := self.RatingDb.SetActionPlans(attr.ActionPlanId, ats); err != nil {
				return 0, err
			}
			return 0, nil
		}, 0, utils.ACTION_TIMING_PREFIX)
		if err != nil {
			return utils.NewErrServerError(err)
		}
		if self.Sched != nil {
			self.Sched.LoadActionPlans(self.RatingDb)
			self.Sched.Restart()
		}
	}
	*reply = OK // This will mark saving of the account, error still can show up in actionTimingsId
	return nil
}