diff --git a/agents/astagent.go b/agents/astagent.go
index 717bcaedb..b9d6ce29e 100644
--- a/agents/astagent.go
+++ b/agents/astagent.go
@@ -272,7 +272,8 @@ func (sma *AsteriskAgent) handleChannelStateChange(ev *SMAsteriskEvent) {
fmt.Sprintf("<%s> error: %s when attempting to initiate session for channelID: %s",
utils.AsteriskAgent, err.Error(), ev.ChannelID()))
return
- } else if initSessionArgs.InitSession && (initReply.MaxUsage == nil || *initReply.MaxUsage == time.Duration(0)) {
+ }
+ if initSessionArgs.InitSession && (initReply.MaxUsage == nil || *initReply.MaxUsage == time.Duration(0)) {
sma.hangupChannel(ev.ChannelID(), "")
return
}
@@ -381,6 +382,51 @@ func (*AsteriskAgent) V1DisconnectPeer(args *utils.DPRArgs, reply *string) (err
}
// DisconnectWarning is used to implement the sessions.BiRPClient interface
-func (*AsteriskAgent) DisconnectWarning(args map[string]interface{}, reply *string) (err error) {
- return utils.ErrNotImplemented
+func (sma *AsteriskAgent) DisconnectWarning(args map[string]interface{}, reply *string) (err error) {
+ channelID := engine.NewMapEvent(args).GetStringIgnoreErrors(channelID)
+ if err = sma.playFileOnChannel(channelID, sma.cgrCfg.AsteriskAgentCfg().LowBalanceAnnFile); err != nil {
+ utils.Logger.Warning(
+ fmt.Sprintf("<%s> failed play file <%s> on channel <%s> because: %s",
+ utils.AsteriskAgent, sma.cgrCfg.AsteriskAgentCfg().LowBalanceAnnFile,
+ channelID, err.Error()))
+ return
+ }
+ *reply = utils.OK
+ return
+}
+
+// hangupChannel will disconnect from CGRateS side with congestion reason
+func (sma *AsteriskAgent) playFileOnChannel(channelID, file string) (err error) {
+ if file == utils.EmptyString {
+ return
+ }
+ _, err = sma.astConn.Call(aringo.HTTP_POST, fmt.Sprintf("http://%s/ari/channels/%s/play",
+ sma.cgrCfg.AsteriskAgentCfg().AsteriskConns[sma.astConnIdx].Address, channelID),
+ url.Values{"media": {file}})
+ return
+}
+
+// Sets the call timeout valid of starting of the call
+func (sma *AsteriskAgent) setMaxCallDuration(channelID string, connIdx int,
+ maxDur time.Duration, destNr string) (err error) {
+ if len(sma.cgrCfg.AsteriskAgentCfg().EmptyBalanceContext) != 0 {
+ if _, err = sma.astConn.Call(aringo.HTTP_POST, fmt.Sprintf("http://%s/ari/channels/%s/continue",
+ sma.cgrCfg.AsteriskAgentCfg().AsteriskConns[sma.astConnIdx].Address, channelID),
+ url.Values{"context": {sma.cgrCfg.AsteriskAgentCfg().EmptyBalanceContext}}); err != nil {
+ utils.Logger.Err(
+ fmt.Sprintf("<%s> Could not transfer the call to empty balance context, error: <%s>, channelID: %v",
+ utils.FreeSWITCHAgent, err.Error(), connIdx))
+ }
+ return
+ }
+ if len(sma.cgrCfg.AsteriskAgentCfg().EmptyBalanceAnnFile) != 0 {
+ if err = sma.playFileOnChannel(channelID, sma.cgrCfg.AsteriskAgentCfg().EmptyBalanceAnnFile); err != nil {
+ utils.Logger.Warning(
+ fmt.Sprintf("<%s> failed play file <%s> on channel <%s> because: %s",
+ utils.AsteriskAgent, sma.cgrCfg.AsteriskAgentCfg().EmptyBalanceAnnFile,
+ channelID, err.Error()))
+ }
+ return
+ }
+ return
}
diff --git a/agents/asterisk_event.go b/agents/asterisk_event.go
index 829f1c8b9..99f2cfb17 100644
--- a/agents/asterisk_event.go
+++ b/agents/asterisk_event.go
@@ -28,7 +28,12 @@ import (
)
func NewSMAsteriskEvent(ariEv map[string]interface{}, asteriskIP, asteriskAlias string) *SMAsteriskEvent {
- smsmaEv := &SMAsteriskEvent{ariEv: ariEv, asteriskIP: asteriskIP, cachedFields: make(map[string]string)}
+ smsmaEv := &SMAsteriskEvent{
+ ariEv: ariEv,
+ asteriskIP: asteriskIP,
+ cachedFields: make(map[string]string),
+ opts: make(map[string]interface{}),
+ }
smsmaEv.parseStasisArgs() // Populate appArgs
return smsmaEv
}
@@ -258,7 +263,7 @@ func (smaEv *SMAsteriskEvent) AsMapStringInterface() (mp map[string]interface{})
return
}
-// AsCDR converts AsteriskEvent into CGREvent
+// AsCGREvent converts AsteriskEvent into CGREvent
func (smaEv *SMAsteriskEvent) AsCGREvent(timezone string) (cgrEv *utils.CGREvent, err error) {
setupTime, err := utils.ParseTimeDetectLayout(
smaEv.Timestamp(), timezone)
diff --git a/cmd/cgr-loader/cgr-loader.go b/cmd/cgr-loader/cgr-loader.go
index 273680133..1dffe3028 100755
--- a/cmd/cgr-loader/cgr-loader.go
+++ b/cmd/cgr-loader/cgr-loader.go
@@ -113,7 +113,7 @@ func loadConfig() (ldrCfg *config.CGRConfig) {
}
// Data for DataDB
if *dataDBType != dfltCfg.DataDbCfg().DataDbType {
- ldrCfg.DataDbCfg().DataDbType = strings.TrimPrefix(*dataDBType, "*")
+ ldrCfg.DataDbCfg().DataDbType = strings.TrimPrefix(*dataDBType, utils.Meta)
}
if *dataDBHost != dfltCfg.DataDbCfg().DataDbHost {
@@ -146,7 +146,7 @@ func loadConfig() (ldrCfg *config.CGRConfig) {
// Data for StorDB
if *storDBType != dfltCfg.StorDbCfg().Type {
- ldrCfg.StorDbCfg().Type = strings.TrimPrefix(*storDBType, "*")
+ ldrCfg.StorDbCfg().Type = strings.TrimPrefix(*storDBType, utils.Meta)
}
if *storDBHost != dfltCfg.StorDbCfg().Host {
@@ -169,7 +169,7 @@ func loadConfig() (ldrCfg *config.CGRConfig) {
ldrCfg.StorDbCfg().Password = *storDBPasswd
}
- if *tpid != dfltCfg.LoaderCgrCfg().DataPath {
+ if *tpid != dfltCfg.LoaderCgrCfg().TpID {
ldrCfg.LoaderCgrCfg().TpID = *tpid
}
@@ -342,13 +342,13 @@ func main() {
if err = tpReader.RemoveFromDatabase(*verbose, *disableReverse); err != nil {
log.Fatal("Could not delete from database: ", err)
}
- return
+ } else {
+ // write maps to database
+ if err = tpReader.WriteToDatabase(*verbose, *disableReverse); err != nil {
+ log.Fatal("Could not write to database: ", err)
+ }
}
- // write maps to database
- if err = tpReader.WriteToDatabase(*verbose, *disableReverse); err != nil {
- log.Fatal("Could not write to database: ", err)
- }
// reload cache
if err = tpReader.ReloadCache(ldrCfg.GeneralCfg().DefaultCaching, *verbose, map[string]interface{}{
utils.OptsAPIKey: *apiKey,
@@ -356,6 +356,7 @@ func main() {
}); err != nil {
log.Fatal("Could not reload cache: ", err)
}
+
if len(ldrCfg.LoaderCgrCfg().SchedulerConns) != 0 {
if err = tpReader.ReloadScheduler(*verbose); err != nil {
log.Fatal("Could not reload scheduler: ", err)
diff --git a/cmd/cgr-loader/cgr-loader_it_test.go b/cmd/cgr-loader/cgr-loader_it_test.go
new file mode 100644
index 000000000..cb0259ee1
--- /dev/null
+++ b/cmd/cgr-loader/cgr-loader_it_test.go
@@ -0,0 +1,313 @@
+// +build integration
+
+/*
+Real-time Online/Offline Charging System (OerS) 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 main
+
+import (
+ "bytes"
+ "flag"
+ "os/exec"
+ "path"
+ "reflect"
+ "testing"
+ "time"
+
+ "github.com/cgrates/cgrates/config"
+ "github.com/cgrates/cgrates/engine"
+ "github.com/cgrates/cgrates/utils"
+ "github.com/cgrates/rpcclient"
+)
+
+var (
+ dataDir = flag.String("data_dir", "/usr/share/cgrates", "CGR data dir path here")
+)
+
+func TestLoadConfig(t *testing.T) {
+ // DataDb
+ *cfgPath = path.Join(*dataDir, "conf", "samples", "tutmongo")
+ *dataDBType = utils.Meta + utils.REDIS
+ *dataDBHost = "localhost"
+ *dataDBPort = "2012"
+ *dataDBName = "100"
+ *dataDBUser = "cgrates2"
+ *dataDBPasswd = "toor"
+ *dbRedisSentinel = "sentinel1"
+ expDBcfg := &config.DataDbCfg{
+ DataDbType: utils.REDIS,
+ DataDbHost: "localhost",
+ DataDbPort: "2012",
+ DataDbName: "100",
+ DataDbUser: "cgrates2",
+ DataDbPass: "toor",
+ DataDbSentinelName: "sentinel1",
+ QueryTimeout: 10 * time.Second,
+ ClusterSync: 5 * time.Second,
+ RmtConns: []string{},
+ RplConns: []string{},
+ }
+ // StorDB
+ *storDBType = utils.MetaPostgres
+ *storDBHost = "localhost"
+ *storDBPort = "2012"
+ *storDBName = "cgrates2"
+ *storDBUser = "10"
+ *storDBPasswd = "toor"
+ expStorDB := &config.StorDbCfg{
+ Type: utils.POSTGRES,
+ Host: "localhost",
+ Port: "2012",
+ Name: "cgrates2",
+ User: "10",
+ Password: "toor",
+ MaxOpenConns: 100,
+ MaxIdleConns: 10,
+ SSLMode: "disable",
+ StringIndexedFields: []string{},
+ PrefixIndexedFields: []string{},
+ QueryTimeout: 10 * time.Second,
+ }
+ // Loader
+ *tpid = "1"
+ *disableReverse = true
+ *dataPath = "./path"
+ *fieldSep = "$"
+ *cacheSAddress = ""
+ *schedulerAddress = ""
+ // General
+ *cachingArg = utils.MetaLoad
+ *dbDataEncoding = utils.MetaJSON
+ ldrCfg := loadConfig()
+ ldrCfg.DataDbCfg().Items = nil
+ ldrCfg.StorDbCfg().Items = nil
+ if !reflect.DeepEqual(ldrCfg.DataDbCfg(), expDBcfg) {
+ t.Errorf("Expected %s received %s", utils.ToJSON(expDBcfg), utils.ToJSON(ldrCfg.DataDbCfg()))
+ }
+ if ldrCfg.GeneralCfg().DBDataEncoding != utils.MetaJSON {
+ t.Errorf("Expected %s received %s", utils.MetaJSON, ldrCfg.GeneralCfg().DBDataEncoding)
+ }
+ if !reflect.DeepEqual(ldrCfg.StorDbCfg(), expStorDB) {
+ t.Errorf("Expected %s received %s", utils.ToJSON(expStorDB), utils.ToJSON(ldrCfg.StorDbCfg()))
+ }
+ if !ldrCfg.LoaderCgrCfg().DisableReverse {
+ t.Errorf("Expected %v received %v", true, ldrCfg.LoaderCgrCfg().DisableReverse)
+ }
+ if ldrCfg.GeneralCfg().DefaultCaching != utils.MetaLoad {
+ t.Errorf("Expected %s received %s", utils.MetaLoad, ldrCfg.GeneralCfg().DefaultCaching)
+ }
+ if *importID == utils.EmptyString {
+ t.Errorf("Expected importID to be populated")
+ }
+ if ldrCfg.LoaderCgrCfg().TpID != "1" {
+ t.Errorf("Expected %s received %s", "1", ldrCfg.LoaderCgrCfg().TpID)
+ }
+ if ldrCfg.LoaderCgrCfg().DataPath != "./path" {
+ t.Errorf("Expected %s received %s", "./path", ldrCfg.LoaderCgrCfg().DataPath)
+ }
+ if ldrCfg.LoaderCgrCfg().FieldSeparator != '$' {
+ t.Errorf("Expected %v received %v", '$', ldrCfg.LoaderCgrCfg().FieldSeparator)
+ }
+ if !reflect.DeepEqual(ldrCfg.LoaderCgrCfg().CachesConns, []string{}) {
+ t.Errorf("Expected %v received %v", []string{}, ldrCfg.LoaderCgrCfg().CachesConns)
+ }
+ if !reflect.DeepEqual(ldrCfg.LoaderCgrCfg().SchedulerConns, []string{}) {
+ t.Errorf("Expected %v received %v", []string{}, ldrCfg.LoaderCgrCfg().SchedulerConns)
+ }
+ *cacheSAddress = "127.0.0.1"
+ *schedulerAddress = "127.0.0.2"
+ *rpcEncoding = utils.MetaJSON
+ ldrCfg = loadConfig()
+ expAddrs := []string{"127.0.0.1"}
+ if !reflect.DeepEqual(ldrCfg.LoaderCgrCfg().CachesConns, expAddrs) {
+ t.Errorf("Expected %v received %v", expAddrs, ldrCfg.LoaderCgrCfg().CachesConns)
+ }
+ expAddrs = []string{"127.0.0.2"}
+ if !reflect.DeepEqual(ldrCfg.LoaderCgrCfg().SchedulerConns, expAddrs) {
+ t.Errorf("Expected %v received %v", expAddrs, ldrCfg.LoaderCgrCfg().SchedulerConns)
+ }
+ expaddr := map[string]*config.RPCConn{
+ utils.MetaInternal: {
+ Strategy: rpcclient.PoolFirst,
+ PoolSize: 0,
+ Conns: []*config.RemoteHost{{
+ Address: utils.MetaInternal,
+ }},
+ },
+ "*localhost": {
+ Strategy: rpcclient.PoolFirst,
+ Conns: []*config.RemoteHost{{Address: "127.0.0.1:2012", Transport: utils.MetaJSON}},
+ },
+ "127.0.0.1": {
+ Strategy: rpcclient.PoolFirst,
+ Conns: []*config.RemoteHost{{Address: "127.0.0.1", Transport: utils.MetaJSON}},
+ },
+ "127.0.0.2": {
+ Strategy: rpcclient.PoolFirst,
+ Conns: []*config.RemoteHost{{Address: "127.0.0.2", Transport: utils.MetaJSON}},
+ },
+ }
+ if !reflect.DeepEqual(ldrCfg.RPCConns(), expaddr) {
+ t.Errorf("Expected %v received %v", utils.ToJSON(expaddr), utils.ToJSON(ldrCfg.RPCConns()))
+ }
+}
+
+var (
+ ldrItCfgPath string
+ ldrItCfg *config.CGRConfig
+ db engine.DataDB
+
+ ldrItTests = []func(t *testing.T){
+ testLoadItLoadConfig,
+ testLoadItResetDataDB,
+ testLoadItResetStorDb,
+ testLoadItStartLoader,
+ testLoadItConnectToDB,
+ testLoadItCheckAttributes,
+ testLoadItStartLoaderRemove,
+ testLoadItCheckAttributes2,
+ testLoadItStartLoaderToStorDB,
+ testLoadItCheckAttributes2,
+ testLoadItStartLoaderFromStorDB,
+ testLoadItCheckAttributes,
+ }
+)
+
+func TestLoadIt(t *testing.T) {
+ for _, stest := range ldrItTests {
+ t.Run("TestLoadIt", stest)
+ }
+}
+
+func testLoadItLoadConfig(t *testing.T) {
+ var err error
+ ldrItCfgPath = path.Join(*dataDir, "conf", "samples", "tutmongo")
+ if ldrItCfg, err = config.NewCGRConfigFromPath(ldrItCfgPath); err != nil {
+ t.Error(err)
+ }
+}
+
+func testLoadItResetDataDB(t *testing.T) {
+ if err := engine.InitDataDb(ldrItCfg); err != nil {
+ t.Fatal(err)
+ }
+}
+
+func testLoadItResetStorDb(t *testing.T) {
+ if err := engine.InitStorDb(ldrItCfg); err != nil {
+ t.Fatal(err)
+ }
+}
+
+func testLoadItStartLoader(t *testing.T) {
+ cmd := exec.Command("cgr-loader", "-config_path="+ldrItCfgPath, "-path="+path.Join(*dataDir, "tariffplans", "tutorial"), "-caches_address=", "-scheduler_address=")
+ output := bytes.NewBuffer(nil)
+ outerr := bytes.NewBuffer(nil)
+ cmd.Stdout = output
+ cmd.Stderr = outerr
+ if err := cmd.Run(); err != nil {
+ t.Log(cmd.Args)
+ t.Log(output.String())
+ t.Log(outerr.String())
+ t.Fatal(err)
+ }
+}
+
+func testLoadItConnectToDB(t *testing.T) {
+ var err error
+ if db, err = engine.NewDataDBConn(ldrItCfg.DataDbCfg().DataDbType,
+ ldrItCfg.DataDbCfg().DataDbHost, ldrItCfg.DataDbCfg().DataDbPort,
+ ldrItCfg.DataDbCfg().DataDbName, ldrItCfg.DataDbCfg().DataDbUser,
+ ldrItCfg.DataDbCfg().DataDbPass, ldrItCfg.GeneralCfg().DBDataEncoding,
+ ldrItCfg.DataDbCfg().DataDbSentinelName, ldrItCfg.DataDbCfg().RedisCluster,
+ ldrItCfg.DataDbCfg().ClusterSync, ldrItCfg.DataDbCfg().ClusterOnDownDelay,
+ ldrItCfg.DataDbCfg().Items); err != nil {
+ t.Fatal(err)
+ }
+}
+
+func testLoadItCheckAttributes(t *testing.T) {
+ eAttrPrf := &engine.AttributeProfile{
+ Tenant: "cgrates.org",
+ ID: "ATTR_1001_SIMPLEAUTH",
+ FilterIDs: []string{"*string:~*req.Account:1001"},
+ Contexts: []string{"simpleauth"},
+ Attributes: []*engine.Attribute{
+ {
+ FilterIDs: []string{},
+ Path: utils.MetaReq + utils.NestingSep + "Password",
+ Type: utils.META_CONSTANT,
+ Value: config.NewRSRParsersMustCompile("CGRateS.org", utils.INFIELD_SEP),
+ },
+ },
+ Weight: 20.0,
+ }
+ if attr, err := db.GetAttributeProfileDrv("cgrates.org", "ATTR_1001_SIMPLEAUTH"); err != nil {
+ t.Fatal(err)
+ } else if attr.Compile(); !reflect.DeepEqual(eAttrPrf, attr) {
+ t.Errorf("Expecting: %+v, received: %+v", utils.ToJSON(eAttrPrf), utils.ToJSON(attr))
+ }
+}
+
+func testLoadItStartLoaderRemove(t *testing.T) {
+ cmd := exec.Command("cgr-loader", "-config_path="+ldrItCfgPath, "-path="+path.Join(*dataDir, "tariffplans", "tutorial"), "-caches_address=", "-scheduler_address=", "-remove")
+ output := bytes.NewBuffer(nil)
+ outerr := bytes.NewBuffer(nil)
+ cmd.Stdout = output
+ cmd.Stderr = outerr
+ if err := cmd.Run(); err != nil {
+ t.Log(cmd.Args)
+ t.Log(output.String())
+ t.Log(outerr.String())
+ t.Fatal(err)
+ }
+}
+
+func testLoadItCheckAttributes2(t *testing.T) {
+ if _, err := db.GetAttributeProfileDrv("cgrates.org", "ATTR_1001_SIMPLEAUTH"); err != utils.ErrNotFound {
+ t.Fatal(err)
+ }
+}
+
+func testLoadItStartLoaderToStorDB(t *testing.T) {
+ cmd := exec.Command("cgr-loader", "-config_path="+ldrItCfgPath, "-path="+path.Join(*dataDir, "tariffplans", "tutorial"), "-caches_address=", "-scheduler_address=", "-to_stordb", "-tpid=TPID")
+ output := bytes.NewBuffer(nil)
+ outerr := bytes.NewBuffer(nil)
+ cmd.Stdout = output
+ cmd.Stderr = outerr
+ if err := cmd.Run(); err != nil {
+ t.Log(cmd.Args)
+ t.Log(output.String())
+ t.Log(outerr.String())
+ t.Fatal(err)
+ }
+}
+
+func testLoadItStartLoaderFromStorDB(t *testing.T) {
+ cmd := exec.Command("cgr-loader", "-config_path="+ldrItCfgPath, "-path="+path.Join(*dataDir, "tariffplans", "tutorial"), "-caches_address=", "-scheduler_address=", "-from_stordb", "-tpid=TPID")
+ output := bytes.NewBuffer(nil)
+ outerr := bytes.NewBuffer(nil)
+ cmd.Stdout = output
+ cmd.Stderr = outerr
+ if err := cmd.Run(); err != nil {
+ t.Log(cmd.Args)
+ t.Log(output.String())
+ t.Log(outerr.String())
+ t.Fatal(err)
+ }
+}
diff --git a/config/config_defaults.go b/config/config_defaults.go
index e5aafefe7..021bb3f9e 100755
--- a/config/config_defaults.go
+++ b/config/config_defaults.go
@@ -329,8 +329,8 @@ const CGRATES_CFG_JSON = `
"header_define_character": ":", // the starting character for header definition used in case of CSV files
"run_delay": "0", // sleep interval in seconds between consecutive runs, -1 to use automation via inotify or 0 to disable running all together
"concurrent_requests": 1024, // maximum simultaneous requests/files to process, 0 for unlimited
- "source_path": "/var/spool/cgrates/ers/in", // read data from this path
- "processed_path": "/var/spool/cgrates/ers/out", // move processed data here
+ "source_path": "/var/spool/cgrates/ers/in", // read data from this path
+ "processed_path": "/var/spool/cgrates/ers/out", // move processed data here
"xml_root_path": "", // path towards one event in case of XML CDRs
"tenant": "", // tenant used by import
"timezone": "", // timezone for timestamps where not specified <""|UTC|Local|$IANA_TZ_DB>
@@ -439,6 +439,9 @@ const CGRATES_CFG_JSON = `
"enabled": false, // starts the Asterisk agent:
"sessions_conns": ["*internal"],
"create_cdr": false, // create CDR out of events and sends it to CDRS component
+ "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)
"asterisk_conns":[ // instantiate connections to multiple Asterisk servers
{"address": "127.0.0.1:8088", "user": "cgrates", "password": "CGRateS.org", "connect_attempts": 3,"reconnects": 5}
],
diff --git a/config/config_json_test.go b/config/config_json_test.go
index 4812c7b40..830e9940d 100755
--- a/config/config_json_test.go
+++ b/config/config_json_test.go
@@ -716,9 +716,12 @@ func TestKamAgentJsonCfg(t *testing.T) {
func TestAsteriskAgentJsonCfg(t *testing.T) {
eCfg := &AsteriskAgentJsonCfg{
- Enabled: utils.BoolPointer(false),
- Sessions_conns: &[]string{utils.MetaInternal},
- Create_cdr: utils.BoolPointer(false),
+ Enabled: utils.BoolPointer(false),
+ Sessions_conns: &[]string{utils.MetaInternal},
+ Create_cdr: utils.BoolPointer(false),
+ Empty_balance_ann_file: utils.StringPointer(""),
+ Empty_balance_context: utils.StringPointer(""),
+ Low_balance_ann_file: utils.StringPointer(""),
Asterisk_conns: &[]*AstConnJsonCfg{
{
Address: utils.StringPointer("127.0.0.1:8088"),
diff --git a/config/libconfig_json.go b/config/libconfig_json.go
index ac3ed19ef..3bb1d3887 100755
--- a/config/libconfig_json.go
+++ b/config/libconfig_json.go
@@ -291,10 +291,13 @@ type AstConnJsonCfg struct {
}
type AsteriskAgentJsonCfg struct {
- Enabled *bool
- Sessions_conns *[]string
- Create_cdr *bool
- Asterisk_conns *[]*AstConnJsonCfg
+ Enabled *bool
+ Sessions_conns *[]string
+ Create_cdr *bool
+ Low_balance_ann_file *string
+ Empty_balance_context *string
+ Empty_balance_ann_file *string
+ Asterisk_conns *[]*AstConnJsonCfg
}
type CacheParamJsonCfg struct {
diff --git a/config/sessionscfg.go b/config/sessionscfg.go
index ecfe04834..d35f93bc7 100644
--- a/config/sessionscfg.go
+++ b/config/sessionscfg.go
@@ -631,10 +631,13 @@ func (aConnCfg *AsteriskConnCfg) AsMapInterface() map[string]interface{} {
}
type AsteriskAgentCfg struct {
- Enabled bool
- SessionSConns []string
- CreateCDR bool
- AsteriskConns []*AsteriskConnCfg
+ Enabled bool
+ SessionSConns []string
+ CreateCDR bool
+ LowBalanceAnnFile string
+ EmptyBalanceContext string
+ EmptyBalanceAnnFile string
+ AsteriskConns []*AsteriskConnCfg
}
func (aCfg *AsteriskAgentCfg) loadFromJsonCfg(jsnCfg *AsteriskAgentJsonCfg) (err error) {
@@ -658,6 +661,17 @@ func (aCfg *AsteriskAgentCfg) loadFromJsonCfg(jsnCfg *AsteriskAgentJsonCfg) (err
if jsnCfg.Create_cdr != nil {
aCfg.CreateCDR = *jsnCfg.Create_cdr
}
+ if jsnCfg.Low_balance_ann_file != nil {
+ aCfg.LowBalanceAnnFile = *jsnCfg.Low_balance_ann_file
+ }
+ if jsnCfg.Empty_balance_context != nil {
+ aCfg.EmptyBalanceContext = *jsnCfg.Empty_balance_context
+ }
+
+ if jsnCfg.Empty_balance_ann_file != nil {
+ aCfg.EmptyBalanceAnnFile = *jsnCfg.Empty_balance_ann_file
+ }
+
if jsnCfg.Asterisk_conns != nil {
aCfg.AsteriskConns = make([]*AsteriskConnCfg, len(*jsnCfg.Asterisk_conns))
for i, jsnAConn := range *jsnCfg.Asterisk_conns {