Various loader and apier fixes

This commit is contained in:
DanB
2013-11-17 23:06:20 +01:00
parent f5257b46a5
commit f38f04f6c5
13 changed files with 282 additions and 212 deletions

View File

@@ -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"

View File

@@ -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"

View File

@@ -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"

View File

@@ -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"

View File

@@ -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`)
);

View File

@@ -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{

View File

@@ -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)
}
}

View File

@@ -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)

View File

@@ -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,

View File

@@ -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 {

View File

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

View File

@@ -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())

View File

@@ -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