Adding ActionTimings api methods

This commit is contained in:
DanB
2013-07-19 09:37:07 +02:00
parent e7de9222d1
commit 092a80d9d4
9 changed files with 371 additions and 118 deletions

97
apier/tpactiontimings.go Normal file
View File

@@ -0,0 +1,97 @@
/*
Rating system designed to be used in VoIP Carriers World
Copyright (C) 2013 ITsysCOM
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package apier
import (
"errors"
"fmt"
"github.com/cgrates/cgrates/utils"
)
// Creates a new ActionTimings profile within a tariff plan
func (self *Apier) SetTPActionTimings(attrs utils.ApiTPActionTimings, reply *string) error {
if missing := utils.MissingStructFields(&attrs, []string{"TPid", "ActionsId", "ActionTimings"}); len(missing) != 0 {
return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing)
}
for _, at := range attrs.ActionTimings {
requiredFields := []string{"ActionsId", "TimingId", "Weight"}
if missing := utils.MissingStructFields(&at, requiredFields); len(missing) != 0 {
return fmt.Errorf("%s:Action:%s:%v", utils.ERR_MANDATORY_IE_MISSING, at.ActionsId, missing)
}
}
if exists, err := self.StorDb.ExistsTPActionTimings(attrs.TPid, attrs.ActionTimingsId); err != nil {
return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error())
} else if exists {
return errors.New(utils.ERR_DUPLICATE)
}
ats := make(map[string][]*utils.TPActionTimingsRow, 1) // Only one id will be stored in the map
for _,at := range attrs.ActionTimings {
ats[attrs.ActionTimingsId] = append( ats[attrs.ActionTimingsId], &utils.TPActionTimingsRow{at.ActionsId, at.TimingId, at.Weight} )
}
if err := self.StorDb.SetTPActionTimings(attrs.TPid, ats); err != nil {
return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error())
}
*reply = "OK"
return nil
}
type AttrGetTPActionTimings struct {
TPid string // Tariff plan id
ActionTimingsId string // ActionTimings id
}
// Queries specific ActionTimings profile on tariff plan
func (self *Apier) GetTPActionTimings(attrs AttrGetTPActionTimings, reply *utils.ApiTPActionTimings) error {
if missing := utils.MissingStructFields(&attrs, []string{"TPid", "ActionTimingsId"}); len(missing) != 0 { //Params missing
return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing)
}
if ats, err := self.StorDb.GetTPActionTimings(attrs.TPid, attrs.ActionTimingsId); err != nil {
return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error())
} else if len(ats) == 0 {
return errors.New(utils.ERR_NOT_FOUND)
} else { // Got the data we need, convert it from []TPActionTimingsRow into ApiTPActionTimings
atRply := &utils.ApiTPActionTimings{ attrs.TPid, attrs.ActionTimingsId, make([]utils.ApiActionTiming, len(ats[attrs.ActionTimingsId])) }
for idx,row := range ats[attrs.ActionTimingsId] {
atRply.ActionTimings[idx] = utils.ApiActionTiming{ row.ActionsId, row.TimingId, row.Weight }
}
*reply = *atRply
}
return nil
}
type AttrGetTPActionTimingIds struct {
TPid string // Tariff plan id
}
// Queries ActionTimings identities on specific tariff plan.
func (self *Apier) GetTPActionTimingIds(attrs AttrGetTPActionTimingIds, reply *[]string) error {
if missing := utils.MissingStructFields(&attrs, []string{"TPid"}); len(missing) != 0 { //Params missing
return fmt.Errorf("%s:%v", utils.ERR_MANDATORY_IE_MISSING, missing)
}
if ids, err := self.StorDb.GetTPActionTimingIds(attrs.TPid); err != nil {
return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error())
} else if ids == nil {
return errors.New(utils.ERR_NOT_FOUND)
} else {
*reply = ids
}
return nil
}

View File

@@ -189,7 +189,7 @@ Actions
.. toctree::
:maxdepth: 2
api_actions
api_tpactions
6.1.5. Management API

View File

@@ -87,6 +87,10 @@ type DataStorage interface {
SetTPActions(*utils.TPActions) error
GetTPActions(string, string) (*utils.TPActions, error)
GetTPActionIds(string) ([]string, error)
ExistsTPActionTimings(string, string) (bool, error)
SetTPActionTimings(string, map[string][]*utils.TPActionTimingsRow) error
GetTPActionTimings(string, string) (map[string][]*utils.TPActionTimingsRow, error)
GetTPActionTimingIds(string) ([]string, error)
// End Apier functions
GetActions(string) (Actions, error)
SetActions(string, Actions) error

View File

@@ -189,6 +189,22 @@ func (ms *MapStorage) GetTPActionIds(tpid string) ([]string, error) {
return nil, errors.New(utils.ERR_NOT_IMPLEMENTED)
}
func (ms *MapStorage) ExistsTPActionTimings(tpid, atId string) (bool, error) {
return false, errors.New(utils.ERR_NOT_IMPLEMENTED)
}
func (ms *MapStorage) SetTPActionTimings(tpid string, ats map[string][]*utils.TPActionTimingsRow) error {
return errors.New(utils.ERR_NOT_IMPLEMENTED)
}
func (ms *MapStorage) GetTPActionTimings(tpid, atId string) (map[string][]*utils.TPActionTimingsRow, error) {
return nil, errors.New(utils.ERR_NOT_IMPLEMENTED)
}
func (ms *MapStorage) GetTPActionTimingIds(tpid string) ([]string, error) {
return nil, errors.New(utils.ERR_NOT_IMPLEMENTED)
}
func (ms *MapStorage) GetActions(key string) (as Actions, err error) {
if values, ok := ms.dict[ACTION_PREFIX+key]; ok {
err = ms.ms.Unmarshal(values, &as)

View File

@@ -264,6 +264,22 @@ func (ms *MongoStorage) GetTPActionIds(tpid string) ([]string, error) {
return nil, errors.New(utils.ERR_NOT_IMPLEMENTED)
}
func (ms *MongoStorage) ExistsTPActionTimings(tpid, atId string) (bool, error) {
return false, errors.New(utils.ERR_NOT_IMPLEMENTED)
}
func (ms *MongoStorage) SetTPActionTimings(tpid string, ats map[string][]*utils.TPActionTimingsRow) error {
return errors.New(utils.ERR_NOT_IMPLEMENTED)
}
func (ms *MongoStorage) GetTPActionTimings(tpid, atId string) (map[string][]*utils.TPActionTimingsRow, error) {
return nil, errors.New(utils.ERR_NOT_IMPLEMENTED)
}
func (ms *MongoStorage) GetTPActionTimingIds(tpid string) ([]string, error) {
return nil, errors.New(utils.ERR_NOT_IMPLEMENTED)
}
func (ms *MongoStorage) GetActions(key string) (as Actions, err error) {
result := AcKeyValue{}
err = ms.db.C("actions").Find(bson.M{"key": key}).One(&result)

View File

@@ -219,6 +219,22 @@ func (rs *RedisStorage) GetTPActionIds(tpid string) ([]string, error) {
return nil, errors.New(utils.ERR_NOT_IMPLEMENTED)
}
func (rs *RedisStorage) ExistsTPActionTimings(tpid, atId string) (bool, error) {
return false, errors.New(utils.ERR_NOT_IMPLEMENTED)
}
func (rs *RedisStorage) SetTPActionTimings(tpid string, ats map[string][]*utils.TPActionTimingsRow) error {
return errors.New(utils.ERR_NOT_IMPLEMENTED)
}
func (rs *RedisStorage) GetTPActionTimings(tpid, atId string) (map[string][]*utils.TPActionTimingsRow, error) {
return nil, errors.New(utils.ERR_NOT_IMPLEMENTED)
}
func (rs *RedisStorage) GetTPActionTimingIds(tpid string) ([]string, error) {
return nil, errors.New(utils.ERR_NOT_IMPLEMENTED)
}
func (rs *RedisStorage) GetActions(key string) (as Actions, err error) {
var values string
if values, err = rs.db.Get(ACTION_PREFIX + key); err == nil {

View File

@@ -586,16 +586,92 @@ func (self *SQLStorage) GetTPActionIds(tpid string) ([]string, error) {
return ids, nil
}
func (self *SQLStorage) ExistsTPActionTimings(tpid, atId string) (bool, error) {
var exists bool
err := self.Db.QueryRow(fmt.Sprintf("SELECT EXISTS (SELECT 1 FROM %s WHERE tpid='%s' AND tag='%s')", utils.TBL_TP_ACTION_TIMINGS, tpid, atId)).Scan(&exists)
if err != nil {
return false, err
}
return exists, nil
}
// Sets actionTimings in sqlDB. Imput is expected in form map[actionTimingId][]rows, eg a full .csv file content
func (self *SQLStorage) SetTPActionTimings(tpid string, ats map[string][]*utils.TPActionTimingsRow) error {
if len(ats) == 0 {
return nil //Nothing to set
}
qry := fmt.Sprintf("INSERT INTO %s (tpid,tag,actions_tag,timing_tag,weight) VALUES ", utils.TBL_TP_ACTION_TIMINGS)
for atId, atRows := range ats {
for idx, atsRow := range atRows {
if idx != 0 { //Consecutive values after the first will be prefixed with "," as separator
qry += ","
}
qry += fmt.Sprintf("('%s','%s','%s','%s',%f)",
tpid, atId, atsRow.ActionsId, atsRow.TimingId, atsRow.Weight)
}
}
if _, err := self.Db.Exec(qry); err != nil {
return err
}
return nil
}
func (self *SQLStorage) GetTPActionTimings(tpid, atId string) (map[string][]*utils.TPActionTimingsRow, error) {
ats := make(map[string][]*utils.TPActionTimingsRow)
q := fmt.Sprintf("SELECT tag,actions_tag,timing_tag,weight FROM %s WHERE tpid='%s'", utils.TBL_TP_ACTION_TIMINGS, tpid)
if atId != "" {
q += fmt.Sprintf(" AND tag='%s'", atId)
}
rows, err := self.Db.Query(q)
if err != nil {
return nil, err
}
defer rows.Close()
i := 0
for rows.Next() {
i++ //Keep here a reference so we know we got at least one result
var tag, actionsId, timingId string
var weight float64
if err = rows.Scan(&tag, &actionsId, &timingId, &weight); err!= nil {
return nil, err
}
ats[tag] = append(ats[tag], &utils.TPActionTimingsRow{actionsId, timingId, weight})
}
return ats, nil
}
func (self *SQLStorage) GetTPActionTimingIds(tpid string) ([]string, error) {
rows, err := self.Db.Query(fmt.Sprintf("SELECT DISTINCT tag FROM %s where tpid='%s'", utils.TBL_TP_ACTION_TIMINGS, tpid))
if err != nil {
return nil, err
}
defer rows.Close()
ids := []string{}
i := 0
for rows.Next() {
i++ //Keep here a reference so we know we got at least one
var id string
if err = rows.Scan(&id); err != nil {
return nil, err
}
ids = append(ids, id)
}
if i == 0 {
return nil, nil
}
return ids, nil
}
func (self *SQLStorage) GetUserBalance(string) (ub *UserBalance, err error) { return }
func (self *SQLStorage) SetUserBalance(ub *UserBalance) (err error) { return }
func (self *SQLStorage) GetActions(string) (as Actions, err error) {
return
}
func (self *SQLStorage) SetActions(key string, as Actions) (err error) { return }
func (self *SQLStorage) GetUserBalance(string) (ub *UserBalance, err error) { return }
func (self *SQLStorage) SetUserBalance(ub *UserBalance) (err error) { return }
func (self *SQLStorage) GetActionTimings(key string) (ats ActionTimings, err error) { return }
func (self *SQLStorage) SetActionTimings(key string, ats ActionTimings) (err error) { return }
@@ -978,7 +1054,7 @@ func (self *SQLStorage) GetTpActionTriggers(tpid, tag string) (map[string][]*Act
var id int
var threshold, weight float64
var tpid, tag, balances_tag, direction, destinations_tag, actions_tag, thresholdType string
if err := rows.Scan(&id, &tpid, &tag, &balances_tag, &direction, &threshold, &thresholdType, &destinations_tag, &actions_tag, &weight); err != nil {
if err := rows.Scan(&id, &tpid, &tag, &balances_tag, &direction, &thresholdType, &threshold, &destinations_tag, &actions_tag, &weight); err != nil {
return nil, err
}
@@ -986,8 +1062,8 @@ func (self *SQLStorage) GetTpActionTriggers(tpid, tag string) (map[string][]*Act
Id: utils.GenUUID(),
BalanceId: balances_tag,
Direction: direction,
ThresholdValue: threshold,
ThresholdType: thresholdType,
ThresholdValue: threshold,
DestinationId: destinations_tag,
ActionsId: actions_tag,
Weight: weight,

137
utils/apitpdata.go Normal file
View File

@@ -0,0 +1,137 @@
/*
Rating system designed to be used in VoIP Carriers World
Copyright (C) 2013 ITsysCOM
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package utils
// This file deals with tp_* data definition
type TPRate struct {
TPid string // Tariff plan id
RateId string // Rate id
RateSlots []RateSlot // One or more RateSlots
}
type RateSlot struct {
ConnectFee float64 // ConnectFee applied once the call is answered
Rate float64 // Rate applied
RatedUnits int // Number of billing units this rate applies to
RateIncrements int // This rate will apply in increments of duration
RoundingMethod string // Use this method to round the cost
RoundingDecimals int // Round the cost number of decimals
Weight float64 // Rate's priority when dealing with grouped rates
}
type TPDestinationRate struct {
TPid string // Tariff plan id
DestinationRateId string // DestinationRate profile id
DestinationRates []DestinationRate // Set of destinationid-rateid bindings
}
type DestinationRate struct {
DestinationId string // The destination identity
RateId string // The rate identity
}
type TPDestRateTiming struct {
TPid string // Tariff plan id
DestRateTimingId string // DestinationRate profile id
DestRateTimings []DestRateTiming // Set of destinationid-rateid bindings
}
type DestRateTiming struct {
DestRatesId 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
}
type TPRateProfile struct {
TPid string // Tariff plan id
RateProfileId string // RateProfile id
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
RatesFallbackSubject string // Fallback on this subject if rates not found for destination
RatingActivations []RatingActivation // Activate rate profiles at specific time
}
type RatingActivation struct {
ActivationTime int64 // Time when this profile will become active, defined as unix epoch time
DestRateTimingId string // Id of DestRateTiming profile
}
type AttrTPRateProfileIds struct {
TPid string // Tariff plan id
Tenant string // Tenant's Id
TOR string // TypeOfRecord
Direction string // Traffic direction
Subject string // Rating subject, usually the same as account
}
type TPActions struct {
TPid string // Tariff plan id
ActionsId string // Actions id
Actions []Action // Set of actions this Actions profile will perform
}
type Action struct {
Identifier string // Identifier mapped in the code
BalanceId string // Type of balance the action will operate on
Direction string // Balance direction
Units float64 // Number of units to add/deduct
ExpirationTime int64 // Time when the units will expire
DestinationId string // Destination profile id
RateType string // Type of price <ABSOLUTE|PERCENT>
Rate float64 // Price value
MinutesWeight float64 // Minutes weight
Weight float64 // Action's weight
}
type ApiTPActionTimings struct {
TPid string // Tariff plan id
ActionTimingsId string // ActionTimings id
ActionTimings []ApiActionTiming // Set of ActionTiming bindings this profile will group
}
type ApiActionTiming struct {
ActionsId string // Actions id
TimingId string // Timing profile id
Weight float64 // Binding's weight
}
type TPActionTriggers struct {
TPid string // Tariff plan id
ActionTriggerId string // ActionTrigger id
BalanceId string // Id of the balance this trigger monitors
Direction string // Traffic direction
ThresholdType string // This threshold type
ThresholdValue float64 // Threshold
DestinationId string // Id of the destination profile
ActionsId string // Actions which will execute on threshold reached
Weight float64 // weight
}
type TPAccountActions struct {
TPid string // Tariff plan id
AccountActionsId string // AccountActions id
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
}

View File

@@ -18,120 +18,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
package utils
// This file deals with tp_* data definition
type TPRate struct {
TPid string // Tariff plan id
RateId string // Rate id
RateSlots []RateSlot // One or more RateSlots
}
type RateSlot struct {
ConnectFee float64 // ConnectFee applied once the call is answered
Rate float64 // Rate applied
RatedUnits int // Number of billing units this rate applies to
RateIncrements int // This rate will apply in increments of duration
RoundingMethod string // Use this method to round the cost
RoundingDecimals int // Round the cost number of decimals
Weight float64 // Rate's priority when dealing with grouped rates
}
type TPDestinationRate struct {
TPid string // Tariff plan id
DestinationRateId string // DestinationRate profile id
DestinationRates []DestinationRate // Set of destinationid-rateid bindings
}
type DestinationRate struct {
DestinationId string // The destination identity
RateId string // The rate identity
}
type TPDestRateTiming struct {
TPid string // Tariff plan id
DestRateTimingId string // DestinationRate profile id
DestRateTimings []DestRateTiming // Set of destinationid-rateid bindings
}
type DestRateTiming struct {
DestRatesId 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
}
type TPRateProfile struct {
TPid string // Tariff plan id
RateProfileId string // RateProfile id
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
RatesFallbackSubject string // Fallback on this subject if rates not found for destination
RatingActivations []RatingActivation // Activate rate profiles at specific time
}
type RatingActivation struct {
ActivationTime int64 // Time when this profile will become active, defined as unix epoch time
DestRateTimingId string // Id of DestRateTiming profile
}
type AttrTPRateProfileIds struct {
TPid string // Tariff plan id
Tenant string // Tenant's Id
TOR string // TypeOfRecord
Direction string // Traffic direction
Subject string // Rating subject, usually the same as account
}
type TPActions struct {
TPid string // Tariff plan id
ActionsId string // Actions id
Actions []Action // Set of actions this Actions profile will perform
}
type Action struct {
Identifier string // Identifier mapped in the code
BalanceId string // Type of balance the action will operate on
Direction string // Balance direction
Units float64 // Number of units to add/deduct
ExpirationTime int64 // Time when the units will expire
DestinationId string // Destination profile id
RateType string // Type of price <ABSOLUTE|PERCENT>
Rate float64 // Price value
MinutesWeight float64 // Minutes weight
Weight float64 // Action's weight
}
type TPActionTimings struct {
TPid string // Tariff plan id
ActionTimingsId string // ActionTimings id
ActionTimings []ActionTiming // Set of ActionTiming bindings this profile will group
}
type ActionTiming struct {
// Represents a single row in .csv or storDb, id will be used as key in the map holding all rows
type TPActionTimingsRow struct {
ActionsId string // Actions id
TimingId string // Timing profile id
Weight float64 // Binding's weight
}
type TPActionTriggers struct {
TPid string // Tariff plan id
ActionTriggerId string // ActionTrigger id
BalanceId string // Id of the balance this trigger monitors
Direction string // Traffic direction
ThresholdType string // This threshold type
ThresholdValue float64 // Threshold
DestinationId string // Id of the destination profile
ActionsId string // Actions which will execute on threshold reached
Weight float64 // weight
}
type TPAccountActions struct {
TPid string // Tariff plan id
AccountActionsId string // AccountActions id
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
}