add rating profile tp and apier methods

This commit is contained in:
Radu Ioan Fericean
2014-08-25 16:26:18 +03:00
parent c1d5f00956
commit f30b3dc063
5 changed files with 172 additions and 53 deletions

View File

@@ -147,7 +147,7 @@ func (self *ApierV1) RemTPAccountActions(attrs AttrGetTPAccountActions, reply *s
if err := aa.SetAccountActionId(attrs.AccountActionsId); err != nil {
return err
}
if err := self.StorDb.RemTPData(utils.TBL_TP_ACCOUNT_ACTIONS, aa.Tpid, aa.Loadid, aa.Tenant, aa.Account, aa.Direction); err != nil {
if err := self.StorDb.RemTPData(utils.TBL_TP_ACCOUNT_ACTIONS, aa.Tpid, aa.Loadid, aa.Direction, aa.Tenant, aa.Account); err != nil {
return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error())
} else {
*reply = "OK"

View File

@@ -24,6 +24,7 @@ import (
"errors"
"fmt"
"github.com/cgrates/cgrates/engine"
"github.com/cgrates/cgrates/utils"
)
@@ -39,13 +40,13 @@ func (self *ApierV1) SetTPRatingProfile(attrs utils.TPRatingProfile, reply *stri
return nil
}
type AttrGetTPRatingProfile struct {
type AttrGetTPRatingProfileByLoadId struct {
TPid string // Tariff plan id
LoadId string // RatingProfile id
}
// Queries specific RatingProfile on tariff plan
func (self *ApierV1) GetTPRatingProfiles(attrs utils.TPRatingProfile, reply *[]*utils.TPRatingProfile) error {
func (self *ApierV1) GetTPRatingProfilesByLoadId(attrs utils.TPRatingProfile, reply *[]*utils.TPRatingProfile) error {
mndtryFlds := []string{"TPid", "LoadId"}
if len(attrs.Subject) != 0 { // If Subject provided as filter, make all related fields mandatory
mndtryFlds = append(mndtryFlds, "Tenant", "TOR", "Direction", "Subject")
@@ -91,12 +92,67 @@ func (self *ApierV1) GetTPRatingProfileLoadIds(attrs utils.AttrTPRatingProfileId
return nil
}
// Removes specific RatingProfile on Tariff plan
func (self *ApierV1) RemTPRatingProfile(attrs utils.TPRatingProfile, reply *string) error {
if missing := utils.MissingStructFields(&attrs, []string{"TPid", "LoadId", "Tenant", "TOR", "Direction", "Subject"}); len(missing) != 0 { //Params missing
type AttrGetTPRatingProfiles struct {
TPid string // Tariff plan id
RatingProfilesId string // RatingProfile id
}
// Queries specific RatingProfile on tariff plan
func (self *ApierV1) GetTPRatingProfiles(attrs AttrGetTPRatingProfiles, reply *utils.TPRatingProfile) error {
if missing := utils.MissingStructFields(&attrs, []string{"TPid", "RatingProfilesId"}); len(missing) != 0 { //Params missing
return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing)
}
if err := self.StorDb.RemTPData(utils.TBL_TP_RATE_PROFILES, attrs.TPid, attrs.LoadId, attrs.Tenant, attrs.Category, attrs.Direction, attrs.Subject); err != nil {
tmpRpf := &utils.TPRatingProfile{TPid: attrs.TPid}
if err := tmpRpf.SetRatingProfilesId(attrs.RatingProfilesId); err != nil {
return err
}
if rpfs, err := self.StorDb.GetTpRatingProfiles(tmpRpf); err != nil {
return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error())
} else if len(rpfs) == 0 {
return errors.New(utils.ERR_NOT_FOUND)
} else {
rpf := rpfs[tmpRpf.KeyId()]
tpdc := utils.TPRatingProfile{
TPid: attrs.TPid,
RatingPlanActivations: rpf.RatingPlanActivations,
}
if err := tpdc.SetRatingProfilesId(attrs.RatingProfilesId); err != nil {
return err
}
*reply = tpdc
}
return nil
}
type AttrGetTPRatingProfileIds struct {
TPid string // Tariff plan id
}
// Queries RatingProfiles identities on specific tariff plan.
func (self *ApierV1) GetTPRatingProfileIds(attrs AttrGetTPRatingProfileIds, reply *[]string) error {
if missing := utils.MissingStructFields(&attrs, []string{"TPid"}); len(missing) != 0 { //Params missing
return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing)
}
if ids, err := self.StorDb.GetTPTableIds(attrs.TPid, utils.TBL_TP_RATE_PROFILES, utils.TPDistinctIds{"loadid", "direction", "tenant", "category", "subject"}, nil); err != nil {
return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error())
} else if ids == nil {
return errors.New(utils.ERR_NOT_FOUND)
} else {
*reply = ids
}
return nil
}
// Removes specific RatingProfiles on Tariff plan
func (self *ApierV1) RemTPRatingProfiles(attrs AttrGetTPRatingProfiles, reply *string) error {
if missing := utils.MissingStructFields(&attrs, []string{"TPid", "RatingProfilesId"}); len(missing) != 0 { //Params missing
return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing)
}
tmpRpf := engine.TpRatingProfile{}
if err := tmpRpf.SetRatingProfileId(attrs.RatingProfilesId); err != nil {
return err
}
if err := self.StorDb.RemTPData(utils.TBL_TP_RATE_PROFILES, attrs.TPid, tmpRpf.Loadid, tmpRpf.Direction, tmpRpf.Tenant, tmpRpf.Category, tmpRpf.Subject); err != nil {
return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error())
} else {
*reply = "OK"

View File

@@ -76,6 +76,32 @@ type TpRatingPlan struct {
Weight float64
}
type TpRatingProfile struct {
Tbid int64 `gorm:"primary_key:yes"`
Tpid string
Loadid string
Direction string
Tenant string
Category string
Subject string
ActivationTime string
RatingPlanId string
FallbackSubjects string
}
func (rpf *TpRatingProfile) SetRatingProfileId(id string) error {
ids := strings.Split(id, utils.TP_ID_SEP)
if len(ids) != 5 {
return fmt.Errorf("Wrong TP Rating Profile Id: %s", id)
}
rpf.Loadid = ids[0]
rpf.Direction = ids[1]
rpf.Tenant = ids[2]
rpf.Category = ids[3]
rpf.Subject = ids[4]
return nil
}
type TpLcrRules struct {
Tbid int64 `gorm:"primary_key:yes"`
Tpid string
@@ -152,7 +178,7 @@ type TpAccountAction struct {
func (aa *TpAccountAction) SetAccountActionId(id string) error {
ids := strings.Split(id, utils.TP_ID_SEP)
if len(ids) != 4 {
return fmt.Errorf("Wrong TP Account Action Id!")
return fmt.Errorf("Wrong TP Account Action Id: %s", id)
}
aa.Loadid = ids[0]
aa.Direction = ids[1]

View File

@@ -163,10 +163,10 @@ func (self *SQLStorage) RemTPData(table, tpid string, args ...string) error {
q := fmt.Sprintf("DELETE FROM %s WHERE tpid='%s' AND id='%s'", table, tpid, args[0])
switch table {
case utils.TBL_TP_RATE_PROFILES:
q = fmt.Sprintf("DELETE FROM %s WHERE tpid='%s' AND loadid='%s' AND tenant='%s' AND category='%s' AND direction='%s' AND subject='%s'",
q = fmt.Sprintf("DELETE FROM %s WHERE tpid='%s' AND loadid='%s' AND direction='%s' AND tenant='%s' AND category='%s' AND subject='%s'",
table, tpid, args[0], args[1], args[2], args[3], args[4])
case utils.TBL_TP_ACCOUNT_ACTIONS:
q = fmt.Sprintf("DELETE FROM %s WHERE tpid='%s' AND loadid='%s' AND tenant='%s' AND account='%s' AND direction='%s'",
q = fmt.Sprintf("DELETE FROM %s WHERE tpid='%s' AND loadid='%s' AND direction='%s' AND tenant='%s' AND account='%s'",
table, tpid, args[0], args[1], args[2], args[3])
case utils.TBL_TP_DERIVED_CHARGERS:
q = fmt.Sprintf("DELETE FROM %s WHERE tpid='%s' AND loadid='%s' AND direction='%s' AND tenant='%s' AND category='%s' AND account='%s' AND subject='%s'",
@@ -264,28 +264,35 @@ func (self *SQLStorage) SetTPRatingPlans(tpid string, drts map[string][]*utils.T
return nil
}
func (self *SQLStorage) SetTPRatingProfiles(tpid string, rps map[string]*utils.TPRatingProfile) error {
if len(rps) == 0 {
func (self *SQLStorage) SetTPRatingProfiles(tpid string, rpfs map[string]*utils.TPRatingProfile) error {
if len(rpfs) == 0 {
return nil //Nothing to set
}
var buffer bytes.Buffer
buffer.WriteString(fmt.Sprintf("INSERT INTO %s (tpid,loadid,direction,tenant,category,subject,activation_time,rating_plan_id,fallback_subjects) VALUES ",
utils.TBL_TP_RATE_PROFILES))
i := 0
for _, rp := range rps {
for _, rpa := range rp.RatingPlanActivations {
if i != 0 { //Consecutive values after the first will be prefixed with "," as separator
buffer.WriteRune(',')
}
buffer.WriteString(fmt.Sprintf("('%s', '%s', '%s', '%s', '%s', '%s', '%s','%s','%s')", tpid, rp.LoadId, rp.Direction, rp.Tenant, rp.Category,
rp.Subject, rpa.ActivationTime, rpa.RatingPlanId, rpa.FallbackSubjects))
i++
tx := self.db.Begin()
for _, rpf := range rpfs {
// parse identifiers
tx.Where("tpid = ?", tpid).
Where("direction = ?", rpf.Direction).
Where("tenant = ?", rpf.Tenant).
Where("subject = ?", rpf.Subject).
Where("category = ?", rpf.Category).
Where("loadid = ?", rpf.LoadId).
Delete(TpRatingProfile{})
for _, ra := range rpf.RatingPlanActivations {
tx.Save(TpRatingProfile{
Tpid: rpf.TPid,
Loadid: rpf.LoadId,
Tenant: rpf.Tenant,
Category: rpf.Category,
Subject: rpf.Subject,
Direction: rpf.Direction,
ActivationTime: ra.ActivationTime,
RatingPlanId: ra.RatingPlanId,
FallbackSubjects: ra.FallbackSubjects,
})
}
}
buffer.WriteString(" ON DUPLICATE KEY UPDATE fallback_subjects=values(fallback_subjects)")
if _, err := self.Db.Exec(buffer.String()); err != nil {
return err
}
tx.Commit()
return nil
}
@@ -1238,44 +1245,50 @@ func (self *SQLStorage) GetTpRatingPlans(tpid, tag string) (map[string][]*utils.
}
func (self *SQLStorage) GetTpRatingProfiles(qryRpf *utils.TPRatingProfile) (map[string]*utils.TPRatingProfile, error) {
q := fmt.Sprintf("SELECT loadid,direction,tenant,category,subject,activation_time,rating_plan_id,fallback_subjects FROM %s WHERE tpid='%s'",
utils.TBL_TP_RATE_PROFILES, qryRpf.TPid)
if len(qryRpf.LoadId) != 0 {
q += fmt.Sprintf(" AND loadid='%s'", qryRpf.LoadId)
}
rpfs := make(map[string]*utils.TPRatingProfile)
var tpRpfs []TpRatingProfile
q := self.db.Where("tpid = ?", qryRpf.TPid)
if len(qryRpf.Direction) != 0 {
q += fmt.Sprintf(" AND direction='%s'", qryRpf.Direction)
q = q.Where("direction = ?", qryRpf.Direction)
}
if len(qryRpf.Tenant) != 0 {
q += fmt.Sprintf(" AND tenant='%s'", qryRpf.Tenant)
q = q.Where("tenant = ?", qryRpf.Tenant)
}
if len(qryRpf.Category) != 0 {
q += fmt.Sprintf(" AND category='%s'", qryRpf.Category)
q = q.Where("category = ?", qryRpf.Category)
}
if len(qryRpf.Subject) != 0 {
q += fmt.Sprintf(" AND subject='%s'", qryRpf.Subject)
q = q.Where("subject = ?", qryRpf.Subject)
}
rows, err := self.Db.Query(q)
if err != nil {
if len(qryRpf.LoadId) != 0 {
q = q.Where("loadid = ?", qryRpf.LoadId)
}
if err := q.Find(&tpRpfs).Error; err != nil {
return nil, err
}
defer rows.Close()
rpfs := make(map[string]*utils.TPRatingProfile)
for rows.Next() {
var rcvLoadId, tenant, category, direction, subject, fallback_subjects, rating_plan_tag, activation_time string
if err := rows.Scan(&rcvLoadId, &direction, &tenant, &category, &subject, &activation_time, &rating_plan_tag, &fallback_subjects); err != nil {
return nil, err
for _, tpRpf := range tpRpfs {
rp := &utils.TPRatingProfile{
TPid: tpRpf.Tpid,
LoadId: tpRpf.Loadid,
Direction: tpRpf.Direction,
Tenant: tpRpf.Tenant,
Category: tpRpf.Category,
Subject: tpRpf.Subject,
}
rp := &utils.TPRatingProfile{TPid: qryRpf.TPid, LoadId: rcvLoadId, Direction: direction, Tenant: tenant, Category: category, Subject: subject}
if existingRp, has := rpfs[rp.KeyId()]; !has {
rp.RatingPlanActivations = []*utils.TPRatingActivation{
&utils.TPRatingActivation{ActivationTime: activation_time, RatingPlanId: rating_plan_tag, FallbackSubjects: fallback_subjects}}
ra := &utils.TPRatingActivation{
ActivationTime: tpRpf.ActivationTime,
RatingPlanId: tpRpf.RatingPlanId,
FallbackSubjects: tpRpf.FallbackSubjects,
}
if existingRpf, exists := rpfs[rp.KeyId()]; !exists {
rp.RatingPlanActivations = []*utils.TPRatingActivation{ra}
rpfs[rp.KeyId()] = rp
} else { // Exists, update
existingRp.RatingPlanActivations = append(existingRp.RatingPlanActivations,
&utils.TPRatingActivation{ActivationTime: activation_time, RatingPlanId: rating_plan_tag, FallbackSubjects: fallback_subjects})
existingRpf.RatingPlanActivations = append(existingRpf.RatingPlanActivations, ra)
}
}
return rpfs, nil
}

View File

@@ -170,11 +170,35 @@ func (self *TPRatingProfile) KeyId() string {
return fmt.Sprintf("%s:%s:%s:%s", self.Direction, self.Tenant, self.Category, self.Subject)
}
func (rpf *TPRatingProfile) GetRatingProfilesId() string {
return rpf.LoadId +
TP_ID_SEP +
rpf.Direction +
TP_ID_SEP +
rpf.Tenant +
TP_ID_SEP +
rpf.Category +
TP_ID_SEP +
rpf.Subject
}
func (rpf *TPRatingProfile) SetRatingProfilesId(id string) error {
ids := strings.Split(id, TP_ID_SEP)
if len(ids) != 5 {
return fmt.Errorf("Wrong TP Rating Profiles Id: %s", id)
}
rpf.LoadId = ids[0]
rpf.Direction = ids[1]
rpf.Tenant = ids[2]
rpf.Category = ids[3]
rpf.Subject = ids[4]
return nil
}
type TPRatingActivation struct {
ActivationTime string // Time when this profile will become active, defined as unix epoch time
RatingPlanId string // Id of RatingPlan profile
FallbackSubjects string // So we follow the api
Weight float64
}
// Helper to return the subject fallback keys we need in dataDb