diff --git a/agents/fsagent.go b/agents/fsagent.go index 2395d5f50..8cc1673e2 100644 --- a/agents/fsagent.go +++ b/agents/fsagent.go @@ -32,10 +32,10 @@ import ( type fsSockWithConfig struct { fsSock *fsock.FSock - cfg *config.FsConnConfig + cfg *config.FsConnCfg } -func NewFSsessions(fsAgentConfig *config.FsAgentConfig, +func NewFSsessions(fsAgentConfig *config.FsAgentCfg, smg *utils.BiRPCInternalClient, timezone string) (fsa *FSsessions) { fsa = &FSsessions{ cfg: fsAgentConfig, @@ -51,7 +51,7 @@ func NewFSsessions(fsAgentConfig *config.FsAgentConfig, // The freeswitch session manager type holding a buffer for the network connection // and the active sessions type FSsessions struct { - cfg *config.FsAgentConfig + cfg *config.FsAgentCfg conns map[string]*fsSockWithConfig // Keep the list here for connection management purposes senderPools map[string]*fsock.FSockPool // Keep sender pools here smg *utils.BiRPCInternalClient @@ -68,8 +68,8 @@ func (sm *FSsessions) createHandlers() map[string][]func(string, string) { NewFSEvent(body), connId) } handlers := map[string][]func(string, string){ - "CHANNEL_ANSWER": []func(string, string){ca}, - "CHANNEL_HANGUP_COMPLETE": []func(string, string){ch}, + "CHANNEL_ANSWER": {ca}, + "CHANNEL_HANGUP_COMPLETE": {ch}, } if sm.cfg.SubscribePark { cp := func(body, connId string) { @@ -271,7 +271,7 @@ func (sm *FSsessions) onChannelHangupComplete(fsev FSEvent, connId string) { // Connects to the freeswitch mod_event_socket server and starts // listening for events. func (sm *FSsessions) Connect() error { - eventFilters := map[string][]string{"Call-Direction": []string{"inbound"}} + eventFilters := map[string][]string{"Call-Direction": {"inbound"}} errChan := make(chan error) for _, connCfg := range sm.cfg.EventSocketConns { connId := utils.GenUUID() diff --git a/config/config.go b/config/config.go index a6eae3bd5..7668f8786 100755 --- a/config/config.go +++ b/config/config.go @@ -33,7 +33,7 @@ import ( var ( DBDefaults DbDefaults cgrCfg *CGRConfig // will be shared - dfltFsConnConfig *FsConnConfig // Default FreeSWITCH Connection configuration, built out of json default configuration + dfltFsConnConfig *FsConnCfg // Default FreeSWITCH Connection configuration, built out of json default configuration dfltKamConnConfig *KamConnConfig // Default Kamailio Connection configuration dfltHaPoolConfig *HaPoolConfig dfltAstConnCfg *AsteriskConnCfg @@ -146,8 +146,8 @@ func NewDefaultCGRConfig() (*CGRConfig, error) { cfg.CdrcProfiles = make(map[string][]*CdrcCfg) cfg.analyzerSCfg = new(AnalyzerSCfg) cfg.sessionSCfg = new(SessionSCfg) + cfg.fsAgentCfg = new(FsAgentCfg) - cfg.fsAgentCfg = new(FsAgentConfig) cfg.kamAgentCfg = new(KamAgentCfg) cfg.SmOsipsConfig = new(SmOsipsConfig) cfg.asteriskAgentCfg = new(AsteriskAgentCfg) @@ -260,7 +260,6 @@ type CGRConfig struct { CdrcProfiles map[string][]*CdrcCfg // Number of CDRC instances running imports, format map[dirPath][]{Configs} loaderCfg []*LoaderSCfg // LoaderS configurations - fsAgentCfg *FsAgentConfig // FreeSWITCHAgent configuration kamAgentCfg *KamAgentCfg // KamailioAgent Configuration SmOsipsConfig *SmOsipsConfig // SMOpenSIPS Configuration asteriskAgentCfg *AsteriskAgentCfg // SMAsterisk Configuration @@ -305,6 +304,7 @@ type CGRConfig struct { cdrsCfg *CdrsCfg // Cdrs config cdrStatsCfg *CdrStatsCfg // CdrStats config - deprecated sessionSCfg *SessionSCfg // SessionS config + fsAgentCfg *FsAgentCfg // FreeSWITCHAgent config analyzerSCfg *AnalyzerSCfg } @@ -827,6 +827,9 @@ func (self *CGRConfig) loadFromJsonCfg(jsnCfg *CgrJsonCfg) (err error) { if err != nil { return err } + if err := self.fsAgentCfg.loadFromJsonCfg(jsnSmFsCfg); err != nil { + return err + } jsnKamAgentCfg, err := jsnCfg.KamAgentJsonCfg() if err != nil { @@ -1008,12 +1011,6 @@ func (self *CGRConfig) loadFromJsonCfg(jsnCfg *CgrJsonCfg) (err error) { } } - if jsnSmFsCfg != nil { - if err := self.fsAgentCfg.loadFromJsonCfg(jsnSmFsCfg); err != nil { - return err - } - } - if jsnKamAgentCfg != nil { if err := self.kamAgentCfg.loadFromJsonCfg(jsnKamAgentCfg); err != nil { return err @@ -1223,7 +1220,7 @@ func (cfg *CGRConfig) SessionSCfg() *SessionSCfg { return cfg.sessionSCfg } -func (self *CGRConfig) FsAgentCfg() *FsAgentConfig { +func (self *CGRConfig) FsAgentCfg() *FsAgentCfg { return self.fsAgentCfg } diff --git a/config/config_test.go b/config/config_test.go index 6af525033..46da8fd4b 100755 --- a/config/config_test.go +++ b/config/config_test.go @@ -54,7 +54,7 @@ func TestCgrCfgLoadWithDefaults(t *testing.T) { t.Error(err) } eCgrCfg.fsAgentCfg.Enabled = true - eCgrCfg.fsAgentCfg.EventSocketConns = []*FsConnConfig{ + eCgrCfg.fsAgentCfg.EventSocketConns = []*FsConnCfg{ {Address: "1.2.3.4:8021", Password: "ClueCon", Reconnects: 3, Alias: "123"}, {Address: "1.2.3.5:8021", Password: "ClueCon", Reconnects: 5, Alias: "124"}, } @@ -751,7 +751,7 @@ func TestCgrCfgJSONDefaultsCacheCFG(t *testing.T) { } func TestCgrCfgJSONDefaultsFsAgentConfig(t *testing.T) { - eFsAgentCfg := &FsAgentConfig{ + eFsAgentCfg := &FsAgentCfg{ Enabled: false, SessionSConns: []*HaPoolConfig{ {Address: "*internal"}}, @@ -761,9 +761,12 @@ func TestCgrCfgJSONDefaultsFsAgentConfig(t *testing.T) { EmptyBalanceContext: "", EmptyBalanceAnnFile: "", MaxWaitConnection: 2 * time.Second, - EventSocketConns: []*FsConnConfig{ - {Address: "127.0.0.1:8021", - Password: "ClueCon", Reconnects: 5, Alias: "127.0.0.1:8021"}}, + EventSocketConns: []*FsConnCfg{{ + Address: "127.0.0.1:8021", + Password: "ClueCon", + Reconnects: 5, + Alias: "127.0.0.1:8021", + }}, } if !reflect.DeepEqual(cgrCfg.fsAgentCfg, eFsAgentCfg) { diff --git a/config/smconfig.go b/config/smconfig.go index 29b7f21cd..fee5a6faf 100644 --- a/config/smconfig.go +++ b/config/smconfig.go @@ -61,23 +61,23 @@ func (self *HaPoolConfig) loadFromJsonCfg(jsnCfg *HaPoolJsonCfg) error { } // Returns the first cached default value for a FreeSWITCHAgent connection -func NewDfltFsConnConfig() *FsConnConfig { +func NewDfltFsConnConfig() *FsConnCfg { if dfltFsConnConfig == nil { - return new(FsConnConfig) // No defaults, most probably we are building the defaults now + return new(FsConnCfg) // No defaults, most probably we are building the defaults now } dfltVal := *dfltFsConnConfig // Copy the value instead of it's pointer return &dfltVal } // One connection to FreeSWITCH server -type FsConnConfig struct { +type FsConnCfg struct { Address string Password string Reconnects int Alias string } -func (self *FsConnConfig) loadFromJsonCfg(jsnCfg *FsConnJsonCfg) error { +func (self *FsConnCfg) loadFromJsonCfg(jsnCfg *FsConnJsonCfg) error { if jsnCfg == nil { return nil } @@ -243,7 +243,7 @@ func (self *SessionSCfg) loadFromJsonCfg(jsnCfg *SessionSJsonCfg) (err error) { return nil } -type FsAgentConfig struct { +type FsAgentCfg struct { Enabled bool SessionSConns []*HaPoolConfig SubscribePark bool @@ -254,10 +254,10 @@ type FsAgentConfig struct { EmptyBalanceContext string EmptyBalanceAnnFile string MaxWaitConnection time.Duration - EventSocketConns []*FsConnConfig + EventSocketConns []*FsConnCfg } -func (self *FsAgentConfig) loadFromJsonCfg(jsnCfg *FreeswitchAgentJsonCfg) error { +func (self *FsAgentCfg) loadFromJsonCfg(jsnCfg *FreeswitchAgentJsonCfg) error { if jsnCfg == nil { return nil } @@ -296,7 +296,7 @@ func (self *FsAgentConfig) loadFromJsonCfg(jsnCfg *FreeswitchAgentJsonCfg) error } } if jsnCfg.Event_socket_conns != nil { - self.EventSocketConns = make([]*FsConnConfig, len(*jsnCfg.Event_socket_conns)) + self.EventSocketConns = make([]*FsConnCfg, len(*jsnCfg.Event_socket_conns)) for idx, jsnConnCfg := range *jsnCfg.Event_socket_conns { self.EventSocketConns[idx] = NewDfltFsConnConfig() self.EventSocketConns[idx].loadFromJsonCfg(jsnConnCfg) diff --git a/config/smconfig_test.go b/config/smconfig_test.go index e4ed0e026..0444b5f76 100644 --- a/config/smconfig_test.go +++ b/config/smconfig_test.go @@ -26,7 +26,7 @@ import ( "github.com/cgrates/cgrates/utils" ) -func TestFsAgentConfigLoadFromJsonCfg(t *testing.T) { +func TestFsAgentCfgloadFromJsonCfg1(t *testing.T) { fsAgentJsnCfg := &FreeswitchAgentJsonCfg{ Enabled: utils.BoolPointer(true), Create_cdr: utils.BoolPointer(true), @@ -44,16 +44,16 @@ func TestFsAgentConfigLoadFromJsonCfg(t *testing.T) { }, }, } - eFsAgentConfig := &FsAgentConfig{ + eFsAgentConfig := &FsAgentCfg{ Enabled: true, CreateCdr: true, SubscribePark: true, - EventSocketConns: []*FsConnConfig{ + EventSocketConns: []*FsConnCfg{ {Address: "1.2.3.4:8021", Password: "ClueCon", Reconnects: 5, Alias: "1.2.3.4:8021"}, {Address: "2.3.4.5:8021", Password: "ClueCon", Reconnects: 5, Alias: "2.3.4.5:8021"}, }, } - fsAgentCfg := new(FsAgentConfig) + fsAgentCfg := new(FsAgentCfg) if err := fsAgentCfg.loadFromJsonCfg(fsAgentJsnCfg); err != nil { t.Error(err) } else if !reflect.DeepEqual(eFsAgentConfig, fsAgentCfg) { @@ -119,11 +119,64 @@ func TestSessionSCfgloadFromJsonCfg(t *testing.T) { } if jsnCfg, err := NewCgrJsonCfgFromReader(strings.NewReader(cfgJSONStr)); err != nil { t.Error(err) - } else if jsnSchCfg, err := jsnCfg.SessionSJsonCfg(); err != nil { + } else if jsnSesCfg, err := jsnCfg.SessionSJsonCfg(); err != nil { t.Error(err) - } else if err = sescfg.loadFromJsonCfg(jsnSchCfg); err != nil { + } else if err = sescfg.loadFromJsonCfg(jsnSesCfg); err != nil { t.Error(err) } else if !reflect.DeepEqual(expected, sescfg) { - t.Errorf("Expected: %+v , recived: %+v", expected, sescfg) + t.Errorf("Expected: %+v , recived: %+v", utils.ToJSON(expected), utils.ToJSON(sescfg)) + } +} + +func TestFsAgentCfgloadFromJsonCfg2(t *testing.T) { + var fsagcfg, expected FsAgentCfg + if err := fsagcfg.loadFromJsonCfg(nil); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(fsagcfg, expected) { + t.Errorf("Expected: %+v ,recived: %+v", expected, fsagcfg) + } + if err := fsagcfg.loadFromJsonCfg(new(FreeswitchAgentJsonCfg)); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(fsagcfg, expected) { + t.Errorf("Expected: %+v ,recived: %+v", expected, fsagcfg) + } + cfgJSONStr := `{ +"freeswitch_agent": { + "enabled": false, // starts the FreeSWITCH agent: + "sessions_conns": [ + {"address": "*internal"} // connection towards session service: <*internal> + ], + "subscribe_park": true, // subscribe via fsock to receive park events + "create_cdr": false, // create CDR out of events and sends them to CDRS component + "extra_fields": [], // extra fields to store in auth/CDRs when creating them + //"min_dur_low_balance": "5s", // threshold which will trigger low balance warnings for prepaid calls (needs to be lower than debit_interval) + //"low_balance_ann_file": "", // file to be played when low balance is reached for prepaid calls + "empty_balance_context": "", // if defined, prepaid calls will be transferred to this context on empty balance + "empty_balance_ann_file": "", // file to be played before disconnecting prepaid calls on empty balance (applies only if no context defined) + "max_wait_connection": "2s", // maximum duration to wait for a connection to be retrieved from the pool + "event_socket_conns":[ // instantiate connections to multiple FreeSWITCH servers + {"address": "127.0.0.1:8021", "password": "ClueCon", "reconnects": 5,"alias":""} + ], +}, +}` + expected = FsAgentCfg{ + SessionSConns: []*HaPoolConfig{{Address: "*internal"}}, + SubscribePark: true, + MaxWaitConnection: time.Duration(2 * time.Second), + EventSocketConns: []*FsConnCfg{{ + Address: "127.0.0.1:8021", + Password: "ClueCon", + Reconnects: 5, + Alias: "127.0.0.1:8021", + }}, + } + if jsnCfg, err := NewCgrJsonCfgFromReader(strings.NewReader(cfgJSONStr)); err != nil { + t.Error(err) + } else if jsnFsAgCfg, err := jsnCfg.FreeswitchAgentJsonCfg(); err != nil { + t.Error(err) + } else if err = fsagcfg.loadFromJsonCfg(jsnFsAgCfg); err != nil { + t.Error(err) + } else if !reflect.DeepEqual(expected, fsagcfg) { + t.Errorf("Expected: %+v , recived: %+v", utils.ToJSON(expected), utils.ToJSON(fsagcfg)) } }