TPCSVImporter ActionTriggers

This commit is contained in:
DanB
2013-07-30 17:03:16 +02:00
parent d483a6669f
commit c60b26c0c4
14 changed files with 101 additions and 57 deletions

View File

@@ -38,12 +38,12 @@ func (self *Apier) SetTPActionTriggers(attrs utils.ApiTPActionTriggers, reply *s
}
aTriggers := make([]*engine.ActionTrigger, len(attrs.ActionTriggers))
for idx, at := range attrs.ActionTriggers {
requiredFields := []string{"BalanceId", "Direction", "ThresholdType", "ThresholdValue", "ActionsId", "Weight"}
requiredFields := []string{"BalanceType", "Direction", "ThresholdType", "ThresholdValue", "ActionsId", "Weight"}
if missing := utils.MissingStructFields(&at, requiredFields); len(missing) != 0 {
return fmt.Errorf("%s:Balance:%s:%v", utils.ERR_MANDATORY_IE_MISSING, at.BalanceId, missing)
return fmt.Errorf("%s:Balance:%s:%v", utils.ERR_MANDATORY_IE_MISSING, at.BalanceType, missing)
}
at := &engine.ActionTrigger{
BalanceId: at.BalanceId,
BalanceId: at.BalanceType,
Direction: at.Direction,
ThresholdType: at.ThresholdType,
ThresholdValue: at.ThresholdValue,
@@ -82,7 +82,7 @@ func (self *Apier) GetTPActionTriggers(attrs AttrGetTPActionTriggers, reply *uti
aTriggers := make([]utils.ApiActionTrigger, len(ats[attrs.ActionTriggersId]))
for idx, row := range ats[attrs.ActionTriggersId] {
aTriggers[idx] = utils.ApiActionTrigger{
BalanceId: row.BalanceId,
BalanceType: row.BalanceId,
Direction: row.Direction,
ThresholdType: row.ThresholdType,
ThresholdValue: row.ThresholdValue,

View File

@@ -252,7 +252,7 @@ func main() {
}
defer loggerDb.Close()
engine.SetStorageLogger(loggerDb)
engine.SetRoundingMethodAndDecimals(cfg.RaterRoundingMethod, cfg.RaterRoundingDecimals)
engine.SetRoundingMethodAndDecimals(cfg.RoundingMethod, cfg.RoundingDecimals)
if cfg.SMDebitInterval > 0 {
if dp, err := time.ParseDuration(fmt.Sprintf("%vs", cfg.SMDebitInterval)); err == nil {

View File

@@ -35,10 +35,7 @@ const (
REDIS = "redis"
SAME = "same"
FS = "freeswitch"
PREPAID = "prepaid"
POSTPAID = "postpaid"
PSEUDOPREPAID = "pseudoprepaid"
RATED = "rated"
)
// Holds system configuration, defaults are overwritten with values from config file if found
@@ -60,11 +57,11 @@ type CGRConfig struct {
DefaultTOR string // set default type of record
DefaultTenant string // set default tenant
DefaultSubject string // set default rating subject, useful in case of fallback
RoundingMethod string // Rounding method for the end price: <*up|*middle|*down>
RoundingDecimals int // Number of decimals to round end prices at
RaterEnabled bool // start standalone server (no balancer)
RaterBalancer string // balancer address host:port
RaterListen string // listening address host:port
RaterRoundingMethod string // Rounding method for the end price: <up|middle|down>
RaterRoundingDecimals int // Number of decimals to round end prices at
BalancerEnabled bool
BalancerListen string // Json RPC server address
SchedulerEnabled bool
@@ -114,15 +111,15 @@ func (self *CGRConfig) setDefaults() error {
self.StorDBUser = "cgrates"
self.StorDBPass = "CGRateS.org"
self.RPCEncoding = JSON
self.DefaultReqType = "rated"
self.DefaultReqType = utils.RATED
self.DefaultTOR = "0"
self.DefaultTenant = "0"
self.DefaultSubject = "0"
self.RoundingMethod = utils.ROUNDING_MIDDLE
self.RoundingDecimals = 4
self.RaterEnabled = false
self.RaterBalancer = DISABLED
self.RaterListen = "127.0.0.1:2012"
self.RaterRoundingMethod = utils.ROUNDING_MIDDLE
self.RaterRoundingDecimals = 4
self.BalancerEnabled = false
self.BalancerListen = "127.0.0.1:2013"
self.SchedulerEnabled = false
@@ -239,6 +236,12 @@ func loadConfig(c *conf.ConfigFile) (*CGRConfig, error) {
if hasOpt = c.HasOption("global", "default_subject"); hasOpt {
cfg.DefaultSubject, _ = c.GetString("global", "default_subject")
}
if hasOpt = c.HasOption("global", "rounding_method"); hasOpt {
cfg.RoundingMethod, _ = c.GetString("global", "rounding_method")
}
if hasOpt = c.HasOption("global", "rounding_decimals"); hasOpt {
cfg.RoundingDecimals, _ = c.GetInt("global", "rounding_decimals")
}
if hasOpt = c.HasOption("rater", "enabled"); hasOpt {
cfg.RaterEnabled, _ = c.GetBool("rater", "enabled")
}
@@ -248,12 +251,6 @@ func loadConfig(c *conf.ConfigFile) (*CGRConfig, error) {
if hasOpt = c.HasOption("rater", "listen"); hasOpt {
cfg.RaterListen, _ = c.GetString("rater", "listen")
}
if hasOpt = c.HasOption("rater", "rounding_method"); hasOpt {
cfg.RaterRoundingMethod, _ = c.GetString("rater", "rounding_method")
}
if hasOpt = c.HasOption("rater", "rounding_decimals"); hasOpt {
cfg.RaterRoundingDecimals, _ = c.GetInt("rater", "rounding_decimals")
}
if hasOpt = c.HasOption("balancer", "enabled"); hasOpt {
cfg.BalancerEnabled, _ = c.GetBool("balancer", "enabled")
}

View File

@@ -47,15 +47,15 @@ func TestDefaults(t *testing.T) {
eCfg.StorDBUser = "cgrates"
eCfg.StorDBPass = "CGRateS.org"
eCfg.RPCEncoding = JSON
eCfg.DefaultReqType = RATED
eCfg.DefaultReqType = utils.RATED
eCfg.DefaultTOR = "0"
eCfg.DefaultTenant = "0"
eCfg.DefaultSubject = "0"
eCfg.RoundingMethod = utils.ROUNDING_MIDDLE
eCfg.RoundingDecimals = 4
eCfg.RaterEnabled = false
eCfg.RaterBalancer = DISABLED
eCfg.RaterListen = "127.0.0.1:2012"
eCfg.RaterRoundingMethod = utils.ROUNDING_MIDDLE
eCfg.RaterRoundingDecimals = 4
eCfg.BalancerEnabled = false
eCfg.BalancerListen = "127.0.0.1:2013"
eCfg.SchedulerEnabled = false
@@ -142,11 +142,11 @@ func TestConfigFromFile(t *testing.T) {
eCfg.DefaultTOR = "test"
eCfg.DefaultTenant = "test"
eCfg.DefaultSubject = "test"
eCfg.RoundingMethod = "test"
eCfg.RoundingDecimals = 99
eCfg.RaterEnabled = true
eCfg.RaterBalancer = "test"
eCfg.RaterListen = "test"
eCfg.RaterRoundingMethod = "test"
eCfg.RaterRoundingDecimals = 99
eCfg.BalancerEnabled = true
eCfg.BalancerListen = "test"
eCfg.SchedulerEnabled = true

View File

@@ -19,6 +19,8 @@ default_reqtype = test # Default request type to consider when missing from r
default_tor = test # Default Type of Record to consider when missing from requests.
default_tenant = test # Default Tenant to consider when missing from requests.
default_subject = test # Default rating Subject to consider when missing from requests.
rounding_method = test # Rounding method for floats/costs: <up|middle|down>
rounding_decimals = 99 # Number of decimals to round floats/costs at
[balancer]
@@ -29,8 +31,6 @@ listen = test # Balancer listen interface: <disabled|x.y.z.y:1234>.
enabled = true # Enable Rater service: <true|false>.
balancer = test # Register to Balancer as worker: <enabled|disabled>.
listen = test # Rater's listening interface: <internal|x.y.z.y:1234>.
rounding_method = test # Rounding method for the end price: <up|middle|down>
rounding_decimals = 99 # Number of decimals to round prices at
[scheduler]
enabled = true # Starts Scheduler service: <true|false>.

View File

@@ -22,6 +22,8 @@
# default_tor = 0 # Default Type of Record to consider when missing from requests.
# default_tenant = 0 # Default Tenant to consider when missing from requests.
# default_subject = 0 # Default rating Subject to consider when missing from requests.
# rounding_method = *middle # Rounding method for floats/costs: <*up|*middle|*down>
# rounding_decimals = 4 # Number of decimals to round float/costs at
[balancer]
@@ -32,8 +34,6 @@
# enabled = false # Enable Rater service: <true|false>.
# balancer = disabled # Register to Balancer as worker: <enabled|disabled>.
# listen = 127.0.0.1:2012 # Rater's listening interface: <internal|x.y.z.y:1234>.
# rounding_method = middle # Rounding method for the end price: <up|middle|down>
# rounding_decimals = 4 # Number of decimals to round end prices at
[scheduler]
# enabled = false # Starts Scheduler service: <true|false>.

View File

@@ -117,11 +117,11 @@ CREATE TABLE `tp_actions` (
`action` varchar(24) NOT NULL,
`balance_type` varchar(24) NOT NULL,
`direction` varchar(8) NOT NULL,
`units` DECIMAL(5,2) NOT NULL,
`units` DECIMAL(8,4) NOT NULL,
`expiry_time` int(16) NOT NULL,
`destination_tag` varchar(24) NOT NULL,
`rate_type` varchar(8) NOT NULL,
`rate` DECIMAL(5,4) NOT NULL,
`rate` DECIMAL(8,4) NOT NULL,
`minutes_weight` DECIMAL(5,2) NOT NULL,
`weight` DECIMAL(5,2) NOT NULL,
PRIMARY KEY (`id`),
@@ -155,8 +155,8 @@ CREATE TABLE `tp_action_triggers` (
`tag` varchar(24) NOT NULL,
`balance_type` varchar(24) NOT NULL,
`direction` varchar(8) NOT NULL,
`threshold_type` char(11) NOT NULL,
`threshold_value` DECIMAL(5,4) NOT NULL,
`threshold_type` char(12) NOT NULL,
`threshold_value` DECIMAL(8,4) NOT NULL,
`destination_tag` varchar(24) NOT NULL,
`actions_tag` varchar(24) NOT NULL,
`weight` DECIMAL(5,2) NOT NULL,

View File

@@ -134,7 +134,7 @@ Queries specific Actions profile on tariff plan.
Units float64 // Number of units to add/deduct
ExpiryTime int64 // Time when the units will expire
DestinationId string // Destination profile id
RateType string // Type of price <ABSOLUTE|PERCENT>
RateType string // Type of price <*absolute|*percent>
Rate float64 // Price value
MinutesWeight float64 // Minutes weight
Weight float64 // Action's weight

View File

@@ -16,7 +16,7 @@ Creates a new ActionTriggers profile within a tariff plan.
}
type ApiActionTrigger struct {
BalanceId string // Id of the balance this trigger monitors
BalanceType string // Id of the balance this trigger monitors
Direction string // Traffic direction
ThresholdType string // This threshold type
ThresholdValue float64 // Threshold
@@ -25,7 +25,7 @@ Creates a new ActionTriggers profile within a tariff plan.
Weight float64 // weight
}
Mandatory parameters: ``[]string{"TPid", "ActionTriggersId","BalanceId", "Direction", "ThresholdType", "ThresholdValue", "ActionsId", "Weight"}``
Mandatory parameters: ``[]string{"TPid", "ActionTriggersId","BalanceType", "Direction", "ThresholdType", "ThresholdValue", "ActionsId", "Weight"}``
*JSON sample*:
::
@@ -38,7 +38,7 @@ Creates a new ActionTriggers profile within a tariff plan.
"ActionTriggers": [
{
"ActionsId": "ACTION_1",
"BalanceId": "MONETARY",
"BalanceType": "MONETARY",
"DestinationId": "",
"Direction": "OUT",
"ThresholdType": "MIN_BALANCE",
@@ -124,7 +124,7 @@ Queries specific ActionTriggers profile on tariff plan.
}
type ApiActionTrigger struct {
BalanceId string // Id of the balance this trigger monitors
BalanceType string // Id of the balance this trigger monitors
Direction string // Traffic direction
ThresholdType string // This threshold type
ThresholdValue float64 // Threshold
@@ -143,9 +143,9 @@ Queries specific ActionTriggers profile on tariff plan.
"ActionTriggers": [
{
"ActionsId": "ACTION_1",
"BalanceId": "MONETARY",
"BalanceType": "*monetary",
"DestinationId": "",
"Direction": "OUT",
"Direction": "*out",
"ThresholdType": "MIN_BALANCE",
"ThresholdValue": 5,
"Weight": 10

View File

@@ -375,6 +375,53 @@ func (self *TPCSVImporter) importActionTimings(fn string) error {
}
func (self *TPCSVImporter) importActionTriggers(fn string) error {
log.Printf("Processing file: <%s> ", fn)
fParser, err := NewTPCSVFileParser(self.DirPath, fn)
if err != nil {
return err
}
lineNr := 0
for {
lineNr++
record, err := fParser.ParseNextLine()
if err == io.EOF { // Reached end of file
break
} else if err != nil {
if self.Verbose {
log.Printf("Ignoring line %d, warning: <%s> ", lineNr, err.Error())
}
continue
}
tag, balanceType, direction, thresholdType, destinationTag, actionsTag := record[0], record[1], record[2], record[3], record[5], record[6]
threshold, err := strconv.ParseFloat(record[4], 64)
if err != nil {
if self.Verbose {
log.Printf("Ignoring line %d, warning: <%s> ", lineNr, err.Error())
}
continue
}
weight, err := strconv.ParseFloat(record[7], 64)
if err != nil {
if self.Verbose {
log.Printf("Ignoring line %d, warning: <%s> ", lineNr, err.Error())
}
continue
}
at := &ActionTrigger{
BalanceId: balanceType,
Direction: direction,
ThresholdType: thresholdType,
ThresholdValue: threshold,
DestinationId: destinationTag,
Weight: weight,
ActionsId: actionsTag,
}
if err := self.StorDb.SetTPActionTriggers(self.TPid, map[string][]*ActionTrigger{tag: []*ActionTrigger{at}}); err != nil {
if self.Verbose {
log.Printf("Ignoring line %d, storDb operational error: <%s> ", lineNr, err.Error())
}
}
}
return nil
}

View File

@@ -123,7 +123,7 @@ type ApiTPActionTriggers struct {
}
type ApiActionTrigger struct {
BalanceId string // Id of the balance this trigger monitors
BalanceType string // Type of balance this trigger monitors
Direction string // Traffic direction
ThresholdType string // This threshold type
ThresholdValue float64 // Threshold

View File

@@ -49,8 +49,8 @@ const (
ACTION_TIMINGS_NRCOLS = 4
ACTION_TRIGGERS_NRCOLS = 8
ACCOUNT_ACTIONS_NRCOLS = 5
ROUNDING_UP = "up"
ROUNDING_MIDDLE = "middle"
ROUNDING_DOWN = "down"
ROUNDING_UP = "*up"
ROUNDING_MIDDLE = "*middle"
ROUNDING_DOWN = "*down"
COMMENT_CHAR = '#'
)

View File

@@ -78,11 +78,11 @@ func Round(x float64, prec int, method string) float64 {
_, frac := math.Modf(intermed)
switch method {
case "*up":
case ROUNDING_UP:
rounder = math.Ceil(intermed)
case "*down":
case ROUNDING_DOWN:
rounder = math.Floor(intermed)
case "*middle":
case ROUNDING_MIDDLE:
if frac >= 0.5 {
rounder = math.Ceil(intermed)
} else {

View File

@@ -41,7 +41,7 @@ func TestUUID(t *testing.T) {
}
func TestRoundUp(t *testing.T) {
result := Round(12.52, 0, "*middle")
result := Round(12.52, 0, ROUNDING_UP)
expected := 13.0
if result != expected {
t.Errorf("Error rounding up: sould be %v was %v", expected, result)
@@ -49,7 +49,7 @@ func TestRoundUp(t *testing.T) {
}
func TestRoundUpMiddle(t *testing.T) {
result := Round(12.5, 0, "*middle")
result := Round(12.5, 0, ROUNDING_UP)
expected := 13.0
if result != expected {
t.Errorf("Error rounding up: sould be %v was %v", expected, result)
@@ -57,7 +57,7 @@ func TestRoundUpMiddle(t *testing.T) {
}
func TestRoundDown(t *testing.T) {
result := Round(12.49, 0, "*middle")
result := Round(12.49, 0, ROUNDING_MIDDLE)
expected := 12.0
if result != expected {
t.Errorf("Error rounding up: sould be %v was %v", expected, result)
@@ -65,7 +65,7 @@ func TestRoundDown(t *testing.T) {
}
func TestRoundPrec(t *testing.T) {
result := Round(12.49, 1, "*middle")
result := Round(12.49, 1, ROUNDING_UP)
expected := 12.5
if result != expected {
t.Errorf("Error rounding up: sould be %v was %v", expected, result)
@@ -73,7 +73,7 @@ func TestRoundPrec(t *testing.T) {
}
func TestRoundPrecNothing(t *testing.T) {
result := Round(12.49, 2, "*middle")
result := Round(12.49, 2, ROUNDING_MIDDLE)
expected := 12.49
if result != expected {
t.Errorf("Error rounding up: sould be %v was %v", expected, result)
@@ -89,7 +89,7 @@ func TestRoundPrecNoTouch(t *testing.T) {
}
func TestRoundByMethodUp1(t *testing.T) {
result := Round(12.49, 1, "*up")
result := Round(12.49, 1, ROUNDING_UP)
expected := 12.5
if result != expected {
t.Errorf("Error rounding up: sould be %v was %v", expected, result)
@@ -97,7 +97,7 @@ func TestRoundByMethodUp1(t *testing.T) {
}
func TestRoundByMethodUp2(t *testing.T) {
result := Round(12.21, 1, "*up")
result := Round(12.21, 1, ROUNDING_UP)
expected := 12.3
if result != expected {
t.Errorf("Error rounding up: sould be %v was %v", expected, result)
@@ -105,15 +105,15 @@ func TestRoundByMethodUp2(t *testing.T) {
}
func TestRoundByMethodDown1(t *testing.T) {
result := Round(12.49, 1, "*down")
result := Round(12.49, 1, ROUNDING_DOWN)
expected := 12.4
if result != expected {
t.Errorf("Error rounding up: sould be %v was %v", expected, result)
t.Errorf("Error rounding down: sould be %v was %v", expected, result)
}
}
func TestRoundByMethodDown2(t *testing.T) {
result := Round(12.21, 1, "*down")
result := Round(12.21, 1, ROUNDING_DOWN)
expected := 12.2
if result != expected {
t.Errorf("Error rounding up: sould be %v was %v", expected, result)