Example #1
0
func (tpr *TpReader) LoadAccountActionsFiltered(qriedAA *TpAccountAction) error {
	accountActions, err := tpr.lr.GetTpAccountActions(qriedAA)
	if err != nil {
		return errors.New(err.Error() + ": " + fmt.Sprintf("%+v", qriedAA))
	}
	storAas, err := TpAccountActions(accountActions).GetAccountActions()
	if err != nil {
		return err
	}
	for _, accountAction := range storAas {
		id := accountAction.KeyId()
		var actionsIds []string // collects action ids
		// action timings
		if accountAction.ActionPlanId != "" {
			// get old userBalanceIds
			exitingAccountIds := make(utils.StringMap)
			existingActionPlan, err := tpr.ratingStorage.GetActionPlan(accountAction.ActionPlanId, true)
			if err == nil && existingActionPlan != nil {
				exitingAccountIds = existingActionPlan.AccountIDs
			}

			tpap, err := tpr.lr.GetTpActionPlans(tpr.tpid, accountAction.ActionPlanId)
			if err != nil {
				return errors.New(err.Error() + " (ActionPlan): " + accountAction.ActionPlanId)
			} else if len(tpap) == 0 {
				return fmt.Errorf("no action plan with id <%s>", accountAction.ActionPlanId)
			}
			aps, err := TpActionPlans(tpap).GetActionPlans()
			if err != nil {
				return err
			}
			var actionPlan *ActionPlan
			ats := aps[accountAction.ActionPlanId]
			for _, at := range ats {
				// Check action exists before saving it inside actionTiming key
				// ToDo: try saving the key after the actions was retrieved in order to save one query here.
				if actions, err := tpr.lr.GetTpActions(tpr.tpid, at.ActionsId); err != nil {
					return errors.New(err.Error() + " (Actions): " + at.ActionsId)
				} else if len(actions) == 0 {
					return fmt.Errorf("no action with id <%s>", at.ActionsId)
				}
				var t *utils.TPTiming
				if at.TimingId != utils.ASAP {
					tptm, err := tpr.lr.GetTpTimings(tpr.tpid, at.TimingId)
					if err != nil {
						return errors.New(err.Error() + " (Timing): " + at.TimingId)
					} else if len(tptm) == 0 {
						return fmt.Errorf("no timing with id <%s>", at.TimingId)
					}
					tm, err := TpTimings(tptm).GetTimings()
					if err != nil {
						return err
					}
					t = tm[at.TimingId]
				} else {
					t = tpr.timings[at.TimingId] // *asap
				}
				if actionPlan == nil {
					actionPlan = &ActionPlan{
						Id: accountAction.ActionPlanId,
					}
				}
				actionPlan.ActionTimings = append(actionPlan.ActionTimings, &ActionTiming{
					Uuid:   utils.GenUUID(),
					Weight: at.Weight,
					Timing: &RateInterval{
						Timing: &RITiming{
							Months:    t.Months,
							MonthDays: t.MonthDays,
							WeekDays:  t.WeekDays,
							StartTime: t.StartTime,
						},
					},
					ActionsID: at.ActionsId,
				})
				// collect action ids from timings
				actionsIds = append(actionsIds, at.ActionsId)
				exitingAccountIds[id] = true
				actionPlan.AccountIDs = exitingAccountIds
			}

			// write tasks
			for _, at := range actionPlan.ActionTimings {
				if at.IsASAP() {
					for accID := range actionPlan.AccountIDs {
						t := &Task{
							Uuid:      utils.GenUUID(),
							AccountID: accID,
							ActionsID: at.ActionsID,
						}
						if err = tpr.ratingStorage.PushTask(t); err != nil {
							return err
						}
					}
				}
			}
			// write action plan
			err = tpr.ratingStorage.SetActionPlan(accountAction.ActionPlanId, actionPlan, false)
			if err != nil {
				return errors.New(err.Error() + " (SetActionPlan): " + accountAction.ActionPlanId)
			}
		}
		// action triggers
		var actionTriggers ActionTriggers
		//ActionTriggerPriotityList []*ActionTrigger
		if accountAction.ActionTriggersId != "" {
			tpatrs, err := tpr.lr.GetTpActionTriggers(tpr.tpid, accountAction.ActionTriggersId)
			if err != nil {
				return errors.New(err.Error() + " (ActionTriggers): " + accountAction.ActionTriggersId)
			}
			atrs, err := TpActionTriggers(tpatrs).GetActionTriggers()
			if err != nil {
				return err
			}

			atrsMap := make(map[string][]*ActionTrigger)
			for key, atrsLst := range atrs {
				atrs := make([]*ActionTrigger, len(atrsLst))
				for idx, apiAtr := range atrsLst {
					minSleep, _ := utils.ParseDurationWithSecs(apiAtr.MinSleep)
					balanceExpTime, _ := utils.ParseDate(apiAtr.BalanceExpirationDate)
					expTime, _ := utils.ParseTimeDetectLayout(apiAtr.ExpirationDate, tpr.timezone)
					actTime, _ := utils.ParseTimeDetectLayout(apiAtr.ActivationDate, tpr.timezone)
					if apiAtr.UniqueID == "" {
						apiAtr.UniqueID = utils.GenUUID()
					}
					atrs[idx] = &ActionTrigger{
						ID:                    key,
						UniqueID:              apiAtr.UniqueID,
						ThresholdType:         apiAtr.ThresholdType,
						ThresholdValue:        apiAtr.ThresholdValue,
						Recurrent:             apiAtr.Recurrent,
						MinSleep:              minSleep,
						ExpirationDate:        expTime,
						ActivationDate:        actTime,
						BalanceId:             apiAtr.BalanceId,
						BalanceType:           apiAtr.BalanceType,
						BalanceDirections:     utils.ParseStringMap(apiAtr.BalanceDirections),
						BalanceDestinationIds: utils.ParseStringMap(apiAtr.BalanceDestinationIds),
						BalanceWeight:         apiAtr.BalanceWeight,
						BalanceExpirationDate: balanceExpTime,
						BalanceTimingTags:     utils.ParseStringMap(apiAtr.BalanceTimingTags),
						BalanceRatingSubject:  apiAtr.BalanceRatingSubject,
						BalanceCategories:     utils.ParseStringMap(apiAtr.BalanceCategories),
						BalanceSharedGroups:   utils.ParseStringMap(apiAtr.BalanceSharedGroups),
						BalanceBlocker:        apiAtr.BalanceBlocker,
						BalanceDisabled:       apiAtr.BalanceDisabled,
						Weight:                apiAtr.Weight,
						ActionsId:             apiAtr.ActionsId,
					}
				}
				atrsMap[key] = atrs
			}
			actionTriggers = atrsMap[accountAction.ActionTriggersId]
			// collect action ids from triggers
			for _, atr := range actionTriggers {
				actionsIds = append(actionsIds, atr.ActionsId)
			}
			// write action triggers
			err = tpr.ratingStorage.SetActionTriggers(accountAction.ActionTriggersId, actionTriggers)
			if err != nil {
				return errors.New(err.Error() + " (SetActionTriggers): " + accountAction.ActionTriggersId)
			}
		}

		// actions
		acts := make(map[string][]*Action)
		for _, actId := range actionsIds {
			tpas, err := tpr.lr.GetTpActions(tpr.tpid, actId)
			if err != nil {
				return err
			}
			as, err := TpActions(tpas).GetActions()
			if err != nil {
				return err
			}
			for tag, tpacts := range as {
				enacts := make([]*Action, len(tpacts))
				for idx, tpact := range tpacts {
					// check filter field
					if len(tpact.Filter) > 0 {
						if _, err := structmatcher.NewStructMatcher(tpact.Filter); err != nil {
							return fmt.Errorf("error parsing action %s filter field: %v", tag, err)
						}
					}
					enacts[idx] = &Action{
						Id:               tag + strconv.Itoa(idx),
						ActionType:       tpact.Identifier,
						BalanceType:      tpact.BalanceType,
						Weight:           tpact.Weight,
						ExtraParameters:  tpact.ExtraParameters,
						ExpirationString: tpact.ExpiryTime,
						Filter:           tpact.Filter,
						Balance: &Balance{
							Id:             tpact.BalanceId,
							Value:          tpact.Units,
							Weight:         tpact.BalanceWeight,
							RatingSubject:  tpact.RatingSubject,
							Categories:     utils.ParseStringMap(tpact.Categories),
							Directions:     utils.ParseStringMap(tpact.Directions),
							DestinationIds: utils.ParseStringMap(tpact.DestinationIds),
							SharedGroups:   utils.ParseStringMap(tpact.SharedGroups),
							TimingIDs:      utils.ParseStringMap(tpact.TimingTags),
							Blocker:        tpact.BalanceBlocker,
							Disabled:       tpact.BalanceDisabled,
						},
					}
				}
				acts[tag] = enacts
			}
		}
		// write actions
		for k, as := range acts {
			err = tpr.ratingStorage.SetActions(k, as)
			if err != nil {
				return err
			}
		}
		ub, err := tpr.accountingStorage.GetAccount(id)
		if err != nil {
			ub = &Account{
				Id: id,
			}
		}
		ub.ActionTriggers = actionTriggers
		// init counters
		ub.InitCounters()
		if err := tpr.accountingStorage.SetAccount(ub); err != nil {
			return err
		}
	}
	return nil
}
Example #2
0
func (tpr *TpReader) LoadCdrStatsFiltered(tag string, save bool) (err error) {
	tps, err := tpr.lr.GetTpCdrStats(tpr.tpid, tag)
	if err != nil {
		return err
	}
	storStats, err := TpCdrStats(tps).GetCdrStats()
	if err != nil {
		return err
	}
	var actionsIds []string // collect action ids
	for tag, tpStats := range storStats {
		for _, tpStat := range tpStats {
			var cs *CdrStats
			var exists bool
			if cs, exists = tpr.cdrStats[tag]; !exists {
				cs = &CdrStats{Id: tag}
			}
			// action triggers
			triggerTag := tpStat.ActionTriggers
			if triggerTag != "" {
				_, exists := tpr.actionsTriggers[triggerTag]
				if !exists {
					tpatrs, err := tpr.lr.GetTpActionTriggers(tpr.tpid, triggerTag)
					if err != nil {
						return errors.New(err.Error() + " (ActionTriggers): " + triggerTag)
					}
					atrsM, err := TpActionTriggers(tpatrs).GetActionTriggers()
					if err != nil {
						return err
					}

					for _, atrsLst := range atrsM {
						atrs := make([]*ActionTrigger, len(atrsLst))
						for idx, apiAtr := range atrsLst {
							minSleep, _ := utils.ParseDurationWithSecs(apiAtr.MinSleep)
							balanceExpTime, _ := utils.ParseDate(apiAtr.BalanceExpirationDate)
							expTime, _ := utils.ParseTimeDetectLayout(apiAtr.ExpirationDate, tpr.timezone)
							actTime, _ := utils.ParseTimeDetectLayout(apiAtr.ActivationDate, tpr.timezone)
							if apiAtr.UniqueID == "" {
								apiAtr.UniqueID = utils.GenUUID()
							}
							atrs[idx] = &ActionTrigger{
								ID:                    triggerTag,
								UniqueID:              apiAtr.UniqueID,
								ThresholdType:         apiAtr.ThresholdType,
								ThresholdValue:        apiAtr.ThresholdValue,
								Recurrent:             apiAtr.Recurrent,
								MinSleep:              minSleep,
								ExpirationDate:        expTime,
								ActivationDate:        actTime,
								BalanceId:             apiAtr.BalanceId,
								BalanceType:           apiAtr.BalanceType,
								BalanceDirections:     utils.ParseStringMap(apiAtr.BalanceDirections),
								BalanceDestinationIds: utils.ParseStringMap(apiAtr.BalanceDestinationIds),
								BalanceWeight:         apiAtr.BalanceWeight,
								BalanceExpirationDate: balanceExpTime,
								BalanceRatingSubject:  apiAtr.BalanceRatingSubject,
								BalanceCategories:     utils.ParseStringMap(apiAtr.BalanceCategories),
								BalanceSharedGroups:   utils.ParseStringMap(apiAtr.BalanceSharedGroups),
								BalanceTimingTags:     utils.ParseStringMap(apiAtr.BalanceTimingTags),
								Weight:                apiAtr.Weight,
								ActionsId:             apiAtr.ActionsId,
							}
						}
						tpr.actionsTriggers[triggerTag] = atrs
					}
				}
				// collect action ids from triggers
				for _, atr := range tpr.actionsTriggers[triggerTag] {
					actionsIds = append(actionsIds, atr.ActionsId)
				}
			}
			triggers, exists := tpr.actionsTriggers[triggerTag]
			if triggerTag != "" && !exists {
				// only return error if there was something there for the tag
				return fmt.Errorf("could not get action triggers for cdr stats id %s: %s", cs.Id, triggerTag)
			}
			// write action triggers
			err = tpr.ratingStorage.SetActionTriggers(triggerTag, triggers)
			if err != nil {
				return errors.New(err.Error() + " (SetActionTriggers): " + triggerTag)
			}
			UpdateCdrStats(cs, triggers, tpStat, tpr.timezone)
			tpr.cdrStats[tag] = cs
		}
	}
	// actions
	for _, actId := range actionsIds {
		_, exists := tpr.actions[actId]
		if !exists {
			tpas, err := tpr.lr.GetTpActions(tpr.tpid, actId)
			if err != nil {
				return err
			}
			as, err := TpActions(tpas).GetActions()
			if err != nil {
				return err
			}
			for tag, tpacts := range as {
				enacts := make([]*Action, len(tpacts))
				for idx, tpact := range tpacts {
					// check filter field
					if len(tpact.Filter) > 0 {
						if _, err := structmatcher.NewStructMatcher(tpact.Filter); err != nil {
							return fmt.Errorf("error parsing action %s filter field: %v", tag, err)
						}
					}
					enacts[idx] = &Action{
						Id:               tag + strconv.Itoa(idx),
						ActionType:       tpact.Identifier,
						BalanceType:      tpact.BalanceType,
						Weight:           tpact.Weight,
						ExtraParameters:  tpact.ExtraParameters,
						ExpirationString: tpact.ExpiryTime,
						Filter:           tpact.Filter,
						Balance: &Balance{
							Id:             tpact.BalanceId,
							Value:          tpact.Units,
							Weight:         tpact.BalanceWeight,
							RatingSubject:  tpact.RatingSubject,
							Categories:     utils.ParseStringMap(tpact.Categories),
							Directions:     utils.ParseStringMap(tpact.Directions),
							DestinationIds: utils.ParseStringMap(tpact.DestinationIds),
							SharedGroups:   utils.ParseStringMap(tpact.SharedGroups),
							TimingIDs:      utils.ParseStringMap(tpact.TimingTags),
							Blocker:        tpact.BalanceBlocker,
							Disabled:       tpact.BalanceDisabled,
						},
					}
				}
				tpr.actions[tag] = enacts
			}
		}
	}

	if save {
		// write actions
		for k, as := range tpr.actions {
			err = tpr.ratingStorage.SetActions(k, as)
			if err != nil {
				return err
			}
		}
		for _, stat := range tpr.cdrStats {
			if err := tpr.ratingStorage.SetCdrStats(stat); err != nil {
				return err
			}
		}
	}
	return nil
}
Example #3
0
func (tpr *TpReader) LoadActions() (err error) {
	tps, err := tpr.lr.GetTpActions(tpr.tpid, "")
	if err != nil {
		return err
	}

	storActs, err := TpActions(tps).GetActions()
	if err != nil {
		return err
	}
	// map[string][]*Action
	for tag, tpacts := range storActs {
		acts := make([]*Action, len(tpacts))
		for idx, tpact := range tpacts {
			// check filter field
			if len(tpact.Filter) > 0 {
				if _, err := structmatcher.NewStructMatcher(tpact.Filter); err != nil {
					return fmt.Errorf("error parsing action %s filter field: %v", tag, err)
				}
			}
			acts[idx] = &Action{
				Id:               tag + strconv.Itoa(idx),
				ActionType:       tpact.Identifier,
				BalanceType:      tpact.BalanceType,
				Weight:           tpact.Weight,
				ExtraParameters:  tpact.ExtraParameters,
				ExpirationString: tpact.ExpiryTime,
				Filter:           tpact.Filter,
				Balance: &Balance{
					Id:             tpact.BalanceId,
					Value:          tpact.Units,
					Weight:         tpact.BalanceWeight,
					RatingSubject:  tpact.RatingSubject,
					Categories:     utils.ParseStringMap(tpact.Categories),
					Directions:     utils.ParseStringMap(tpact.Directions),
					DestinationIds: utils.ParseStringMap(tpact.DestinationIds),
					SharedGroups:   utils.ParseStringMap(tpact.SharedGroups),
					TimingIDs:      utils.ParseStringMap(tpact.TimingTags),
					Blocker:        tpact.BalanceBlocker,
					Disabled:       tpact.BalanceDisabled,
				},
			}
			// load action timings from tags
			if tpact.TimingTags != "" {
				timingIds := strings.Split(tpact.TimingTags, utils.INFIELD_SEP)
				for _, timingID := range timingIds {
					if timing, found := tpr.timings[timingID]; found {
						acts[idx].Balance.Timings = append(acts[idx].Balance.Timings, &RITiming{
							Years:     timing.Years,
							Months:    timing.Months,
							MonthDays: timing.MonthDays,
							WeekDays:  timing.WeekDays,
							StartTime: timing.StartTime,
							EndTime:   timing.EndTime,
						})
					} else {
						return fmt.Errorf("could not find timing: %v", timingID)
					}
				}
			}
		}
		tpr.actions[tag] = acts
	}
	return nil
}