Configuration with suppliers option, integration tests file for suppliers

This commit is contained in:
DanB
2017-11-27 20:15:30 +01:00
parent a295b3474b
commit d1e5ad908a
10 changed files with 249 additions and 2 deletions

View File

@@ -103,7 +103,7 @@ func TestSMGV1CacheStats(t *testing.T) {
expectedStats := &utils.CacheStats{Destinations: 5, ReverseDestinations: 7, RatingPlans: 4, RatingProfiles: 10,
Actions: 9, ActionPlans: 4, AccountActionPlans: 5, SharedGroups: 1, DerivedChargers: 1,
LcrProfiles: 5, CdrStats: 6, Users: 3, Aliases: 1, ReverseAliases: 2, ResourceProfiles: 3, Resources: 3, StatQueues: 1,
StatQueueProfiles: 1, Thresholds: 7, ThresholdProfiles: 7, Filters: 16, LCRProfiles: 1}
StatQueueProfiles: 1, Thresholds: 7, ThresholdProfiles: 7, Filters: 16, SupplierProfiles: 2}
var args utils.AttrCacheStats
if err := smgV1Rpc.Call("ApierV1.GetCacheStats", args, &rcvStats); err != nil {
t.Error("Got error on ApierV1.GetCacheStats: ", err.Error())

View File

@@ -0,0 +1,136 @@
// +build integration
/*
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 <http://www.gnu.org/licenses/>
*/
package v1
import (
"net/rpc"
"net/rpc/jsonrpc"
"path"
"testing"
"time"
"github.com/cgrates/cgrates/config"
"github.com/cgrates/cgrates/engine"
"github.com/cgrates/cgrates/utils"
)
var (
splSv1CfgPath string
splSv1Cfg *config.CGRConfig
splSv1Rpc *rpc.Client
splSv1ConfDIR string //run tests for specific configuration
splsDelay int
)
var sTestsSupplierSV1 = []func(t *testing.T){
testV1SplSLoadConfig,
testV1SplSInitDataDb,
testV1SplSResetStorDb,
testV1SplSStartEngine,
testV1SplSRpcConn,
testV1SplSFromFolder,
testV1SplSGetWeightSuppliers,
testV1SplSStopEngine,
}
// Test start here
func TestSuplSV1ITMySQL(t *testing.T) {
splSv1ConfDIR = "tutmysql"
for _, stest := range sTestsSupplierSV1 {
t.Run(splSv1ConfDIR, stest)
}
}
func TestSuplSV1ITMongo(t *testing.T) {
splSv1ConfDIR = "tutmongo"
time.Sleep(time.Duration(2 * time.Second)) // give time for engine to start
for _, stest := range sTestsSupplierSV1 {
t.Run(splSv1ConfDIR, stest)
}
}
func testV1SplSLoadConfig(t *testing.T) {
var err error
splSv1CfgPath = path.Join(*dataDir, "conf", "samples", splSv1ConfDIR)
if splSv1Cfg, err = config.NewCGRConfigFromFolder(splSv1CfgPath); err != nil {
t.Error(err)
}
switch splSv1ConfDIR {
case "tutmongo": // Mongo needs more time to reset db, need to investigate
splsDelay = 4000
default:
splsDelay = 1000
}
}
func testV1SplSInitDataDb(t *testing.T) {
if err := engine.InitDataDb(splSv1Cfg); err != nil {
t.Fatal(err)
}
}
// Wipe out the cdr database
func testV1SplSResetStorDb(t *testing.T) {
if err := engine.InitStorDb(splSv1Cfg); err != nil {
t.Fatal(err)
}
}
func testV1SplSStartEngine(t *testing.T) {
if _, err := engine.StopStartEngine(splSv1CfgPath, splsDelay); err != nil {
t.Fatal(err)
}
}
func testV1SplSRpcConn(t *testing.T) {
var err error
splSv1Rpc, err = jsonrpc.Dial("tcp", splSv1Cfg.RPCJSONListen) // We connect over JSON so we can also troubleshoot if needed
if err != nil {
t.Fatal("Could not connect to rater: ", err.Error())
}
}
func testV1SplSFromFolder(t *testing.T) {
var reply string
attrs := &utils.AttrLoadTpFromFolder{FolderPath: path.Join(*dataDir, "tariffplans", "tutorial")}
if err := splSv1Rpc.Call("ApierV1.LoadTariffPlanFromFolder", attrs, &reply); err != nil {
t.Error(err)
}
time.Sleep(500 * time.Millisecond)
}
func testV1SplSGetWeightSuppliers(t *testing.T) {
ev := &engine.SupplierEvent{
Tenant: "cgrates.org",
ID: "testV1SplSGetWeightSuppliers",
Event: map[string]interface{}{},
}
var suplsReply engine.SortedSuppliers
if err := splSv1Rpc.Call(utils.SupplierSv1GetSuppliers,
ev, &suplsReply); err != nil {
t.Error(err)
}
}
func testV1SplSStopEngine(t *testing.T) {
if err := engine.KillEngine(100); err != nil {
t.Error(err)
}
}

View File

@@ -276,6 +276,7 @@ type CGRConfig struct {
resourceSCfg *ResourceSConfig // Configuration for resource limiter
statsCfg *StatSCfg // Configuration for StatS
thresholdSCfg *ThresholdSCfg // configuration for ThresholdS
supplierSCfg *SupplierSCfg // configuration for SupplierS
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
@@ -680,6 +681,11 @@ func (self *CGRConfig) loadFromJsonCfg(jsnCfg *CgrJsonCfg) (err error) {
return err
}
jsnSupplierSCfg, err := jsnCfg.SupplierSJsonCfg()
if err != nil {
return err
}
jsnMailerCfg, err := jsnCfg.MailerJsonCfg()
if err != nil {
return err
@@ -1167,6 +1173,15 @@ func (self *CGRConfig) loadFromJsonCfg(jsnCfg *CgrJsonCfg) (err error) {
}
}
if jsnSupplierSCfg != nil {
if self.supplierSCfg == nil {
self.supplierSCfg = new(SupplierSCfg)
}
if self.supplierSCfg.loadFromJsonCfg(jsnSupplierSCfg); err != nil {
return err
}
}
if jsnUserServCfg != nil {
if jsnUserServCfg.Enabled != nil {
self.UserServerEnabled = *jsnUserServCfg.Enabled
@@ -1234,6 +1249,10 @@ func (cfg *CGRConfig) ThresholdSCfg() *ThresholdSCfg {
return cfg.thresholdSCfg
}
func (cfg *CGRConfig) SuplierSCfg() *SupplierSCfg {
return cfg.supplierSCfg
}
// ToDo: fix locking here
func (self *CGRConfig) SMAsteriskCfg() *SMAsteriskCfg {
cfgChan := <-self.ConfigReloads[utils.SMAsterisk] // Lock config for read or reloads

View File

@@ -446,6 +446,12 @@ const CGRATES_CFG_JSON = `
},
"suppliers": {
"enabled": false, // starts SupplierS service: <true|false>.
"indexed_fields": [], // query indexes based on these fields for faster processing
},
"mailer": {
"server": "localhost", // the server to use when sending emails out
"auth_user": "cgrates", // authenticate to email server using this user

View File

@@ -60,6 +60,7 @@ const (
RESOURCES_JSON = "resources"
STATS_JSON = "stats"
THRESHOLDS_JSON = "thresholds"
SupplierSJson = "suppliers"
FILTERS_JSON = "filters"
MAILER_JSN = "mailer"
SURETAX_JSON = "suretax"
@@ -400,6 +401,18 @@ func (self CgrJsonCfg) ThresholdSJsonCfg() (*ThresholdSJsonCfg, error) {
return cfg, nil
}
func (self CgrJsonCfg) SupplierSJsonCfg() (*SupplierSJsonCfg, error) {
rawCfg, hasKey := self[SupplierSJson]
if !hasKey {
return nil, nil
}
cfg := new(SupplierSJsonCfg)
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 {

View File

@@ -746,6 +746,18 @@ func TestDfThresholdSJsonCfg(t *testing.T) {
}
}
func TestDfSupplierSJsonCfg(t *testing.T) {
eCfg := &SupplierSJsonCfg{
Enabled: utils.BoolPointer(false),
Indexed_fields: utils.StringSlicePointer([]string{}),
}
if cfg, err := dfCgrJsonCfg.SupplierSJsonCfg(); 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"),

View File

@@ -667,7 +667,17 @@ func TestCgrCfgJSONDefaultThresholdSCfg(t *testing.T) {
IndexedFields: []string{},
}
if !reflect.DeepEqual(eThresholdSCfg, cgrCfg.thresholdSCfg) {
t.Errorf("received: %+v, expecting: %+v", eThresholdSCfg, cgrCfg.statsCfg)
t.Errorf("received: %+v, expecting: %+v", eThresholdSCfg, cgrCfg.thresholdSCfg)
}
}
func TestCgrCfgJSONDefaultSupplierSCfg(t *testing.T) {
eSupplSCfg := &SupplierSCfg{
Enabled: false,
IndexedFields: []string{},
}
if !reflect.DeepEqual(eSupplSCfg, cgrCfg.supplierSCfg) {
t.Errorf("received: %+v, expecting: %+v", eSupplSCfg, cgrCfg.supplierSCfg)
}
}

View File

@@ -410,6 +410,12 @@ type ThresholdSJsonCfg struct {
Indexed_fields *[]string
}
// Supplier service config section
type SupplierSJsonCfg struct {
Enabled *bool
Indexed_fields *[]string
}
// Mailer config section
type MailerJsonCfg struct {
Server *string

40
config/supplierscfg.go Normal file
View File

@@ -0,0 +1,40 @@
/*
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 <http://www.gnu.org/licenses/>
*/
package config
type SupplierSCfg struct {
Enabled bool
IndexedFields []string
}
func (spl *SupplierSCfg) loadFromJsonCfg(jsnCfg *SupplierSJsonCfg) (err error) {
if jsnCfg == nil {
return nil
}
if jsnCfg.Enabled != nil {
spl.Enabled = *jsnCfg.Enabled
}
if jsnCfg.Indexed_fields != nil {
spl.IndexedFields = make([]string, len(*jsnCfg.Indexed_fields))
for i, fID := range *jsnCfg.Indexed_fields {
spl.IndexedFields[i] = fID
}
}
return nil
}

View File

@@ -604,6 +604,11 @@ const (
MetaSetVersions = "*set_versions"
)
// MetaSupplierAPIs
const (
SupplierSv1GetSuppliers = "SupplierSv1.GetSuppliers"
)
func buildCacheInstRevPrefixes() {
CachePrefixToInstance = make(map[string]string)
for k, v := range CacheInstanceToPrefix {