mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
ARIEvent with value caching, pass attributes to Stasis app
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
[internal]
|
||||
exten => _1XXX,1,NoOp()
|
||||
same => n,Stasis(cgrates_auth)
|
||||
same => n,Stasis(cgrates_auth,cgr_reqtype=*prepaid,cgr_destination=${EXTEN})
|
||||
same => n,Dial(PJSIP/${EXTEN},30)
|
||||
same => n,Hangup()
|
||||
|
||||
|
||||
@@ -17,19 +17,42 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
package sessionmanager
|
||||
|
||||
import (
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
const (
|
||||
ARIStasisStart = "StasisStart"
|
||||
)
|
||||
|
||||
type ARIEvent map[string]interface{}
|
||||
func NewARIEvent(ev map[string]interface{}) *ARIEvent {
|
||||
return &ARIEvent{ev: ev}
|
||||
}
|
||||
|
||||
func (aev ARIEvent) Type() string {
|
||||
typ, _ := aev["type"].(string)
|
||||
return typ
|
||||
type ARIEvent struct { // Standalone struct so we can cache the fields while we parse them
|
||||
ev map[string]interface{}
|
||||
evType *string
|
||||
channelID *string
|
||||
}
|
||||
|
||||
func (aev *ARIEvent) Type() string {
|
||||
if aev.evType == nil {
|
||||
typ, _ := aev.ev["type"].(string)
|
||||
aev.evType = utils.StringPointer(typ)
|
||||
}
|
||||
return *aev.evType
|
||||
}
|
||||
|
||||
func (aev ARIEvent) ChannelID() string {
|
||||
channelData, _ := aev["channel"].(map[string]interface{})
|
||||
channelID, _ := channelData["id"].(string)
|
||||
return channelID
|
||||
if aev.channelID == nil {
|
||||
channelData, _ := aev.ev["channel"].(map[string]interface{})
|
||||
channelID, _ := channelData["id"].(string)
|
||||
aev.channelID = utils.StringPointer(channelID)
|
||||
}
|
||||
return *aev.channelID
|
||||
}
|
||||
|
||||
func (aev ARIEvent) AsSMGenericSessionStart() (smgEv SMGenericEvent, err error) {
|
||||
smgEv = SMGenericEvent{utils.EVENT_NAME: utils.CGR_SESSION_START}
|
||||
return smgEv, nil
|
||||
}
|
||||
|
||||
@@ -23,23 +23,28 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
stasisStart = `{"application":"cgrates_auth","type":"StasisStart","timestamp":"2016-09-12T13:53:48.919+0200","args":[],"channel":{"id":"1473681228.6","state":"Ring","name":"PJSIP/1001-00000004","caller":{"name":"1001","number":"1001"},"language":"en","connected":{"name":"","number":""},"accountcode":"","dialplan":{"context":"internal","exten":"1002","priority":2},"creationtime":"2016-09-12T13:53:48.918+0200"}}`
|
||||
channelStateChange = `{"application":"cgrates_auth","type":"ChannelStateChange","timestamp":"2016-09-12T13:53:52.110+0200","channel":{"id":"1473681228.6","state":"Up","name":"PJSIP/1001-00000004","caller":{"name":"1001","number":"1001"},"language":"en","connected":{"name":"","number":"1002"},"accountcode":"","dialplan":{"context":"internal","exten":"1002","priority":3},"creationtime":"2016-09-12T13:53:48.918+0200"}}`
|
||||
channelDestroyed = `{"type":"ChannelDestroyed","timestamp":"2016-09-12T13:54:27.335+0200","application":"cgrates_auth","cause_txt":"Normal Clearing","channel":{"id":"1473681228.6","state":"Up","name":"PJSIP/1001-00000004","caller":{"name":"1001","number":"1001"},"language":"en","connected":{"name":"","number":"1002"},"accountcode":"","dialplan":{"context":"internal","exten":"1002","priority":3},"creationtime":"2016-09-12T13:53:48.918+0200"},"cause":16}`
|
||||
stasisStart = `{"application":"cgrates_auth","type":"StasisStart","timestamp":"2016-09-12T13:53:48.919+0200","args":[],"channel":{"id":"1473681228.6","state":"Ring","name":"PJSIP/1001-00000004","caller":{"name":"1001","number":"1001"},"language":"en","connected":{"name":"","number":""},"accountcode":"","dialplan":{"context":"internal","exten":"1002","priority":2},"creationtime":"2016-09-12T13:53:48.918+0200"}}`
|
||||
channelStateChange = `{"application":"cgrates_auth","type":"ChannelStateChange","timestamp":"2016-09-12T13:53:52.110+0200","channel":{"id":"1473681228.6","state":"Up","name":"PJSIP/1001-00000004","caller":{"name":"1001","number":"1001"},"language":"en","connected":{"name":"","number":"1002"},"accountcode":"","dialplan":{"context":"internal","exten":"1002","priority":3},"creationtime":"2016-09-12T13:53:48.918+0200"}}`
|
||||
channelAnsweredDestroyed = `{"type":"ChannelDestroyed","timestamp":"2016-09-12T13:54:27.335+0200","application":"cgrates_auth","cause_txt":"Normal Clearing","channel":{"id":"1473681228.6","state":"Up","name":"PJSIP/1001-00000004","caller":{"name":"1001","number":"1001"},"language":"en","connected":{"name":"","number":"1002"},"accountcode":"","dialplan":{"context":"internal","exten":"1002","priority":3},"creationtime":"2016-09-12T13:53:48.918+0200"},"cause":16}`
|
||||
channelUnansweredDestroyed = `{"type":"ChannelDestroyed","timestamp":"2016-09-12T18:00:18.121+0200","application":"cgrates_auth","cause_txt":"Normal Clearing","channel":{"id":"1473696018.2","state":"Ring","name":"PJSIP/1002-00000002","caller":{"name":"1002","number":"1002"},"language":"en","connected":{"name":"","number":""},"accountcode":"","dialplan":{"context":"internal","exten":"1002","priority":2},"creationtime":"2016-09-12T18:00:18.109+0200"},"cause":16}`
|
||||
)
|
||||
|
||||
func TestSMAEventType(t *testing.T) {
|
||||
var ev map[string]interface{}
|
||||
if err := json.Unmarshal([]byte(stasisStart), &ev); err != nil {
|
||||
t.Error(err)
|
||||
} else if ARIEvent(ev).Type() != "StasisStart" {
|
||||
t.Error("Received type:", ARIEvent(ev).Type())
|
||||
}
|
||||
ariEv := NewARIEvent(ev)
|
||||
if ariEv.Type() != "StasisStart" {
|
||||
t.Error("Received type:", ariEv.Type())
|
||||
}
|
||||
ev = make(map[string]interface{}) // Clear previous data
|
||||
if err := json.Unmarshal([]byte("{}"), &ev); err != nil {
|
||||
t.Error(err)
|
||||
} else if ARIEvent(ev).Type() != "" {
|
||||
t.Error("Received type:", ARIEvent(ev).Type())
|
||||
}
|
||||
ariEv = NewARIEvent(ev)
|
||||
if ariEv.Type() != "" {
|
||||
t.Error("Received type:", ariEv.Type())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,13 +52,17 @@ func TestSMAEventChannelID(t *testing.T) {
|
||||
var ev map[string]interface{}
|
||||
if err := json.Unmarshal([]byte(stasisStart), &ev); err != nil {
|
||||
t.Error(err)
|
||||
} else if ARIEvent(ev).ChannelID() != "1473681228.6" {
|
||||
t.Error("Received type:", ARIEvent(ev).ChannelID())
|
||||
}
|
||||
ariEv := NewARIEvent(ev)
|
||||
if ariEv.ChannelID() != "1473681228.6" {
|
||||
t.Error("Received type:", ariEv.ChannelID())
|
||||
}
|
||||
ev = make(map[string]interface{}) // Clear previous data
|
||||
if err := json.Unmarshal([]byte("{}"), &ev); err != nil {
|
||||
t.Error(err)
|
||||
} else if ARIEvent(ev).ChannelID() != "" {
|
||||
t.Error("Received type:", ARIEvent(ev).ChannelID())
|
||||
}
|
||||
ariEv = NewARIEvent(ev)
|
||||
if ariEv.ChannelID() != "" {
|
||||
t.Error("Received type:", ariEv.ChannelID())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,21 +66,38 @@ func (sma *SMAsterisk) ListenAndServe() (err error) {
|
||||
case err = <-sma.astErrChan:
|
||||
return err
|
||||
case astRawEv := <-sma.astEvChan:
|
||||
ariEvent := ARIEvent(astRawEv)
|
||||
if ariEvent.Type() == ARIStasisStart {
|
||||
channelID := ariEvent.ChannelID()
|
||||
if _, err := sma.astConn.Call(aringo.HTTP_POST, fmt.Sprintf("http://%s/ari/applications/%s/subscription?eventSource=channel:%s",
|
||||
sma.cgrCfg.SMAsteriskCfg().AsteriskConns[sma.astConnIdx].Address, CGRAuthAPP, channelID), nil); err != nil {
|
||||
}
|
||||
if _, err := sma.astConn.Call(aringo.HTTP_POST, fmt.Sprintf("http://%s/ari/channels/%s/continue",
|
||||
sma.cgrCfg.SMAsteriskCfg().AsteriskConns[sma.astConnIdx].Address, channelID), url.Values{"channelId": {channelID}}); err != nil {
|
||||
}
|
||||
ariEvent := NewARIEvent(astRawEv)
|
||||
switch ariEvent.Type() {
|
||||
case ARIStasisStart:
|
||||
go sma.handleStasisStart(ariEvent)
|
||||
}
|
||||
}
|
||||
}
|
||||
panic("<SMAsterisk> ListenAndServe out of select")
|
||||
}
|
||||
|
||||
func (sma *SMAsterisk) handleStasisStart(ev *ARIEvent) {
|
||||
channelID := ev.ChannelID()
|
||||
|
||||
if _, err := sma.astConn.Call(aringo.HTTP_POST, fmt.Sprintf("http://%s/ari/applications/%s/subscription?eventSource=channel:%s",
|
||||
sma.cgrCfg.SMAsteriskCfg().AsteriskConns[sma.astConnIdx].Address, CGRAuthAPP, channelID), nil); err != nil {
|
||||
|
||||
utils.Logger.Err(fmt.Sprintf("<SMAsterisk> Error: %s when subscribing to events for channelID: %s", err.Error(), channelID))
|
||||
|
||||
if _, err := sma.astConn.Call(aringo.HTTP_DELETE, fmt.Sprintf("http://%s/ari/channels/%s",
|
||||
sma.cgrCfg.SMAsteriskCfg().AsteriskConns[sma.astConnIdx].Address, channelID), url.Values{"reason": {"congestion"}}); err != nil {
|
||||
utils.Logger.Err(fmt.Sprintf("<SMAsterisk> Error: %s when attempting to disconnect channelID: %s", err.Error(), channelID))
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if _, err := sma.astConn.Call(aringo.HTTP_POST, fmt.Sprintf("http://%s/ari/channels/%s/continue",
|
||||
sma.cgrCfg.SMAsteriskCfg().AsteriskConns[sma.astConnIdx].Address, channelID), url.Values{"channelId": {channelID}}); err != nil {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Called to shutdown the service
|
||||
func (rls *SMAsterisk) ServiceShutdown() error {
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user