mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-24 16:48:45 +05:00
TPCSVImporter ActionTriggers
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>.
|
||||
|
||||
@@ -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>.
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 = '#'
|
||||
)
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user