From 3181c0c535e1574859bc504688d437f69433c386 Mon Sep 17 00:00:00 2001 From: DanB Date: Sun, 1 Oct 2017 15:01:19 +0200 Subject: [PATCH] Config options for thresholds --- config/config.go | 19 ++++++++++++++++ config/config_defaults.go | 23 ++++++++++++------- config/config_json.go | 14 ++++++++++++ config/config_json_test.go | 15 ++++++++++++- config/config_test.go | 10 +++++++++ config/libconfig_json.go | 7 ++++++ config/thresholdscfg.go | 46 ++++++++++++++++++++++++++++++++++++++ engine/thresholds.go | 2 +- utils/consts.go | 1 + 9 files changed, 127 insertions(+), 10 deletions(-) create mode 100644 config/thresholdscfg.go diff --git a/config/config.go b/config/config.go index 7e64c96ac..8832accf2 100755 --- a/config/config.go +++ b/config/config.go @@ -269,6 +269,7 @@ type CGRConfig struct { UserServerIndexes []string // List of user profile field indexes resourceSCfg *ResourceSConfig // Configuration for resource limiter statsCfg *StatSCfg // Configuration for StatS + thresholdSCfg *ThresholdSCfg // configuration for ThresholdS MailerServer string // The server to use when sending emails out MailerAuthUser string // Authenticate to email server using this user MailerAuthPass string // Authenticate to email server with this password @@ -644,6 +645,11 @@ func (self *CGRConfig) loadFromJsonCfg(jsnCfg *CgrJsonCfg) error { return err } + jsnThresholdSCfg, err := jsnCfg.ThresholdSJsonCfg() + if err != nil { + return err + } + jsnMailerCfg, err := jsnCfg.MailerJsonCfg() if err != nil { return err @@ -1098,6 +1104,15 @@ func (self *CGRConfig) loadFromJsonCfg(jsnCfg *CgrJsonCfg) error { } } + if jsnThresholdSCfg != nil { + if self.thresholdSCfg == nil { + self.thresholdSCfg = new(ThresholdSCfg) + } + if self.thresholdSCfg.loadFromJsonCfg(jsnThresholdSCfg); err != nil { + return err + } + } + if jsnUserServCfg != nil { if jsnUserServCfg.Enabled != nil { self.UserServerEnabled = *jsnUserServCfg.Enabled @@ -1161,6 +1176,10 @@ func (cfg *CGRConfig) StatSCfg() *StatSCfg { return cfg.statsCfg } +func (cfg *CGRConfig) ThresholdSCfg() *ThresholdSCfg { + return cfg.thresholdSCfg +} + // ToDo: fix locking here func (self *CGRConfig) SMAsteriskCfg() *SMAsteriskCfg { cfgChan := <-self.ConfigReloads[utils.SMAsterisk] // Lock config for read or reloads diff --git a/config/config_defaults.go b/config/config_defaults.go index 153f4fa99..5eed6a527 100755 --- a/config/config_defaults.go +++ b/config/config_defaults.go @@ -395,31 +395,38 @@ const CGRATES_CFG_JSON = ` "pubsubs": { - "enabled": false, // starts PubSub service: . + "enabled": false, // starts PubSub service: . }, "aliases": { - "enabled": false, // starts Aliases service: . + "enabled": false, // starts Aliases service: . }, "users": { - "enabled": false, // starts User service: . - "indexes": [], // user profile field indexes + "enabled": false, // starts User service: . + "indexes": [], // user profile field indexes }, "resources": { - "enabled": false, // starts ResourceLimiter service: . - "stats_conns": [], // address where to reach the stats service, empty to disable stats functionality: <""|*internal|x.y.z.y:1234> - "store_interval": "", // dump cache regularly to dataDB, 0 - dump at start/shutdown: <""|*never|$dur> + "enabled": false, // starts ResourceLimiter service: . + "store_interval": "", // dump cache regularly to dataDB, 0 - dump at start/shutdown: <""|*never|$dur> + "stats_conns": [], // address where to reach the stats service, empty to disable stats functionality: <""|*internal|x.y.z.y:1234> }, "stats": { "enabled": false, // starts Stat service: . - "store_interval": "0s", // dump cache regularly to dataDB, 0 - dump at start/shutdown: <""|*never|$dur> + "store_interval": "", // dump cache regularly to dataDB, 0 - dump at start/shutdown: <""|*never|$dur> +}, + + +"thresholds": { + "enabled": false, // starts ThresholdS service: . + "store_interval": "", // dump cache regularly to dataDB, 0 - dump at start/shutdown: <""|*never|$dur> + "filtered_fields": [], // match filters based on these fields for dynamic filtering, empty to use all }, diff --git a/config/config_json.go b/config/config_json.go index 96dac541d..f3e2d2cf1 100644 --- a/config/config_json.go +++ b/config/config_json.go @@ -57,6 +57,8 @@ const ( ALIASESSERV_JSN = "aliases" USERSERV_JSN = "users" RESOURCES_JSON = "resources" + STATS_JSON = "stats" + THRESHOLDS_JSON = "thresholds" MAILER_JSN = "mailer" SURETAX_JSON = "suretax" ) @@ -372,6 +374,18 @@ func (self CgrJsonCfg) StatSJsonCfg() (*StatServJsonCfg, error) { return cfg, nil } +func (self CgrJsonCfg) ThresholdSJsonCfg() (*ThresholdSJsonCfg, error) { + rawCfg, hasKey := self[THRESHOLDS_JSON] + if !hasKey { + return nil, nil + } + cfg := new(ThresholdSJsonCfg) + if err := json.Unmarshal(*rawCfg, cfg); err != nil { + return nil, err + } + return cfg, nil +} + func (self CgrJsonCfg) MailerJsonCfg() (*MailerJsonCfg, error) { rawCfg, hasKey := self[MAILER_JSN] if !hasKey { diff --git a/config/config_json_test.go b/config/config_json_test.go index 3fde3d27c..46cc06a1a 100755 --- a/config/config_json_test.go +++ b/config/config_json_test.go @@ -693,7 +693,7 @@ func TestDfResourceLimiterSJsonCfg(t *testing.T) { func TestDfStatServiceJsonCfg(t *testing.T) { eCfg := &StatServJsonCfg{ Enabled: utils.BoolPointer(false), - Store_interval: utils.StringPointer("0s"), + Store_interval: utils.StringPointer(""), } if cfg, err := dfCgrJsonCfg.StatSJsonCfg(); err != nil { t.Error(err) @@ -702,6 +702,19 @@ func TestDfStatServiceJsonCfg(t *testing.T) { } } +func TestDfThresholdSJsonCfg(t *testing.T) { + eCfg := &ThresholdSJsonCfg{ + Enabled: utils.BoolPointer(false), + Store_interval: utils.StringPointer(""), + Filtered_fields: utils.StringSlicePointer([]string{}), + } + if cfg, err := dfCgrJsonCfg.ThresholdSJsonCfg(); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(eCfg, cfg) { + t.Errorf("expecting: %+v, received: %+v", eCfg, cfg) + } +} + func TestDfMailerJsonCfg(t *testing.T) { eCfg := &MailerJsonCfg{ Server: utils.StringPointer("localhost"), diff --git a/config/config_test.go b/config/config_test.go index 8cf538ade..dab9dd61b 100755 --- a/config/config_test.go +++ b/config/config_test.go @@ -587,6 +587,16 @@ func TestCgrCfgJSONDefaultStatsCfg(t *testing.T) { } } +func TestCgrCfgJSONDefaultThresholdSCfg(t *testing.T) { + eThresholdSCfg := &ThresholdSCfg{ + Enabled: false, + StoreInterval: 0, + } + if !reflect.DeepEqual(eThresholdSCfg, cgrCfg.thresholdSCfg) { + t.Errorf("received: %+v, expecting: %+v", eThresholdSCfg, cgrCfg.statsCfg) + } +} + func TestCgrCfgJSONDefaultsDiameterAgentCfg(t *testing.T) { testDA := &DiameterAgentCfg{ Enabled: false, diff --git a/config/libconfig_json.go b/config/libconfig_json.go index 2f6ae15a6..b4d4835f9 100755 --- a/config/libconfig_json.go +++ b/config/libconfig_json.go @@ -393,6 +393,13 @@ type StatServJsonCfg struct { Store_interval *string } +// Threshold service config section +type ThresholdSJsonCfg struct { + Enabled *bool + Store_interval *string + Filtered_fields *[]string +} + // Mailer config section type MailerJsonCfg struct { Server *string diff --git a/config/thresholdscfg.go b/config/thresholdscfg.go new file mode 100644 index 000000000..78b7a24d0 --- /dev/null +++ b/config/thresholdscfg.go @@ -0,0 +1,46 @@ +/* +Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments +Copyright (C) ITsysCOM GmbH + +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 +*/ + +package config + +import ( + "time" + + "github.com/cgrates/cgrates/utils" +) + +type ThresholdSCfg struct { + Enabled bool + StoreInterval time.Duration // Dump regularly from cache into dataDB + FilteredFields []string +} + +func (t *ThresholdSCfg) loadFromJsonCfg(jsnCfg *ThresholdSJsonCfg) (err error) { + if jsnCfg == nil { + return nil + } + if jsnCfg.Enabled != nil { + t.Enabled = *jsnCfg.Enabled + } + if jsnCfg.Store_interval != nil { + if t.StoreInterval, err = utils.ParseDurationWithSecs(*jsnCfg.Store_interval); err != nil { + return err + } + } + return nil +} diff --git a/engine/thresholds.go b/engine/thresholds.go index c971f14bf..7461a5f73 100644 --- a/engine/thresholds.go +++ b/engine/thresholds.go @@ -120,7 +120,7 @@ func (ts Thresholds) Sort() { sort.Slice(ts, func(i, j int) bool { return ts[i].tPrfl.Weight > ts[j].tPrfl.Weight }) } -func NewThresholdService(dm *DataManager, filterFields []string, storeInterval time.Duration, +func NewThresholdService(dm *DataManager, filteredFields []string, storeInterval time.Duration, statS rpcclient.RpcClientConnection) (tS *ThresholdService, err error) { return &ThresholdService{dm: dm, filterFields: filterFields, diff --git a/utils/consts.go b/utils/consts.go index b2462568d..8980d7822 100755 --- a/utils/consts.go +++ b/utils/consts.go @@ -452,6 +452,7 @@ const ( EventResourcesPrefix = "ers_" MetaSysLog = "*syslog" MetaStdLog = "*stdout" + MetaNever = "*never" ) func buildCacheInstRevPrefixes() {