From ebbadb50dd22bff667c0e88dc2c63c91d6552f54 Mon Sep 17 00:00:00 2001 From: DanB Date: Tue, 16 Jul 2013 21:18:08 +0200 Subject: [PATCH] Apier.SetRatingProfile method fixups --- apier/apier.go | 51 +++++------------ rater/loader_db.go | 50 ++++++++++------- rater/loader_helpers.go | 5 +- rater/ratingprofile.go | 3 +- rater/storage_sql.go | 119 +++++++++++++++++++++------------------- 5 files changed, 114 insertions(+), 114 deletions(-) diff --git a/apier/apier.go b/apier/apier.go index 7d6ab5e12..381bae028 100644 --- a/apier/apier.go +++ b/apier/apier.go @@ -19,7 +19,6 @@ along with this program. If not, see package apier import ( - "errors" "fmt" "github.com/cgrates/cgrates/rater" "github.com/cgrates/cgrates/scheduler" @@ -32,32 +31,6 @@ type Apier struct { Sched *scheduler.Scheduler } -type AttrDestination struct { - Id string - Prefixes []string -} - -func (self *Apier) GetDestination(attr *AttrDestination, reply *AttrDestination) error { - if dst, err := self.DataDb.GetDestination(attr.Id); err != nil { - return errors.New(utils.ERR_NOT_FOUND) - } else { - reply.Id = dst.Id - reply.Prefixes = dst.Prefixes - } - return nil -} - -func (self *Apier) SetDestination(attr *AttrDestination, reply *float64) error { - d := &rater.Destination{ - Id: attr.Id, - Prefixes: attr.Prefixes, - } - if err := self.DataDb.SetDestination(d); err != nil { - return err - } - return nil -} - type AttrGetBalance struct { Tenant string Account string @@ -147,20 +120,26 @@ func (self *Apier) ExecuteAction(attr *AttrExecuteAction, reply *float64) error } type AttrSetRatingProfile struct { - TPID string + TPid string RateProfileId string } -func (self *Apier) SetRatingProfile(attr *AttrSetRatingProfile, reply *float64) error { - dbReader := rater.NewDbReader(self.StorDb, self.DataDb, attr.TPID) - - newRP, err := dbReader.LoadRatingProfileByTag(attr.RateProfileId) - if err != nil { - return err +func (self *Apier) SetRatingProfile(attrs AttrSetRatingProfile, reply *string) error { + if missing := utils.MissingStructFields(&attrs, []string{"TPid", "RateProfileId"}); len(missing) != 0 { + return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing) } + dbReader := rater.NewDbReader(self.StorDb, self.DataDb, attrs.TPid) + newRP, err := dbReader.LoadRatingProfileByTag(attrs.RateProfileId) + if err != nil { + return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error()) + } err = self.DataDb.SetRatingProfile(newRP) - return err + if err != nil { + return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error()) + } + *reply = "OK" + return nil } type AttrActionTrigger struct { @@ -174,7 +153,7 @@ type AttrActionTrigger struct { ActionsId string } -func (self *Apier) AddTriggeredAction(attr *AttrActionTrigger, reply *float64) error { +func (self *Apier) AddTriggeredAction(attr AttrActionTrigger, reply *float64) error { if attr.Direction == "" { attr.Direction = rater.OUTBOUND } diff --git a/rater/loader_db.go b/rater/loader_db.go index 17c4c2cf9..7fffc230f 100644 --- a/rater/loader_db.go +++ b/rater/loader_db.go @@ -184,14 +184,11 @@ func (dbr *DbReader) LoadRatingProfiles() error { return err } for _, rp := range rpfs { - at, err := time.Parse(time.RFC3339, rp.activationTime) - if err != nil { - return errors.New(fmt.Sprintf("Cannot parse activation time from %v", rp.activationTime)) - } + at := time.Unix(rp.activationTime, 0) for _, d := range dbr.destinations { - ap, exists := dbr.activationPeriods[rp.ratesTimingTag] + ap, exists := dbr.activationPeriods[rp.destRatesTimingTag] if !exists { - return errors.New(fmt.Sprintf("Could not load rating timing for tag: %v", rp.ratesTimingTag)) + return errors.New(fmt.Sprintf("Could not load rating timing for tag: %v", rp.destRatesTimingTag)) } newAP := &ActivationPeriod{ActivationTime: at} //copy(newAP.Intervals, ap.Intervals) @@ -209,39 +206,50 @@ func (dbr *DbReader) LoadRatingProfileByTag(tag string) (*RatingProfile, error) rpm, err := dbr.storDB.GetTpRatingProfiles(dbr.tpid, tag) if err != nil { return nil, err + } else if len(rpm)==0 { + return nil, fmt.Errorf("No RateProfile with id: %s", tag) } for _, ratingProfile := range rpm { resultRatingProfile.FallbackKey = ratingProfile.FallbackKey // it will be the last fallback key - at, err := time.Parse(time.RFC3339, ratingProfile.activationTime) - if err != nil { - return nil, errors.New(fmt.Sprintf("Cannot parse activation time from %v", ratingProfile.activationTime)) - } - rtm, err := dbr.storDB.GetTpDestinationRateTimings(dbr.tpid, ratingProfile.ratesTimingTag) + at := time.Unix(ratingProfile.activationTime, 0) + drtm, err := dbr.storDB.GetTpDestinationRateTimings(dbr.tpid, ratingProfile.destRatesTimingTag) if err != nil { return nil, err + } else if len(drtm)==0 { + return nil, fmt.Errorf("No DestRateTimings profile with id: %s", ratingProfile.destRatesTimingTag) } - for _, rateTiming := range rtm { - tm, err := dbr.storDB.GetTpTimings(dbr.tpid, rateTiming.TimingsTag) + for _, destrateTiming := range drtm { + tm, err := dbr.storDB.GetTpTimings(dbr.tpid, destrateTiming.TimingsTag) if err != nil { return nil, err + } else if len(tm)==0 { + return nil, fmt.Errorf("No Timings profile with id: %s", destrateTiming.TimingsTag) } - rateTiming.timing = tm[rateTiming.TimingsTag] - drm, err := dbr.storDB.GetTpDestinationRates(dbr.tpid, rateTiming.DestinationRatesTag) + destrateTiming.timing = tm[destrateTiming.TimingsTag] + drm, err := dbr.storDB.GetTpDestinationRates(dbr.tpid, destrateTiming.DestinationRatesTag) if err != nil { return nil, err + } else if len(drm)==0 { + return nil, fmt.Errorf("No Timings profile with id: %s", destrateTiming.DestinationRatesTag) } - for _, drate := range drm[rateTiming.DestinationRatesTag] { - _, exists := activationPeriods[rateTiming.Tag] - if !exists { - activationPeriods[rateTiming.Tag] = &ActivationPeriod{} + for _, drate := range drm[destrateTiming.DestinationRatesTag] { + rt, err := dbr.storDB.GetTpRates(dbr.tpid, drate.RateTag) + if err != nil { + return nil, err + } else if len(rt)==0 { + return nil, fmt.Errorf("No Rates profile with id: %s", drate.RateTag) } - activationPeriods[rateTiming.Tag].AddIntervalIfNotPresent(rateTiming.GetInterval(drate)) + drate.Rate = rt[drate.RateTag] + if _, exists := activationPeriods[destrateTiming.Tag]; !exists { + activationPeriods[destrateTiming.Tag] = &ActivationPeriod{} + } + activationPeriods[destrateTiming.Tag].AddIntervalIfNotPresent(destrateTiming.GetInterval(drate)) dm, err := dbr.storDB.GetTpDestinations(dbr.tpid, drate.DestinationsTag) if err != nil { return nil, err } for _, destination := range dm { - ap := activationPeriods[ratingProfile.ratesTimingTag] + ap := activationPeriods[ratingProfile.destRatesTimingTag] newAP := &ActivationPeriod{ActivationTime: at} newAP.Intervals = append(newAP.Intervals, ap.Intervals...) resultRatingProfile.AddActivationPeriodIfNotPresent(destination.Id, newAP) diff --git a/rater/loader_helpers.go b/rater/loader_helpers.go index b874029a2..d4f866cbd 100644 --- a/rater/loader_helpers.go +++ b/rater/loader_helpers.go @@ -44,7 +44,10 @@ type TPLoader interface { type Rate struct { Tag string - ConnectFee, Price, PricedUnits, RateIncrements, Weight float64 + ConnectFee, Price, PricedUnits, RateIncrements float64 + RoundingMethod string + RoundingDecimals int + Weight float64 } func NewRate(tag, connectFee, price, pricedUnits, rateIncrements, weight string) (r *Rate, err error) { diff --git a/rater/ratingprofile.go b/rater/ratingprofile.go index 4e84cc905..12586140f 100644 --- a/rater/ratingprofile.go +++ b/rater/ratingprofile.go @@ -32,7 +32,8 @@ type RatingProfile struct { Id string FallbackKey string DestinationMap map[string][]*ActivationPeriod - tag, ratesTimingTag, activationTime string // used only for loading + tag, destRatesTimingTag string // used only for loading + activationTime int64 } // Adds an activation period that applyes to current rating profile if not already present. diff --git a/rater/storage_sql.go b/rater/storage_sql.go index ff4264a0f..02dab59e1 100644 --- a/rater/storage_sql.go +++ b/rater/storage_sql.go @@ -630,18 +630,19 @@ func (self *SQLStorage) GetAllRatedCdr() ([]utils.CDR, error) { func (self *SQLStorage) GetTpDestinations(tpid, tag string) ([]*Destination, error) { var dests []*Destination - q := fmt.Sprintf("SELECT * FROM %s WHERE tpid=%s", utils.TBL_TP_DESTINATIONS, tpid) + q := fmt.Sprintf("SELECT * FROM %s WHERE tpid='%s'", utils.TBL_TP_DESTINATIONS, tpid) if tag != "" { - q += "AND tag=" + tag + q += fmt.Sprintf(" AND tag='%s'", tag) } - rows, err := self.Db.Query(q, tpid) + rows, err := self.Db.Query(q) if err != nil { return nil, err } + defer rows.Close() for rows.Next() { var id int var tpid, tag, prefix string - if err := rows.Scan(id, tpid, &tag, &prefix); err != nil { + if err := rows.Scan(&id, &tpid, &tag, &prefix); err != nil { return nil, err } var dest *Destination @@ -657,78 +658,80 @@ func (self *SQLStorage) GetTpDestinations(tpid, tag string) ([]*Destination, err } dest.Prefixes = append(dest.Prefixes, prefix) } - return dests, rows.Err() + return dests, nil } func (self *SQLStorage) GetTpRates(tpid, tag string) (map[string]*Rate, error) { rts := make(map[string]*Rate) - q := fmt.Sprintf("SELECT * FROM %s WHERE tpid=%s", utils.TBL_TP_RATES, tpid) + q := fmt.Sprintf("SELECT tag, connect_fee, rate, rated_units, rate_increments, rounding_method, rounding_decimals, weight FROM %s WHERE tpid='%s' ", utils.TBL_TP_RATES, tpid) if tag != "" { - q += "AND tag=" + tag + q += fmt.Sprintf(" AND tag='%s'", tag) } - rows, err := self.Db.Query(q, tpid) + rows, err := self.Db.Query(q) if err != nil { return nil, err } + defer rows.Close() for rows.Next() { - var id int - var tpid, tag string - var connect_fee, rate, priced_units, rate_increments float64 - if err := rows.Scan(&id, &tpid, &tag, &connect_fee, &rate, &priced_units, &rate_increments); err != nil { + var tag, roundingMethod string + var connect_fee, rate, priced_units, rate_increments, weight float64 + var roundingDecimals int + if err := rows.Scan(&tag, &connect_fee, &rate, &priced_units, &rate_increments, &roundingMethod, &roundingDecimals, &weight); err != nil { return nil, err } - r := &Rate{ Tag: tag, ConnectFee: connect_fee, Price: rate, PricedUnits: priced_units, RateIncrements: rate_increments, + RoundingMethod: roundingMethod, + RoundingDecimals: roundingDecimals, + Weight: weight, } - rts[tag] = r } - return rts, rows.Err() + return rts, nil } func (self *SQLStorage) GetTpDestinationRates(tpid, tag string) (map[string][]*DestinationRate, error) { rts := make(map[string][]*DestinationRate) - q := fmt.Sprintf("SELECT * FROM %s WHERE tpid=%s", utils.TBL_TP_DESTINATION_RATES, tpid) + q := fmt.Sprintf("SELECT * FROM %s WHERE tpid='%s'", utils.TBL_TP_DESTINATION_RATES, tpid) if tag != "" { - q += "AND tag=" + tag + q += fmt.Sprintf(" AND tag='%s'", tag) } - rows, err := self.Db.Query(q, tpid) + rows, err := self.Db.Query(q) if err != nil { return nil, err } + defer rows.Close() for rows.Next() { var id int var tpid, tag, destinations_tag, rate_tag string - if err := rows.Scan(&id, &tpid, &tag, destinations_tag, rate_tag); err != nil { + if err := rows.Scan(&id, &tpid, &tag, &destinations_tag, &rate_tag); err != nil { return nil, err } - dr := &DestinationRate{ Tag: tag, DestinationsTag: destinations_tag, RateTag: rate_tag, } - rts[tag] = append(rts[tag], dr) } - return rts, rows.Err() + return rts, nil } func (self *SQLStorage) GetTpTimings(tpid, tag string) (map[string]*Timing, error) { tms := make(map[string]*Timing) - q := fmt.Sprintf("SELECT * FROM %s WHERE tpid=%s", utils.TBL_TP_TIMINGS, tpid) + q := fmt.Sprintf("SELECT * FROM %s WHERE tpid='%s'", utils.TBL_TP_TIMINGS, tpid) if tag != "" { - q += "AND tag=" + tag + q += fmt.Sprintf(" AND tag='%s'", tag) } - rows, err := self.Db.Query(q, tpid) + rows, err := self.Db.Query(q) if err != nil { return nil, err } + defer rows.Close() for rows.Next() { var id int var tpid, tag, years, months, month_days, week_days, start_time string @@ -737,19 +740,20 @@ func (self *SQLStorage) GetTpTimings(tpid, tag string) (map[string]*Timing, erro } tms[tag] = NewTiming(tag, years, months, month_days, week_days, start_time) } - return tms, rows.Err() + return tms, nil } func (self *SQLStorage) GetTpDestinationRateTimings(tpid, tag string) ([]*DestinationRateTiming, error) { var rts []*DestinationRateTiming - q := fmt.Sprintf("SELECT * FROM %s WHERE tpid=%s", utils.TBL_TP_DESTRATE_TIMINGS, tpid) + q := fmt.Sprintf("SELECT * FROM %s WHERE tpid='%s'", utils.TBL_TP_DESTRATE_TIMINGS, tpid) if tag != "" { - q += "AND tag=" + tag + q += fmt.Sprintf(" AND tag='%s'", tag) } - rows, err := self.Db.Query(q, tpid) + rows, err := self.Db.Query(q) if err != nil { return nil, err } + defer rows.Close() for rows.Next() { var id int var weight float64 @@ -765,24 +769,25 @@ func (self *SQLStorage) GetTpDestinationRateTimings(tpid, tag string) ([]*Destin } rts = append(rts, rt) } - return rts, rows.Err() + return rts, nil } func (self *SQLStorage) GetTpRatingProfiles(tpid, tag string) (map[string]*RatingProfile, error) { rpfs := make(map[string]*RatingProfile) - q := fmt.Sprintf("SELECT * FROM %s WHERE tpid=%s", utils.TBL_TP_RATE_PROFILES, tpid) + q := fmt.Sprintf("SELECT tag,tenant,tor,direction,subject,activation_time,destrates_timing_tag,rates_fallback_subject FROM %s WHERE tpid='%s'", + utils.TBL_TP_RATE_PROFILES, tpid) if tag != "" { - q += "AND tag=" + tag + q += fmt.Sprintf(" AND tag='%s'", tag) } - rows, err := self.Db.Query(q, tpid) + rows, err := self.Db.Query(q) if err != nil { return nil, err } + defer rows.Close() for rows.Next() { - var id int - var tpid, tag, tenant, tor, direction, subject, fallback_subject, rates_timing_tag, activation_time string - - if err := rows.Scan(&id, &tag, &tpid, &tenant, &tor, &direction, &subject, &fallback_subject, &rates_timing_tag, &activation_time); err != nil { + var tag, tenant, tor, direction, subject, fallback_subject, destrates_timing_tag string + var activation_time int64 + if err := rows.Scan(&tag, &tenant, &tor, &direction, &subject, &activation_time, &destrates_timing_tag, &fallback_subject); err != nil { return nil, err } key := fmt.Sprintf("%s:%s:%s:%s", direction, tenant, tor, subject) @@ -791,24 +796,25 @@ func (self *SQLStorage) GetTpRatingProfiles(tpid, tag string) (map[string]*Ratin rp = &RatingProfile{Id: key, tag: tag} rpfs[key] = rp } - rp.ratesTimingTag = rates_timing_tag + rp.destRatesTimingTag = destrates_timing_tag rp.activationTime = activation_time if fallback_subject != "" { rp.FallbackKey = fmt.Sprintf("%s:%s:%s:%s", direction, tenant, tor, fallback_subject) } } - return rpfs, rows.Err() + return rpfs, nil } func (self *SQLStorage) GetTpActions(tpid, tag string) (map[string][]*Action, error) { as := make(map[string][]*Action) - q := fmt.Sprintf("SELECT * FROM %s WHERE tpid=%s", utils.TBL_TP_ACTIONS, tpid) + q := fmt.Sprintf("SELECT * FROM %s WHERE tpid='%s'", utils.TBL_TP_ACTIONS, tpid) if tag != "" { - q += "AND tag=" + tag + q += fmt.Sprintf(" AND tag='%s'", tag) } - rows, err := self.Db.Query(q, tpid) + rows, err := self.Db.Query(q) if err != nil { return nil, err } + defer rows.Close() for rows.Next() { var id int var units, rate, minutes_weight, weight float64 @@ -849,19 +855,20 @@ func (self *SQLStorage) GetTpActions(tpid, tag string) (map[string][]*Action, er } as[tag] = append(as[tag], a) } - return as, rows.Err() + return as, nil } func (self *SQLStorage) GetTpActionTimings(tpid, tag string) (ats map[string][]*ActionTiming, err error) { ats = make(map[string][]*ActionTiming) - q := fmt.Sprintf("SELECT * FROM %s WHERE tpid=%s", utils.TBL_TP_ACTION_TIMINGS, tpid) + q := fmt.Sprintf("SELECT * FROM %s WHERE tpid='%s'", utils.TBL_TP_ACTION_TIMINGS, tpid) if tag != "" { - q += "AND tag=" + tag + q += fmt.Sprintf(" AND tag='%s'", tag) } - rows, err := self.Db.Query(q, tpid) + rows, err := self.Db.Query(q) if err != nil { return nil, err } + defer rows.Close() for rows.Next() { var id int var weight float64 @@ -878,19 +885,20 @@ func (self *SQLStorage) GetTpActionTimings(tpid, tag string) (ats map[string][]* } ats[tag] = append(ats[tag], at) } - return ats, rows.Err() + return ats, nil } func (self *SQLStorage) GetTpActionTriggers(tpid, tag string) (map[string][]*ActionTrigger, error) { ats := make(map[string][]*ActionTrigger) - q := fmt.Sprintf("SELECT * FROM %s WHERE tpid=%s", utils.TBL_TP_ACTION_TRIGGERS, tpid) + q := fmt.Sprintf("SELECT * FROM %s WHERE tpid='%s'", utils.TBL_TP_ACTION_TRIGGERS, tpid) if tag != "" { - q += "AND tag=" + tag + q += fmt.Sprintf(" AND tag='%s'", tag) } - rows, err := self.Db.Query(q, tpid) + rows, err := self.Db.Query(q) if err != nil { return nil, err } + defer rows.Close() for rows.Next() { var id int var threshold, weight float64 @@ -910,19 +918,20 @@ func (self *SQLStorage) GetTpActionTriggers(tpid, tag string) (map[string][]*Act } ats[tag] = append(ats[tag], at) } - return ats, rows.Err() + return ats, nil } func (self *SQLStorage) GetTpAccountActions(tpid, tag string) ([]*AccountAction, error) { var acs []*AccountAction - q := fmt.Sprintf("SELECT * FROM %s WHERE tpid=%s", utils.TBL_TP_ACCOUNT_ACTIONS, tpid) + q := fmt.Sprintf("SELECT * FROM %s WHERE tpid='%s'", utils.TBL_TP_ACCOUNT_ACTIONS, tpid) if tag != "" { - q += "AND tag=" + tag + q += fmt.Sprintf(" AND tag='%s'", tag) } - rows, err := self.Db.Query(q, tpid) + rows, err := self.Db.Query(q) if err != nil { return nil, err } + defer rows.Close() for rows.Next() { var id int var tpid, tenant, account, direction, action_timings_tag, action_triggers_tag string @@ -939,5 +948,5 @@ func (self *SQLStorage) GetTpAccountActions(tpid, tag string) ([]*AccountAction, } acs = append(acs, aa) } - return acs, rows.Err() + return acs, nil }