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 }
// 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 }
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 }
// 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 }