예제 #1
0
func (rs *RedisStorage) PreloadCacheForPrefix(prefix string) error {
	transID := cache.BeginTransaction()
	cache.RemPrefixKey(prefix, false, transID)
	keyList, err := rs.GetKeysForPrefix(prefix)
	if err != nil {
		cache.RollbackTransaction(transID)
		return err
	}
	switch prefix {
	case utils.RATING_PLAN_PREFIX:
		for _, key := range keyList {
			_, err := rs.GetRatingPlan(key[len(utils.RATING_PLAN_PREFIX):], true, transID)
			if err != nil {
				cache.RollbackTransaction(transID)
				return err
			}
		}
	case utils.ResourceLimitsPrefix:
		for _, key := range keyList {
			_, err = rs.GetResourceLimit(key[len(utils.ResourceLimitsPrefix):], true, transID)
			if err != nil {
				cache.RollbackTransaction(transID)
				return err
			}
		}
	default:
		return utils.ErrInvalidKey
	}
	cache.CommitTransaction(transID)
	return nil
}
예제 #2
0
파일: apier.go 프로젝트: rinor/cgrates
// 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, utils.NonTransactional); 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, utils.NonTransactional); err != nil {
		return utils.NewErrServerError(err)
	}
	cache.RemPrefixKey(utils.RATING_PLAN_PREFIX, true, "")
	self.RatingDb.PreloadCacheForPrefix(utils.RATING_PLAN_PREFIX)
	*reply = OK
	return nil
}
예제 #3
0
func (rs *RedisStorage) UpdateReverseAlias(oldAl, newAl *Alias, transactionID string) error {
	// FIXME: thi can be optimized
	cache.RemPrefixKey(utils.REVERSE_ALIASES_PREFIX, cacheCommit(transactionID), transactionID)
	rs.SetReverseAlias(newAl, transactionID)
	return nil
}
예제 #4
0
// CacheDataFromDB loads data to cache
// prfx represents the cache prefix, ids should be nil if all available data should be loaded
// mustBeCached specifies that data needs to be cached in order to be retrieved from db
func (rs *RedisStorage) CacheDataFromDB(prfx string, ids []string, mustBeCached bool) (err error) {
	if !utils.IsSliceMember([]string{utils.DESTINATION_PREFIX,
		utils.REVERSE_DESTINATION_PREFIX,
		utils.RATING_PLAN_PREFIX,
		utils.RATING_PROFILE_PREFIX,
		utils.ACTION_PREFIX,
		utils.ACTION_PLAN_PREFIX,
		utils.SHARED_GROUP_PREFIX,
		utils.DERIVEDCHARGERS_PREFIX,
		utils.LCR_PREFIX,
		utils.ALIASES_PREFIX,
		utils.REVERSE_ALIASES_PREFIX,
		utils.ResourceLimitsPrefix}, prfx) {
		return utils.NewCGRError(utils.REDIS,
			utils.MandatoryIEMissingCaps,
			utils.UnsupportedCachePrefix,
			fmt.Sprintf("prefix <%s> is not a supported cache prefix", prfx))
	}
	if ids == nil {
		if ids, err = rs.GetKeysForPrefix(prfx); err != nil {
			return utils.NewCGRError(utils.REDIS,
				utils.ServerErrorCaps,
				err.Error(),
				fmt.Sprintf("redis error <%s> querying keys for prefix: <%s>", prfx))
		}
		cache.RemPrefixKey(prfx, true, utils.NonTransactional)
	}
	for _, dataID := range ids {
		if mustBeCached {
			if _, hasIt := cache.Get(prfx + dataID); !hasIt { // only cache if previously there
				continue
			}
		}
		switch prfx {
		case utils.DESTINATION_PREFIX:
			_, err = rs.GetDestination(dataID, false, utils.NonTransactional)
		case utils.REVERSE_DESTINATION_PREFIX:
			_, err = rs.GetReverseDestination(dataID, false, utils.NonTransactional)
		case utils.RATING_PLAN_PREFIX:
			_, err = rs.GetRatingPlan(dataID, false, utils.NonTransactional)
		case utils.RATING_PROFILE_PREFIX:
			_, err = rs.GetRatingProfile(dataID, false, utils.NonTransactional)
		case utils.ACTION_PREFIX:
			_, err = rs.GetActions(dataID, false, utils.NonTransactional)
		case utils.ACTION_PLAN_PREFIX:
			_, err = rs.GetActionPlan(dataID, false, utils.NonTransactional)
		case utils.SHARED_GROUP_PREFIX:
			_, err = rs.GetSharedGroup(dataID, false, utils.NonTransactional)
		case utils.DERIVEDCHARGERS_PREFIX:
			_, err = rs.GetDerivedChargers(dataID, false, utils.NonTransactional)
		case utils.LCR_PREFIX:
			_, err = rs.GetLCR(dataID, false, utils.NonTransactional)
		case utils.ALIASES_PREFIX:
			_, err = rs.GetAlias(dataID, false, utils.NonTransactional)
		case utils.REVERSE_ALIASES_PREFIX:
			_, err = rs.GetReverseAlias(dataID, false, utils.NonTransactional)
		case utils.ResourceLimitsPrefix:
			_, err = rs.GetResourceLimit(dataID, false, utils.NonTransactional)
		}
		if err != nil {
			return utils.NewCGRError(utils.REDIS,
				utils.ServerErrorCaps,
				err.Error(),
				fmt.Sprintf("error <%s> querying redis for category: <%s>, dataID: <%s>", prfx, dataID))
		}
	}
	return
}