mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-19 22:28:45 +05:00
SMAsterisk configuration, initial structures
This commit is contained in:
@@ -45,6 +45,7 @@ var (
|
||||
dfltFsConnConfig *FsConnConfig // Default FreeSWITCH Connection configuration, built out of json default configuration
|
||||
dfltKamConnConfig *KamConnConfig // Default Kamailio Connection configuration
|
||||
dfltHaPoolConfig *HaPoolConfig
|
||||
dfltAstConnCfg *AsteriskConnCfg
|
||||
)
|
||||
|
||||
// Used to retrieve system configuration from other packages
|
||||
@@ -66,6 +67,7 @@ func NewDefaultCGRConfig() (*CGRConfig, error) {
|
||||
cfg.SmFsConfig = new(SmFsConfig)
|
||||
cfg.SmKamConfig = new(SmKamConfig)
|
||||
cfg.SmOsipsConfig = new(SmOsipsConfig)
|
||||
cfg.SMAsteriskCfg = new(SMAsteriskCfg)
|
||||
cfg.diameterAgentCfg = new(DiameterAgentCfg)
|
||||
cfg.ConfigReloads = make(map[string]chan struct{})
|
||||
cfg.ConfigReloads[utils.CDRC] = make(chan struct{}, 1)
|
||||
@@ -88,6 +90,7 @@ func NewDefaultCGRConfig() (*CGRConfig, error) {
|
||||
cfg.dfltCdrcProfile = cfg.CdrcProfiles["/var/spool/cgrates/cdrc/in"][0].Clone()
|
||||
dfltFsConnConfig = cfg.SmFsConfig.EventSocketConns[0] // We leave it crashing here on purpose if no Connection defaults defined
|
||||
dfltKamConnConfig = cfg.SmKamConfig.EvapiConns[0]
|
||||
dfltAstConnCfg = cfg.SMAsteriskCfg.AsteriskConns[0]
|
||||
if err := cfg.checkConfigSanity(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -242,6 +245,7 @@ type CGRConfig struct {
|
||||
SmFsConfig *SmFsConfig // SMFreeSWITCH configuration
|
||||
SmKamConfig *SmKamConfig // SM-Kamailio Configuration
|
||||
SmOsipsConfig *SmOsipsConfig // SMOpenSIPS Configuration
|
||||
SMAsteriskCfg *SMAsteriskCfg // SMAsterisk Configuration
|
||||
diameterAgentCfg *DiameterAgentCfg // DiameterAgent configuration
|
||||
HistoryServer string // Address where to reach the master history server: <internal|x.y.z.y:1234>
|
||||
HistoryServerEnabled bool // Starts History as server: <true|false>.
|
||||
@@ -421,7 +425,7 @@ func (self *CGRConfig) checkConfigSanity() error {
|
||||
}
|
||||
for _, smOsipsRaterConn := range self.SmOsipsConfig.RALsConns {
|
||||
if smOsipsRaterConn.Address == utils.MetaInternal && !self.RALsEnabled {
|
||||
return errors.New("<SMOpenSIPS> RALs not enabled but requested by SMOpenSIPS component.")
|
||||
return errors.New("<SMOpenSIPS> RALs not enabled.")
|
||||
}
|
||||
}
|
||||
if len(self.SmOsipsConfig.CDRsConns) == 0 {
|
||||
@@ -430,7 +434,18 @@ func (self *CGRConfig) checkConfigSanity() error {
|
||||
|
||||
for _, smOsipsCDRSConn := range self.SmOsipsConfig.CDRsConns {
|
||||
if smOsipsCDRSConn.Address == utils.MetaInternal && !self.CDRSEnabled {
|
||||
return errors.New("<SMOpenSIPS> CDRS not enabled but referenced by SMOpenSIPS component")
|
||||
return errors.New("<SMOpenSIPS> CDRS not enabled.")
|
||||
}
|
||||
}
|
||||
}
|
||||
// SMOpenSIPS checks
|
||||
if self.SMAsteriskCfg.Enabled {
|
||||
if len(self.SMAsteriskCfg.SMGConns) == 0 {
|
||||
return errors.New("<SMAsterisk> SMG definition is mandatory!")
|
||||
}
|
||||
for _, smAstSMGConn := range self.SMAsteriskCfg.SMGConns {
|
||||
if smAstSMGConn.Address == utils.MetaInternal && !self.SmGenericConfig.Enabled {
|
||||
return errors.New("<SMAsterisk> SMG not enabled.")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -548,6 +563,11 @@ func (self *CGRConfig) loadFromJsonCfg(jsnCfg *CgrJsonCfg) error {
|
||||
return err
|
||||
}
|
||||
|
||||
jsnSMAstCfg, err := jsnCfg.SmAsteriskJsonCfg()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
jsnDACfg, err := jsnCfg.DiameterAgentJsonCfg()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -975,6 +995,12 @@ func (self *CGRConfig) loadFromJsonCfg(jsnCfg *CgrJsonCfg) error {
|
||||
}
|
||||
}
|
||||
|
||||
if jsnSMAstCfg != nil {
|
||||
if err := self.SMAsteriskCfg.loadFromJsonCfg(jsnSMAstCfg); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if jsnDACfg != nil {
|
||||
if err := self.diameterAgentCfg.loadFromJsonCfg(jsnDACfg); err != nil {
|
||||
return err
|
||||
|
||||
@@ -331,6 +331,21 @@ const CGRATES_CFG_JSON = `
|
||||
},
|
||||
|
||||
|
||||
"sm_asterisk": {
|
||||
"enabled": false, // starts Asterisk SessionManager service: <true|false>
|
||||
"sm_generic_conns": [
|
||||
{"address": "*internal"} // connection towards SMG component for session management
|
||||
],
|
||||
"session_terminate_subscriber": {"address": "*internal"}, // handler for session_terminate events generated by SMG
|
||||
"debit_interval": "10s", // interval to perform debits on.
|
||||
"min_call_duration": "0s", // only authorize calls with allowed duration higher than this
|
||||
"max_call_duration": "3h", // maximum call duration a prepaid call can last
|
||||
"asterisk_conns":[ // instantiate connections to multiple Asterisk servers
|
||||
{"address": "127.0.0.1:8088", "user": "cgrates", "password": "CGRateS.org", "reconnects": 5}
|
||||
],
|
||||
},
|
||||
|
||||
|
||||
"diameter_agent": {
|
||||
"enabled": false, // enables the diameter agent: <true|false>
|
||||
"listen": "127.0.0.1:3868", // address where to listen for diameter requests <x.y.z.y:1234>
|
||||
|
||||
@@ -44,6 +44,7 @@ const (
|
||||
SMFS_JSN = "sm_freeswitch"
|
||||
SMKAM_JSN = "sm_kamailio"
|
||||
SMOSIPS_JSN = "sm_opensips"
|
||||
SMAsteriskJSN = "sm_asterisk"
|
||||
SM_JSN = "session_manager"
|
||||
FS_JSN = "freeswitch"
|
||||
KAMAILIO_JSN = "kamailio"
|
||||
@@ -261,6 +262,18 @@ func (self CgrJsonCfg) SmOsipsJsonCfg() (*SmOsipsJsonCfg, error) {
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
func (self CgrJsonCfg) SmAsteriskJsonCfg() (*SMAsteriskJsonCfg, error) {
|
||||
rawCfg, hasKey := self[SMAsteriskJSN]
|
||||
if !hasKey {
|
||||
return nil, nil
|
||||
}
|
||||
cfg := new(SMAsteriskJsonCfg)
|
||||
if err := json.Unmarshal(*rawCfg, cfg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
func (self CgrJsonCfg) DiameterAgentJsonCfg() (*DiameterAgentJsonCfg, error) {
|
||||
rawCfg, hasKey := self[DA_JSN]
|
||||
if !hasKey {
|
||||
|
||||
@@ -516,6 +516,33 @@ func TestSmOsipsJsonCfg(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSmAsteriskJsonCfg(t *testing.T) {
|
||||
eCfg := &SMAsteriskJsonCfg{
|
||||
Enabled: utils.BoolPointer(false),
|
||||
Sm_generic_conns: &[]*HaPoolJsonCfg{
|
||||
&HaPoolJsonCfg{
|
||||
Address: utils.StringPointer(utils.MetaInternal),
|
||||
}},
|
||||
Session_terminate_subscriber: &HaPoolJsonCfg{Address: utils.StringPointer(utils.MetaInternal)},
|
||||
Debit_interval: utils.StringPointer("10s"),
|
||||
Min_call_duration: utils.StringPointer("0s"),
|
||||
Max_call_duration: utils.StringPointer("3h"),
|
||||
Asterisk_conns: &[]*AstConnJsonCfg{
|
||||
&AstConnJsonCfg{
|
||||
Address: utils.StringPointer("127.0.0.1:8088"),
|
||||
User: utils.StringPointer("cgrates"),
|
||||
Password: utils.StringPointer("CGRateS.org"),
|
||||
Reconnects: utils.IntPointer(5),
|
||||
},
|
||||
},
|
||||
}
|
||||
if cfg, err := dfCgrJsonCfg.SmAsteriskJsonCfg(); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(eCfg, cfg) {
|
||||
t.Error("Received: ", cfg)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDiameterAgentJsonCfg(t *testing.T) {
|
||||
eCfg := &DiameterAgentJsonCfg{
|
||||
Enabled: utils.BoolPointer(false),
|
||||
|
||||
@@ -214,6 +214,23 @@ type HaPoolJsonCfg struct {
|
||||
Transport *string
|
||||
}
|
||||
|
||||
type AstConnJsonCfg struct {
|
||||
Address *string
|
||||
User *string
|
||||
Password *string
|
||||
Reconnects *int
|
||||
}
|
||||
|
||||
type SMAsteriskJsonCfg struct {
|
||||
Enabled *bool
|
||||
Sm_generic_conns *[]*HaPoolJsonCfg // Connections towards generic SM
|
||||
Session_terminate_subscriber *HaPoolJsonCfg
|
||||
Debit_interval *string
|
||||
Min_call_duration *string
|
||||
Max_call_duration *string
|
||||
Asterisk_conns *[]*AstConnJsonCfg
|
||||
}
|
||||
|
||||
type CacheParamJsonCfg struct {
|
||||
Limit *int
|
||||
Ttl *string
|
||||
|
||||
@@ -435,3 +435,85 @@ func (self *SmOsipsConfig) loadFromJsonCfg(jsnCfg *SmOsipsJsonCfg) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Uses stored defaults so we can pre-populate by loading from JSON config
|
||||
func NewDefaultAsteriskConnCfg() *AsteriskConnCfg {
|
||||
if dfltAstConnCfg == nil {
|
||||
return new(AsteriskConnCfg) // No defaults, most probably we are building the defaults now
|
||||
}
|
||||
dfltVal := *dfltAstConnCfg // Copy the value instead of it's pointer
|
||||
return &dfltVal
|
||||
}
|
||||
|
||||
type AsteriskConnCfg struct {
|
||||
Address string
|
||||
User string
|
||||
Password string
|
||||
Reconnects int
|
||||
}
|
||||
|
||||
func (aConnCfg *AsteriskConnCfg) loadFromJsonCfg(jsnCfg *AstConnJsonCfg) error {
|
||||
if jsnCfg.Address != nil {
|
||||
aConnCfg.Address = *jsnCfg.Address
|
||||
}
|
||||
if jsnCfg.User != nil {
|
||||
aConnCfg.User = *jsnCfg.User
|
||||
}
|
||||
if jsnCfg.Password != nil {
|
||||
aConnCfg.Password = *jsnCfg.Password
|
||||
}
|
||||
if jsnCfg.Reconnects != nil {
|
||||
aConnCfg.Reconnects = *jsnCfg.Reconnects
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type SMAsteriskCfg struct {
|
||||
Enabled bool
|
||||
SMGConns []*HaPoolConfig
|
||||
SessionTerminateSubscriber *HaPoolConfig
|
||||
DebitInterval time.Duration
|
||||
MinCallDuration time.Duration
|
||||
MaxCallDuration time.Duration
|
||||
AsteriskConns []*AsteriskConnCfg
|
||||
}
|
||||
|
||||
func (aCfg *SMAsteriskCfg) loadFromJsonCfg(jsnCfg *SMAsteriskJsonCfg) (err error) {
|
||||
if jsnCfg.Enabled != nil {
|
||||
aCfg.Enabled = *jsnCfg.Enabled
|
||||
}
|
||||
if jsnCfg.Sm_generic_conns != nil {
|
||||
aCfg.SMGConns = make([]*HaPoolConfig, len(*jsnCfg.Sm_generic_conns))
|
||||
for idx, jsnHaCfg := range *jsnCfg.Sm_generic_conns {
|
||||
aCfg.SMGConns[idx] = NewDfltHaPoolConfig()
|
||||
aCfg.SMGConns[idx].loadFromJsonCfg(jsnHaCfg)
|
||||
}
|
||||
}
|
||||
if jsnCfg.Session_terminate_subscriber != nil {
|
||||
aCfg.SessionTerminateSubscriber = NewDfltHaPoolConfig()
|
||||
aCfg.SessionTerminateSubscriber.loadFromJsonCfg(jsnCfg.Session_terminate_subscriber)
|
||||
}
|
||||
if jsnCfg.Debit_interval != nil {
|
||||
if aCfg.DebitInterval, err = utils.ParseDurationWithSecs(*jsnCfg.Debit_interval); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if jsnCfg.Min_call_duration != nil {
|
||||
if aCfg.MinCallDuration, err = utils.ParseDurationWithSecs(*jsnCfg.Min_call_duration); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if jsnCfg.Max_call_duration != nil {
|
||||
if aCfg.MaxCallDuration, err = utils.ParseDurationWithSecs(*jsnCfg.Max_call_duration); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if jsnCfg.Asterisk_conns != nil {
|
||||
aCfg.AsteriskConns = make([]*AsteriskConnCfg, len(*jsnCfg.Asterisk_conns))
|
||||
for i, jsnAConn := range *jsnCfg.Asterisk_conns {
|
||||
aCfg.AsteriskConns[i] = NewDefaultAsteriskConnCfg()
|
||||
aCfg.AsteriskConns[i].loadFromJsonCfg(jsnAConn)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
28
sessionmanager/smasterisk.go
Normal file
28
sessionmanager/smasterisk.go
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
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 sessionmanager
|
||||
|
||||
import (
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/rpcclient"
|
||||
)
|
||||
|
||||
type SMAsterisk struct {
|
||||
cgrCfg *config.CGRConfig // Separate from smCfg since there can be multiple
|
||||
smg rpcclient.RpcClientConnection
|
||||
}
|
||||
Reference in New Issue
Block a user