mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-24 00:28:44 +05:00
Various loader and apier fixes
This commit is contained in:
@@ -27,10 +27,10 @@ import (
|
||||
// Creates a new AccountActions profile within a tariff plan
|
||||
func (self *ApierV1) SetTPAccountActions(attrs utils.TPAccountActions, reply *string) error {
|
||||
if missing := utils.MissingStructFields(&attrs,
|
||||
[]string{"TPid", "AccountActionsId", "Tenant", "Account", "Direction", "ActionTimingsId", "ActionTriggersId"}); len(missing) != 0 {
|
||||
[]string{"TPid", "LoadId", "Tenant", "Account", "Direction", "ActionTimingsId", "ActionTriggersId"}); len(missing) != 0 {
|
||||
return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing)
|
||||
}
|
||||
if err := self.StorDb.SetTPAccountActions(attrs.TPid, map[string]*utils.TPAccountActions{attrs.AccountActionsId: &attrs}); err != nil {
|
||||
if err := self.StorDb.SetTPAccountActions(attrs.TPid, map[string]*utils.TPAccountActions{attrs.KeyId(): &attrs}); err != nil {
|
||||
return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error())
|
||||
}
|
||||
*reply = "OK"
|
||||
@@ -39,26 +39,33 @@ func (self *ApierV1) SetTPAccountActions(attrs utils.TPAccountActions, reply *st
|
||||
|
||||
type AttrGetTPAccountActions struct {
|
||||
TPid string // Tariff plan id
|
||||
AccountActionsId string // AccountActions id
|
||||
LoadId string // AccountActions id
|
||||
|
||||
}
|
||||
|
||||
// Queries specific AccountActions profile on tariff plan
|
||||
func (self *ApierV1) GetTPAccountActions(attrs AttrGetTPAccountActions, reply *utils.TPAccountActions) error {
|
||||
if missing := utils.MissingStructFields(&attrs, []string{"TPid", "AccountActionsId"}); len(missing) != 0 { //Params missing
|
||||
func (self *ApierV1) GetTPAccountActions(attrs utils.TPAccountActions, reply *[]*utils.TPAccountActions) error {
|
||||
mndtryFlds := []string{"TPid", "LoadId"}
|
||||
if len(attrs.Account) != 0 { // If account provided as filter, make all related fields mandatory
|
||||
mndtryFlds = append(mndtryFlds, "Tenant", "Account", "Direction")
|
||||
}
|
||||
if missing := utils.MissingStructFields(&attrs, mndtryFlds); len(missing) != 0 { //Params missing
|
||||
return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing)
|
||||
}
|
||||
if aa, err := self.StorDb.GetTpAccountActions(attrs.TPid, attrs.AccountActionsId); err != nil {
|
||||
if aa, err := self.StorDb.GetTpAccountActions(&attrs); err != nil {
|
||||
return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error())
|
||||
} else if len(aa) == 0 {
|
||||
return errors.New(utils.ERR_NOT_FOUND)
|
||||
} else {
|
||||
*reply = utils.TPAccountActions{TPid: attrs.TPid,
|
||||
AccountActionsId: attrs.AccountActionsId,
|
||||
Tenant: aa[attrs.AccountActionsId].Tenant,
|
||||
Account: aa[attrs.AccountActionsId].Account,
|
||||
Direction: aa[attrs.AccountActionsId].Direction,
|
||||
ActionTimingsId: aa[attrs.AccountActionsId].ActionTimingsTag,
|
||||
ActionTriggersId: aa[attrs.AccountActionsId].ActionTriggersTag}
|
||||
var acts []*utils.TPAccountActions
|
||||
if len(attrs.Account) != 0 {
|
||||
acts = []*utils.TPAccountActions{aa[attrs.KeyId()]}
|
||||
} else {
|
||||
for _, actLst := range aa {
|
||||
acts = append(acts, actLst)
|
||||
}
|
||||
}
|
||||
*reply = acts
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -68,7 +75,7 @@ type AttrGetTPAccountActionIds struct {
|
||||
}
|
||||
|
||||
// Queries AccountActions identities on specific tariff plan.
|
||||
func (self *ApierV1) GetTPAccountActionIds(attrs AttrGetTPAccountActionIds, reply *[]string) error {
|
||||
func (self *ApierV1) GetTPAccountActionLoadIds(attrs AttrGetTPAccountActionIds, 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)
|
||||
}
|
||||
@@ -83,11 +90,11 @@ func (self *ApierV1) GetTPAccountActionIds(attrs AttrGetTPAccountActionIds, repl
|
||||
}
|
||||
|
||||
// Removes specific AccountActions on Tariff plan
|
||||
func (self *ApierV1) RemTPAccountActions(attrs AttrGetTPAccountActions, reply *string) error {
|
||||
if missing := utils.MissingStructFields(&attrs, []string{"TPid", "AccountActionsId"}); len(missing) != 0 { //Params missing
|
||||
func (self *ApierV1) RemTPAccountActions(attrs utils.TPAccountActions, reply *string) error {
|
||||
if missing := utils.MissingStructFields(&attrs, []string{"TPid", "LoadId", "Tenant", "Account", "Direction"}); len(missing) != 0 { //Params missing
|
||||
return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing)
|
||||
}
|
||||
if err := self.StorDb.RemTPData(utils.TBL_TP_ACCOUNT_ACTIONS, attrs.TPid, attrs.AccountActionsId); err != nil {
|
||||
if err := self.StorDb.RemTPData(utils.TBL_TP_ACCOUNT_ACTIONS, attrs.TPid, attrs.LoadId, attrs.Tenant, attrs.Account, attrs.Direction); err != nil {
|
||||
return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error())
|
||||
} else {
|
||||
*reply = "OK"
|
||||
|
||||
@@ -28,10 +28,10 @@ import (
|
||||
|
||||
// Creates a new DestinationRateTiming profile within a tariff plan
|
||||
func (self *ApierV1) SetTPRatingPlan(attrs utils.TPRatingPlan, reply *string) error {
|
||||
if missing := utils.MissingStructFields(&attrs, []string{"TPid", "RatingPlanId", "RatingPlans"}); len(missing) != 0 {
|
||||
if missing := utils.MissingStructFields(&attrs, []string{"TPid", "RatingPlanId", "RatingPlanBindings"}); len(missing) != 0 {
|
||||
return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing)
|
||||
}
|
||||
if err := self.StorDb.SetTPRatingPlans(attrs.TPid, map[string][]*utils.RatingPlan{attrs.RatingPlanId: attrs.RatingPlans}); err != nil {
|
||||
if err := self.StorDb.SetTPRatingPlans(attrs.TPid, map[string][]*utils.TPRatingPlanBinding{attrs.RatingPlanId: attrs.RatingPlanBindings}); err != nil {
|
||||
return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error())
|
||||
}
|
||||
*reply = "OK"
|
||||
|
||||
@@ -28,10 +28,10 @@ import (
|
||||
|
||||
// Creates a new RatingProfile within a tariff plan
|
||||
func (self *ApierV1) SetTPRatingProfile(attrs utils.TPRatingProfile, reply *string) error {
|
||||
if missing := utils.MissingStructFields(&attrs, []string{"TPid", "RatingProfileId", "Tenant", "TOR", "Direction", "Subject", "RatingPlanActivations"}); len(missing) != 0 {
|
||||
if missing := utils.MissingStructFields(&attrs, []string{"TPid", "LoadId", "Tenant", "TOR", "Direction", "Subject", "RatingPlanActivations"}); len(missing) != 0 {
|
||||
return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing)
|
||||
}
|
||||
if err := self.StorDb.SetTPRatingProfiles(attrs.TPid, map[string]*utils.TPRatingProfile{attrs.RatingProfileId: &attrs}); err != nil {
|
||||
if err := self.StorDb.SetTPRatingProfiles(attrs.TPid, map[string]*utils.TPRatingProfile{attrs.KeyId(): &attrs}); err != nil {
|
||||
return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error())
|
||||
}
|
||||
*reply = "OK"
|
||||
@@ -40,26 +40,38 @@ func (self *ApierV1) SetTPRatingProfile(attrs utils.TPRatingProfile, reply *stri
|
||||
|
||||
type AttrGetTPRatingProfile struct {
|
||||
TPid string // Tariff plan id
|
||||
RatingProfileId string // RatingProfile id
|
||||
LoadId string // RatingProfile id
|
||||
}
|
||||
|
||||
// Queries specific RatingProfile on tariff plan
|
||||
func (self *ApierV1) GetTPRatingProfile(attrs AttrGetTPRatingProfile, reply *utils.TPRatingProfile) error {
|
||||
if missing := utils.MissingStructFields(&attrs, []string{"TPid", "RatingProfileId"}); len(missing) != 0 { //Params missing
|
||||
func (self *ApierV1) GetTPRatingProfiles(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")
|
||||
}
|
||||
if missing := utils.MissingStructFields(&attrs, mndtryFlds); len(missing) != 0 { //Params missing
|
||||
return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing)
|
||||
}
|
||||
if dr, err := self.StorDb.GetTPRatingProfile(attrs.TPid, attrs.RatingProfileId); err != nil {
|
||||
if dr, err := self.StorDb.GetTpRatingProfiles(&attrs); err != nil {
|
||||
return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error())
|
||||
} else if dr == nil {
|
||||
return errors.New(utils.ERR_NOT_FOUND)
|
||||
} else {
|
||||
*reply = *dr
|
||||
var rpfs []*utils.TPRatingProfile
|
||||
if len(attrs.Subject) != 0 {
|
||||
rpfs = []*utils.TPRatingProfile{dr[attrs.KeyId()]}
|
||||
} else {
|
||||
for _, rpfLst := range dr {
|
||||
rpfs = append(rpfs, rpfLst)
|
||||
}
|
||||
}
|
||||
*reply = rpfs
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Queries RatingProfile identities on specific tariff plan.
|
||||
func (self *ApierV1) GetTPRatingProfileIds(attrs utils.AttrTPRatingProfileIds, reply *[]string) error {
|
||||
func (self *ApierV1) GetTPRatingProfileLoadIds(attrs utils.AttrTPRatingProfileIds, 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)
|
||||
}
|
||||
@@ -75,11 +87,11 @@ func (self *ApierV1) GetTPRatingProfileIds(attrs utils.AttrTPRatingProfileIds, r
|
||||
|
||||
|
||||
// Removes specific RatingProfile on Tariff plan
|
||||
func (self *ApierV1) RemTPRatingProfile(attrs AttrGetTPRatingProfile, reply *string) error {
|
||||
if missing := utils.MissingStructFields(&attrs, []string{"TPid", "RatingProfileId"}); len(missing) != 0 { //Params missing
|
||||
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
|
||||
return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing)
|
||||
}
|
||||
if err := self.StorDb.RemTPData(utils.TBL_TP_RATE_PROFILES, attrs.TPid, attrs.RatingProfileId); err != nil {
|
||||
if err := self.StorDb.RemTPData(utils.TBL_TP_RATE_PROFILES, attrs.TPid, attrs.LoadId, attrs.Tenant, attrs.TOR, attrs.Direction, attrs.Subject); err != nil {
|
||||
return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error())
|
||||
} else {
|
||||
*reply = "OK"
|
||||
|
||||
@@ -94,7 +94,7 @@ func (self *ApierV1) RemTPTiming(attrs AttrGetTPTiming, reply *string) error {
|
||||
if missing := utils.MissingStructFields(&attrs, []string{"TPid", "TimingId"}); len(missing) != 0 { //Params missing
|
||||
return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing)
|
||||
}
|
||||
if err := self.StorDb.RemTPData(utils.TBL_TP_RATES, attrs.TPid, attrs.TimingId); err != nil {
|
||||
if err := self.StorDb.RemTPData(utils.TBL_TP_TIMINGS, attrs.TPid, attrs.TimingId); err != nil {
|
||||
return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error())
|
||||
} else {
|
||||
*reply = "OK"
|
||||
|
||||
@@ -92,7 +92,7 @@ CREATE TABLE `tp_rating_plans` (
|
||||
CREATE TABLE `tp_rating_profiles` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`tpid` varchar(64) NOT NULL,
|
||||
`tag` varchar(64) NOT NULL,
|
||||
`loadid` varchar(64) NOT NULL,
|
||||
`tenant` varchar(64) NOT NULL,
|
||||
`tor` varchar(16) NOT NULL,
|
||||
`direction` varchar(8) NOT NULL,
|
||||
@@ -101,8 +101,8 @@ CREATE TABLE `tp_rating_profiles` (
|
||||
`rating_plan_tag` varchar(64) NOT NULL,
|
||||
`fallback_subjects` varchar(64),
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `tpid_tag` (`tpid`, `tag`),
|
||||
UNIQUE KEY `tpid_tag_tenant_tor_dir_subj_atime` (`tpid`,`tag`, `tenant`,`tor`,`direction`,`subject`,`activation_time`)
|
||||
KEY `tpid_tag` (`tpid`, `loadid`),
|
||||
UNIQUE KEY `tpid_tag_tenant_tor_dir_subj_atime` (`tpid`,`loadid`, `tenant`,`tor`,`direction`,`subject`,`activation_time`)
|
||||
);
|
||||
|
||||
--
|
||||
@@ -171,7 +171,7 @@ CREATE TABLE `tp_action_triggers` (
|
||||
CREATE TABLE `tp_account_actions` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`tpid` varchar(64) NOT NULL,
|
||||
`tag` varchar(64) NOT NULL,
|
||||
`loadid` varchar(64) NOT NULL,
|
||||
`tenant` varchar(64) NOT NULL,
|
||||
`account` varchar(64) NOT NULL,
|
||||
`direction` varchar(8) NOT NULL,
|
||||
@@ -179,5 +179,5 @@ CREATE TABLE `tp_account_actions` (
|
||||
`action_triggers_tag` varchar(64),
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `tpid` (`tpid`),
|
||||
UNIQUE KEY `unique_tp_account` (`tpid`,`tag`,`tenant`,`account`,`direction`)
|
||||
UNIQUE KEY `unique_tp_account` (`tpid`,`loadid`,`tenant`,`account`,`direction`)
|
||||
);
|
||||
|
||||
@@ -375,7 +375,7 @@ func (csvr *CSVReader) LoadRatingProfiles() (err error) {
|
||||
}
|
||||
if fallbacksubject != "" {
|
||||
var sslice utils.StringSlice = rpa.FallbackKeys
|
||||
for _, fbs := range strings.Split(fallbacksubject, ";") {
|
||||
for _, fbs := range strings.Split(fallbacksubject, FALLBACK_SEP) {
|
||||
newKey := fmt.Sprintf("%s:%s:%s:%s", direction, tenant, tor, fbs)
|
||||
if !sslice.Contains(newKey) {
|
||||
rpa.FallbackKeys = append(rpa.FallbackKeys, newKey)
|
||||
@@ -462,7 +462,7 @@ func (csvr *CSVReader) LoadActionTimings() (err error) {
|
||||
}
|
||||
at := &ActionTiming{
|
||||
Id: utils.GenUUID(),
|
||||
Tag: record[2],
|
||||
Tag: record[0],
|
||||
Weight: weight,
|
||||
Timing: &RateInterval{
|
||||
Timing: &RITiming{
|
||||
|
||||
@@ -604,7 +604,7 @@ func TestLoadActionTimings(t *testing.T) {
|
||||
atm := csvr.actionsTimings["MORE_MINUTES"][0]
|
||||
expected := &ActionTiming{
|
||||
Id: atm.Id,
|
||||
Tag: "ONE_TIME_RUN",
|
||||
Tag: "MORE_MINUTES",
|
||||
UserBalanceIds: []string{"*out:vdf:minitsboy"},
|
||||
Timing: &RateInterval{
|
||||
Timing: &RITiming{
|
||||
@@ -619,7 +619,7 @@ func TestLoadActionTimings(t *testing.T) {
|
||||
ActionsId: "MINI",
|
||||
}
|
||||
if !reflect.DeepEqual(atm, expected) {
|
||||
t.Error("Error loading action timing: ", atm)
|
||||
t.Error("Error loading action timing: ", atm, expected)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ func NewDbReader(storDB LoadStorage, storage DataStorage, tpid string) *DbReader
|
||||
c.dataDb = storage
|
||||
c.tpid = tpid
|
||||
c.actionsTimings = make(map[string][]*ActionTiming)
|
||||
c.actionsTriggers = make(map[string][]*ActionTrigger)
|
||||
c.ratingPlans = make(map[string]*RatingPlan)
|
||||
c.ratingProfiles = make(map[string]*RatingProfile)
|
||||
return c
|
||||
@@ -180,51 +181,52 @@ func (dbr *DbReader) LoadDestinationRates() (err error) {
|
||||
}
|
||||
|
||||
func (dbr *DbReader) LoadRatingPlans() error {
|
||||
drts, err := dbr.storDb.GetTpRatingPlans(dbr.tpid, "")
|
||||
mpRpls, err := dbr.storDb.GetTpRatingPlans(dbr.tpid, "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, drt := range drts.RatingPlans {
|
||||
t, exists := dbr.timings[drt.TimingId]
|
||||
if !exists {
|
||||
return errors.New(fmt.Sprintf("Could not get timing for tag %v", drt.TimingId))
|
||||
}
|
||||
drt.SetTiming(t)
|
||||
drs, exists := dbr.destinationRates[drt.DestinationRatesId]
|
||||
if !exists {
|
||||
return errors.New(fmt.Sprintf("Could not find destination rate for tag %v", drt.DestinationRatesId))
|
||||
}
|
||||
|
||||
plan, exists := dbr.ratingPlans[drts.RatingPlanId]
|
||||
if !exists {
|
||||
plan = &RatingPlan{Id: drts.RatingPlanId}
|
||||
dbr.ratingPlans[drts.RatingPlanId] = plan
|
||||
}
|
||||
for _, dr := range drs.DestinationRates {
|
||||
plan.AddRateInterval(dr.DestinationId, GetRateInterval(drt, dr))
|
||||
for tag, rplBnds := range mpRpls {
|
||||
for _,rplBnd := range rplBnds {
|
||||
t, exists := dbr.timings[rplBnd.TimingId]
|
||||
if !exists {
|
||||
return errors.New(fmt.Sprintf("Could not get timing for tag %v", rplBnd.TimingId))
|
||||
}
|
||||
rplBnd.SetTiming(t)
|
||||
drs, exists := dbr.destinationRates[rplBnd.DestinationRatesId]
|
||||
if !exists {
|
||||
return errors.New(fmt.Sprintf("Could not find destination rate for tag %v", rplBnd.DestinationRatesId))
|
||||
}
|
||||
plan, exists := dbr.ratingPlans[tag]
|
||||
if !exists {
|
||||
plan = &RatingPlan{Id: tag}
|
||||
dbr.ratingPlans[plan.Id] = plan
|
||||
}
|
||||
for _, dr := range drs.DestinationRates {
|
||||
plan.AddRateInterval(dr.DestinationId, GetRateInterval(rplBnd, dr))
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dbr *DbReader) LoadRatingProfiles() error {
|
||||
mpTpRpfs, err := dbr.storDb.GetTpRatingProfiles(dbr.tpid, "") //map[string]*utils.TPRatingProfile
|
||||
mpTpRpfs, err := dbr.storDb.GetTpRatingProfiles(&utils.TPRatingProfile{TPid:dbr.tpid}) //map[string]*utils.TPRatingProfile
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, tpRpf := range mpTpRpfs {
|
||||
rpf := &RatingProfile{Id: tpRpf.RatingProfileId}
|
||||
rpf := &RatingProfile{Id: tpRpf.KeyId()}
|
||||
for _, tpRa := range tpRpf.RatingPlanActivations {
|
||||
at, err := utils.ParseDate(tpRa.ActivationTime)
|
||||
if err != nil {
|
||||
return errors.New(fmt.Sprintf("Cannot parse activation time from %v", tpRa.ActivationTime))
|
||||
}
|
||||
_, exists := dbr.ratingPlans[rpf.Id]
|
||||
_, exists := dbr.ratingPlans[tpRa.RatingPlanId]
|
||||
if !exists {
|
||||
if dbExists, err := dbr.dataDb.ExistsData(RATING_PLAN_PREFIX, rpf.Id); err != nil {
|
||||
if dbExists, err := dbr.dataDb.ExistsData(RATING_PLAN_PREFIX, tpRa.RatingPlanId); err != nil {
|
||||
return err
|
||||
} else if !dbExists {
|
||||
return errors.New(fmt.Sprintf("Could not load rating plans for tag: %v", rpf.Id))
|
||||
return errors.New(fmt.Sprintf("Could not load rating plans for tag: %v", tpRa.RatingPlanId))
|
||||
}
|
||||
}
|
||||
rpf.RatingPlanActivations = append(rpf.RatingPlanActivations,
|
||||
@@ -234,81 +236,85 @@ func (dbr *DbReader) LoadRatingProfiles() error {
|
||||
FallbackKeys: strings.Split(tpRa.FallbackSubjects,FALLBACK_SEP),
|
||||
})
|
||||
}
|
||||
dbr.ratingProfiles[rpf.Id] = rpf
|
||||
dbr.ratingProfiles[tpRpf.KeyId()] = rpf
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dbr *DbReader) LoadRatingPlanByTag(tag string) error {
|
||||
ratingPlan := &RatingPlan{}
|
||||
rps, err := dbr.storDb.GetTpRatingPlans(dbr.tpid, tag)
|
||||
if err != nil || len(rps.RatingPlans) == 0 {
|
||||
mpRpls, err := dbr.storDb.GetTpRatingPlans(dbr.tpid, tag)
|
||||
if err != nil || len(mpRpls) == 0 {
|
||||
return fmt.Errorf("No DestRateTimings profile with id %s: %v", tag, err)
|
||||
}
|
||||
for _, rp := range rps.RatingPlans {
|
||||
Logger.Debug(fmt.Sprintf("Rating Plan: %v", rp))
|
||||
tm, err := dbr.storDb.GetTpTimings(dbr.tpid, rp.TimingId)
|
||||
Logger.Debug(fmt.Sprintf("Timing: %v", tm))
|
||||
if err != nil || len(tm) == 0 {
|
||||
return fmt.Errorf("No Timings profile with id %s: %v", rp.TimingId, err)
|
||||
}
|
||||
rp.SetTiming(tm[rp.TimingId])
|
||||
drm, err := dbr.storDb.GetTpDestinationRates(dbr.tpid, rp.DestinationRatesId)
|
||||
if err != nil || len(drm) == 0 {
|
||||
return fmt.Errorf("No DestinationRates profile with id %s: %v", rp.DestinationRatesId, err)
|
||||
}
|
||||
for _, drate := range drm[rp.DestinationRatesId].DestinationRates {
|
||||
Logger.Debug(fmt.Sprintf("Destination rate: %v", drate))
|
||||
rt, err := dbr.storDb.GetTpRates(dbr.tpid, drate.RateId)
|
||||
if err != nil || len(rt) == 0 {
|
||||
return fmt.Errorf("No Rates profile with id %s: %v", drate.RateId, err)
|
||||
for tag, rplBnds := range mpRpls {
|
||||
ratingPlan := &RatingPlan{Id: tag}
|
||||
for _, rp := range rplBnds {
|
||||
Logger.Debug(fmt.Sprintf("Rating Plan binding: %v", rp))
|
||||
tm, err := dbr.storDb.GetTpTimings(dbr.tpid, rp.TimingId)
|
||||
Logger.Debug(fmt.Sprintf("Timing: %v", tm))
|
||||
if err != nil || len(tm) == 0 {
|
||||
return fmt.Errorf("No Timings profile with id %s: %v", rp.TimingId, err)
|
||||
}
|
||||
Logger.Debug(fmt.Sprintf("Rate: %v", rt))
|
||||
drate.Rate = rt[drate.RateId]
|
||||
ratingPlan.AddRateInterval(drate.DestinationId, GetRateInterval(rp, drate))
|
||||
|
||||
dms, err := dbr.storDb.GetTpDestinations(dbr.tpid, drate.DestinationId)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if len(dms) == 0 {
|
||||
if dbExists, err := dbr.dataDb.ExistsData(DESTINATION_PREFIX, drate.DestinationId); err != nil {
|
||||
return err
|
||||
} else if !dbExists {
|
||||
return fmt.Errorf("Could not get destination for tag %v", drate.DestinationId)
|
||||
rp.SetTiming(tm[rp.TimingId])
|
||||
drm, err := dbr.storDb.GetTpDestinationRates(dbr.tpid, rp.DestinationRatesId)
|
||||
if err != nil || len(drm) == 0 {
|
||||
return fmt.Errorf("No DestinationRates profile with id %s: %v", rp.DestinationRatesId, err)
|
||||
}
|
||||
for _, drate := range drm[rp.DestinationRatesId].DestinationRates {
|
||||
Logger.Debug(fmt.Sprintf("Destination rate: %v", drate))
|
||||
rt, err := dbr.storDb.GetTpRates(dbr.tpid, drate.RateId)
|
||||
if err != nil || len(rt) == 0 {
|
||||
return fmt.Errorf("No Rates profile with id %s: %v", drate.RateId, err)
|
||||
}
|
||||
Logger.Debug(fmt.Sprintf("Rate: %v", rt))
|
||||
drate.Rate = rt[drate.RateId]
|
||||
ratingPlan.AddRateInterval(drate.DestinationId, GetRateInterval(rp, drate))
|
||||
|
||||
dms, err := dbr.storDb.GetTpDestinations(dbr.tpid, drate.DestinationId)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if len(dms) == 0 {
|
||||
if dbExists, err := dbr.dataDb.ExistsData(DESTINATION_PREFIX, drate.DestinationId); err != nil {
|
||||
return err
|
||||
} else if !dbExists {
|
||||
return fmt.Errorf("Could not get destination for tag %v", drate.DestinationId)
|
||||
}
|
||||
continue
|
||||
}
|
||||
Logger.Debug(fmt.Sprintf("Tag: %s Destinations: %v", drate.DestinationId, dms))
|
||||
for _, destination := range dms {
|
||||
Logger.Debug(fmt.Sprintf("Destination: %v", destination))
|
||||
dbr.dataDb.SetDestination(destination)
|
||||
}
|
||||
continue
|
||||
}
|
||||
Logger.Debug(fmt.Sprintf("Tag: %s Destinations: %v", drate.DestinationId, dms))
|
||||
for _, destination := range dms {
|
||||
Logger.Debug(fmt.Sprintf("Destination: %v", destination))
|
||||
dbr.dataDb.SetDestination(destination)
|
||||
}
|
||||
}
|
||||
if err := dbr.dataDb.SetRatingPlan(ratingPlan); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return dbr.dataDb.SetRatingPlan(ratingPlan)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dbr *DbReader) LoadRatingProfileByTag(tag string) error {
|
||||
resultRatingProfile := &RatingProfile{}
|
||||
mpTpRpfs, err := dbr.storDb.GetTpRatingProfiles(dbr.tpid, tag) //map[string]*utils.TPRatingProfile
|
||||
mpTpRpfs, err := dbr.storDb.GetTpRatingProfiles(&utils.TPRatingProfile{TPid:dbr.tpid, LoadId:tag}) //map[string]*utils.TPRatingProfile
|
||||
if err != nil || len(mpTpRpfs) == 0 {
|
||||
return fmt.Errorf("No RateProfile with id %s: %v", tag, err)
|
||||
}
|
||||
for _, tpRpf := range mpTpRpfs {
|
||||
Logger.Debug(fmt.Sprintf("Rating profile: %v", tpRpf))
|
||||
resultRatingProfile.Id = tpRpf.RatingProfileId
|
||||
///
|
||||
resultRatingProfile.Id = tpRpf.KeyId()
|
||||
for _, tpRa := range tpRpf.RatingPlanActivations {
|
||||
at, err := utils.ParseDate(tpRa.ActivationTime)
|
||||
if err != nil {
|
||||
return errors.New(fmt.Sprintf("Cannot parse activation time from %v", tpRa.ActivationTime))
|
||||
}
|
||||
_, exists := dbr.ratingPlans[resultRatingProfile.Id]
|
||||
_, exists := dbr.ratingPlans[tpRa.RatingPlanId]
|
||||
if !exists {
|
||||
if dbExists, err := dbr.dataDb.ExistsData(RATING_PLAN_PREFIX, resultRatingProfile.Id); err != nil {
|
||||
if dbExists, err := dbr.dataDb.ExistsData(RATING_PLAN_PREFIX, tpRa.RatingPlanId); err != nil {
|
||||
return err
|
||||
} else if !dbExists {
|
||||
return errors.New(fmt.Sprintf("Could not load rating plans for tag: %v", resultRatingProfile.Id))
|
||||
return errors.New(fmt.Sprintf("Could not load rating plans for tag: %v", tpRa.RatingPlanId))
|
||||
}
|
||||
}
|
||||
resultRatingProfile.RatingPlanActivations = append(resultRatingProfile.RatingPlanActivations,
|
||||
@@ -334,9 +340,9 @@ func (dbr *DbReader) LoadActionTimings() (err error) {
|
||||
if !exists {
|
||||
return errors.New(fmt.Sprintf("ActionTiming: Could not load the action for tag: %v", at.ActionsId))
|
||||
}
|
||||
t, exists := dbr.timings[atId]
|
||||
t, exists := dbr.timings[at.TimingId]
|
||||
if !exists {
|
||||
return errors.New(fmt.Sprintf("ActionTiming: Could not load the timing for tag: %v", atId))
|
||||
return errors.New(fmt.Sprintf("ActionTiming: Could not load the timing for tag: %v", at.TimingId))
|
||||
}
|
||||
actTmg := &ActionTiming{
|
||||
Id: utils.GenUUID(),
|
||||
@@ -344,6 +350,7 @@ func (dbr *DbReader) LoadActionTimings() (err error) {
|
||||
Weight: at.Weight,
|
||||
Timing: &RateInterval{
|
||||
Timing: &RITiming{
|
||||
Years: t.Years,
|
||||
Months: t.Months,
|
||||
MonthDays: t.MonthDays,
|
||||
WeekDays: t.WeekDays,
|
||||
@@ -382,38 +389,35 @@ func (dbr *DbReader) LoadActionTriggers() (err error) {
|
||||
}
|
||||
|
||||
func (dbr *DbReader) LoadAccountActions() (err error) {
|
||||
acs, err := dbr.storDb.GetTpAccountActions(dbr.tpid, "")
|
||||
acs, err := dbr.storDb.GetTpAccountActions(&utils.TPAccountActions{TPid:dbr.tpid})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, aa := range acs {
|
||||
tag := fmt.Sprintf("%s:%s:%s", aa.Direction, aa.Tenant, aa.Account)
|
||||
aTriggers, exists := dbr.actionsTriggers[aa.ActionTriggersTag]
|
||||
if aa.ActionTriggersTag != "" && !exists {
|
||||
// only return error if there was something there for the tag
|
||||
return errors.New(fmt.Sprintf("Could not get action triggers for tag %v", aa.ActionTriggersTag))
|
||||
aTriggers, exists := dbr.actionsTriggers[aa.ActionTriggersId]
|
||||
if !exists {
|
||||
return errors.New(fmt.Sprintf("Could not get action triggers for tag %v", aa.ActionTriggersId))
|
||||
}
|
||||
ub := &UserBalance{
|
||||
Type: UB_TYPE_PREPAID,
|
||||
Id: tag,
|
||||
Id: aa.KeyId(),
|
||||
ActionTriggers: aTriggers,
|
||||
}
|
||||
dbr.accountActions = append(dbr.accountActions, ub)
|
||||
|
||||
aTimings, exists := dbr.actionsTimings[aa.ActionTimingsTag]
|
||||
aTimings, exists := dbr.actionsTimings[aa.ActionTimingsId]
|
||||
if !exists {
|
||||
log.Printf("Could not get action timing for tag %v", aa.ActionTimingsTag)
|
||||
log.Printf("Could not get action timing for tag %v", aa.ActionTimingsId)
|
||||
// must not continue here
|
||||
}
|
||||
for _, at := range aTimings {
|
||||
at.UserBalanceIds = append(at.UserBalanceIds, tag)
|
||||
at.UserBalanceIds = append(at.UserBalanceIds, aa.KeyId())
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dbr *DbReader) LoadAccountActionsByTag(tag string) error {
|
||||
accountActions, err := dbr.storDb.GetTpAccountActions(dbr.tpid, tag)
|
||||
accountActions, err := dbr.storDb.GetTpAccountActions(&utils.TPAccountActions{TPid:dbr.tpid, LoadId:tag})
|
||||
if err != nil {
|
||||
return err
|
||||
} else if len(accountActions) == 0 {
|
||||
@@ -427,23 +431,23 @@ func (dbr *DbReader) LoadAccountActionsByTag(tag string) error {
|
||||
var actionsIds []string // collects action ids
|
||||
|
||||
// action timings
|
||||
if accountAction.ActionTimingsTag != "" {
|
||||
if accountAction.ActionTimingsId != "" {
|
||||
// get old userBalanceIds
|
||||
var exitingUserBalanceIds []string
|
||||
existingActionTimings, err := dbr.dataDb.GetActionTimings(accountAction.ActionTimingsTag)
|
||||
existingActionTimings, err := dbr.dataDb.GetActionTimings(accountAction.ActionTimingsId)
|
||||
if err == nil && len(existingActionTimings) > 0 {
|
||||
// all action timings from a specific tag shuld have the same list of user balances from the first one
|
||||
exitingUserBalanceIds = existingActionTimings[0].UserBalanceIds
|
||||
}
|
||||
|
||||
actionTimingsMap, err := dbr.storDb.GetTpActionTimings(dbr.tpid, accountAction.ActionTimingsTag)
|
||||
actionTimingsMap, err := dbr.storDb.GetTpActionTimings(dbr.tpid, accountAction.ActionTimingsId)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if len(actionTimingsMap) == 0 {
|
||||
return fmt.Errorf("No ActionTimings with id <%s>", accountAction.ActionTimingsTag)
|
||||
return fmt.Errorf("No ActionTimings with id <%s>", accountAction.ActionTimingsId)
|
||||
}
|
||||
var actionTimings []*ActionTiming
|
||||
ats := actionTimingsMap[accountAction.ActionTimingsTag]
|
||||
ats := actionTimingsMap[accountAction.ActionTimingsId]
|
||||
for _, at := range ats {
|
||||
existsAction, err := dbr.storDb.ExistsTPActions(dbr.tpid, at.ActionsId)
|
||||
if err != nil {
|
||||
@@ -451,16 +455,16 @@ func (dbr *DbReader) LoadAccountActionsByTag(tag string) error {
|
||||
} else if !existsAction {
|
||||
return fmt.Errorf("No Action with id <%s>", at.ActionsId)
|
||||
}
|
||||
timingsMap, err := dbr.storDb.GetTpTimings(dbr.tpid, accountAction.ActionTimingsTag)
|
||||
timingsMap, err := dbr.storDb.GetTpTimings(dbr.tpid, accountAction.ActionTimingsId)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if len(timingsMap) == 0 {
|
||||
return fmt.Errorf("No Timing with id <%s>", accountAction.ActionTimingsTag)
|
||||
return fmt.Errorf("No Timing with id <%s>", accountAction.ActionTimingsId)
|
||||
}
|
||||
t := timingsMap[accountAction.ActionTimingsTag]
|
||||
t := timingsMap[accountAction.ActionTimingsId]
|
||||
actTmg := &ActionTiming{
|
||||
Id: utils.GenUUID(),
|
||||
Tag: accountAction.ActionTimingsTag,
|
||||
Tag: accountAction.ActionTimingsId,
|
||||
Weight: at.Weight,
|
||||
Timing: &RateInterval{
|
||||
Timing: &RITiming{
|
||||
@@ -489,7 +493,7 @@ func (dbr *DbReader) LoadAccountActionsByTag(tag string) error {
|
||||
}
|
||||
|
||||
// write action timings
|
||||
err = dbr.dataDb.SetActionTimings(accountAction.ActionTimingsTag, actionTimings)
|
||||
err = dbr.dataDb.SetActionTimings(accountAction.ActionTimingsId, actionTimings)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -498,8 +502,8 @@ func (dbr *DbReader) LoadAccountActionsByTag(tag string) error {
|
||||
// action triggers
|
||||
var actionTriggers ActionTriggerPriotityList
|
||||
//ActionTriggerPriotityList []*ActionTrigger
|
||||
if accountAction.ActionTriggersTag != "" {
|
||||
apiAtrsMap, err := dbr.storDb.GetTpActionTriggers(dbr.tpid, accountAction.ActionTriggersTag)
|
||||
if accountAction.ActionTriggersId != "" {
|
||||
apiAtrsMap, err := dbr.storDb.GetTpActionTriggers(dbr.tpid, accountAction.ActionTriggersId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -519,7 +523,7 @@ func (dbr *DbReader) LoadAccountActionsByTag(tag string) error {
|
||||
}
|
||||
atrsMap[key] = atrs
|
||||
}
|
||||
actionTriggers = atrsMap[accountAction.ActionTriggersTag]
|
||||
actionTriggers = atrsMap[accountAction.ActionTriggersId]
|
||||
// collect action ids from triggers
|
||||
for _, atr := range actionTriggers {
|
||||
actionsIds = append(actionsIds, atr.ActionsId)
|
||||
|
||||
@@ -106,20 +106,20 @@ func NewTiming(timingInfo ...string) (rt *utils.TPTiming) {
|
||||
return
|
||||
}
|
||||
|
||||
func NewRatingPlan(timing *utils.TPTiming, weight string) (drt *utils.RatingPlan) {
|
||||
func NewRatingPlan(timing *utils.TPTiming, weight string) (drt *utils.TPRatingPlanBinding) {
|
||||
w, err := strconv.ParseFloat(weight, 64)
|
||||
if err != nil {
|
||||
log.Printf("Error parsing weight unit from: %v", weight)
|
||||
return
|
||||
}
|
||||
drt = &utils.RatingPlan{
|
||||
drt = &utils.TPRatingPlanBinding{
|
||||
Weight: w,
|
||||
}
|
||||
drt.SetTiming(timing)
|
||||
return
|
||||
}
|
||||
|
||||
func GetRateInterval(rpl *utils.RatingPlan, dr *utils.DestinationRate) (i *RateInterval) {
|
||||
func GetRateInterval(rpl *utils.TPRatingPlanBinding, dr *utils.DestinationRate) (i *RateInterval) {
|
||||
i = &RateInterval{
|
||||
Timing: &RITiming{
|
||||
Years: rpl.Timing().Years,
|
||||
|
||||
@@ -105,7 +105,7 @@ type LoadStorage interface {
|
||||
ExistsTPTiming(string, string) (bool, error)
|
||||
GetTPTiming(string, string) (*utils.TPTiming, error)
|
||||
GetTPTimingIds(string) ([]string, error)
|
||||
RemTPData(string, string, string) error
|
||||
RemTPData(string, string, ...string) error
|
||||
SetTPDestination(string, *Destination) error
|
||||
ExistsTPDestination(string, string) (bool, error)
|
||||
GetTPDestination(string, string) (*Destination, error)
|
||||
@@ -119,7 +119,7 @@ type LoadStorage interface {
|
||||
GetTPDestinationRate(string, string) (*utils.TPDestinationRate, error)
|
||||
GetTPDestinationRateIds(string) ([]string, error)
|
||||
ExistsTPRatingPlan(string, string) (bool, error)
|
||||
SetTPRatingPlans(string, map[string][]*utils.RatingPlan) error
|
||||
SetTPRatingPlans(string, map[string][]*utils.TPRatingPlanBinding) error
|
||||
GetTPRatingPlan(string, string) (*utils.TPRatingPlan, error)
|
||||
GetTPRatingPlanIds(string) ([]string, error)
|
||||
ExistsTPRatingProfile(string, string) (bool, error)
|
||||
@@ -145,12 +145,12 @@ type LoadStorage interface {
|
||||
GetTpTimings(string, string) (map[string]*utils.TPTiming, error)
|
||||
GetTpRates(string, string) (map[string]*utils.TPRate, error)
|
||||
GetTpDestinationRates(string, string) (map[string]*utils.TPDestinationRate, error)
|
||||
GetTpRatingPlans(string, string) (*utils.TPRatingPlan, error)
|
||||
GetTpRatingProfiles(string, string) (map[string]*utils.TPRatingProfile, error)
|
||||
GetTpRatingPlans(string, string) (map[string][]*utils.TPRatingPlanBinding, error)
|
||||
GetTpRatingProfiles(*utils.TPRatingProfile) (map[string]*utils.TPRatingProfile, error)
|
||||
GetTpActions(string, string) (map[string][]*Action, error)
|
||||
GetTpActionTimings(string, string) (map[string][]*utils.TPActionTiming, error)
|
||||
GetTpActionTriggers(string, string) (map[string][]*utils.TPActionTrigger, error)
|
||||
GetTpAccountActions(string, string) (map[string]*AccountAction, error)
|
||||
GetTpAccountActions(*utils.TPAccountActions) (map[string]*utils.TPAccountActions, error)
|
||||
}
|
||||
|
||||
type Marshaler interface {
|
||||
|
||||
@@ -119,8 +119,16 @@ func (self *SQLStorage) GetTPTimingIds(tpid string) ([]string, error) {
|
||||
|
||||
|
||||
|
||||
func (self *SQLStorage) RemTPData(table, tpid, tag string) error {
|
||||
q := fmt.Sprintf("DELETE FROM %s WHERE tpid='%s' AND tag='%s'", table, tpid, tag)
|
||||
func (self *SQLStorage) RemTPData(table, tpid string, args ...string) error {
|
||||
q := fmt.Sprintf("DELETE FROM %s WHERE tpid='%s' AND tag='%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 tor='%s' AND direction='%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'",
|
||||
table, tpid, args[0], args[1], args[2], args[3])
|
||||
}
|
||||
if _, err := self.Db.Exec(q); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -375,7 +383,7 @@ func (self *SQLStorage) ExistsTPRatingPlan(tpid, drtId string) (bool, error) {
|
||||
return exists, nil
|
||||
}
|
||||
|
||||
func (self *SQLStorage) SetTPRatingPlans(tpid string, drts map[string][]*utils.RatingPlan) error {
|
||||
func (self *SQLStorage) SetTPRatingPlans(tpid string, drts map[string][]*utils.TPRatingPlanBinding) error {
|
||||
if len(drts) == 0 {
|
||||
return nil //Nothing to set
|
||||
}
|
||||
@@ -414,7 +422,7 @@ func (self *SQLStorage) GetTPRatingPlan(tpid, drtId string) (*utils.TPRatingPlan
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
drt.RatingPlans = append(drt.RatingPlans, &utils.RatingPlan{DestinationRatesId:drTag, TimingId:timingTag, Weight:weight})
|
||||
drt.RatingPlanBindings = append(drt.RatingPlanBindings, &utils.TPRatingPlanBinding{DestinationRatesId:drTag, TimingId:timingTag, Weight:weight})
|
||||
}
|
||||
if i == 0 {
|
||||
return nil, nil
|
||||
@@ -465,25 +473,25 @@ func (self *SQLStorage) SetTPRatingProfiles(tpid string, rps map[string]*utils.T
|
||||
if i != 0 { //Consecutive values after the first will be prefixed with "," as separator
|
||||
vals += ","
|
||||
}
|
||||
vals += fmt.Sprintf("('%s', '%s', '%s', '%s', '%s', '%s', '%s','%s','%s')", tpid, rp.RatingProfileId, rp.Tenant, rp.TOR, rp.Direction,
|
||||
vals += fmt.Sprintf("('%s', '%s', '%s', '%s', '%s', '%s', '%s','%s','%s')", tpid, rp.LoadId, rp.Tenant, rp.TOR, rp.Direction,
|
||||
rp.Subject, rpa.ActivationTime, rpa.RatingPlanId, rpa.FallbackSubjects)
|
||||
i++
|
||||
}
|
||||
}
|
||||
qry := fmt.Sprintf("INSERT INTO %s (tpid,tag,tenant,tor,direction,subject,activation_time,rating_plan_tag,fallback_subjects) VALUES %s ON DUPLICATE KEY UPDATE fallback_subjects=values(fallback_subjects)", utils.TBL_TP_RATE_PROFILES, vals)
|
||||
qry := fmt.Sprintf("INSERT INTO %s (tpid,loadid,tenant,tor,direction,subject,activation_time,rating_plan_tag,fallback_subjects) VALUES %s ON DUPLICATE KEY UPDATE fallback_subjects=values(fallback_subjects)", utils.TBL_TP_RATE_PROFILES, vals)
|
||||
if _, err := self.Db.Exec(qry); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SQLStorage) GetTPRatingProfile(tpid, rpId string) (*utils.TPRatingProfile, error) {
|
||||
rows, err := self.Db.Query(fmt.Sprintf("SELECT tenant,tor,direction,subject,activation_time,rating_plan_tag,fallback_subjects FROM %s WHERE tpid='%s' AND tag='%s'", utils.TBL_TP_RATE_PROFILES, tpid, rpId))
|
||||
func (self *SQLStorage) GetTPRatingProfile(tpid, loadId string) (*utils.TPRatingProfile, error) {
|
||||
rows, err := self.Db.Query(fmt.Sprintf("SELECT tenant,tor,direction,subject,activation_time,rating_plan_tag,fallback_subjects FROM %s WHERE tpid='%s' AND loadid='%s'", utils.TBL_TP_RATE_PROFILES, tpid, loadId))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
rp := &utils.TPRatingProfile{TPid: tpid, RatingProfileId: rpId}
|
||||
rp := &utils.TPRatingProfile{TPid: tpid, LoadId: loadId}
|
||||
i := 0
|
||||
for rows.Next() {
|
||||
i++ //Keep here a reference so we know we got at least one result
|
||||
@@ -507,7 +515,7 @@ func (self *SQLStorage) GetTPRatingProfile(tpid, rpId string) (*utils.TPRatingPr
|
||||
}
|
||||
|
||||
func (self *SQLStorage) GetTPRatingProfileIds(filters *utils.AttrTPRatingProfileIds) ([]string, error) {
|
||||
qry := fmt.Sprintf("SELECT DISTINCT tag FROM %s where tpid='%s'", utils.TBL_TP_RATE_PROFILES, filters.TPid)
|
||||
qry := fmt.Sprintf("SELECT DISTINCT loadid FROM %s where tpid='%s'", utils.TBL_TP_RATE_PROFILES, filters.TPid)
|
||||
if filters.Tenant != "" {
|
||||
qry += fmt.Sprintf(" AND tenant='%s'", filters.Tenant)
|
||||
}
|
||||
@@ -770,15 +778,15 @@ func (self *SQLStorage) SetTPAccountActions(tpid string, aa map[string]*utils.TP
|
||||
}
|
||||
vals := ""
|
||||
i := 0
|
||||
for aaId, aActs := range aa {
|
||||
for _, aActs := range aa {
|
||||
if i != 0 { //Consecutive values after the first will be prefixed with "," as separator
|
||||
vals += ","
|
||||
}
|
||||
vals += fmt.Sprintf("('%s','%s','%s','%s','%s','%s','%s')",
|
||||
tpid, aaId, aActs.Tenant, aActs.Account, aActs.Direction, aActs.ActionTimingsId, aActs.ActionTriggersId)
|
||||
tpid, aActs.LoadId, aActs.Tenant, aActs.Account, aActs.Direction, aActs.ActionTimingsId, aActs.ActionTriggersId)
|
||||
i++
|
||||
}
|
||||
qry := fmt.Sprintf("INSERT INTO %s (tpid, tag, tenant, account, direction, action_timings_tag, action_triggers_tag) VALUES %s ON DUPLICATE KEY UPDATE action_timings_tag=values(action_timings_tag), action_triggers_tag=values(action_triggers_tag)", utils.TBL_TP_ACCOUNT_ACTIONS, vals)
|
||||
qry := fmt.Sprintf("INSERT INTO %s (tpid, loadid, tenant, account, direction, action_timings_tag, action_triggers_tag) VALUES %s ON DUPLICATE KEY UPDATE action_timings_tag=values(action_timings_tag), action_triggers_tag=values(action_triggers_tag)", utils.TBL_TP_ACCOUNT_ACTIONS, vals)
|
||||
if _, err := self.Db.Exec(qry); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -786,7 +794,7 @@ func (self *SQLStorage) SetTPAccountActions(tpid string, aa map[string]*utils.TP
|
||||
}
|
||||
|
||||
func (self *SQLStorage) GetTPAccountActionIds(tpid string) ([]string, error) {
|
||||
rows, err := self.Db.Query(fmt.Sprintf("SELECT DISTINCT tag FROM %s where tpid='%s'", utils.TBL_TP_ACCOUNT_ACTIONS, tpid))
|
||||
rows, err := self.Db.Query(fmt.Sprintf("SELECT DISTINCT loadid FROM %s where tpid='%s'", utils.TBL_TP_ACCOUNT_ACTIONS, tpid))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1085,8 +1093,8 @@ func (self *SQLStorage) GetTpTimings(tpid, tag string) (map[string]*utils.TPTimi
|
||||
return tms, nil
|
||||
}
|
||||
|
||||
func (self *SQLStorage) GetTpRatingPlans(tpid, tag string) (*utils.TPRatingPlan, error) {
|
||||
rts := &utils.TPRatingPlan{RatingPlanId: tag}
|
||||
func (self *SQLStorage) GetTpRatingPlans(tpid, tag string) (map[string][]*utils.TPRatingPlanBinding, error) {
|
||||
rpbns := make(map[string][]*utils.TPRatingPlanBinding)
|
||||
q := fmt.Sprintf("SELECT * FROM %s WHERE tpid='%s'", utils.TBL_TP_RATING_PLANS, tpid)
|
||||
if tag != "" {
|
||||
q += fmt.Sprintf(" AND tag='%s'", tag)
|
||||
@@ -1103,44 +1111,62 @@ func (self *SQLStorage) GetTpRatingPlans(tpid, tag string) (*utils.TPRatingPlan,
|
||||
if err := rows.Scan(&id, &tpid, &tag, &destination_rates_tag, &timings_tag, &weight); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rt := &utils.RatingPlan{
|
||||
rpb := &utils.TPRatingPlanBinding{
|
||||
DestinationRatesId: destination_rates_tag,
|
||||
Weight: weight,
|
||||
TimingId: timings_tag,
|
||||
Weight: weight,
|
||||
}
|
||||
if rpBnLst,exists := rpbns[tag]; exists {
|
||||
rpBnLst = append(rpBnLst, rpb)
|
||||
} else { // New
|
||||
rpbns[tag] = []*utils.TPRatingPlanBinding{rpb}
|
||||
}
|
||||
rts.RatingPlans = append(rts.RatingPlans, rt)
|
||||
}
|
||||
return rts, nil
|
||||
return rpbns, nil
|
||||
}
|
||||
|
||||
func (self *SQLStorage) GetTpRatingProfiles(tpid, tag string) (map[string]*utils.TPRatingProfile, error) {
|
||||
rpfs := make(map[string]*utils.TPRatingProfile)
|
||||
q := fmt.Sprintf("SELECT tag,tenant,tor,direction,subject,activation_time,rating_plan_tag,fallback_subjects FROM %s WHERE tpid='%s'",
|
||||
utils.TBL_TP_RATE_PROFILES, tpid)
|
||||
if tag != "" {
|
||||
q += fmt.Sprintf(" AND tag='%s'", tag)
|
||||
func (self *SQLStorage) GetTpRatingProfiles(qryRpf *utils.TPRatingProfile) (map[string]*utils.TPRatingProfile, error) {
|
||||
q := fmt.Sprintf("SELECT loadid,tenant,tor,direction,subject,activation_time,rating_plan_tag,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)
|
||||
}
|
||||
if len(qryRpf.Tenant) != 0 {
|
||||
q += fmt.Sprintf(" AND tenant='%s'", qryRpf.Tenant)
|
||||
}
|
||||
if len(qryRpf.TOR) != 0 {
|
||||
q += fmt.Sprintf(" AND tor='%s'", qryRpf.TOR)
|
||||
}
|
||||
if len(qryRpf.Direction) != 0 {
|
||||
q += fmt.Sprintf(" AND direction='%s'", qryRpf.Direction)
|
||||
}
|
||||
if len(qryRpf.Subject) != 0 {
|
||||
q += fmt.Sprintf(" AND subject='%s'", qryRpf.Subject)
|
||||
}
|
||||
rows, err := self.Db.Query(q)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
rpfs := make(map[string]*utils.TPRatingProfile)
|
||||
for rows.Next() {
|
||||
var rcvTag, tenant, tor, direction, subject, fallback_subjects, rating_plan_tag, activation_time string
|
||||
if err := rows.Scan(&rcvTag, &tenant, &tor, &direction, &subject, &activation_time, &rating_plan_tag, &fallback_subjects); err != nil {
|
||||
var rcvLoadId, tenant, tor, direction, subject, fallback_subjects, rating_plan_tag, activation_time string
|
||||
if err := rows.Scan(&rcvLoadId, &tenant, &tor, &direction, &subject, &activation_time, &rating_plan_tag, &fallback_subjects); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _,ok := rpfs[rcvTag]; !ok {
|
||||
rpfs[rcvTag] = &utils.TPRatingProfile{TPid: tpid, RatingProfileId: rcvTag, Tenant: tenant, TOR: tor, Direction:direction, Subject:subject,
|
||||
RatingPlanActivations: []*utils.TPRatingActivation{
|
||||
&utils.TPRatingActivation{ActivationTime:activation_time, RatingPlanId:rating_plan_tag, FallbackSubjects:fallback_subjects}}}
|
||||
} else {
|
||||
rpfs[rcvTag].RatingPlanActivations = append( rpfs[rcvTag].RatingPlanActivations,
|
||||
rp := &utils.TPRatingProfile{TPid: qryRpf.TPid, LoadId: rcvLoadId, Tenant: tenant, TOR: tor, Direction:direction, 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}}
|
||||
rpfs[rp.KeyId()] = rp
|
||||
} else { // Exists, update
|
||||
existingRp.RatingPlanActivations = append( existingRp.RatingPlanActivations,
|
||||
&utils.TPRatingActivation{ActivationTime:activation_time, RatingPlanId:rating_plan_tag, FallbackSubjects:fallback_subjects} )
|
||||
}
|
||||
}
|
||||
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)
|
||||
@@ -1168,6 +1194,7 @@ func (self *SQLStorage) GetTpActions(tpid, tag string) (map[string][]*Action, er
|
||||
ExtraParameters: extra_parameters,
|
||||
ExpirationString: expirationDate,
|
||||
Balance: &Balance{
|
||||
Uuid: utils.GenUUID(),
|
||||
Value: units,
|
||||
Weight: balance_weight,
|
||||
RateSubject: rating_subject,
|
||||
@@ -1239,29 +1266,41 @@ func (self *SQLStorage) GetTpActionTriggers(tpid, tag string) (map[string][]*uti
|
||||
return ats, nil
|
||||
}
|
||||
|
||||
func (self *SQLStorage) GetTpAccountActions(tpid, tag string) (map[string]*AccountAction, error) {
|
||||
q := fmt.Sprintf("SELECT tag, tenant, account, direction, action_timings_tag, action_triggers_tag FROM %s WHERE tpid='%s'", utils.TBL_TP_ACCOUNT_ACTIONS, tpid)
|
||||
if tag != "" {
|
||||
q += fmt.Sprintf(" AND tag='%s'", tag)
|
||||
func (self *SQLStorage) GetTpAccountActions(aaFltr *utils.TPAccountActions) (map[string]*utils.TPAccountActions, error) {
|
||||
q := fmt.Sprintf("SELECT loadid, tenant, account, direction, action_timings_tag, action_triggers_tag FROM %s WHERE tpid='%s'", utils.TBL_TP_ACCOUNT_ACTIONS, aaFltr.TPid)
|
||||
if len(aaFltr.LoadId) != 0 {
|
||||
q += fmt.Sprintf(" AND loadid='%s'", aaFltr.LoadId)
|
||||
}
|
||||
if len(aaFltr.Tenant) != 0 {
|
||||
q += fmt.Sprintf(" AND tenant='%s'", aaFltr.Tenant)
|
||||
}
|
||||
if len(aaFltr.Account) != 0 {
|
||||
q += fmt.Sprintf(" AND account='%s'", aaFltr.Account)
|
||||
}
|
||||
if len(aaFltr.Direction) != 0 {
|
||||
q += fmt.Sprintf(" AND direction='%s'", aaFltr.Direction)
|
||||
}
|
||||
rows, err := self.Db.Query(q)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
aa := make(map[string]*AccountAction)
|
||||
aa := make(map[string]*utils.TPAccountActions)
|
||||
for rows.Next() {
|
||||
var aaId, tenant, account, direction, action_timings_tag, action_triggers_tag string
|
||||
if err := rows.Scan(&aaId, &tenant, &account, &direction, &action_timings_tag, &action_triggers_tag); err != nil {
|
||||
var aaLoadId, tenant, account, direction, action_timings_tag, action_triggers_tag string
|
||||
if err := rows.Scan(&aaLoadId, &tenant, &account, &direction, &action_timings_tag, &action_triggers_tag); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
aa[aaId] = &AccountAction{
|
||||
Tenant: tenant,
|
||||
Account: account,
|
||||
Direction: direction,
|
||||
ActionTimingsTag: action_timings_tag,
|
||||
ActionTriggersTag: action_triggers_tag,
|
||||
aacts := &utils.TPAccountActions{
|
||||
TPid: aaFltr.TPid,
|
||||
LoadId: aaLoadId,
|
||||
Tenant: tenant,
|
||||
Account: account,
|
||||
Direction: direction,
|
||||
ActionTimingsId: action_timings_tag,
|
||||
ActionTriggersId: action_triggers_tag,
|
||||
}
|
||||
aa[aacts.KeyId()] = aacts
|
||||
}
|
||||
return aa, nil
|
||||
}
|
||||
|
||||
@@ -210,14 +210,14 @@ func (self *TPCSVImporter) importRatingPlans(fn string) error {
|
||||
}
|
||||
continue
|
||||
}
|
||||
drt := []*utils.RatingPlan{
|
||||
&utils.RatingPlan{
|
||||
drt := []*utils.TPRatingPlanBinding{
|
||||
&utils.TPRatingPlanBinding{
|
||||
DestinationRatesId: record[1],
|
||||
Weight: weight,
|
||||
TimingId: record[2],
|
||||
},
|
||||
}
|
||||
if err := self.StorDb.SetTPRatingPlans(self.TPid, map[string][]*utils.RatingPlan{record[0]: drt}); err != nil {
|
||||
if err := self.StorDb.SetTPRatingPlans(self.TPid, map[string][]*utils.TPRatingPlanBinding{record[0]: drt}); err != nil {
|
||||
if self.Verbose {
|
||||
log.Printf("Ignoring line %d, storDb operational error: <%s> ", lineNr, err.Error())
|
||||
}
|
||||
@@ -252,12 +252,12 @@ func (self *TPCSVImporter) importRatingProfiles(fn string) error {
|
||||
}
|
||||
continue
|
||||
}
|
||||
rpTag := "TPCSV" //Autogenerate rating profile id
|
||||
loadId := "TPCSV" //Autogenerate rating profile id
|
||||
if self.ImportId != "" {
|
||||
rpTag += "_" + self.ImportId
|
||||
loadId += "_" + self.ImportId
|
||||
}
|
||||
rp := &utils.TPRatingProfile{
|
||||
RatingProfileId:rpTag,
|
||||
LoadId: loadId,
|
||||
Tenant: tenant,
|
||||
TOR: tor,
|
||||
Direction: direction,
|
||||
@@ -265,7 +265,7 @@ func (self *TPCSVImporter) importRatingProfiles(fn string) error {
|
||||
RatingPlanActivations: []*utils.TPRatingActivation{
|
||||
&utils.TPRatingActivation{ ActivationTime: record[4], RatingPlanId: ratingPlanTag, FallbackSubjects: fallbacksubject}},
|
||||
}
|
||||
if err := self.StorDb.SetTPRatingProfiles(self.TPid, map[string]*utils.TPRatingProfile{rpTag: rp}); err != nil {
|
||||
if err := self.StorDb.SetTPRatingProfiles(self.TPid, map[string]*utils.TPRatingProfile{rp.KeyId(): rp}); err != nil {
|
||||
if self.Verbose {
|
||||
log.Printf("Ignoring line %d, storDb operational error: <%s> ", lineNr, err.Error())
|
||||
}
|
||||
@@ -441,14 +441,13 @@ func (self *TPCSVImporter) importAccountActions(fn string) error {
|
||||
continue
|
||||
}
|
||||
tenant, account, direction, actionTimingsTag, actionTriggersTag := record[0], record[1], record[2], record[3], record[4]
|
||||
tag := "TPCSV" //Autogenerate account actions profile id
|
||||
loadId := "TPCSV" //Autogenerate account actions profile id
|
||||
if self.ImportId != "" {
|
||||
tag += "_" + self.ImportId
|
||||
}
|
||||
aa := map[string]*utils.TPAccountActions{
|
||||
tag: &utils.TPAccountActions{TPid: self.TPid, AccountActionsId: tag, Tenant: tenant, Account: account, Direction: direction,
|
||||
ActionTimingsId: actionTimingsTag, ActionTriggersId: actionTriggersTag},
|
||||
loadId += "_" + self.ImportId
|
||||
}
|
||||
tpaa := &utils.TPAccountActions{TPid: self.TPid, LoadId: loadId, Tenant: tenant, Account: account, Direction: direction,
|
||||
ActionTimingsId: actionTimingsTag, ActionTriggersId: actionTriggersTag}
|
||||
aa := map[string]*utils.TPAccountActions{tpaa.KeyId(): tpaa}
|
||||
if err := self.StorDb.SetTPAccountActions(self.TPid, aa); err != nil {
|
||||
if self.Verbose {
|
||||
log.Printf("Ignoring line %d, storDb operational error: <%s> ", lineNr, err.Error())
|
||||
|
||||
@@ -20,6 +20,7 @@ package utils
|
||||
|
||||
import (
|
||||
"time"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// This file deals with tp_* data definition
|
||||
@@ -103,33 +104,37 @@ type TPTiming struct {
|
||||
type TPRatingPlan struct {
|
||||
TPid string // Tariff plan id
|
||||
RatingPlanId string // RatingPlan profile id
|
||||
RatingPlans []*RatingPlan // Set of destinationid-rateid bindings
|
||||
RatingPlanBindings []*TPRatingPlanBinding // Set of destinationid-rateid bindings
|
||||
}
|
||||
|
||||
type RatingPlan struct {
|
||||
type TPRatingPlanBinding struct {
|
||||
DestinationRatesId string // The DestinationRate identity
|
||||
TimingId string // The timing identity
|
||||
Weight float64 // Binding priority taken into consideration when more DestinationRates are active on a time slot
|
||||
timing *TPTiming // Not exporting it via JSON
|
||||
}
|
||||
|
||||
func(self *RatingPlan) SetTiming(tm *TPTiming) {
|
||||
func(self *TPRatingPlanBinding) SetTiming(tm *TPTiming) {
|
||||
self.timing = tm
|
||||
}
|
||||
|
||||
func(self *RatingPlan) Timing() *TPTiming {
|
||||
func(self *TPRatingPlanBinding) Timing() *TPTiming {
|
||||
return self.timing
|
||||
}
|
||||
|
||||
type TPRatingProfile struct {
|
||||
TPid string // Tariff plan id
|
||||
RatingProfileId string // RatingProfile id
|
||||
LoadId string // Gives ability to load specific RatingProfile based on load identifier, hence being able to keep history also in stordb
|
||||
Tenant string // Tenant's Id
|
||||
TOR string // TypeOfRecord
|
||||
Direction string // Traffic direction, OUT is the only one supported for now
|
||||
Subject string // Rating subject, usually the same as account
|
||||
RatingPlanActivations []*TPRatingActivation // Activate rate profiles at specific time
|
||||
}
|
||||
// Used as key in nosql db (eg: redis)
|
||||
func(self *TPRatingProfile) KeyId() string {
|
||||
return fmt.Sprintf("%s:%s:%s:%s", self.Direction, self.Tenant, self.TOR, self.Subject)
|
||||
}
|
||||
|
||||
type TPRatingActivation struct {
|
||||
ActivationTime string // Time when this profile will become active, defined as unix epoch time
|
||||
@@ -156,7 +161,7 @@ type TPAction struct {
|
||||
BalanceType string // Type of balance the action will operate on
|
||||
Direction string // Balance direction
|
||||
Units float64 // Number of units to add/deduct
|
||||
ExpiryTime string // Time when the units will expire\
|
||||
ExpiryTime string // Time when the units will expire
|
||||
DestinationId string // Destination profile id
|
||||
RatingSubject string // Reference a rate subject defined in RatingProfiles
|
||||
BalanceWeight float64 // Balance weight
|
||||
@@ -195,13 +200,17 @@ type TPActionTrigger struct {
|
||||
|
||||
type TPAccountActions struct {
|
||||
TPid string // Tariff plan id
|
||||
AccountActionsId string // AccountActions id, used to group actions on a load
|
||||
LoadId string // LoadId, used to group actions on a load
|
||||
Tenant string // Tenant's Id
|
||||
Account string // Account name
|
||||
Direction string // Traffic direction
|
||||
ActionTimingsId string // Id of ActionTimings profile to use
|
||||
ActionTriggersId string // Id of ActionTriggers profile to use
|
||||
}
|
||||
// Returns the id used in some nosql dbs (eg: redis)
|
||||
func(self *TPAccountActions) KeyId() string {
|
||||
return fmt.Sprintf("%s:%s:%s", self.Direction, self.Tenant, self.Account)
|
||||
}
|
||||
|
||||
|
||||
// Data used to do remote cache reloads via api
|
||||
|
||||
Reference in New Issue
Block a user