示例#1
0
func (mig MigratorRC8) migrateAccountsInt() error {
	keys, err := mig.db.Cmd("KEYS", utils.ACCOUNT_PREFIX+"*").List()
	if err != nil {
		return err
	}
	newAccounts := make([]*engine.Account, 0)
	var migratedKeys []string
	// get existing accounts
	for _, key := range keys {
		log.Printf("Migrating account: %s...", key)
		values, err := mig.db.Cmd("GET", key).Bytes()
		if err != nil {
			continue
		}
		var oldAcc Account1
		if err = mig.ms.Unmarshal(values, &oldAcc); err != nil {
			return err
		}
		// transfer data into new structurse
		newAcc := &engine.Account{
			ID:             oldAcc.Id,
			BalanceMap:     make(map[string]engine.Balances, len(oldAcc.BalanceMap)),
			UnitCounters:   make(engine.UnitCounters),
			ActionTriggers: make(engine.ActionTriggers, len(oldAcc.ActionTriggers)),
			AllowNegative:  oldAcc.AllowNegative,
			Disabled:       oldAcc.Disabled,
		}
		// balances
		balanceErr := false
		for key, oldBalChain := range oldAcc.BalanceMap {
			newAcc.BalanceMap[key] = make(engine.Balances, len(oldBalChain))
			for index, oldBal := range oldBalChain {
				newAcc.BalanceMap[key][index] = &engine.Balance{
					Uuid:           oldBal.Uuid,
					ID:             oldBal.Id,
					Value:          oldBal.Value,
					Directions:     oldBal.Directions,
					ExpirationDate: oldBal.ExpirationDate,
					Weight:         oldBal.Weight,
					DestinationIDs: oldBal.DestinationIds,
					RatingSubject:  oldBal.RatingSubject,
					Categories:     oldBal.Categories,
					SharedGroups:   oldBal.SharedGroups,
					Timings:        oldBal.Timings,
					TimingIDs:      oldBal.TimingIDs,
					Disabled:       oldBal.Disabled,
					Factor:         oldBal.Factor,
					Blocker:        oldBal.Blocker,
				}
			}
		}
		if balanceErr {
			continue
		}
		// unit counters
		for _, oldUc := range oldAcc.UnitCounters {
			newUc := &engine.UnitCounter{
				Counters: make(engine.CounterFilters, len(oldUc.Balances)),
			}
			for index, oldUcBal := range oldUc.Balances {
				b := &engine.Balance{
					Uuid:           oldUcBal.Uuid,
					ID:             oldUcBal.Id,
					Value:          oldUcBal.Value,
					Directions:     oldUcBal.Directions,
					ExpirationDate: oldUcBal.ExpirationDate,
					Weight:         oldUcBal.Weight,
					DestinationIDs: oldUcBal.DestinationIds,
					RatingSubject:  oldUcBal.RatingSubject,
					Categories:     oldUcBal.Categories,
					SharedGroups:   oldUcBal.SharedGroups,
					Timings:        oldUcBal.Timings,
					TimingIDs:      oldUcBal.TimingIDs,
					Disabled:       oldUcBal.Disabled,
					Factor:         oldUcBal.Factor,
					Blocker:        oldUcBal.Blocker,
				}
				bf := &engine.BalanceFilter{}
				bf.LoadFromBalance(b)
				cf := &engine.CounterFilter{
					Value:  oldUcBal.Value,
					Filter: bf,
				}
				newUc.Counters[index] = cf
			}
			newAcc.UnitCounters[oldUc.BalanceType] = append(newAcc.UnitCounters[oldUc.BalanceType], newUc)
		}
		// action triggers
		for index, oldAtr := range oldAcc.ActionTriggers {
			at := &engine.ActionTrigger{
				ID:             oldAtr.ID,
				UniqueID:       oldAtr.UniqueID,
				ThresholdType:  oldAtr.ThresholdType,
				ThresholdValue: oldAtr.ThresholdValue,
				Recurrent:      oldAtr.Recurrent,
				MinSleep:       oldAtr.MinSleep,
				Weight:         oldAtr.Weight,
				ActionsID:      oldAtr.ActionsId,
				MinQueuedItems: oldAtr.MinQueuedItems,
				Executed:       oldAtr.Executed,
			}
			bf := &engine.BalanceFilter{}
			if oldAtr.BalanceId != "" {
				bf.ID = utils.StringPointer(oldAtr.BalanceId)
			}
			if oldAtr.BalanceType != "" {
				bf.Type = utils.StringPointer(oldAtr.BalanceType)
			}
			if oldAtr.BalanceRatingSubject != "" {
				bf.RatingSubject = utils.StringPointer(oldAtr.BalanceRatingSubject)
			}
			if !oldAtr.BalanceDirections.IsEmpty() {
				bf.Directions = utils.StringMapPointer(oldAtr.BalanceDirections)
			}
			if !oldAtr.BalanceDestinationIds.IsEmpty() {
				bf.DestinationIDs = utils.StringMapPointer(oldAtr.BalanceDestinationIds)
			}
			if !oldAtr.BalanceTimingTags.IsEmpty() {
				bf.TimingIDs = utils.StringMapPointer(oldAtr.BalanceTimingTags)
			}
			if !oldAtr.BalanceCategories.IsEmpty() {
				bf.Categories = utils.StringMapPointer(oldAtr.BalanceCategories)
			}
			if !oldAtr.BalanceSharedGroups.IsEmpty() {
				bf.SharedGroups = utils.StringMapPointer(oldAtr.BalanceSharedGroups)
			}
			if oldAtr.BalanceWeight != 0 {
				bf.Weight = utils.Float64Pointer(oldAtr.BalanceWeight)
			}
			if oldAtr.BalanceDisabled != false {
				bf.Disabled = utils.BoolPointer(oldAtr.BalanceDisabled)
			}
			if !oldAtr.BalanceExpirationDate.IsZero() {
				bf.ExpirationDate = utils.TimePointer(oldAtr.BalanceExpirationDate)
			}
			at.Balance = bf
			newAcc.ActionTriggers[index] = at
		}
		newAcc.InitCounters()
		newAccounts = append(newAccounts, newAcc)
		migratedKeys = append(migratedKeys, key)
	}
	// write data back
	for _, newAcc := range newAccounts {
		result, err := mig.ms.Marshal(newAcc)
		if err != nil {
			return err
		}
		if err := mig.db.Cmd("SET", utils.ACCOUNT_PREFIX+newAcc.ID, result).Err; err != nil {
			return err
		}
	}
	notMigrated := len(keys) - len(migratedKeys)
	if notMigrated > 0 {
		log.Printf("WARNING: there are %d accounts that failed migration!", notMigrated)
	}
	return err
}
示例#2
0
func (mig MigratorRC8) migrateActionTriggersInt() error {
	keys, err := mig.db.Cmd("KEYS", utils.ACTION_TRIGGER_PREFIX+"*").List()
	if err != nil {
		return err
	}
	newAtrsMap := make(map[string]engine.ActionTriggers, len(keys))
	for _, key := range keys {
		log.Printf("Migrating action trigger: %s...", key)
		var oldAtrs ActionTriggers1
		var values []byte
		if values, err = mig.db.Cmd("GET", key).Bytes(); err == nil {
			if err := mig.ms.Unmarshal(values, &oldAtrs); err != nil {
				return err
			}
		}
		newAtrs := make(engine.ActionTriggers, len(oldAtrs))
		for index, oldAtr := range oldAtrs {
			at := &engine.ActionTrigger{
				ID:             oldAtr.ID,
				UniqueID:       oldAtr.UniqueID,
				ThresholdType:  oldAtr.ThresholdType,
				ThresholdValue: oldAtr.ThresholdValue,
				Recurrent:      oldAtr.Recurrent,
				MinSleep:       oldAtr.MinSleep,
				Weight:         oldAtr.Weight,
				ActionsID:      oldAtr.ActionsId,
				MinQueuedItems: oldAtr.MinQueuedItems,
				Executed:       oldAtr.Executed,
			}
			bf := &engine.BalanceFilter{}
			if oldAtr.BalanceId != "" {
				bf.ID = utils.StringPointer(oldAtr.BalanceId)
			}
			if oldAtr.BalanceType != "" {
				bf.Type = utils.StringPointer(oldAtr.BalanceType)
			}
			if oldAtr.BalanceRatingSubject != "" {
				bf.RatingSubject = utils.StringPointer(oldAtr.BalanceRatingSubject)
			}
			if !oldAtr.BalanceDirections.IsEmpty() {
				bf.Directions = utils.StringMapPointer(oldAtr.BalanceDirections)
			}
			if !oldAtr.BalanceDestinationIds.IsEmpty() {
				bf.DestinationIDs = utils.StringMapPointer(oldAtr.BalanceDestinationIds)
			}
			if !oldAtr.BalanceTimingTags.IsEmpty() {
				bf.TimingIDs = utils.StringMapPointer(oldAtr.BalanceTimingTags)
			}
			if !oldAtr.BalanceCategories.IsEmpty() {
				bf.Categories = utils.StringMapPointer(oldAtr.BalanceCategories)
			}
			if !oldAtr.BalanceSharedGroups.IsEmpty() {
				bf.SharedGroups = utils.StringMapPointer(oldAtr.BalanceSharedGroups)
			}
			if oldAtr.BalanceWeight != 0 {
				bf.Weight = utils.Float64Pointer(oldAtr.BalanceWeight)
			}
			if oldAtr.BalanceDisabled != false {
				bf.Disabled = utils.BoolPointer(oldAtr.BalanceDisabled)
			}
			if !oldAtr.BalanceExpirationDate.IsZero() {
				bf.ExpirationDate = utils.TimePointer(oldAtr.BalanceExpirationDate)
			}
			at.Balance = bf
			newAtrs[index] = at
		}
		newAtrsMap[key] = newAtrs
	}
	// write data back
	for key, atrs := range newAtrsMap {
		result, err := mig.ms.Marshal(&atrs)
		if err != nil {
			return err
		}
		if err = mig.db.Cmd("SET", key, result).Err; err != nil {
			return err
		}
	}
	return nil
}
示例#3
0
func (mig MigratorRC8) migrateActionsInt() error {
	keys, err := mig.db.Cmd("KEYS", utils.ACTION_PREFIX+"*").List()
	if err != nil {
		return err
	}
	newAcsMap := make(map[string]engine.Actions, len(keys))
	for _, key := range keys {
		log.Printf("Migrating action: %s...", key)
		var oldAcs Actions1
		var values []byte
		if values, err = mig.db.Cmd("GET", key).Bytes(); err == nil {
			if err := mig.ms.Unmarshal(values, &oldAcs); err != nil {
				return err
			}
		}
		newAcs := make(engine.Actions, len(oldAcs))
		for index, oldAc := range oldAcs {
			a := &engine.Action{
				Id:               oldAc.Id,
				ActionType:       oldAc.ActionType,
				ExtraParameters:  oldAc.ExtraParameters,
				ExpirationString: oldAc.ExpirationString,
				Filter:           oldAc.Filter,
				Weight:           oldAc.Weight,
				Balance:          &engine.BalanceFilter{},
			}
			bf := a.Balance
			if oldAc.Balance.Uuid != "" {
				bf.Uuid = utils.StringPointer(oldAc.Balance.Uuid)
			}
			if oldAc.Balance.Id != "" {
				bf.ID = utils.StringPointer(oldAc.Balance.Id)
			}
			if oldAc.BalanceType != "" {
				bf.Type = utils.StringPointer(oldAc.BalanceType)
			}
			if oldAc.Balance.Value != 0 {
				bf.Value = &utils.ValueFormula{Static: oldAc.Balance.Value}
			}
			if oldAc.Balance.RatingSubject != "" {
				bf.RatingSubject = utils.StringPointer(oldAc.Balance.RatingSubject)
			}
			if !oldAc.Balance.DestinationIds.IsEmpty() {
				bf.DestinationIDs = utils.StringMapPointer(oldAc.Balance.DestinationIds)
			}
			if !oldAc.Balance.TimingIDs.IsEmpty() {
				bf.TimingIDs = utils.StringMapPointer(oldAc.Balance.TimingIDs)
			}
			if !oldAc.Balance.Categories.IsEmpty() {
				bf.Categories = utils.StringMapPointer(oldAc.Balance.Categories)
			}
			if !oldAc.Balance.SharedGroups.IsEmpty() {
				bf.SharedGroups = utils.StringMapPointer(oldAc.Balance.SharedGroups)
			}
			if oldAc.Balance.Weight != 0 {
				bf.Weight = utils.Float64Pointer(oldAc.Balance.Weight)
			}
			if oldAc.Balance.Disabled != false {
				bf.Disabled = utils.BoolPointer(oldAc.Balance.Disabled)
			}
			if !oldAc.Balance.ExpirationDate.IsZero() {
				bf.ExpirationDate = utils.TimePointer(oldAc.Balance.ExpirationDate)
			}
			bf.Timings = oldAc.Balance.Timings
			newAcs[index] = a
		}
		newAcsMap[key] = newAcs
	}
	// write data back
	for key, acs := range newAcsMap {
		result, err := mig.ms.Marshal(&acs)
		if err != nil {
			return err
		}
		if err = mig.db.Cmd("SET", key, result).Err; err != nil {
			return err
		}
	}
	return nil
}
示例#4
0
func (mig MigratorRC8) migrateAccounts() error {
	keys, err := mig.db.Cmd("KEYS", OLD_ACCOUNT_PREFIX+"*").List()
	if err != nil {
		return err
	}
	newAccounts := make([]*engine.Account, 0)
	var migratedKeys []string
	// get existing accounts
	for _, key := range keys {
		log.Printf("Migrating account: %s...", key)
		values, err := mig.db.Cmd("GET", key).Bytes()
		if err != nil {
			continue
		}
		var oldAcc Account
		if err = mig.ms.Unmarshal(values, &oldAcc); err != nil {
			return err
		}
		// transfer data into new structurse
		newAcc := &engine.Account{
			ID:             oldAcc.Id,
			BalanceMap:     make(map[string]engine.Balances, len(oldAcc.BalanceMap)),
			UnitCounters:   make(engine.UnitCounters, len(oldAcc.UnitCounters)),
			ActionTriggers: make(engine.ActionTriggers, len(oldAcc.ActionTriggers)),
			AllowNegative:  oldAcc.AllowNegative,
			Disabled:       oldAcc.Disabled,
		}
		// fix id
		idElements := strings.Split(newAcc.ID, utils.CONCATENATED_KEY_SEP)
		if len(idElements) != 3 {
			log.Printf("Malformed account ID %s", oldAcc.Id)
			continue
		}
		newAcc.ID = fmt.Sprintf("%s:%s", idElements[1], idElements[2])
		// balances
		balanceErr := false
		for oldBalKey, oldBalChain := range oldAcc.BalanceMap {
			keyElements := strings.Split(oldBalKey, "*")
			if len(keyElements) != 3 {
				log.Printf("Malformed balance key in %s: %s", oldAcc.Id, oldBalKey)
				balanceErr = true
				break
			}
			newBalKey := "*" + keyElements[1]
			newBalDirection := "*" + keyElements[2]
			newAcc.BalanceMap[newBalKey] = make(engine.Balances, len(oldBalChain))
			for index, oldBal := range oldBalChain {
				// check default to set new id
				if oldBal.IsDefault() {
					oldBal.Id = utils.META_DEFAULT
				}
				newAcc.BalanceMap[newBalKey][index] = &engine.Balance{
					Uuid:           oldBal.Uuid,
					ID:             oldBal.Id,
					Value:          oldBal.Value,
					Directions:     utils.ParseStringMap(newBalDirection),
					ExpirationDate: oldBal.ExpirationDate,
					Weight:         oldBal.Weight,
					DestinationIDs: utils.ParseStringMap(oldBal.DestinationIds),
					RatingSubject:  oldBal.RatingSubject,
					Categories:     utils.ParseStringMap(oldBal.Category),
					SharedGroups:   utils.ParseStringMap(oldBal.SharedGroup),
					Timings:        oldBal.Timings,
					TimingIDs:      utils.ParseStringMap(oldBal.TimingIDs),
					Disabled:       oldBal.Disabled,
				}
			}
		}
		if balanceErr {
			continue
		}
		// unit counters
		for _, oldUc := range oldAcc.UnitCounters {
			newUc := &engine.UnitCounter{
				Counters: make(engine.CounterFilters, len(oldUc.Balances)),
			}
			for index, oldUcBal := range oldUc.Balances {
				bf := &engine.BalanceFilter{}
				if oldUcBal.Uuid != "" {
					bf.Uuid = utils.StringPointer(oldUcBal.Uuid)
				}
				if oldUcBal.Id != "" {
					bf.ID = utils.StringPointer(oldUcBal.Id)
				}
				if oldUc.BalanceType != "" {
					bf.Type = utils.StringPointer(oldUc.BalanceType)
				}
				// the value was used for counter value
				/*if oldUcBal.Value != 0 {
					bf.Value = utils.Float64Pointer(oldUcBal.Value)
				}*/
				if oldUc.Direction != "" {
					bf.Directions = utils.StringMapPointer(utils.ParseStringMap(oldUc.Direction))
				}
				if !oldUcBal.ExpirationDate.IsZero() {
					bf.ExpirationDate = utils.TimePointer(oldUcBal.ExpirationDate)
				}
				if oldUcBal.Weight != 0 {
					bf.Weight = utils.Float64Pointer(oldUcBal.Weight)
				}
				if oldUcBal.DestinationIds != "" {
					bf.DestinationIDs = utils.StringMapPointer(utils.ParseStringMap(oldUcBal.DestinationIds))
				}
				if oldUcBal.RatingSubject != "" {
					bf.RatingSubject = utils.StringPointer(oldUcBal.RatingSubject)
				}
				if oldUcBal.Category != "" {
					bf.Categories = utils.StringMapPointer(utils.ParseStringMap(oldUcBal.Category))
				}
				if oldUcBal.SharedGroup != "" {
					bf.SharedGroups = utils.StringMapPointer(utils.ParseStringMap(oldUcBal.SharedGroup))
				}
				if oldUcBal.TimingIDs != "" {
					bf.TimingIDs = utils.StringMapPointer(utils.ParseStringMap(oldUcBal.TimingIDs))
				}
				if oldUcBal.Disabled != false {
					bf.Disabled = utils.BoolPointer(oldUcBal.Disabled)
				}
				bf.Timings = oldUcBal.Timings
				cf := &engine.CounterFilter{
					Value:  oldUcBal.Value,
					Filter: bf,
				}
				newUc.Counters[index] = cf
			}
			newAcc.UnitCounters[oldUc.BalanceType] = append(newAcc.UnitCounters[oldUc.BalanceType], newUc)
		}
		// action triggers
		for index, oldAtr := range oldAcc.ActionTriggers {
			at := &engine.ActionTrigger{
				UniqueID:       oldAtr.Id,
				ThresholdType:  oldAtr.ThresholdType,
				ThresholdValue: oldAtr.ThresholdValue,
				Recurrent:      oldAtr.Recurrent,
				MinSleep:       oldAtr.MinSleep,
				Weight:         oldAtr.Weight,
				ActionsID:      oldAtr.ActionsId,
				MinQueuedItems: oldAtr.MinQueuedItems,
				Executed:       oldAtr.Executed,
			}
			bf := &engine.BalanceFilter{}
			if oldAtr.BalanceId != "" {
				bf.ID = utils.StringPointer(oldAtr.BalanceId)
			}
			if oldAtr.BalanceType != "" {
				bf.Type = utils.StringPointer(oldAtr.BalanceType)
			}
			if oldAtr.BalanceRatingSubject != "" {
				bf.RatingSubject = utils.StringPointer(oldAtr.BalanceRatingSubject)
			}
			if oldAtr.BalanceDirection != "" {
				bf.Directions = utils.StringMapPointer(utils.ParseStringMap(oldAtr.BalanceDirection))
			}
			if oldAtr.BalanceDestinationIds != "" {
				bf.DestinationIDs = utils.StringMapPointer(utils.ParseStringMap(oldAtr.BalanceDestinationIds))
			}
			if oldAtr.BalanceTimingTags != "" {
				bf.TimingIDs = utils.StringMapPointer(utils.ParseStringMap(oldAtr.BalanceTimingTags))
			}
			if oldAtr.BalanceCategory != "" {
				bf.Categories = utils.StringMapPointer(utils.ParseStringMap(oldAtr.BalanceCategory))
			}
			if oldAtr.BalanceSharedGroup != "" {
				bf.SharedGroups = utils.StringMapPointer(utils.ParseStringMap(oldAtr.BalanceSharedGroup))
			}
			if oldAtr.BalanceWeight != 0 {
				bf.Weight = utils.Float64Pointer(oldAtr.BalanceWeight)
			}
			if oldAtr.BalanceDisabled != false {
				bf.Disabled = utils.BoolPointer(oldAtr.BalanceDisabled)
			}
			if !oldAtr.BalanceExpirationDate.IsZero() {
				bf.ExpirationDate = utils.TimePointer(oldAtr.BalanceExpirationDate)
			}
			at.Balance = bf
			newAcc.ActionTriggers[index] = at
			if newAcc.ActionTriggers[index].ThresholdType == "*min_counter" ||
				newAcc.ActionTriggers[index].ThresholdType == "*max_counter" {
				newAcc.ActionTriggers[index].ThresholdType = strings.Replace(newAcc.ActionTriggers[index].ThresholdType, "_", "_event_", 1)
			}
		}
		newAcc.InitCounters()
		newAccounts = append(newAccounts, newAcc)
		migratedKeys = append(migratedKeys, key)
	}
	// write data back
	for _, newAcc := range newAccounts {
		result, err := mig.ms.Marshal(newAcc)
		if err != nil {
			return err
		}
		if err := mig.db.Cmd("SET", utils.ACCOUNT_PREFIX+newAcc.ID, result).Err; err != nil {
			return err
		}
	}
	// delete old data
	log.Printf("Deleting migrated accounts...")
	for _, key := range migratedKeys {
		if err := mig.db.Cmd("DEL", key).Err; err != nil {
			return err
		}
	}
	notMigrated := len(keys) - len(migratedKeys)
	if notMigrated > 0 {
		log.Printf("WARNING: there are %d accounts that failed migration!", notMigrated)
	}
	return err
}