mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
Renaming sessionmanager package into sessions
This commit is contained in:
@@ -21,7 +21,7 @@ package agents
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/cgrates/cgrates/sessionmanager"
|
||||
"github.com/cgrates/cgrates/sessions"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
@@ -174,7 +174,7 @@ func (smaEv *SMAsteriskEvent) ExtraParameters() (extraParams map[string]string)
|
||||
return
|
||||
}
|
||||
|
||||
func (smaEv *SMAsteriskEvent) AsSMGenericEvent() *sessionmanager.SMGenericEvent {
|
||||
func (smaEv *SMAsteriskEvent) AsSMGenericEvent() *sessions.SMGenericEvent {
|
||||
var evName string
|
||||
switch smaEv.EventType() {
|
||||
case ARIStasisStart:
|
||||
@@ -184,7 +184,7 @@ func (smaEv *SMAsteriskEvent) AsSMGenericEvent() *sessionmanager.SMGenericEvent
|
||||
case ARIChannelDestroyed:
|
||||
evName = SMASessionTerminate
|
||||
}
|
||||
smgEv := sessionmanager.SMGenericEvent{utils.EVENT_NAME: evName}
|
||||
smgEv := sessions.SMGenericEvent{utils.EVENT_NAME: evName}
|
||||
smgEv[utils.OriginID] = smaEv.ChannelID()
|
||||
if smaEv.RequestType() != "" {
|
||||
smgEv[utils.RequestType] = smaEv.RequestType()
|
||||
@@ -213,7 +213,7 @@ func (smaEv *SMAsteriskEvent) AsSMGenericEvent() *sessionmanager.SMGenericEvent
|
||||
|
||||
// Updates fields in smgEv based on own fields
|
||||
// Using pointer so we update it directly in cache
|
||||
func (smaEv *SMAsteriskEvent) UpdateSMGEvent(smgEv *sessionmanager.SMGenericEvent) error {
|
||||
func (smaEv *SMAsteriskEvent) UpdateSMGEvent(smgEv *sessions.SMGenericEvent) error {
|
||||
resSMGEv := *smgEv
|
||||
switch smaEv.EventType() {
|
||||
case ARIChannelStateChange:
|
||||
|
||||
@@ -22,7 +22,7 @@ import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/cgrates/cgrates/sessionmanager"
|
||||
"github.com/cgrates/cgrates/sessions"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
@@ -383,7 +383,7 @@ func TestSMAEventAsSMGenericEvent(t *testing.T) {
|
||||
if err := json.Unmarshal([]byte(stasisStart), &ev); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
eSMGEv := &sessionmanager.SMGenericEvent{
|
||||
eSMGEv := &sessions.SMGenericEvent{
|
||||
utils.EVENT_NAME: SMAAuthorization,
|
||||
utils.OriginID: "1473681228.6",
|
||||
utils.RequestType: "*prepaid",
|
||||
@@ -407,7 +407,7 @@ func TestSMAEventUpdateSMGEventAnswered(t *testing.T) {
|
||||
t.Error(err)
|
||||
}
|
||||
smaEv := NewSMAsteriskEvent(ev, "127.0.0.1")
|
||||
smgEv := &sessionmanager.SMGenericEvent{
|
||||
smgEv := &sessions.SMGenericEvent{
|
||||
utils.EVENT_NAME: SMAAuthorization,
|
||||
utils.OriginID: "1473681228.6",
|
||||
utils.RequestType: "*prepaid",
|
||||
@@ -418,7 +418,7 @@ func TestSMAEventUpdateSMGEventAnswered(t *testing.T) {
|
||||
"extra1": "val1",
|
||||
"extra2": "val2",
|
||||
}
|
||||
eSMGEv := &sessionmanager.SMGenericEvent{
|
||||
eSMGEv := &sessions.SMGenericEvent{
|
||||
utils.EVENT_NAME: SMASessionStart,
|
||||
utils.OriginID: "1473681228.6",
|
||||
utils.RequestType: "*prepaid",
|
||||
@@ -441,7 +441,7 @@ func TestSMAEventUpdateSMGEventAnswered(t *testing.T) {
|
||||
t.Error(err)
|
||||
}
|
||||
smaEv = NewSMAsteriskEvent(ev, "127.0.0.1")
|
||||
eSMGEv = &sessionmanager.SMGenericEvent{
|
||||
eSMGEv = &sessions.SMGenericEvent{
|
||||
utils.EVENT_NAME: SMASessionTerminate,
|
||||
utils.OriginID: "1473681228.6",
|
||||
utils.RequestType: "*prepaid",
|
||||
@@ -463,7 +463,7 @@ func TestSMAEventUpdateSMGEventAnswered(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestSMAEventUpdateSMGEventUnaswered(t *testing.T) {
|
||||
smgEv := &sessionmanager.SMGenericEvent{
|
||||
smgEv := &sessions.SMGenericEvent{
|
||||
utils.EVENT_NAME: SMAAuthorization,
|
||||
utils.OriginID: "1473681228.6",
|
||||
utils.RequestType: "*prepaid",
|
||||
@@ -474,7 +474,7 @@ func TestSMAEventUpdateSMGEventUnaswered(t *testing.T) {
|
||||
"extra1": "val1",
|
||||
"extra2": "val2",
|
||||
}
|
||||
eSMGEv := &sessionmanager.SMGenericEvent{
|
||||
eSMGEv := &sessions.SMGenericEvent{
|
||||
utils.EVENT_NAME: SMASessionTerminate,
|
||||
utils.OriginID: "1473681228.6",
|
||||
utils.RequestType: "*prepaid",
|
||||
@@ -501,7 +501,7 @@ func TestSMAEventUpdateSMGEventUnaswered(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestSMAEventUpdateSMGEventBusy(t *testing.T) {
|
||||
smgEv := &sessionmanager.SMGenericEvent{
|
||||
smgEv := &sessions.SMGenericEvent{
|
||||
utils.EVENT_NAME: SMAAuthorization,
|
||||
utils.OriginID: "1473681228.6",
|
||||
utils.RequestType: "*prepaid",
|
||||
@@ -512,7 +512,7 @@ func TestSMAEventUpdateSMGEventBusy(t *testing.T) {
|
||||
"extra1": "val1",
|
||||
"extra2": "val2",
|
||||
}
|
||||
eSMGEv := &sessionmanager.SMGenericEvent{
|
||||
eSMGEv := &sessions.SMGenericEvent{
|
||||
utils.EVENT_NAME: SMASessionTerminate,
|
||||
utils.OriginID: "1473681228.6",
|
||||
utils.RequestType: "*prepaid",
|
||||
|
||||
@@ -29,7 +29,7 @@ import (
|
||||
|
||||
"github.com/cgrates/aringo"
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/sessionmanager"
|
||||
"github.com/cgrates/cgrates/sessions"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
"github.com/cgrates/rpcclient"
|
||||
)
|
||||
@@ -52,7 +52,7 @@ const (
|
||||
|
||||
func NewSMAsterisk(cgrCfg *config.CGRConfig, astConnIdx int, smgConn *utils.BiRPCInternalClient) (*SMAsterisk, error) {
|
||||
sma := &SMAsterisk{cgrCfg: cgrCfg, smg: smgConn,
|
||||
eventsCache: make(map[string]*sessionmanager.SMGenericEvent)}
|
||||
eventsCache: make(map[string]*sessions.SMGenericEvent)}
|
||||
sma.smg.SetClientConn(sma) // pass the connection to SMA back into smg so we can receive the disconnects
|
||||
return sma, nil
|
||||
}
|
||||
@@ -64,8 +64,8 @@ type SMAsterisk struct {
|
||||
astConn *aringo.ARInGO
|
||||
astEvChan chan map[string]interface{}
|
||||
astErrChan chan error
|
||||
eventsCache map[string]*sessionmanager.SMGenericEvent // used to gather information about events during various phases
|
||||
evCacheMux sync.RWMutex // Protect eventsCache
|
||||
eventsCache map[string]*sessions.SMGenericEvent // used to gather information about events during various phases
|
||||
evCacheMux sync.RWMutex // Protect eventsCache
|
||||
}
|
||||
|
||||
func (sma *SMAsterisk) connectAsterisk() (err error) {
|
||||
@@ -245,7 +245,7 @@ func (sma *SMAsterisk) ServiceShutdown() error {
|
||||
|
||||
// Internal method to disconnect session in asterisk
|
||||
func (sma *SMAsterisk) V1DisconnectSession(args utils.AttrDisconnectSession, reply *string) error {
|
||||
channelID := sessionmanager.SMGenericEvent(args.EventStart).GetOriginID(utils.META_DEFAULT)
|
||||
channelID := sessions.SMGenericEvent(args.EventStart).GetOriginID(utils.META_DEFAULT)
|
||||
if err := sma.hangupChannel(channelID); err != nil {
|
||||
utils.Logger.Err(
|
||||
fmt.Sprintf("<SMAsterisk> Error: %s when attempting to disconnect channelID: %s",
|
||||
|
||||
@@ -24,14 +24,14 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/sessionmanager"
|
||||
"github.com/cgrates/cgrates/sessions"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
"github.com/cgrates/fsock"
|
||||
)
|
||||
|
||||
func NewFSSessionManager(fsAgentConfig *config.FsAgentConfig,
|
||||
smg *utils.BiRPCInternalClient, timezone string) (fsa *FSSessionManager) {
|
||||
fsa = &FSSessionManager{
|
||||
func NewFSsessions(fsAgentConfig *config.FsAgentConfig,
|
||||
smg *utils.BiRPCInternalClient, timezone string) (fsa *FSsessions) {
|
||||
fsa = &FSsessions{
|
||||
cfg: fsAgentConfig,
|
||||
conns: make(map[string]*fsock.FSock),
|
||||
senderPools: make(map[string]*fsock.FSockPool),
|
||||
@@ -44,7 +44,7 @@ func NewFSSessionManager(fsAgentConfig *config.FsAgentConfig,
|
||||
|
||||
// The freeswitch session manager type holding a buffer for the network connection
|
||||
// and the active sessions
|
||||
type FSSessionManager struct {
|
||||
type FSsessions struct {
|
||||
cfg *config.FsAgentConfig
|
||||
conns map[string]*fsock.FSock // Keep the list here for connection management purposes
|
||||
senderPools map[string]*fsock.FSockPool // Keep sender pools here
|
||||
@@ -52,7 +52,7 @@ type FSSessionManager struct {
|
||||
timezone string
|
||||
}
|
||||
|
||||
func (sm *FSSessionManager) createHandlers() map[string][]func(string, string) {
|
||||
func (sm *FSsessions) createHandlers() map[string][]func(string, string) {
|
||||
ca := func(body, connId string) {
|
||||
sm.onChannelAnswer(
|
||||
NewFSEvent(body), connId)
|
||||
@@ -76,7 +76,7 @@ func (sm *FSSessionManager) createHandlers() map[string][]func(string, string) {
|
||||
}
|
||||
|
||||
// Sets the call timeout valid of starting of the call
|
||||
func (sm *FSSessionManager) setMaxCallDuration(uuid, connId string,
|
||||
func (sm *FSsessions) setMaxCallDuration(uuid, connId string,
|
||||
maxDur time.Duration, destNr string) error {
|
||||
if len(sm.cfg.EmptyBalanceContext) != 0 {
|
||||
_, err := sm.conns[connId].SendApiCmd(
|
||||
@@ -115,7 +115,7 @@ func (sm *FSSessionManager) setMaxCallDuration(uuid, connId string,
|
||||
}
|
||||
|
||||
// Sends the transfer command to unpark the call to freeswitch
|
||||
func (sm *FSSessionManager) unparkCall(uuid, connId, call_dest_nb, notify string) (err error) {
|
||||
func (sm *FSsessions) unparkCall(uuid, connId, call_dest_nb, notify string) (err error) {
|
||||
_, err = sm.conns[connId].SendApiCmd(
|
||||
fmt.Sprintf("uuid_setvar %s cgr_notify %s\n\n", uuid, notify))
|
||||
if err != nil {
|
||||
@@ -133,12 +133,12 @@ func (sm *FSSessionManager) unparkCall(uuid, connId, call_dest_nb, notify string
|
||||
return
|
||||
}
|
||||
|
||||
func (sm *FSSessionManager) onChannelPark(fsev FSEvent, connId string) {
|
||||
func (sm *FSsessions) onChannelPark(fsev FSEvent, connId string) {
|
||||
if fsev.GetReqType(utils.META_DEFAULT) == utils.META_NONE { // Not for us
|
||||
return
|
||||
}
|
||||
authArgs := fsev.V1AuthorizeArgs()
|
||||
var authReply sessionmanager.V1AuthorizeReply
|
||||
var authReply sessions.V1AuthorizeReply
|
||||
if err := sm.smg.Call(utils.SessionSv1AuthorizeEvent, authArgs, &authReply); err != nil {
|
||||
utils.Logger.Err(
|
||||
fmt.Sprintf("<%s> Could not authorize event %s, error: %s",
|
||||
@@ -198,7 +198,7 @@ func (sm *FSSessionManager) onChannelPark(fsev FSEvent, connId string) {
|
||||
fsev.GetCallDestNr(utils.META_DEFAULT), AUTH_OK)
|
||||
}
|
||||
|
||||
func (sm *FSSessionManager) onChannelAnswer(fsev FSEvent, connId string) {
|
||||
func (sm *FSsessions) onChannelAnswer(fsev FSEvent, connId string) {
|
||||
if fsev.GetReqType(utils.META_DEFAULT) == utils.META_NONE { // Do not process this request
|
||||
return
|
||||
}
|
||||
@@ -210,7 +210,7 @@ func (sm *FSSessionManager) onChannelAnswer(fsev FSEvent, connId string) {
|
||||
}
|
||||
initSessionArgs := fsev.V1InitSessionArgs()
|
||||
initSessionArgs.CGREvent.Event[FsConnID] = connId // Attach the connection ID so we can properly disconnect later
|
||||
var initReply sessionmanager.V1InitSessionReply
|
||||
var initReply sessions.V1InitSessionReply
|
||||
if err := sm.smg.Call(utils.SessionSv1InitiateSession,
|
||||
initSessionArgs, &initReply); err != nil {
|
||||
utils.Logger.Err(
|
||||
@@ -221,7 +221,7 @@ func (sm *FSSessionManager) onChannelAnswer(fsev FSEvent, connId string) {
|
||||
}
|
||||
}
|
||||
|
||||
func (sm *FSSessionManager) onChannelHangupComplete(fsev FSEvent, connId string) {
|
||||
func (sm *FSsessions) onChannelHangupComplete(fsev FSEvent, connId string) {
|
||||
if fsev.GetReqType(utils.META_DEFAULT) == utils.META_NONE { // Do not process this request
|
||||
return
|
||||
}
|
||||
@@ -245,7 +245,7 @@ func (sm *FSSessionManager) onChannelHangupComplete(fsev FSEvent, connId string)
|
||||
|
||||
// Connects to the freeswitch mod_event_socket server and starts
|
||||
// listening for events.
|
||||
func (sm *FSSessionManager) Connect() error {
|
||||
func (sm *FSsessions) Connect() error {
|
||||
eventFilters := map[string][]string{"Call-Direction": []string{"inbound"}}
|
||||
errChan := make(chan error)
|
||||
for _, connCfg := range sm.cfg.EventSocketConns {
|
||||
@@ -280,7 +280,7 @@ func (sm *FSSessionManager) Connect() error {
|
||||
|
||||
// fsev.GetCallDestNr(utils.META_DEFAULT)
|
||||
// Disconnects a session by sending hangup command to freeswitch
|
||||
func (sm *FSSessionManager) disconnectSession(connId, uuid, redirectNr, notify string) error {
|
||||
func (sm *FSsessions) disconnectSession(connId, uuid, redirectNr, notify string) error {
|
||||
if _, err := sm.conns[connId].SendApiCmd(
|
||||
fmt.Sprintf("uuid_setvar %s cgr_notify %s\n\n", uuid, notify)); err != nil {
|
||||
utils.Logger.Err(
|
||||
@@ -317,7 +317,7 @@ func (sm *FSSessionManager) disconnectSession(connId, uuid, redirectNr, notify s
|
||||
return nil
|
||||
}
|
||||
|
||||
func (sm *FSSessionManager) Shutdown() (err error) {
|
||||
func (sm *FSsessions) Shutdown() (err error) {
|
||||
for connId, fSock := range sm.conns {
|
||||
if !fSock.Connected() {
|
||||
utils.Logger.Err(fmt.Sprintf("<%s> Cannot shutdown sessions, fsock not connected for connection id: %s", utils.FreeSWITCHAgent, connId))
|
||||
@@ -332,13 +332,13 @@ func (sm *FSSessionManager) Shutdown() (err error) {
|
||||
}
|
||||
|
||||
// rpcclient.RpcClientConnection interface
|
||||
func (sm *FSSessionManager) Call(serviceMethod string, args interface{}, reply interface{}) error {
|
||||
func (sm *FSsessions) Call(serviceMethod string, args interface{}, reply interface{}) error {
|
||||
return utils.APIerRPCCall(sm, serviceMethod, args, reply)
|
||||
}
|
||||
|
||||
// Internal method to disconnect session in asterisk
|
||||
func (fsa *FSSessionManager) V1DisconnectSession(args utils.AttrDisconnectSession, reply *string) (err error) {
|
||||
fsEv := sessionmanager.SMGenericEvent(args.EventStart)
|
||||
func (fsa *FSsessions) V1DisconnectSession(args utils.AttrDisconnectSession, reply *string) (err error) {
|
||||
fsEv := sessions.SMGenericEvent(args.EventStart)
|
||||
channelID := fsEv.GetOriginID(utils.META_DEFAULT)
|
||||
if err = fsa.disconnectSession(fsEv[FsConnID].(string), channelID, fsEv.GetCallDestNr(utils.META_DEFAULT),
|
||||
utils.ErrInsufficientCredit.Error()); err != nil {
|
||||
|
||||
@@ -26,7 +26,7 @@ import (
|
||||
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
"github.com/cgrates/cgrates/sessionmanager"
|
||||
"github.com/cgrates/cgrates/sessions"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
"github.com/cgrates/fsock"
|
||||
)
|
||||
@@ -369,8 +369,8 @@ func (fsev FSEvent) AsMapStringInterface(timezone string) map[string]interface{}
|
||||
}
|
||||
|
||||
// V1AuthorizeArgs returns the arguments used in SMGv1.Authorize
|
||||
func (fsev FSEvent) V1AuthorizeArgs() (args *sessionmanager.V1AuthorizeArgs) {
|
||||
args = &sessionmanager.V1AuthorizeArgs{ // defaults
|
||||
func (fsev FSEvent) V1AuthorizeArgs() (args *sessions.V1AuthorizeArgs) {
|
||||
args = &sessions.V1AuthorizeArgs{ // defaults
|
||||
GetMaxUsage: true,
|
||||
CGREvent: utils.CGREvent{
|
||||
Tenant: fsev.GetTenant(utils.META_DEFAULT),
|
||||
@@ -398,8 +398,8 @@ func (fsev FSEvent) V1AuthorizeArgs() (args *sessionmanager.V1AuthorizeArgs) {
|
||||
}
|
||||
|
||||
// V1InitSessionArgs returns the arguments used in SessionSv1.InitSession
|
||||
func (fsev FSEvent) V1InitSessionArgs() (args *sessionmanager.V1InitSessionArgs) {
|
||||
args = &sessionmanager.V1InitSessionArgs{ // defaults
|
||||
func (fsev FSEvent) V1InitSessionArgs() (args *sessions.V1InitSessionArgs) {
|
||||
args = &sessions.V1InitSessionArgs{ // defaults
|
||||
InitSession: true,
|
||||
CGREvent: utils.CGREvent{
|
||||
Tenant: fsev.GetTenant(utils.META_DEFAULT),
|
||||
@@ -424,8 +424,8 @@ func (fsev FSEvent) V1InitSessionArgs() (args *sessionmanager.V1InitSessionArgs)
|
||||
}
|
||||
|
||||
// V1TerminateSessionArgs returns the arguments used in SMGv1.TerminateSession
|
||||
func (fsev FSEvent) V1TerminateSessionArgs() (args *sessionmanager.V1TerminateSessionArgs) {
|
||||
args = &sessionmanager.V1TerminateSessionArgs{ // defaults
|
||||
func (fsev FSEvent) V1TerminateSessionArgs() (args *sessions.V1TerminateSessionArgs) {
|
||||
args = &sessions.V1TerminateSessionArgs{ // defaults
|
||||
TerminateSession: true,
|
||||
CGREvent: utils.CGREvent{
|
||||
Tenant: fsev.GetTenant(utils.META_DEFAULT),
|
||||
|
||||
@@ -25,7 +25,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/sessionmanager"
|
||||
"github.com/cgrates/cgrates/sessions"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
"github.com/cgrates/kamevapi"
|
||||
)
|
||||
@@ -103,7 +103,7 @@ func (ka *KamailioAgent) onCgrAuth(evData []byte, connID string) {
|
||||
return
|
||||
}
|
||||
authArgs := kev.V1AuthorizeArgs()
|
||||
var authReply sessionmanager.V1AuthorizeReply
|
||||
var authReply sessions.V1AuthorizeReply
|
||||
err = ka.sessionS.Call(utils.SessionSv1AuthorizeEvent, authArgs, &authReply)
|
||||
if kar, err := kev.AsKamAuthReply(authArgs, &authReply, err); err != nil {
|
||||
utils.Logger.Err(fmt.Sprintf("<%s> failed building auth reply for event: %s, error: %s",
|
||||
@@ -132,7 +132,7 @@ func (ka *KamailioAgent) onCallStart(evData []byte, connID string) {
|
||||
}
|
||||
initSessionArgs := kev.V1InitSessionArgs()
|
||||
initSessionArgs.CGREvent.Event[EvapiConnID] = connID // Attach the connection ID so we can properly disconnect later
|
||||
var initReply sessionmanager.V1InitSessionReply
|
||||
var initReply sessions.V1InitSessionReply
|
||||
if err := ka.sessionS.Call(utils.SessionSv1InitiateSession,
|
||||
initSessionArgs, &initReply); err != nil {
|
||||
utils.Logger.Err(
|
||||
|
||||
@@ -24,7 +24,7 @@ import (
|
||||
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
"github.com/cgrates/cgrates/sessionmanager"
|
||||
"github.com/cgrates/cgrates/sessions"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
@@ -153,8 +153,8 @@ func (kev KamEvent) String() string {
|
||||
return string(mrsh)
|
||||
}
|
||||
|
||||
func (kev KamEvent) V1AuthorizeArgs() (args *sessionmanager.V1AuthorizeArgs) {
|
||||
args = &sessionmanager.V1AuthorizeArgs{
|
||||
func (kev KamEvent) V1AuthorizeArgs() (args *sessions.V1AuthorizeArgs) {
|
||||
args = &sessions.V1AuthorizeArgs{
|
||||
GetMaxUsage: true,
|
||||
CGREvent: utils.CGREvent{
|
||||
Tenant: utils.FirstNonEmpty(kev[utils.Tenant],
|
||||
@@ -183,8 +183,8 @@ func (kev KamEvent) V1AuthorizeArgs() (args *sessionmanager.V1AuthorizeArgs) {
|
||||
}
|
||||
|
||||
// AsKamAuthReply builds up a Kamailio AuthReply based on arguments and reply from SessionS
|
||||
func (kev KamEvent) AsKamAuthReply(authArgs *sessionmanager.V1AuthorizeArgs,
|
||||
authReply *sessionmanager.V1AuthorizeReply, rplyErr error) (kar *KamAuthReply, err error) {
|
||||
func (kev KamEvent) AsKamAuthReply(authArgs *sessions.V1AuthorizeArgs,
|
||||
authReply *sessions.V1AuthorizeReply, rplyErr error) (kar *KamAuthReply, err error) {
|
||||
kar = &KamAuthReply{Event: CGR_AUTH_REPLY,
|
||||
TransactionIndex: kev[KamTRIndex],
|
||||
TransactionLabel: kev[KamTRLabel],
|
||||
@@ -213,8 +213,8 @@ func (kev KamEvent) AsKamAuthReply(authArgs *sessionmanager.V1AuthorizeArgs,
|
||||
}
|
||||
|
||||
// V1InitSessionArgs returns the arguments used in SessionSv1.InitSession
|
||||
func (kev KamEvent) V1InitSessionArgs() (args *sessionmanager.V1InitSessionArgs) {
|
||||
args = &sessionmanager.V1InitSessionArgs{ // defaults
|
||||
func (kev KamEvent) V1InitSessionArgs() (args *sessions.V1InitSessionArgs) {
|
||||
args = &sessions.V1InitSessionArgs{ // defaults
|
||||
InitSession: true,
|
||||
CGREvent: utils.CGREvent{
|
||||
Tenant: utils.FirstNonEmpty(kev[utils.Tenant],
|
||||
@@ -240,8 +240,8 @@ func (kev KamEvent) V1InitSessionArgs() (args *sessionmanager.V1InitSessionArgs)
|
||||
}
|
||||
|
||||
// V1TerminateSessionArgs returns the arguments used in SMGv1.TerminateSession
|
||||
func (kev KamEvent) V1TerminateSessionArgs() (args *sessionmanager.V1TerminateSessionArgs) {
|
||||
args = &sessionmanager.V1TerminateSessionArgs{ // defaults
|
||||
func (kev KamEvent) V1TerminateSessionArgs() (args *sessions.V1TerminateSessionArgs) {
|
||||
args = &sessions.V1TerminateSessionArgs{ // defaults
|
||||
TerminateSession: true,
|
||||
CGREvent: utils.CGREvent{
|
||||
Tenant: utils.FirstNonEmpty(kev[utils.Tenant],
|
||||
|
||||
@@ -36,7 +36,7 @@ import (
|
||||
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
"github.com/cgrates/cgrates/sessionmanager"
|
||||
"github.com/cgrates/cgrates/sessions"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
"github.com/fiorix/go-diameter/diam"
|
||||
"github.com/fiorix/go-diameter/diam/avp"
|
||||
@@ -620,7 +620,7 @@ func (self *CCR) AsDiameterMessage() (*diam.Message, error) {
|
||||
}
|
||||
|
||||
// Extracts data out of CCR into a SMGenericEvent based on the configured template
|
||||
func (self *CCR) AsSMGenericEvent(cfgFlds []*config.CfgCdrField) (sessionmanager.SMGenericEvent, error) {
|
||||
func (self *CCR) AsSMGenericEvent(cfgFlds []*config.CfgCdrField) (sessions.SMGenericEvent, error) {
|
||||
outMap := make(map[string]string) // work with it so we can append values to keys
|
||||
outMap[utils.EVENT_NAME] = DIAMETER_CCR
|
||||
for _, cfgFld := range cfgFlds {
|
||||
@@ -641,7 +641,7 @@ func (self *CCR) AsSMGenericEvent(cfgFlds []*config.CfgCdrField) (sessionmanager
|
||||
break
|
||||
}
|
||||
}
|
||||
return sessionmanager.SMGenericEvent(utils.ConvertMapValStrIf(outMap)), nil
|
||||
return sessions.SMGenericEvent(utils.ConvertMapValStrIf(outMap)), nil
|
||||
}
|
||||
|
||||
func NewBareCCAFromCCR(ccr *CCR, originHost, originRealm string) *CCA {
|
||||
|
||||
@@ -27,7 +27,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/sessionmanager"
|
||||
"github.com/cgrates/cgrates/sessions"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
"github.com/fiorix/go-diameter/diam"
|
||||
"github.com/fiorix/go-diameter/diam/avp"
|
||||
@@ -464,7 +464,7 @@ func TestCCRAsSMGenericEvent(t *testing.T) {
|
||||
})
|
||||
ccr.diamMessage.NewAVP("FramedIPAddress", avp.Mbit, 0, datatype.OctetString("0AE40041"))
|
||||
cfgFlds := make([]*config.CfgCdrField, 0)
|
||||
eSMGEv := sessionmanager.SMGenericEvent{"EventName": "DIAMETER_CCR"}
|
||||
eSMGEv := sessions.SMGenericEvent{"EventName": "DIAMETER_CCR"}
|
||||
if rSMGEv, err := ccr.AsSMGenericEvent(cfgFlds); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(eSMGEv, rSMGEv) {
|
||||
@@ -481,7 +481,7 @@ func TestCCRAsSMGenericEvent(t *testing.T) {
|
||||
Mandatory: true,
|
||||
},
|
||||
}
|
||||
eSMGEv = sessionmanager.SMGenericEvent{"EventName": "DIAMETER_CCR", "LastUsed": "54239"}
|
||||
eSMGEv = sessions.SMGenericEvent{"EventName": "DIAMETER_CCR", "LastUsed": "54239"}
|
||||
if rSMGEv, err := ccr.AsSMGenericEvent(cfgFlds); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(eSMGEv, rSMGEv) {
|
||||
@@ -498,7 +498,7 @@ func TestCCRAsSMGenericEvent(t *testing.T) {
|
||||
Mandatory: true,
|
||||
},
|
||||
}
|
||||
eSMGEv = sessionmanager.SMGenericEvent{"EventName": "DIAMETER_CCR", "LastUsed": "4420"}
|
||||
eSMGEv = sessions.SMGenericEvent{"EventName": "DIAMETER_CCR", "LastUsed": "4420"}
|
||||
if rSMGEv, err := ccr.AsSMGenericEvent(cfgFlds); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(eSMGEv, rSMGEv) {
|
||||
|
||||
@@ -24,7 +24,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/sessionmanager"
|
||||
"github.com/cgrates/cgrates/sessions"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
"github.com/cgrates/radigo"
|
||||
)
|
||||
@@ -134,7 +134,7 @@ func radFieldOutVal(pkt *radigo.Packet, processorVars map[string]string,
|
||||
|
||||
// radPktAsSMGEvent converts a RADIUS packet into SMGEvent
|
||||
func radReqAsSMGEvent(radPkt *radigo.Packet, procVars map[string]string, procFlags utils.StringMap,
|
||||
cfgFlds []*config.CfgCdrField) (smgEv sessionmanager.SMGenericEvent, err error) {
|
||||
cfgFlds []*config.CfgCdrField) (smgEv sessions.SMGenericEvent, err error) {
|
||||
outMap := make(map[string]string) // work with it so we can append values to keys
|
||||
outMap[utils.EVENT_NAME] = EvRadiusReq
|
||||
for _, cfgFld := range cfgFlds {
|
||||
@@ -164,7 +164,7 @@ func radReqAsSMGEvent(radPkt *radigo.Packet, procVars map[string]string, procFla
|
||||
if len(procFlags) != 0 {
|
||||
outMap[utils.CGRFlags] = procFlags.String()
|
||||
}
|
||||
return sessionmanager.SMGenericEvent(utils.ConvertMapValStrIf(outMap)), nil
|
||||
return sessions.SMGenericEvent(utils.ConvertMapValStrIf(outMap)), nil
|
||||
}
|
||||
|
||||
// radReplyAppendAttributes appends attributes to a RADIUS reply based on predefined template
|
||||
|
||||
@@ -25,7 +25,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/sessionmanager"
|
||||
"github.com/cgrates/cgrates/sessions"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
"github.com/cgrates/radigo"
|
||||
)
|
||||
@@ -235,7 +235,7 @@ func TestRadReqAsSMGEvent(t *testing.T) {
|
||||
Value: utils.ParseRSRFieldsMustCompile("Event-Timestamp;^|;Ascend-User-Acct-Time", utils.INFIELD_SEP)},
|
||||
}
|
||||
|
||||
eSMGEv := sessionmanager.SMGenericEvent{
|
||||
eSMGEv := sessions.SMGenericEvent{
|
||||
utils.EVENT_NAME: EvRadiusReq,
|
||||
utils.TOR: utils.VOICE,
|
||||
utils.OriginID: "e4921177ab0e3586c37f6a185864b71a@0:0:0:0:0:0:0:0-75c2f57b-51585361",
|
||||
|
||||
@@ -20,17 +20,17 @@ package v1
|
||||
|
||||
import (
|
||||
"github.com/cenk/rpc2"
|
||||
"github.com/cgrates/cgrates/sessionmanager"
|
||||
"github.com/cgrates/cgrates/sessions"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
func NewSessionSv1(sm *sessionmanager.SMGeneric) *SessionSv1 {
|
||||
func NewSessionSv1(sm *sessions.SMGeneric) *SessionSv1 {
|
||||
return &SessionSv1{SMG: sm}
|
||||
}
|
||||
|
||||
// SessionSv1 exports RPC from SessionSv1
|
||||
type SessionSv1 struct {
|
||||
SMG *sessionmanager.SMGeneric
|
||||
SMG *sessions.SMGeneric
|
||||
}
|
||||
|
||||
// Publishes BiJSONRPC methods exported by SessionSv1
|
||||
@@ -48,27 +48,27 @@ func (ssv1 *SessionSv1) Handlers() map[string]interface{} {
|
||||
}
|
||||
}
|
||||
|
||||
func (ssv1 *SessionSv1) AuthorizeEvent(args *sessionmanager.V1AuthorizeArgs,
|
||||
rply *sessionmanager.V1AuthorizeReply) error {
|
||||
func (ssv1 *SessionSv1) AuthorizeEvent(args *sessions.V1AuthorizeArgs,
|
||||
rply *sessions.V1AuthorizeReply) error {
|
||||
return ssv1.SMG.BiRPCv1AuthorizeEvent(nil, args, rply)
|
||||
}
|
||||
|
||||
func (ssv1 *SessionSv1) AuthorizeEventWithDigest(args *sessionmanager.V1AuthorizeArgs,
|
||||
rply *sessionmanager.V1AuthorizeReplyWithDigest) error {
|
||||
func (ssv1 *SessionSv1) AuthorizeEventWithDigest(args *sessions.V1AuthorizeArgs,
|
||||
rply *sessions.V1AuthorizeReplyWithDigest) error {
|
||||
return ssv1.SMG.BiRPCv1AuthorizeEventWithDigest(nil, args, rply)
|
||||
}
|
||||
|
||||
func (ssv1 *SessionSv1) InitiateSession(args *sessionmanager.V1InitSessionArgs,
|
||||
rply *sessionmanager.V1InitSessionReply) error {
|
||||
func (ssv1 *SessionSv1) InitiateSession(args *sessions.V1InitSessionArgs,
|
||||
rply *sessions.V1InitSessionReply) error {
|
||||
return ssv1.SMG.BiRPCv1InitiateSession(nil, args, rply)
|
||||
}
|
||||
|
||||
func (ssv1 *SessionSv1) UpdateSession(args *sessionmanager.V1UpdateSessionArgs,
|
||||
rply *sessionmanager.V1UpdateSessionReply) error {
|
||||
func (ssv1 *SessionSv1) UpdateSession(args *sessions.V1UpdateSessionArgs,
|
||||
rply *sessions.V1UpdateSessionReply) error {
|
||||
return ssv1.SMG.BiRPCv1UpdateSession(nil, args, rply)
|
||||
}
|
||||
|
||||
func (ssv1 *SessionSv1) TerminateSession(args *sessionmanager.V1TerminateSessionArgs,
|
||||
func (ssv1 *SessionSv1) TerminateSession(args *sessions.V1TerminateSessionArgs,
|
||||
rply *string) error {
|
||||
return ssv1.SMG.BiRPCv1TerminateSession(nil, args, rply)
|
||||
}
|
||||
@@ -77,40 +77,40 @@ func (ssv1 *SessionSv1) ProcessCDR(cgrEv utils.CGREvent, rply *string) error {
|
||||
return ssv1.SMG.BiRPCv1ProcessCDR(nil, cgrEv, rply)
|
||||
}
|
||||
|
||||
func (ssv1 *SessionSv1) ProcessEvent(args *sessionmanager.V1ProcessEventArgs,
|
||||
rply *sessionmanager.V1ProcessEventReply) error {
|
||||
func (ssv1 *SessionSv1) ProcessEvent(args *sessions.V1ProcessEventArgs,
|
||||
rply *sessions.V1ProcessEventReply) error {
|
||||
return ssv1.SMG.BiRPCv1ProcessEvent(nil, args, rply)
|
||||
}
|
||||
|
||||
func (ssv1 *SessionSv1) GetActiveSessions(args map[string]string, rply *[]*sessionmanager.ActiveSession) error {
|
||||
func (ssv1 *SessionSv1) GetActiveSessions(args map[string]string, rply *[]*sessions.ActiveSession) error {
|
||||
return ssv1.SMG.BiRPCV1GetActiveSessions(nil, args, rply)
|
||||
}
|
||||
|
||||
func (ssv1 *SessionSv1) GetPassiveSessions(args map[string]string, rply *[]*sessionmanager.ActiveSession) error {
|
||||
func (ssv1 *SessionSv1) GetPassiveSessions(args map[string]string, rply *[]*sessions.ActiveSession) error {
|
||||
return ssv1.SMG.BiRPCV1GetPassiveSessions(nil, args, rply)
|
||||
}
|
||||
|
||||
func (ssv1 *SessionSv1) BiRpcAuthorizeEvent(clnt *rpc2.Client, args *sessionmanager.V1AuthorizeArgs,
|
||||
rply *sessionmanager.V1AuthorizeReply) error {
|
||||
func (ssv1 *SessionSv1) BiRpcAuthorizeEvent(clnt *rpc2.Client, args *sessions.V1AuthorizeArgs,
|
||||
rply *sessions.V1AuthorizeReply) error {
|
||||
return ssv1.SMG.BiRPCv1AuthorizeEvent(clnt, args, rply)
|
||||
}
|
||||
|
||||
func (ssv1 *SessionSv1) BiRpcAuthorizeEventWithDigest(clnt *rpc2.Client, args *sessionmanager.V1AuthorizeArgs,
|
||||
rply *sessionmanager.V1AuthorizeReplyWithDigest) error {
|
||||
func (ssv1 *SessionSv1) BiRpcAuthorizeEventWithDigest(clnt *rpc2.Client, args *sessions.V1AuthorizeArgs,
|
||||
rply *sessions.V1AuthorizeReplyWithDigest) error {
|
||||
return ssv1.SMG.BiRPCv1AuthorizeEventWithDigest(clnt, args, rply)
|
||||
}
|
||||
|
||||
func (ssv1 *SessionSv1) BiRpcInitiateSession(clnt *rpc2.Client, args *sessionmanager.V1InitSessionArgs,
|
||||
rply *sessionmanager.V1InitSessionReply) error {
|
||||
func (ssv1 *SessionSv1) BiRpcInitiateSession(clnt *rpc2.Client, args *sessions.V1InitSessionArgs,
|
||||
rply *sessions.V1InitSessionReply) error {
|
||||
return ssv1.SMG.BiRPCv1InitiateSession(clnt, args, rply)
|
||||
}
|
||||
|
||||
func (ssv1 *SessionSv1) BiRpcUpdateSession(clnt *rpc2.Client, args *sessionmanager.V1UpdateSessionArgs,
|
||||
rply *sessionmanager.V1UpdateSessionReply) error {
|
||||
func (ssv1 *SessionSv1) BiRpcUpdateSession(clnt *rpc2.Client, args *sessions.V1UpdateSessionArgs,
|
||||
rply *sessions.V1UpdateSessionReply) error {
|
||||
return ssv1.SMG.BiRPCv1UpdateSession(clnt, args, rply)
|
||||
}
|
||||
|
||||
func (ssv1 *SessionSv1) BiRpcTerminateSession(clnt *rpc2.Client, args *sessionmanager.V1TerminateSessionArgs,
|
||||
func (ssv1 *SessionSv1) BiRpcTerminateSession(clnt *rpc2.Client, args *sessions.V1TerminateSessionArgs,
|
||||
rply *string) error {
|
||||
return ssv1.SMG.BiRPCv1TerminateSession(clnt, args, rply)
|
||||
}
|
||||
@@ -119,17 +119,17 @@ func (ssv1 *SessionSv1) BiRpcProcessCDR(clnt *rpc2.Client, cgrEv utils.CGREvent,
|
||||
return ssv1.SMG.BiRPCv1ProcessCDR(clnt, cgrEv, rply)
|
||||
}
|
||||
|
||||
func (ssv1 *SessionSv1) BiRpcProcessEvent(clnt *rpc2.Client, args *sessionmanager.V1ProcessEventArgs,
|
||||
rply *sessionmanager.V1ProcessEventReply) error {
|
||||
func (ssv1 *SessionSv1) BiRpcProcessEvent(clnt *rpc2.Client, args *sessions.V1ProcessEventArgs,
|
||||
rply *sessions.V1ProcessEventReply) error {
|
||||
return ssv1.SMG.BiRPCv1ProcessEvent(clnt, args, rply)
|
||||
}
|
||||
|
||||
func (ssv1 *SessionSv1) BiRPCV1GetActiveSessions(clnt *rpc2.Client, args map[string]string,
|
||||
rply *[]*sessionmanager.ActiveSession) error {
|
||||
rply *[]*sessions.ActiveSession) error {
|
||||
return ssv1.SMG.BiRPCV1GetActiveSessions(clnt, args, rply)
|
||||
}
|
||||
|
||||
func (ssv1 *SessionSv1) BiRPCV1GetPassiveSessions(clnt *rpc2.Client, args map[string]string,
|
||||
rply *[]*sessionmanager.ActiveSession) error {
|
||||
rply *[]*sessions.ActiveSession) error {
|
||||
return ssv1.SMG.BiRPCV1GetPassiveSessions(clnt, args, rply)
|
||||
}
|
||||
|
||||
@@ -20,15 +20,15 @@ package v1
|
||||
|
||||
import (
|
||||
"github.com/cenk/rpc2"
|
||||
"github.com/cgrates/cgrates/sessionmanager"
|
||||
"github.com/cgrates/cgrates/sessions"
|
||||
)
|
||||
|
||||
func NewSMGenericBiRpcV1(sm *sessionmanager.SMGeneric) *SMGenericBiRpcV1 {
|
||||
func NewSMGenericBiRpcV1(sm *sessions.SMGeneric) *SMGenericBiRpcV1 {
|
||||
return &SMGenericBiRpcV1{sm: sm}
|
||||
}
|
||||
|
||||
type SMGenericBiRpcV1 struct {
|
||||
sm *sessionmanager.SMGeneric
|
||||
sm *sessions.SMGeneric
|
||||
}
|
||||
|
||||
// Publishes methods exported by SMGenericBiRpcV1 as SMGenericV1 (so we can handle standard RPC methods via birpc socket)
|
||||
@@ -49,36 +49,36 @@ func (self *SMGenericBiRpcV1) Handlers() map[string]interface{} {
|
||||
}
|
||||
|
||||
/// Returns MaxUsage (for calls in seconds), -1 for no limit
|
||||
func (self *SMGenericBiRpcV1) GetMaxUsage(clnt *rpc2.Client, ev sessionmanager.SMGenericEvent, maxUsage *float64) error {
|
||||
func (self *SMGenericBiRpcV1) GetMaxUsage(clnt *rpc2.Client, ev sessions.SMGenericEvent, maxUsage *float64) error {
|
||||
return self.sm.BiRPCV1GetMaxUsage(clnt, ev, maxUsage)
|
||||
}
|
||||
|
||||
// Called on session start, returns the maximum number of seconds the session can last
|
||||
func (self *SMGenericBiRpcV1) InitiateSession(clnt *rpc2.Client, ev sessionmanager.SMGenericEvent, maxUsage *float64) error {
|
||||
func (self *SMGenericBiRpcV1) InitiateSession(clnt *rpc2.Client, ev sessions.SMGenericEvent, maxUsage *float64) error {
|
||||
return self.sm.BiRPCV1InitiateSession(clnt, ev, maxUsage)
|
||||
}
|
||||
|
||||
// Interim updates, returns remaining duration from the rater
|
||||
func (self *SMGenericBiRpcV1) UpdateSession(clnt *rpc2.Client, ev sessionmanager.SMGenericEvent, maxUsage *float64) error {
|
||||
func (self *SMGenericBiRpcV1) UpdateSession(clnt *rpc2.Client, ev sessions.SMGenericEvent, maxUsage *float64) error {
|
||||
return self.sm.BiRPCV1UpdateSession(clnt, ev, maxUsage)
|
||||
}
|
||||
|
||||
// Called on session end, should stop debit loop
|
||||
func (self *SMGenericBiRpcV1) TerminateSession(clnt *rpc2.Client, ev sessionmanager.SMGenericEvent, reply *string) error {
|
||||
func (self *SMGenericBiRpcV1) TerminateSession(clnt *rpc2.Client, ev sessions.SMGenericEvent, reply *string) error {
|
||||
return self.sm.BiRPCV1TerminateSession(clnt, ev, reply)
|
||||
}
|
||||
|
||||
// Called on individual Events (eg SMS)
|
||||
func (self *SMGenericBiRpcV1) ChargeEvent(clnt *rpc2.Client, ev sessionmanager.SMGenericEvent, maxUsage *float64) error {
|
||||
func (self *SMGenericBiRpcV1) ChargeEvent(clnt *rpc2.Client, ev sessions.SMGenericEvent, maxUsage *float64) error {
|
||||
return self.sm.BiRPCV1ChargeEvent(clnt, ev, maxUsage)
|
||||
}
|
||||
|
||||
// Called on session end, should send the CDR to CDRS
|
||||
func (self *SMGenericBiRpcV1) ProcessCDR(clnt *rpc2.Client, ev sessionmanager.SMGenericEvent, reply *string) error {
|
||||
func (self *SMGenericBiRpcV1) ProcessCDR(clnt *rpc2.Client, ev sessions.SMGenericEvent, reply *string) error {
|
||||
return self.sm.BiRPCV1ProcessCDR(clnt, ev, reply)
|
||||
}
|
||||
|
||||
func (self *SMGenericBiRpcV1) GetActiveSessions(clnt *rpc2.Client, attrs map[string]string, reply *[]*sessionmanager.ActiveSession) error {
|
||||
func (self *SMGenericBiRpcV1) GetActiveSessions(clnt *rpc2.Client, attrs map[string]string, reply *[]*sessions.ActiveSession) error {
|
||||
return self.sm.BiRPCV1GetActiveSessions(clnt, attrs, reply)
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ func (self *SMGenericBiRpcV1) GetActiveSessionsCount(clnt *rpc2.Client, attrs ma
|
||||
return self.sm.BiRPCV1GetActiveSessionsCount(clnt, attrs, reply)
|
||||
}
|
||||
|
||||
func (self *SMGenericBiRpcV1) GetPassiveSessions(clnt *rpc2.Client, attrs map[string]string, reply *[]*sessionmanager.ActiveSession) error {
|
||||
func (self *SMGenericBiRpcV1) GetPassiveSessions(clnt *rpc2.Client, attrs map[string]string, reply *[]*sessions.ActiveSession) error {
|
||||
return self.sm.BiRPCV1GetPassiveSessions(clnt, attrs, reply)
|
||||
}
|
||||
|
||||
@@ -94,10 +94,10 @@ func (self *SMGenericBiRpcV1) GetPassiveSessionsCount(clnt *rpc2.Client, attrs m
|
||||
return self.sm.BiRPCV1GetPassiveSessionsCount(clnt, attrs, reply)
|
||||
}
|
||||
|
||||
func (self *SMGenericBiRpcV1) ReplicateActiveSessions(clnt *rpc2.Client, args sessionmanager.ArgsReplicateSessions, reply *string) error {
|
||||
func (self *SMGenericBiRpcV1) ReplicateActiveSessions(clnt *rpc2.Client, args sessions.ArgsReplicateSessions, reply *string) error {
|
||||
return self.sm.BiRPCV1ReplicateActiveSessions(clnt, args, reply)
|
||||
}
|
||||
|
||||
func (self *SMGenericBiRpcV1) ReplicatePassiveSessions(clnt *rpc2.Client, args sessionmanager.ArgsReplicateSessions, reply *string) error {
|
||||
func (self *SMGenericBiRpcV1) ReplicatePassiveSessions(clnt *rpc2.Client, args sessions.ArgsReplicateSessions, reply *string) error {
|
||||
return self.sm.BiRPCV1ReplicateActiveSessions(clnt, args, reply)
|
||||
}
|
||||
|
||||
@@ -22,51 +22,51 @@ import (
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/cgrates/cgrates/sessionmanager"
|
||||
"github.com/cgrates/cgrates/sessions"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
"github.com/cgrates/rpcclient"
|
||||
)
|
||||
|
||||
func NewSMGenericV1(sm *sessionmanager.SMGeneric) *SMGenericV1 {
|
||||
func NewSMGenericV1(sm *sessions.SMGeneric) *SMGenericV1 {
|
||||
return &SMGenericV1{SMG: sm}
|
||||
}
|
||||
|
||||
// Exports RPC from SMGeneric
|
||||
type SMGenericV1 struct {
|
||||
SMG *sessionmanager.SMGeneric
|
||||
SMG *sessions.SMGeneric
|
||||
}
|
||||
|
||||
// Returns MaxUsage (for calls in seconds), -1 for no limit
|
||||
func (self *SMGenericV1) GetMaxUsage(ev sessionmanager.SMGenericEvent, maxUsage *float64) error {
|
||||
func (self *SMGenericV1) GetMaxUsage(ev sessions.SMGenericEvent, maxUsage *float64) error {
|
||||
return self.SMG.BiRPCV1GetMaxUsage(nil, ev, maxUsage)
|
||||
}
|
||||
|
||||
// Called on session start, returns the maximum number of seconds the session can last
|
||||
func (self *SMGenericV1) InitiateSession(ev sessionmanager.SMGenericEvent, maxUsage *float64) error {
|
||||
func (self *SMGenericV1) InitiateSession(ev sessions.SMGenericEvent, maxUsage *float64) error {
|
||||
return self.SMG.BiRPCV1InitiateSession(nil, ev, maxUsage)
|
||||
}
|
||||
|
||||
// Interim updates, returns remaining duration from the rater
|
||||
func (self *SMGenericV1) UpdateSession(ev sessionmanager.SMGenericEvent, maxUsage *float64) error {
|
||||
func (self *SMGenericV1) UpdateSession(ev sessions.SMGenericEvent, maxUsage *float64) error {
|
||||
return self.SMG.BiRPCV1UpdateSession(nil, ev, maxUsage)
|
||||
}
|
||||
|
||||
// Called on session end, should stop debit loop
|
||||
func (self *SMGenericV1) TerminateSession(ev sessionmanager.SMGenericEvent, reply *string) error {
|
||||
func (self *SMGenericV1) TerminateSession(ev sessions.SMGenericEvent, reply *string) error {
|
||||
return self.SMG.BiRPCV1TerminateSession(nil, ev, reply)
|
||||
}
|
||||
|
||||
// Called on individual Events (eg SMS)
|
||||
func (self *SMGenericV1) ChargeEvent(ev sessionmanager.SMGenericEvent, maxUsage *float64) error {
|
||||
func (self *SMGenericV1) ChargeEvent(ev sessions.SMGenericEvent, maxUsage *float64) error {
|
||||
return self.SMG.BiRPCV1ChargeEvent(nil, ev, maxUsage)
|
||||
}
|
||||
|
||||
// Called on session end, should send the CDR to CDRS
|
||||
func (self *SMGenericV1) ProcessCDR(ev sessionmanager.SMGenericEvent, reply *string) error {
|
||||
func (self *SMGenericV1) ProcessCDR(ev sessions.SMGenericEvent, reply *string) error {
|
||||
return self.SMG.BiRPCV1ProcessCDR(nil, ev, reply)
|
||||
}
|
||||
|
||||
func (self *SMGenericV1) GetActiveSessions(attrs map[string]string, reply *[]*sessionmanager.ActiveSession) error {
|
||||
func (self *SMGenericV1) GetActiveSessions(attrs map[string]string, reply *[]*sessions.ActiveSession) error {
|
||||
return self.SMG.BiRPCV1GetActiveSessions(nil, attrs, reply)
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ func (self *SMGenericV1) GetActiveSessionsCount(attrs map[string]string, reply *
|
||||
return self.SMG.BiRPCV1GetActiveSessionsCount(nil, attrs, reply)
|
||||
}
|
||||
|
||||
func (self *SMGenericV1) GetPassiveSessions(attrs map[string]string, reply *[]*sessionmanager.ActiveSession) error {
|
||||
func (self *SMGenericV1) GetPassiveSessions(attrs map[string]string, reply *[]*sessions.ActiveSession) error {
|
||||
return self.SMG.BiRPCV1GetPassiveSessions(nil, attrs, reply)
|
||||
}
|
||||
|
||||
@@ -82,15 +82,15 @@ func (self *SMGenericV1) GetPassiveSessionsCount(attrs map[string]string, reply
|
||||
return self.SMG.BiRPCV1GetPassiveSessionsCount(nil, attrs, reply)
|
||||
}
|
||||
|
||||
func (self *SMGenericV1) SetPassiveSessions(args sessionmanager.ArgsSetPassiveSessions, reply *string) error {
|
||||
func (self *SMGenericV1) SetPassiveSessions(args sessions.ArgsSetPassiveSessions, reply *string) error {
|
||||
return self.SMG.BiRPCV1SetPassiveSessions(nil, args, reply)
|
||||
}
|
||||
|
||||
func (self *SMGenericV1) ReplicateActiveSessions(args sessionmanager.ArgsReplicateSessions, reply *string) error {
|
||||
func (self *SMGenericV1) ReplicateActiveSessions(args sessions.ArgsReplicateSessions, reply *string) error {
|
||||
return self.SMG.BiRPCV1ReplicateActiveSessions(nil, args, reply)
|
||||
}
|
||||
|
||||
func (self *SMGenericV1) ReplicatePassiveSessions(args sessionmanager.ArgsReplicateSessions, reply *string) error {
|
||||
func (self *SMGenericV1) ReplicatePassiveSessions(args sessions.ArgsReplicateSessions, reply *string) error {
|
||||
return self.SMG.BiRPCV1ReplicatePassiveSessions(nil, args, reply)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
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 (
|
||||
"github.com/cgrates/cgrates/sessionmanager"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
// Interact with SessionManager
|
||||
type SessionManagerV1 struct {
|
||||
SMs []sessionmanager.SessionManager // List of session managers since we support having more than one active session manager running on one host
|
||||
}
|
||||
|
||||
func (self *SessionManagerV1) ActiveSessionMangers(ignored string, reply *[]sessionmanager.SessionManager) error {
|
||||
if len(self.SMs) == 0 {
|
||||
return utils.ErrNotFound
|
||||
}
|
||||
*reply = self.SMs
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SessionManagerV1) ActiveSessions(attrs utils.AttrGetSMASessions, reply *[]*sessionmanager.ActiveSession) error {
|
||||
if attrs.SessionManagerIndex > len(self.SMs)-1 {
|
||||
return utils.ErrNotFound
|
||||
}
|
||||
for _, session := range self.SMs[attrs.SessionManagerIndex].Sessions() {
|
||||
*reply = append(*reply, session.AsActiveSessions()...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -22,7 +22,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/apier/v1"
|
||||
"github.com/cgrates/cgrates/sessionmanager"
|
||||
"github.com/cgrates/cgrates/sessions"
|
||||
)
|
||||
|
||||
type SMGenericV2 struct {
|
||||
@@ -30,21 +30,21 @@ type SMGenericV2 struct {
|
||||
}
|
||||
|
||||
// GetMaxUsage returns maxUsage as time.Duration/int64
|
||||
func (smgv2 *SMGenericV2) GetMaxUsage(ev sessionmanager.SMGenericEvent, maxUsage *time.Duration) error {
|
||||
func (smgv2 *SMGenericV2) GetMaxUsage(ev sessions.SMGenericEvent, maxUsage *time.Duration) error {
|
||||
return smgv2.SMG.BiRPCV2GetMaxUsage(nil, ev, maxUsage)
|
||||
}
|
||||
|
||||
// Called on session start, returns the maximum number of seconds the session can last
|
||||
func (smgv2 *SMGenericV2) InitiateSession(ev sessionmanager.SMGenericEvent, maxUsage *time.Duration) error {
|
||||
func (smgv2 *SMGenericV2) InitiateSession(ev sessions.SMGenericEvent, maxUsage *time.Duration) error {
|
||||
return smgv2.SMG.BiRPCV2InitiateSession(nil, ev, maxUsage)
|
||||
}
|
||||
|
||||
// Interim updates, returns remaining duration from the rater
|
||||
func (smgv2 *SMGenericV2) UpdateSession(ev sessionmanager.SMGenericEvent, maxUsage *time.Duration) error {
|
||||
func (smgv2 *SMGenericV2) UpdateSession(ev sessions.SMGenericEvent, maxUsage *time.Duration) error {
|
||||
return smgv2.SMG.BiRPCV2UpdateSession(nil, ev, maxUsage)
|
||||
}
|
||||
|
||||
// Called on individual Events (eg SMS)
|
||||
func (smgv2 *SMGenericV2) ChargeEvent(ev sessionmanager.SMGenericEvent, maxUsage *time.Duration) error {
|
||||
func (smgv2 *SMGenericV2) ChargeEvent(ev sessions.SMGenericEvent, maxUsage *time.Duration) error {
|
||||
return smgv2.SMG.BiRPCV2ChargeEvent(nil, ev, maxUsage)
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ import (
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
"github.com/cgrates/cgrates/scheduler"
|
||||
"github.com/cgrates/cgrates/servmanager"
|
||||
"github.com/cgrates/cgrates/sessionmanager"
|
||||
"github.com/cgrates/cgrates/sessions"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
"github.com/cgrates/rpcclient"
|
||||
)
|
||||
@@ -180,13 +180,13 @@ func startSessionS(internalSMGChan, internalRaterChan, internalResourceSChan, in
|
||||
return
|
||||
}
|
||||
}
|
||||
smgReplConns, err := sessionmanager.NewSessionReplicationConns(cfg.SessionSCfg().SessionReplicationConns, cfg.Reconnects, cfg.ConnectTimeout, cfg.ReplyTimeout)
|
||||
smgReplConns, err := sessions.NewSessionReplicationConns(cfg.SessionSCfg().SessionReplicationConns, cfg.Reconnects, cfg.ConnectTimeout, cfg.ReplyTimeout)
|
||||
if err != nil {
|
||||
utils.Logger.Crit(fmt.Sprintf("<%s> Could not connect to SMGReplicationConnection error: <%s>", utils.SessionS, err.Error()))
|
||||
exitChan <- true
|
||||
return
|
||||
}
|
||||
sm := sessionmanager.NewSMGeneric(cfg, ralsConns, resSConns, suplSConns,
|
||||
sm := sessions.NewSMGeneric(cfg, ralsConns, resSConns, suplSConns,
|
||||
attrSConns, cdrsConn, smgReplConns, cfg.DefaultTimezone)
|
||||
if err = sm.Connect(); err != nil {
|
||||
utils.Logger.Err(fmt.Sprintf("<%s> error: %s!", utils.SessionS, err))
|
||||
@@ -217,7 +217,7 @@ func startAsteriskAgent(internalSMGChan chan rpcclient.RpcClientConnection, exit
|
||||
utils.Logger.Info("Starting Asterisk agent")
|
||||
smgRpcConn := <-internalSMGChan
|
||||
internalSMGChan <- smgRpcConn
|
||||
birpcClnt := utils.NewBiRPCInternalClient(smgRpcConn.(*sessionmanager.SMGeneric))
|
||||
birpcClnt := utils.NewBiRPCInternalClient(smgRpcConn.(*sessions.SMGeneric))
|
||||
for connIdx := range cfg.AsteriskAgentCfg().AsteriskConns { // Instantiate connections towards asterisk servers
|
||||
sma, err := agents.NewSMAsterisk(cfg, connIdx, birpcClnt)
|
||||
if err != nil {
|
||||
@@ -297,8 +297,8 @@ func startFsAgent(internalSMGChan chan rpcclient.RpcClientConnection, exitChan c
|
||||
utils.Logger.Info("Starting FreeSWITCH agent")
|
||||
smgRpcConn := <-internalSMGChan
|
||||
internalSMGChan <- smgRpcConn
|
||||
birpcClnt := utils.NewBiRPCInternalClient(smgRpcConn.(*sessionmanager.SMGeneric))
|
||||
sm := agents.NewFSSessionManager(cfg.FsAgentCfg(), birpcClnt, cfg.DefaultTimezone)
|
||||
birpcClnt := utils.NewBiRPCInternalClient(smgRpcConn.(*sessions.SMGeneric))
|
||||
sm := agents.NewFSsessions(cfg.FsAgentCfg(), birpcClnt, cfg.DefaultTimezone)
|
||||
if err = sm.Connect(); err != nil {
|
||||
utils.Logger.Err(fmt.Sprintf("<%s> error: %s!", utils.FreeSWITCHAgent, err))
|
||||
}
|
||||
@@ -310,7 +310,7 @@ func startKamAgent(internalSMGChan chan rpcclient.RpcClientConnection, exitChan
|
||||
utils.Logger.Info("Starting Kamailio agent")
|
||||
smgRpcConn := <-internalSMGChan
|
||||
internalSMGChan <- smgRpcConn
|
||||
birpcClnt := utils.NewBiRPCInternalClient(smgRpcConn.(*sessionmanager.SMGeneric))
|
||||
birpcClnt := utils.NewBiRPCInternalClient(smgRpcConn.(*sessions.SMGeneric))
|
||||
ka := agents.NewKamailioAgent(cfg.KamAgentCfg(),
|
||||
birpcClnt, utils.FirstNonEmpty(cfg.KamAgentCfg().Timezone, cfg.DefaultTimezone))
|
||||
|
||||
|
||||
@@ -279,7 +279,6 @@ func startRater(internalRaterChan chan rpcclient.RpcClientConnection, cacheDoneC
|
||||
utils.RegisterRpcParams("UsersV1", &engine.UserMap{})
|
||||
utils.RegisterRpcParams("", &v1.CdrsV1{})
|
||||
utils.RegisterRpcParams("", &v2.CdrsV2{})
|
||||
utils.RegisterRpcParams("", &v1.SessionManagerV1{})
|
||||
utils.RegisterRpcParams("", &v1.SMGenericV1{})
|
||||
utils.RegisterRpcParams("", responder)
|
||||
utils.RegisterRpcParams("", apierRpcV1)
|
||||
|
||||
@@ -19,7 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
package console
|
||||
|
||||
import (
|
||||
"github.com/cgrates/cgrates/sessionmanager"
|
||||
"github.com/cgrates/cgrates/sessions"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
@@ -62,6 +62,6 @@ func (self *CmdActiveSessions) PostprocessRpcParams() error {
|
||||
}
|
||||
|
||||
func (self *CmdActiveSessions) RpcResult() interface{} {
|
||||
var sessions *[]*sessionmanager.ActiveSession
|
||||
var sessions *[]*sessions.ActiveSession
|
||||
return &sessions
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
package console
|
||||
|
||||
import (
|
||||
"github.com/cgrates/cgrates/sessionmanager"
|
||||
"github.com/cgrates/cgrates/sessions"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
@@ -62,6 +62,6 @@ func (self *CmdPassiveSessions) PostprocessRpcParams() error {
|
||||
}
|
||||
|
||||
func (self *CmdPassiveSessions) RpcResult() interface{} {
|
||||
var sessions *[]*sessionmanager.ActiveSession
|
||||
var sessions *[]*sessions.ActiveSession
|
||||
return &sessions
|
||||
}
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
/*
|
||||
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 console
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/cgrates/cgrates/sessionmanager"
|
||||
)
|
||||
|
||||
type AttrSmgEvent struct {
|
||||
Method string // shoul be ignored after RPC call
|
||||
sessionmanager.SMGenericEvent
|
||||
}
|
||||
|
||||
func init() {
|
||||
c := &CmdSmgEvent{
|
||||
name: "smg_event",
|
||||
}
|
||||
commands[c.Name()] = c
|
||||
c.CommandExecuter = &CommandExecuter{c}
|
||||
}
|
||||
|
||||
// Commander implementation
|
||||
type CmdSmgEvent struct {
|
||||
name string
|
||||
rpcMethod string
|
||||
rpcParams interface{}
|
||||
*CommandExecuter
|
||||
}
|
||||
|
||||
func (self *CmdSmgEvent) Name() string {
|
||||
return self.name
|
||||
}
|
||||
|
||||
func (self *CmdSmgEvent) RpcMethod() string {
|
||||
return self.rpcMethod
|
||||
}
|
||||
|
||||
func (self *CmdSmgEvent) RpcParams(reset bool) interface{} {
|
||||
if reset || self.rpcParams == nil {
|
||||
self.rpcParams = &AttrSmgEvent{}
|
||||
}
|
||||
return self.rpcParams
|
||||
}
|
||||
|
||||
func (self *CmdSmgEvent) PostprocessRpcParams() error {
|
||||
param := self.rpcParams.(*AttrSmgEvent)
|
||||
self.rpcMethod = "SMGenericV1." + param.Method
|
||||
self.rpcParams = param.SMGenericEvent
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *CmdSmgEvent) RpcResult() interface{} {
|
||||
methodElems := strings.Split(self.rpcMethod, ".")
|
||||
if len(methodElems) != 2 {
|
||||
return nil
|
||||
}
|
||||
switch methodElems[1] {
|
||||
case "SessionEnd", "ChargeEvent", "ProcessCdr":
|
||||
var s string
|
||||
return &s
|
||||
case "SessionStart", "SessionUpdate", "GetMaxUsage":
|
||||
var f float64
|
||||
return &f
|
||||
case "GetLcrSuppliers":
|
||||
ss := make([]string, 0)
|
||||
return ss
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1,316 +0,0 @@
|
||||
/*
|
||||
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 (
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
"github.com/cgrates/osipsdagram"
|
||||
)
|
||||
|
||||
/*
|
||||
/*&{Name:E_ACC_CDR AttrValues:map[to_tag:5ec6e925 cgr_account:dan setuptime:1 created:1406312794 method:INVITE callid:Y2I5ZDYzMDkzM2YzYjhlZjA2Y2ZhZTJmZTc4MGU4NDI.
|
||||
// sip_reason:OK time:1406312795 cgr_reqtype:prepaid cgr_destination:dan cgr_subject:dan sip_code:200 duration:7 from_tag:a5716471] Values:[]}*/
|
||||
|
||||
const (
|
||||
FROM_TAG = "from_tag"
|
||||
TO_TAG = "to_tag"
|
||||
CALLID = "callid"
|
||||
CGR_CATEGORY = "cgr_category"
|
||||
CGR_REQTYPE = "cgr_reqtype"
|
||||
CGR_TENANT = "cgr_tenant"
|
||||
CGR_SUBJECT = "cgr_subject"
|
||||
CGR_ACCOUNT = "cgr_account"
|
||||
CGR_DESTINATION = "cgr_destination"
|
||||
TIME = "time"
|
||||
SETUP_DURATION = "setuptime"
|
||||
OSIPS_SETUP_TIME = "created"
|
||||
OSIPS_EVENT_TIME = "time"
|
||||
OSIPS_DURATION = "duration"
|
||||
OSIPS_AUTH_OK = "AUTH_OK"
|
||||
OSIPS_INSUFFICIENT_FUNDS = "INSUFFICIENT_FUNDS"
|
||||
OSIPS_DIALOG_ID = "dialog_id"
|
||||
OSIPS_SIPCODE = "sip_code"
|
||||
CGR_SETUPTIME = "cgr_setuptime"
|
||||
CGR_ANSWERTIME = "cgr_answertime"
|
||||
CGR_STOPTIME = "cgr_stoptime"
|
||||
CGR_DURATION = "cgr_duration"
|
||||
CGR_PDD = "cgr_pdd"
|
||||
)
|
||||
|
||||
func NewOsipsEvent(osipsDagramEvent *osipsdagram.OsipsEvent) (*OsipsEvent, error) {
|
||||
return &OsipsEvent{osipsEvent: osipsDagramEvent}, nil
|
||||
}
|
||||
|
||||
type OsipsEvent struct {
|
||||
osipsEvent *osipsdagram.OsipsEvent
|
||||
}
|
||||
|
||||
func (osipsev *OsipsEvent) AsEvent(evStr string) engine.Event {
|
||||
return osipsev
|
||||
}
|
||||
|
||||
func (osipsev *OsipsEvent) String() string {
|
||||
mrsh, _ := json.Marshal(osipsev)
|
||||
return string(mrsh)
|
||||
}
|
||||
|
||||
func (osipsev *OsipsEvent) GetName() string {
|
||||
return osipsev.osipsEvent.Name
|
||||
}
|
||||
|
||||
func (osipsev *OsipsEvent) GetCgrId(timezone string) string {
|
||||
setupTime, _ := osipsev.GetSetupTime(utils.META_DEFAULT, timezone)
|
||||
return utils.Sha1(osipsev.GetUUID(), setupTime.UTC().String())
|
||||
}
|
||||
|
||||
func (osipsev *OsipsEvent) GetUUID() string {
|
||||
return osipsev.osipsEvent.AttrValues[CALLID]
|
||||
}
|
||||
|
||||
// Returns the dialog identifier which opensips needs to disconnect a dialog
|
||||
func (osipsev *OsipsEvent) GetSessionIds() []string {
|
||||
return strings.Split(osipsev.osipsEvent.AttrValues[OSIPS_DIALOG_ID], ":")
|
||||
}
|
||||
|
||||
func (osipsev *OsipsEvent) GetDirection(fieldName string) string {
|
||||
if strings.HasPrefix(fieldName, utils.STATIC_VALUE_PREFIX) { // Static value
|
||||
return fieldName[len(utils.STATIC_VALUE_PREFIX):]
|
||||
}
|
||||
return utils.OUT
|
||||
}
|
||||
|
||||
// Account being charged
|
||||
func (osipsev *OsipsEvent) GetAccount(fieldName string) string {
|
||||
if strings.HasPrefix(fieldName, utils.STATIC_VALUE_PREFIX) { // Static value
|
||||
return fieldName[len(utils.STATIC_VALUE_PREFIX):]
|
||||
}
|
||||
return utils.FirstNonEmpty(osipsev.osipsEvent.AttrValues[fieldName], osipsev.osipsEvent.AttrValues[CGR_ACCOUNT])
|
||||
}
|
||||
|
||||
// Rating subject being charged, falls back on account if missing
|
||||
func (osipsev *OsipsEvent) GetSubject(fieldName string) string {
|
||||
if strings.HasPrefix(fieldName, utils.STATIC_VALUE_PREFIX) { // Static value
|
||||
return fieldName[len(utils.STATIC_VALUE_PREFIX):]
|
||||
}
|
||||
return utils.FirstNonEmpty(osipsev.osipsEvent.AttrValues[fieldName], osipsev.osipsEvent.AttrValues[CGR_SUBJECT], osipsev.GetAccount(fieldName))
|
||||
}
|
||||
|
||||
func (osipsev *OsipsEvent) GetDestination(fieldName string) string {
|
||||
if strings.HasPrefix(fieldName, utils.STATIC_VALUE_PREFIX) { // Static value
|
||||
return fieldName[len(utils.STATIC_VALUE_PREFIX):]
|
||||
}
|
||||
return utils.FirstNonEmpty(osipsev.osipsEvent.AttrValues[fieldName], osipsev.osipsEvent.AttrValues[CGR_DESTINATION])
|
||||
}
|
||||
|
||||
func (osipsev *OsipsEvent) GetCallDestNr(fieldName string) string {
|
||||
return osipsev.GetDestination(fieldName)
|
||||
}
|
||||
|
||||
func (osipsev *OsipsEvent) GetCategory(fieldName string) string {
|
||||
if strings.HasPrefix(fieldName, utils.STATIC_VALUE_PREFIX) { // Static value
|
||||
return fieldName[len(utils.STATIC_VALUE_PREFIX):]
|
||||
}
|
||||
return utils.FirstNonEmpty(osipsev.osipsEvent.AttrValues[fieldName], osipsev.osipsEvent.AttrValues[CGR_CATEGORY], config.CgrConfig().DefaultCategory)
|
||||
}
|
||||
|
||||
func (osipsev *OsipsEvent) GetTenant(fieldName string) string {
|
||||
if strings.HasPrefix(fieldName, utils.STATIC_VALUE_PREFIX) { // Static value
|
||||
return fieldName[len(utils.STATIC_VALUE_PREFIX):]
|
||||
}
|
||||
return utils.FirstNonEmpty(osipsev.osipsEvent.AttrValues[fieldName], osipsev.osipsEvent.AttrValues[CGR_TENANT], config.CgrConfig().DefaultTenant)
|
||||
}
|
||||
func (osipsev *OsipsEvent) GetReqType(fieldName string) string {
|
||||
if strings.HasPrefix(fieldName, utils.STATIC_VALUE_PREFIX) { // Static value
|
||||
return fieldName[len(utils.STATIC_VALUE_PREFIX):]
|
||||
}
|
||||
return utils.FirstNonEmpty(osipsev.osipsEvent.AttrValues[fieldName], osipsev.osipsEvent.AttrValues[CGR_REQTYPE], config.CgrConfig().DefaultReqType)
|
||||
}
|
||||
func (osipsev *OsipsEvent) GetSetupTime(fieldName, timezone string) (time.Time, error) {
|
||||
sTimeStr := utils.FirstNonEmpty(osipsev.osipsEvent.AttrValues[fieldName], osipsev.osipsEvent.AttrValues[OSIPS_SETUP_TIME], osipsev.osipsEvent.AttrValues[OSIPS_EVENT_TIME])
|
||||
if strings.HasPrefix(fieldName, utils.STATIC_VALUE_PREFIX) { // Static value
|
||||
sTimeStr = fieldName[len(utils.STATIC_VALUE_PREFIX):]
|
||||
}
|
||||
return utils.ParseTimeDetectLayout(sTimeStr, timezone)
|
||||
}
|
||||
func (osipsev *OsipsEvent) GetAnswerTime(fieldName, timezone string) (time.Time, error) {
|
||||
aTimeStr := utils.FirstNonEmpty(osipsev.osipsEvent.AttrValues[fieldName], osipsev.osipsEvent.AttrValues[CGR_ANSWERTIME])
|
||||
if strings.HasPrefix(fieldName, utils.STATIC_VALUE_PREFIX) { // Static value
|
||||
aTimeStr = fieldName[len(utils.STATIC_VALUE_PREFIX):]
|
||||
} else if fieldName == utils.META_DEFAULT {
|
||||
aTimeStr = osipsev.osipsEvent.AttrValues[CGR_ANSWERTIME]
|
||||
}
|
||||
return utils.ParseTimeDetectLayout(aTimeStr, timezone)
|
||||
}
|
||||
func (osipsev *OsipsEvent) GetEndTime(fieldName, timezone string) (time.Time, error) {
|
||||
var nilTime time.Time
|
||||
aTime, err := osipsev.GetAnswerTime(utils.META_DEFAULT, timezone)
|
||||
if err != nil {
|
||||
return nilTime, err
|
||||
}
|
||||
dur, err := osipsev.GetDuration(utils.META_DEFAULT)
|
||||
if err != nil {
|
||||
return nilTime, err
|
||||
}
|
||||
return aTime.Add(dur), nil
|
||||
}
|
||||
func (osipsev *OsipsEvent) GetDuration(fieldName string) (time.Duration, error) {
|
||||
durStr := utils.FirstNonEmpty(osipsev.osipsEvent.AttrValues[fieldName], osipsev.osipsEvent.AttrValues[OSIPS_DURATION])
|
||||
if strings.HasPrefix(fieldName, utils.STATIC_VALUE_PREFIX) { // Static value
|
||||
durStr = fieldName[len(utils.STATIC_VALUE_PREFIX):]
|
||||
}
|
||||
return utils.ParseDurationWithSecs(durStr)
|
||||
}
|
||||
func (osipsev *OsipsEvent) GetPdd(fieldName string) (time.Duration, error) {
|
||||
var pddStr string
|
||||
if utils.IsSliceMember([]string{utils.PDD, utils.META_DEFAULT}, fieldName) {
|
||||
pddStr = osipsev.osipsEvent.AttrValues[CGR_PDD]
|
||||
} else if strings.HasPrefix(fieldName, utils.STATIC_VALUE_PREFIX) { // Static value
|
||||
pddStr = fieldName[len(utils.STATIC_VALUE_PREFIX):]
|
||||
} else {
|
||||
pddStr = osipsev.osipsEvent.AttrValues[fieldName]
|
||||
}
|
||||
return utils.ParseDurationWithSecs(pddStr)
|
||||
}
|
||||
func (osipsev *OsipsEvent) GetSupplier(fieldName string) string {
|
||||
if strings.HasPrefix(fieldName, utils.STATIC_VALUE_PREFIX) { // Static value
|
||||
return fieldName[len(utils.STATIC_VALUE_PREFIX):]
|
||||
}
|
||||
return utils.FirstNonEmpty(osipsev.osipsEvent.AttrValues[fieldName], osipsev.osipsEvent.AttrValues[utils.CGR_SUPPLIER])
|
||||
}
|
||||
func (osipsev *OsipsEvent) GetDisconnectCause(fieldName string) string {
|
||||
if strings.HasPrefix(fieldName, utils.STATIC_VALUE_PREFIX) { // Static value
|
||||
return fieldName[len(utils.STATIC_VALUE_PREFIX):]
|
||||
}
|
||||
return utils.FirstNonEmpty(osipsev.osipsEvent.AttrValues[fieldName], osipsev.osipsEvent.AttrValues[OSIPS_SIPCODE], osipsev.osipsEvent.AttrValues[utils.DISCONNECT_CAUSE])
|
||||
}
|
||||
func (osipsEv *OsipsEvent) GetOriginatorIP(fieldName string) string {
|
||||
if osipsEv.osipsEvent == nil || osipsEv.osipsEvent.OriginatorAddress == nil {
|
||||
return ""
|
||||
}
|
||||
return osipsEv.osipsEvent.OriginatorAddress.IP.String()
|
||||
}
|
||||
func (osipsev *OsipsEvent) MissingParameter(timezone string) bool {
|
||||
var nilTime time.Time
|
||||
if osipsev.GetName() == "E_ACC_EVENT" && osipsev.osipsEvent.AttrValues["method"] == "INVITE" {
|
||||
return len(osipsev.GetUUID()) == 0 ||
|
||||
len(osipsev.GetAccount(utils.META_DEFAULT)) == 0 ||
|
||||
len(osipsev.GetDestination(utils.META_DEFAULT)) == 0 ||
|
||||
len(osipsev.osipsEvent.AttrValues[OSIPS_DIALOG_ID]) == 0
|
||||
} else if osipsev.GetName() == "E_ACC_EVENT" && osipsev.osipsEvent.AttrValues["method"] == "BYE" {
|
||||
return len(osipsev.osipsEvent.AttrValues[OSIPS_DIALOG_ID]) == 0 ||
|
||||
len(osipsev.osipsEvent.AttrValues[TIME]) == 0
|
||||
} else if osipsev.GetName() == "E_ACC_EVENT" && osipsev.osipsEvent.AttrValues["method"] == "UPDATE" { // Updated event out of start/stop
|
||||
// Data needed when stopping a prepaid loop or building a CDR with start/stop event
|
||||
setupTime, err := osipsev.GetSetupTime(TIME, timezone)
|
||||
if err != nil || setupTime.Equal(nilTime) {
|
||||
return true
|
||||
}
|
||||
aTime, err := osipsev.GetAnswerTime(utils.META_DEFAULT, timezone)
|
||||
if err != nil || aTime.Equal(nilTime) {
|
||||
return true
|
||||
}
|
||||
endTime, err := osipsev.GetEndTime(utils.META_DEFAULT, timezone)
|
||||
if err != nil || endTime.Equal(nilTime) {
|
||||
return true
|
||||
}
|
||||
_, err = osipsev.GetDuration(utils.META_DEFAULT)
|
||||
if err != nil {
|
||||
return true
|
||||
}
|
||||
if osipsev.osipsEvent.AttrValues[OSIPS_DIALOG_ID] == "" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
func (osipsev *OsipsEvent) ParseEventValue(fld *utils.RSRField, timezone string) string {
|
||||
return ""
|
||||
}
|
||||
func (osipsev *OsipsEvent) PassesFieldFilter(*utils.RSRField) (bool, string) {
|
||||
return false, ""
|
||||
}
|
||||
func (osipsev *OsipsEvent) GetExtraFields() map[string]string {
|
||||
primaryFields := []string{TO_TAG, SETUP_DURATION, OSIPS_SETUP_TIME, "method", "callid", "sip_reason", OSIPS_EVENT_TIME, "sip_code", "duration", "from_tag", "dialog_id",
|
||||
CGR_TENANT, CGR_CATEGORY, CGR_REQTYPE, CGR_ACCOUNT, CGR_SUBJECT, CGR_DESTINATION, utils.CGR_SUPPLIER, CGR_PDD, CGR_ANSWERTIME}
|
||||
extraFields := make(map[string]string)
|
||||
for field, val := range osipsev.osipsEvent.AttrValues {
|
||||
if !utils.IsSliceMember(primaryFields, field) {
|
||||
extraFields[field] = val
|
||||
}
|
||||
}
|
||||
return extraFields
|
||||
}
|
||||
|
||||
func (osipsev *OsipsEvent) DialogId() string {
|
||||
return osipsev.osipsEvent.AttrValues[OSIPS_DIALOG_ID]
|
||||
}
|
||||
|
||||
func (osipsEv *OsipsEvent) AsCDR(timezone string) *engine.CDR {
|
||||
storCdr := new(engine.CDR)
|
||||
storCdr.CGRID = osipsEv.GetCgrId(timezone)
|
||||
storCdr.ToR = utils.VOICE
|
||||
storCdr.OriginID = osipsEv.GetUUID()
|
||||
storCdr.OriginHost = osipsEv.GetOriginatorIP(utils.META_DEFAULT)
|
||||
storCdr.Source = "OSIPS_" + osipsEv.GetName()
|
||||
storCdr.RequestType = osipsEv.GetReqType(utils.META_DEFAULT)
|
||||
storCdr.Tenant = osipsEv.GetTenant(utils.META_DEFAULT)
|
||||
storCdr.Category = osipsEv.GetCategory(utils.META_DEFAULT)
|
||||
storCdr.Account = osipsEv.GetAccount(utils.META_DEFAULT)
|
||||
storCdr.Subject = osipsEv.GetSubject(utils.META_DEFAULT)
|
||||
storCdr.Destination = osipsEv.GetDestination(utils.META_DEFAULT)
|
||||
storCdr.SetupTime, _ = osipsEv.GetSetupTime(utils.META_DEFAULT, timezone)
|
||||
storCdr.AnswerTime, _ = osipsEv.GetAnswerTime(utils.META_DEFAULT, timezone)
|
||||
storCdr.Usage, _ = osipsEv.GetDuration(utils.META_DEFAULT)
|
||||
storCdr.ExtraFields = osipsEv.GetExtraFields()
|
||||
storCdr.Cost = -1
|
||||
return storCdr
|
||||
}
|
||||
|
||||
// Computes duration out of setup time of the callEnd
|
||||
func (osipsEv *OsipsEvent) updateDurationFromEvent(updatedOsipsEv *OsipsEvent) error {
|
||||
endTime, err := updatedOsipsEv.GetSetupTime(TIME, config.CgrConfig().DefaultTimezone)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
answerTime, err := osipsEv.GetAnswerTime(utils.META_DEFAULT, config.CgrConfig().DefaultTimezone)
|
||||
osipsEv.osipsEvent.AttrValues[OSIPS_DURATION] = endTime.Sub(answerTime).String()
|
||||
osipsEv.osipsEvent.AttrValues["method"] = "UPDATE" // So we can know it is an end event
|
||||
osipsEv.osipsEvent.AttrValues[OSIPS_SIPCODE] = updatedOsipsEv.osipsEvent.AttrValues[OSIPS_SIPCODE]
|
||||
return nil
|
||||
}
|
||||
|
||||
func (osipsEv *OsipsEvent) ComputeLcr() bool {
|
||||
if computeLcr, err := strconv.ParseBool(osipsEv.osipsEvent.AttrValues[utils.CGR_COMPUTELCR]); err != nil {
|
||||
return false
|
||||
} else {
|
||||
return computeLcr
|
||||
}
|
||||
}
|
||||
|
||||
func (osipsEv *OsipsEvent) AsMapStringIface() (map[string]interface{}, error) {
|
||||
return nil, utils.ErrNotImplemented
|
||||
}
|
||||
@@ -1,202 +0,0 @@
|
||||
/*
|
||||
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 (
|
||||
"net"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
"github.com/cgrates/osipsdagram"
|
||||
)
|
||||
|
||||
var addr, _ = net.ResolveUDPAddr("udp", "172.16.254.77:42574")
|
||||
var osipsEv = &OsipsEvent{osipsEvent: &osipsdagram.OsipsEvent{Name: "E_ACC_CDR",
|
||||
AttrValues: map[string]string{"to_tag": "4ea9687f", "cgr_account": "dan", "setuptime": "7", "created": "1406370492", "method": "INVITE", "callid": "ODVkMDI2Mzc2MDY5N2EzODhjNTAzNTdlODhiZjRlYWQ",
|
||||
"sip_reason": "OK", "cgr_answertime": "1406370499", "time": "1406370499", "cgr_reqtype": utils.META_PREPAID, "cgr_subject": "dan", "cgr_destination": "+4986517174963", "cgr_tenant": "itsyscom.com", "sip_code": "200",
|
||||
"duration": "20", CGR_PDD: "3s", "from_tag": "eb082607", "extra1": "val1", "extra2": "val2", "cgr_supplier": "supplier3"}, OriginatorAddress: addr}}
|
||||
|
||||
func TestOsipsEventInterface(t *testing.T) {
|
||||
var _ engine.Event = engine.Event(osipsEv)
|
||||
}
|
||||
|
||||
func TestOsipsEventParseStatic(t *testing.T) {
|
||||
setupTime, _ := osipsEv.GetSetupTime("^2013-12-07 08:42:24", "")
|
||||
answerTime, _ := osipsEv.GetAnswerTime("^2013-12-07 08:42:24", "")
|
||||
dur, _ := osipsEv.GetDuration("^60s")
|
||||
PDD, _ := osipsEv.GetPdd("^10s")
|
||||
if osipsEv.GetReqType("^test") != "test" ||
|
||||
osipsEv.GetDirection("^test") != "test" ||
|
||||
osipsEv.GetTenant("^test") != "test" ||
|
||||
osipsEv.GetCategory("^test") != "test" ||
|
||||
osipsEv.GetAccount("^test") != "test" ||
|
||||
osipsEv.GetSubject("^test") != "test" ||
|
||||
osipsEv.GetDestination("^test") != "test" ||
|
||||
setupTime != time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC) ||
|
||||
answerTime != time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC) ||
|
||||
dur != time.Duration(60)*time.Second ||
|
||||
PDD != time.Duration(10)*time.Second ||
|
||||
osipsEv.GetSupplier("^test") != "test" ||
|
||||
osipsEv.GetDisconnectCause("^test") != "test" {
|
||||
t.Error("Values out of static not matching",
|
||||
osipsEv.GetReqType("^test") != "test",
|
||||
osipsEv.GetDirection("^test") != "test",
|
||||
osipsEv.GetTenant("^test") != "test",
|
||||
osipsEv.GetCategory("^test") != "test",
|
||||
osipsEv.GetAccount("^test") != "test",
|
||||
osipsEv.GetSubject("^test") != "test",
|
||||
osipsEv.GetDestination("^test") != "test",
|
||||
setupTime != time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC),
|
||||
answerTime != time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC),
|
||||
dur != time.Duration(60)*time.Second,
|
||||
PDD != time.Duration(10)*time.Second,
|
||||
osipsEv.GetSupplier("^test") != "test",
|
||||
osipsEv.GetDisconnectCause("^test") != "test")
|
||||
}
|
||||
}
|
||||
|
||||
func TestOsipsEventGetValues(t *testing.T) {
|
||||
cfg, _ := config.NewDefaultCGRConfig()
|
||||
config.SetCgrConfig(cfg)
|
||||
setupTime, _ := osipsEv.GetSetupTime(utils.META_DEFAULT, "")
|
||||
eSetupTime, _ := utils.ParseTimeDetectLayout("1406370492", "")
|
||||
answerTime, _ := osipsEv.GetAnswerTime(utils.META_DEFAULT, "")
|
||||
eAnswerTime, _ := utils.ParseTimeDetectLayout("1406370499", "")
|
||||
dur, _ := osipsEv.GetDuration(utils.META_DEFAULT)
|
||||
PDD, _ := osipsEv.GetPdd(utils.META_DEFAULT)
|
||||
endTime, _ := osipsEv.GetEndTime(utils.META_DEFAULT, "")
|
||||
if osipsEv.GetName() != "E_ACC_CDR" ||
|
||||
osipsEv.GetCgrId("") != utils.Sha1("ODVkMDI2Mzc2MDY5N2EzODhjNTAzNTdlODhiZjRlYWQ", setupTime.UTC().String()) ||
|
||||
osipsEv.GetUUID() != "ODVkMDI2Mzc2MDY5N2EzODhjNTAzNTdlODhiZjRlYWQ" ||
|
||||
osipsEv.GetDirection(utils.META_DEFAULT) != utils.OUT ||
|
||||
osipsEv.GetSubject(utils.META_DEFAULT) != "dan" ||
|
||||
osipsEv.GetAccount(utils.META_DEFAULT) != "dan" ||
|
||||
osipsEv.GetDestination(utils.META_DEFAULT) != "+4986517174963" ||
|
||||
osipsEv.GetCallDestNr(utils.META_DEFAULT) != "+4986517174963" ||
|
||||
osipsEv.GetCategory(utils.META_DEFAULT) != cfg.DefaultCategory ||
|
||||
osipsEv.GetTenant(utils.META_DEFAULT) != "itsyscom.com" ||
|
||||
osipsEv.GetReqType(utils.META_DEFAULT) != utils.META_PREPAID ||
|
||||
!setupTime.Equal(eSetupTime) ||
|
||||
!answerTime.Equal(eAnswerTime) ||
|
||||
!endTime.Equal(eAnswerTime.Add(dur)) ||
|
||||
dur != time.Duration(20*time.Second) ||
|
||||
PDD != time.Duration(3)*time.Second ||
|
||||
osipsEv.GetSupplier(utils.META_DEFAULT) != "supplier3" ||
|
||||
osipsEv.GetDisconnectCause(utils.META_DEFAULT) != "200" ||
|
||||
osipsEv.GetOriginatorIP(utils.META_DEFAULT) != "172.16.254.77" {
|
||||
t.Error("GetValues not matching: ", osipsEv.GetName() != "E_ACC_CDR",
|
||||
osipsEv.GetCgrId("") != utils.Sha1("ODVkMDI2Mzc2MDY5N2EzODhjNTAzNTdlODhiZjRlYWQ", setupTime.UTC().String()),
|
||||
osipsEv.GetUUID() != "ODVkMDI2Mzc2MDY5N2EzODhjNTAzNTdlODhiZjRlYWQ",
|
||||
osipsEv.GetDirection(utils.META_DEFAULT) != utils.OUT,
|
||||
osipsEv.GetSubject(utils.META_DEFAULT) != "dan",
|
||||
osipsEv.GetAccount(utils.META_DEFAULT) != "dan",
|
||||
osipsEv.GetDestination(utils.META_DEFAULT) != "+4986517174963",
|
||||
osipsEv.GetCallDestNr(utils.META_DEFAULT) != "+4986517174963",
|
||||
osipsEv.GetCategory(utils.META_DEFAULT) != cfg.DefaultCategory,
|
||||
osipsEv.GetTenant(utils.META_DEFAULT) != "itsyscom.com",
|
||||
osipsEv.GetReqType(utils.META_DEFAULT) != utils.META_PREPAID,
|
||||
!setupTime.Equal(time.Date(2014, 7, 26, 12, 28, 12, 0, time.UTC)),
|
||||
!answerTime.Equal(time.Date(2014, 7, 26, 12, 28, 19, 0, time.Local)),
|
||||
!endTime.Equal(time.Date(2014, 7, 26, 12, 28, 39, 0, time.Local)),
|
||||
dur != time.Duration(20*time.Second),
|
||||
PDD != time.Duration(3)*time.Second,
|
||||
osipsEv.GetSupplier(utils.META_DEFAULT) != "supplier3",
|
||||
osipsEv.GetDisconnectCause(utils.META_DEFAULT) != "200",
|
||||
osipsEv.GetOriginatorIP(utils.META_DEFAULT) != "172.16.254.77",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestOsipsEventMissingParameter(t *testing.T) {
|
||||
if !osipsEv.MissingParameter("") {
|
||||
t.Errorf("Wrongly detected missing parameter: %+v", osipsEv)
|
||||
}
|
||||
osipsEv2 := &OsipsEvent{osipsEvent: &osipsdagram.OsipsEvent{Name: "E_ACC_CDR",
|
||||
AttrValues: map[string]string{"to_tag": "4ea9687f", "cgr_account": "dan", "setuptime": "7", "created": "1406370492", "method": "INVITE", "callid": "ODVkMDI2Mzc2MDY5N2EzODhjNTAzNTdlODhiZjRlYWQ",
|
||||
"sip_reason": "OK", "time": "1406370499", "cgr_reqtype": utils.META_PREPAID, "cgr_subject": "dan", "cgr_tenant": "itsyscom.com", "sip_code": "200",
|
||||
"duration": "20", "from_tag": "eb082607"}}}
|
||||
if !osipsEv2.MissingParameter("") {
|
||||
t.Error("Failed to detect missing parameter.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestOsipsEventAsCDR(t *testing.T) {
|
||||
setupTime, _ := utils.ParseTimeDetectLayout("1406370492", "")
|
||||
answerTime, _ := utils.ParseTimeDetectLayout("1406370499", "")
|
||||
eStoredCdr := &engine.CDR{
|
||||
CGRID: utils.Sha1("ODVkMDI2Mzc2MDY5N2EzODhjNTAzNTdlODhiZjRlYWQ", setupTime.UTC().String()),
|
||||
ToR: utils.VOICE, OriginID: "ODVkMDI2Mzc2MDY5N2EzODhjNTAzNTdlODhiZjRlYWQ",
|
||||
OriginHost: "172.16.254.77", Source: "OSIPS_E_ACC_CDR",
|
||||
RequestType: utils.META_PREPAID,
|
||||
Tenant: "itsyscom.com", Category: "call", Account: "dan", Subject: "dan",
|
||||
Destination: "+4986517174963", SetupTime: setupTime, AnswerTime: answerTime,
|
||||
Usage: time.Duration(20) * time.Second,
|
||||
ExtraFields: map[string]string{"extra1": "val1", "extra2": "val2"}, Cost: -1}
|
||||
if storedCdr := osipsEv.AsCDR(""); !reflect.DeepEqual(eStoredCdr, storedCdr) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", eStoredCdr, storedCdr)
|
||||
}
|
||||
}
|
||||
|
||||
func TestOsipsAccMissedToStoredCdr(t *testing.T) {
|
||||
setupTime, _ := utils.ParseTimeDetectLayout("1431182699", "")
|
||||
osipsEv := &OsipsEvent{osipsEvent: &osipsdagram.OsipsEvent{Name: "E_ACC_MISSED_EVENT",
|
||||
AttrValues: map[string]string{"method": "INVITE", "from_tag": "5cb81eaa", "to_tag": "", "callid": "27b1e6679ad0109b5d756e42bb4c9c28@0:0:0:0:0:0:0:0",
|
||||
"sip_code": "404", "sip_reason": "Not Found", "time": "1431182699", "cgr_answertime": "1431182699", "cgr_reqtype": utils.META_PSEUDOPREPAID,
|
||||
"cgr_account": "1001", "cgr_destination": "1002", utils.CGR_SUPPLIER: "supplier1",
|
||||
"duration": "", "dialog_id": "3547:277000822", "extra1": "val1", "extra2": "val2"}, OriginatorAddress: addr,
|
||||
}}
|
||||
eStoredCdr := &engine.CDR{CGRID: utils.Sha1("27b1e6679ad0109b5d756e42bb4c9c28@0:0:0:0:0:0:0:0", setupTime.UTC().String()),
|
||||
ToR: utils.VOICE, OriginID: "27b1e6679ad0109b5d756e42bb4c9c28@0:0:0:0:0:0:0:0", OriginHost: "172.16.254.77", Source: "OSIPS_E_ACC_MISSED_EVENT",
|
||||
RequestType: utils.META_PSEUDOPREPAID, Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001",
|
||||
Destination: "1002", SetupTime: setupTime, AnswerTime: setupTime,
|
||||
Usage: time.Duration(0), ExtraFields: map[string]string{"extra1": "val1", "extra2": "val2"}, Cost: -1}
|
||||
if storedCdr := osipsEv.AsCDR(""); !reflect.DeepEqual(eStoredCdr, storedCdr) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", eStoredCdr, storedCdr)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestOsipsUpdateDurationFromEvent(t *testing.T) {
|
||||
osipsEv := &OsipsEvent{osipsEvent: &osipsdagram.OsipsEvent{Name: "E_ACC_EVENT",
|
||||
AttrValues: map[string]string{"method": "INVITE", "from_tag": "87d02470", "to_tag": "a671a98", "callid": "05dac0aaa716c9814f855f0e8fee6936@0:0:0:0:0:0:0:0",
|
||||
"sip_code": "200", "sip_reason": "OK", "time": "1430579770", "cgr_answertime": "1430579770", "cgr_reqtype": utils.META_PREPAID,
|
||||
"cgr_account": "1001", "cgr_destination": "1002", utils.CGR_SUPPLIER: "supplier1",
|
||||
"duration": "", "dialog_id": "3547:277000822", "extra1": "val1", "extra2": "val2"}, OriginatorAddress: addr,
|
||||
}}
|
||||
updatedEv := &OsipsEvent{osipsEvent: &osipsdagram.OsipsEvent{Name: "E_ACC_EVENT",
|
||||
AttrValues: map[string]string{"method": "BYE", "from_tag": "a671a98", "to_tag": "87d02470", "callid": "05dac0aaa716c9814f855f0e8fee6936@0:0:0:0:0:0:0:0",
|
||||
"sip_code": "200", "sip_reason": "OK", "time": "1430579797", "cgr_reqtype": "",
|
||||
"cgr_account": "", "cgr_destination": "", utils.CGR_SUPPLIER: "",
|
||||
"duration": "", "dialog_id": "3547:277000822"}, OriginatorAddress: addr,
|
||||
}}
|
||||
eOsipsEv := &OsipsEvent{osipsEvent: &osipsdagram.OsipsEvent{Name: "E_ACC_EVENT",
|
||||
AttrValues: map[string]string{"method": "UPDATE", "from_tag": "87d02470", "to_tag": "a671a98", "callid": "05dac0aaa716c9814f855f0e8fee6936@0:0:0:0:0:0:0:0",
|
||||
"sip_code": "200", "sip_reason": "OK", "time": "1430579770", "cgr_answertime": "1430579770", "cgr_reqtype": utils.META_PREPAID,
|
||||
"cgr_account": "1001", "cgr_destination": "1002", utils.CGR_SUPPLIER: "supplier1",
|
||||
"duration": "27s", "dialog_id": "3547:277000822", "extra1": "val1", "extra2": "val2"}, OriginatorAddress: addr,
|
||||
}}
|
||||
if err := osipsEv.updateDurationFromEvent(updatedEv); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(eOsipsEv, osipsEv) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", eOsipsEv.osipsEvent, osipsEv.osipsEvent)
|
||||
}
|
||||
}
|
||||
@@ -1,343 +0,0 @@
|
||||
/*
|
||||
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 (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
// Session type holding the call information fields, a session delegate for specific
|
||||
// actions and a channel to signal end of the debit loop.
|
||||
type Session struct {
|
||||
eventStart engine.Event // Store the original event who started this session so we can use it's info later (eg: disconnect, cgrid)
|
||||
stopDebit chan struct{} // Channel to communicate with debit loops when closing the session
|
||||
sessionManager SessionManager
|
||||
connId string // Reference towards connection id on the session manager side.
|
||||
warnMinDur time.Duration
|
||||
sessionRuns []*engine.SessionRun
|
||||
}
|
||||
|
||||
func (s *Session) GetSessionRun(runid string) *engine.SessionRun {
|
||||
for _, sr := range s.sessionRuns {
|
||||
if sr.DerivedCharger.RunID == runid {
|
||||
return sr
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Session) SessionRuns() []*engine.SessionRun {
|
||||
return s.sessionRuns
|
||||
}
|
||||
|
||||
// Creates a new session and in case of prepaid starts the debit loop for each of the session runs individually
|
||||
func NewSession(ev engine.Event, connId string, sm SessionManager) *Session {
|
||||
s := &Session{eventStart: ev,
|
||||
stopDebit: make(chan struct{}),
|
||||
sessionManager: sm,
|
||||
connId: connId,
|
||||
}
|
||||
if err := sm.Rater().Call("Responder.GetSessionRuns", ev.AsCDR(s.sessionManager.Timezone()), &s.sessionRuns); err != nil || len(s.sessionRuns) == 0 {
|
||||
return nil
|
||||
}
|
||||
for runIdx := range s.sessionRuns {
|
||||
go s.debitLoop(runIdx) // Send index of the just appended sessionRun
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// the debit loop method (to be stoped by sending somenthing on stopDebit channel)
|
||||
func (s *Session) debitLoop(runIdx int) {
|
||||
nextCd := s.sessionRuns[runIdx].CallDescriptor
|
||||
nextCd.CgrID = s.eventStart.GetCgrId(s.sessionManager.Timezone())
|
||||
index := 0.0
|
||||
debitPeriod := s.sessionManager.DebitInterval()
|
||||
for {
|
||||
select {
|
||||
case <-s.stopDebit:
|
||||
return
|
||||
default:
|
||||
}
|
||||
if index > 0 { // first time use the session start time
|
||||
nextCd.TimeStart = nextCd.TimeEnd
|
||||
}
|
||||
nextCd.TimeEnd = nextCd.TimeStart.Add(debitPeriod)
|
||||
nextCd.LoopIndex = index
|
||||
nextCd.DurationIndex += debitPeriod // first presumed duration
|
||||
cc := new(engine.CallCost)
|
||||
if err := s.sessionManager.Rater().Call("Responder.MaxDebit", nextCd, cc); err != nil {
|
||||
utils.Logger.Err(fmt.Sprintf("Could not complete debit opperation: %v", err))
|
||||
if err.Error() == utils.ErrUnauthorizedDestination.Error() {
|
||||
s.sessionManager.DisconnectSession(s.eventStart, s.connId, utils.ErrUnauthorizedDestination.Error())
|
||||
return
|
||||
}
|
||||
s.sessionManager.DisconnectSession(s.eventStart, s.connId, utils.ErrServerError.Error())
|
||||
return
|
||||
}
|
||||
if cc.GetDuration() == 0 {
|
||||
s.sessionManager.DisconnectSession(s.eventStart, s.connId, utils.ErrInsufficientCredit.Error())
|
||||
return
|
||||
}
|
||||
if s.warnMinDur != time.Duration(0) && cc.GetDuration() <= s.warnMinDur {
|
||||
s.sessionManager.WarnSessionMinDuration(s.eventStart.GetUUID(), s.connId)
|
||||
}
|
||||
s.sessionRuns[runIdx].CallCosts = append(s.sessionRuns[runIdx].CallCosts, cc)
|
||||
nextCd.TimeEnd = cc.GetEndTime() // set debited timeEnd
|
||||
// update call duration with real debited duration
|
||||
nextCd.DurationIndex -= debitPeriod
|
||||
nextCd.DurationIndex += cc.GetDuration()
|
||||
nextCd.MaxCostSoFar += cc.Cost
|
||||
time.Sleep(cc.GetDuration())
|
||||
index++
|
||||
}
|
||||
}
|
||||
|
||||
// Stops the debit loop
|
||||
func (s *Session) Close(ev engine.Event) error {
|
||||
close(s.stopDebit) // Close the channel so all the sessionRuns listening will be notified
|
||||
if _, err := ev.GetEndTime(utils.META_DEFAULT, s.sessionManager.Timezone()); err != nil {
|
||||
utils.Logger.Err("Error parsing event stop time.")
|
||||
for idx := range s.sessionRuns {
|
||||
s.sessionRuns[idx].CallDescriptor.TimeEnd = s.sessionRuns[idx].CallDescriptor.TimeStart.Add(s.sessionRuns[idx].CallDescriptor.DurationIndex)
|
||||
}
|
||||
}
|
||||
|
||||
// Costs refunds
|
||||
for _, sr := range s.SessionRuns() {
|
||||
if len(sr.CallCosts) == 0 {
|
||||
continue // why would we have 0 callcosts
|
||||
}
|
||||
lastCC := sr.CallCosts[len(sr.CallCosts)-1]
|
||||
lastCC.Timespans.Decompress()
|
||||
// put credit back
|
||||
startTime, err := ev.GetAnswerTime(sr.DerivedCharger.AnswerTimeField, s.sessionManager.Timezone())
|
||||
if err != nil {
|
||||
utils.Logger.Crit("Error parsing prepaid call start time from event")
|
||||
return err
|
||||
}
|
||||
duration, err := ev.GetDuration(sr.DerivedCharger.UsageField)
|
||||
if err != nil {
|
||||
utils.Logger.Crit(fmt.Sprintf("Error parsing call duration from event: %s", err.Error()))
|
||||
return err
|
||||
}
|
||||
hangupTime := startTime.Add(duration)
|
||||
err = s.Refund(lastCC, hangupTime)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
go s.SaveOperations()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Session) Refund(lastCC *engine.CallCost, hangupTime time.Time) error {
|
||||
end := lastCC.Timespans[len(lastCC.Timespans)-1].TimeEnd
|
||||
refundDuration := end.Sub(hangupTime)
|
||||
var refundIncrements engine.Increments
|
||||
for i := len(lastCC.Timespans) - 1; i >= 0; i-- {
|
||||
ts := lastCC.Timespans[i]
|
||||
tsDuration := ts.GetDuration()
|
||||
if refundDuration <= tsDuration {
|
||||
|
||||
lastRefundedIncrementIndex := -1
|
||||
for j := len(ts.Increments) - 1; j >= 0; j-- {
|
||||
increment := ts.Increments[j]
|
||||
if increment.Duration <= refundDuration {
|
||||
refundIncrements = append(refundIncrements, increment)
|
||||
refundDuration -= increment.Duration
|
||||
lastRefundedIncrementIndex = j
|
||||
} else {
|
||||
break //increment duration is larger, cannot refund increment
|
||||
}
|
||||
}
|
||||
if lastRefundedIncrementIndex == 0 {
|
||||
lastCC.Timespans[i] = nil
|
||||
lastCC.Timespans = lastCC.Timespans[:i]
|
||||
} else {
|
||||
ts.SplitByIncrement(lastRefundedIncrementIndex)
|
||||
ts.Cost = ts.CalculateCost()
|
||||
}
|
||||
break // do not go to other timespans
|
||||
} else {
|
||||
refundIncrements = append(refundIncrements, ts.Increments...)
|
||||
// remove the timespan entirely
|
||||
lastCC.Timespans[i] = nil
|
||||
lastCC.Timespans = lastCC.Timespans[:i]
|
||||
// continue to the next timespan with what is left to refund
|
||||
refundDuration -= tsDuration
|
||||
}
|
||||
}
|
||||
// show only what was actualy refunded (stopped in timespan)
|
||||
// utils.Logger.Info(fmt.Sprintf("Refund duration: %v", initialRefundDuration-refundDuration))
|
||||
if len(refundIncrements) > 0 {
|
||||
cd := &engine.CallDescriptor{
|
||||
CgrID: s.eventStart.GetCgrId(s.sessionManager.Timezone()),
|
||||
Direction: lastCC.Direction,
|
||||
Tenant: lastCC.Tenant,
|
||||
Category: lastCC.Category,
|
||||
Subject: lastCC.Subject,
|
||||
Account: lastCC.Account,
|
||||
Destination: lastCC.Destination,
|
||||
TOR: lastCC.TOR,
|
||||
Increments: refundIncrements,
|
||||
}
|
||||
cd.Increments.Compress()
|
||||
//utils.Logger.Info(fmt.Sprintf("Refunding duration %v with cd: %+v", refundDuration, cd))
|
||||
var response float64
|
||||
err := s.sessionManager.Rater().Call("Responder.RefundIncrements", cd, &response)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
lastCC.Cost -= refundIncrements.GetTotalCost()
|
||||
lastCC.UpdateRatedUsage()
|
||||
lastCC.Timespans.Compress()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Nice print for session
|
||||
func (s *Session) String() string {
|
||||
sDump, _ := json.Marshal(s)
|
||||
return string(sDump)
|
||||
}
|
||||
|
||||
// Saves call_costs for each session run
|
||||
func (s *Session) SaveOperations() {
|
||||
for _, sr := range s.sessionRuns {
|
||||
if len(sr.CallCosts) == 0 {
|
||||
break // There are no costs to save, ignore the operation
|
||||
}
|
||||
firstCC := sr.CallCosts[0]
|
||||
for _, cc := range sr.CallCosts[1:] {
|
||||
firstCC.Merge(cc)
|
||||
}
|
||||
firstCC.Timespans.Compress()
|
||||
|
||||
firstCC.Round()
|
||||
roundIncrements := firstCC.GetRoundIncrements()
|
||||
if len(roundIncrements) != 0 {
|
||||
cd := firstCC.CreateCallDescriptor()
|
||||
cd.Increments = roundIncrements
|
||||
var response float64
|
||||
if err := s.sessionManager.Rater().Call("Responder.RefundRounding", cd, &response); err != nil {
|
||||
utils.Logger.Err(fmt.Sprintf("<SM> ERROR failed to refund rounding: %v", err))
|
||||
}
|
||||
}
|
||||
smCost := &engine.SMCost{
|
||||
CGRID: s.eventStart.GetCgrId(s.sessionManager.Timezone()),
|
||||
CostSource: utils.SESSION_MANAGER_SOURCE,
|
||||
RunID: sr.DerivedCharger.RunID,
|
||||
OriginHost: s.eventStart.GetOriginatorIP(utils.META_DEFAULT),
|
||||
OriginID: s.eventStart.GetUUID(),
|
||||
CostDetails: firstCC,
|
||||
}
|
||||
var reply string
|
||||
if err := s.sessionManager.CdrSrv().Call("CdrsV1.StoreSMCost", engine.AttrCDRSStoreSMCost{Cost: smCost, CheckDuplicate: true}, &reply); err != nil {
|
||||
// this is a protection against the case when the close event is missed for some reason
|
||||
// when the cdr arrives to cdrserver because our callcost is not there it will be rated
|
||||
// as postpaid. When the close event finally arives we have to refund everything
|
||||
if err == utils.ErrExists {
|
||||
s.Refund(firstCC, firstCC.Timespans[0].TimeStart)
|
||||
} else {
|
||||
utils.Logger.Err(fmt.Sprintf("<SM> ERROR failed to log call cost: %v", err))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Session) AsActiveSessions() []*ActiveSession {
|
||||
var aSessions []*ActiveSession
|
||||
sTime, _ := s.eventStart.GetSetupTime(utils.META_DEFAULT, s.sessionManager.Timezone())
|
||||
aTime, _ := s.eventStart.GetAnswerTime(utils.META_DEFAULT, s.sessionManager.Timezone())
|
||||
usage, _ := s.eventStart.GetDuration(utils.META_DEFAULT)
|
||||
for _, sessionRun := range s.sessionRuns {
|
||||
aSession := &ActiveSession{
|
||||
CGRID: s.eventStart.GetCgrId(s.sessionManager.Timezone()),
|
||||
TOR: utils.VOICE,
|
||||
OriginID: s.eventStart.GetUUID(),
|
||||
CdrHost: s.eventStart.GetOriginatorIP(utils.META_DEFAULT),
|
||||
CdrSource: "FS_" + s.eventStart.GetName(),
|
||||
ReqType: s.eventStart.GetReqType(utils.META_DEFAULT),
|
||||
Tenant: s.eventStart.GetTenant(utils.META_DEFAULT),
|
||||
Category: s.eventStart.GetCategory(utils.META_DEFAULT),
|
||||
Account: s.eventStart.GetAccount(utils.META_DEFAULT),
|
||||
Subject: s.eventStart.GetSubject(utils.META_DEFAULT),
|
||||
Destination: s.eventStart.GetDestination(utils.META_DEFAULT),
|
||||
SetupTime: sTime,
|
||||
AnswerTime: aTime,
|
||||
Usage: usage,
|
||||
ExtraFields: s.eventStart.GetExtraFields(),
|
||||
SMId: "UNKNOWN",
|
||||
}
|
||||
if sessionRun.DerivedCharger != nil {
|
||||
aSession.RunID = sessionRun.DerivedCharger.RunID
|
||||
}
|
||||
if sessionRun.CallDescriptor != nil {
|
||||
aSession.LoopIndex = sessionRun.CallDescriptor.LoopIndex
|
||||
aSession.DurationIndex = sessionRun.CallDescriptor.DurationIndex
|
||||
aSession.MaxRate = sessionRun.CallDescriptor.MaxRate
|
||||
aSession.MaxRateUnit = sessionRun.CallDescriptor.MaxRateUnit
|
||||
aSession.MaxCostSoFar = sessionRun.CallDescriptor.MaxCostSoFar
|
||||
}
|
||||
aSessions = append(aSessions, aSession)
|
||||
}
|
||||
return aSessions
|
||||
}
|
||||
|
||||
func (s *Session) AsMapStringIface() (map[string]interface{}, error) {
|
||||
mp := make(map[string]interface{})
|
||||
v := reflect.ValueOf(s).Elem()
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
mp[v.Type().Field(i).Name] = v.Field(i).Interface()
|
||||
}
|
||||
return mp, nil
|
||||
}
|
||||
|
||||
// Will be used when displaying active sessions via RPC
|
||||
type ActiveSession struct {
|
||||
CGRID string
|
||||
TOR string // type of record, meta-field, should map to one of the TORs hardcoded inside the server <*voice|*data|*sms|*generic>
|
||||
OriginID string // represents the unique accounting id given by the telecom switch generating the CDR
|
||||
CdrHost string // represents the IP address of the host generating the CDR (automatically populated by the server)
|
||||
CdrSource string // formally identifies the source of the CDR (free form field)
|
||||
ReqType string // matching the supported request types by the **CGRateS**, accepted values are hardcoded in the server <prepaid|postpaid|pseudoprepaid|rated>
|
||||
Tenant string // tenant whom this record belongs
|
||||
Category string // free-form filter for this record, matching the category defined in rating profiles.
|
||||
Account string // account id (accounting subsystem) the record should be attached to
|
||||
Subject string // rating subject (rating subsystem) this record should be attached to
|
||||
Destination string // destination to be charged
|
||||
SetupTime time.Time // set-up time of the event. Supported formats: datetime RFC3339 compatible, SQL datetime (eg: MySQL), unix timestamp.
|
||||
AnswerTime time.Time // answer time of the event. Supported formats: datetime RFC3339 compatible, SQL datetime (eg: MySQL), unix timestamp.
|
||||
Usage time.Duration // event usage information (eg: in case of tor=*voice this will represent the total duration of a call)
|
||||
ExtraFields map[string]string // Extra fields to be stored in CDR
|
||||
SMId string
|
||||
SMConnId string
|
||||
RunID string
|
||||
LoopIndex float64 // indicates the position of this segment in a cost request loop
|
||||
DurationIndex time.Duration // the call duration so far (till TimeEnd)
|
||||
MaxRate float64
|
||||
MaxRateUnit time.Duration
|
||||
MaxCostSoFar float64
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
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 (
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
"github.com/cgrates/rpcclient"
|
||||
)
|
||||
|
||||
type SessionManager interface {
|
||||
Rater() rpcclient.RpcClientConnection
|
||||
CdrSrv() rpcclient.RpcClientConnection
|
||||
DebitInterval() time.Duration
|
||||
DisconnectSession(engine.Event, string, string) error
|
||||
WarnSessionMinDuration(string, string)
|
||||
Sessions() []*Session
|
||||
Timezone() string
|
||||
Connect() error
|
||||
Shutdown() error
|
||||
//RemoveSession(string)
|
||||
//SyncSessions() error
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
/*
|
||||
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 (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
"github.com/cgrates/cgrates/guardian"
|
||||
)
|
||||
|
||||
func NewSessions() *Sessions {
|
||||
return &Sessions{
|
||||
sessionsMux: new(sync.Mutex),
|
||||
guard: guardian.Guardian,
|
||||
}
|
||||
}
|
||||
|
||||
type Sessions struct {
|
||||
sessions []*Session
|
||||
sessionsMux *sync.Mutex // Lock the list operations
|
||||
guard *guardian.GuardianLock // Used to lock on uuid
|
||||
}
|
||||
|
||||
func (self *Sessions) indexSession(s *Session) {
|
||||
self.sessionsMux.Lock()
|
||||
self.sessions = append(self.sessions, s)
|
||||
self.sessionsMux.Unlock()
|
||||
}
|
||||
|
||||
func (self *Sessions) getSessions() []*Session {
|
||||
self.sessionsMux.Lock()
|
||||
defer self.sessionsMux.Unlock()
|
||||
return self.sessions
|
||||
}
|
||||
|
||||
// Searches and return the session with the specifed uuid
|
||||
func (self *Sessions) getSession(uuid string) *Session {
|
||||
self.sessionsMux.Lock()
|
||||
defer self.sessionsMux.Unlock()
|
||||
for _, s := range self.sessions {
|
||||
if s.eventStart.GetUUID() == uuid {
|
||||
return s
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Remove session from session list, removes all related in case of multiple runs, true if item was found
|
||||
func (self *Sessions) unindexSession(uuid string) bool {
|
||||
self.sessionsMux.Lock()
|
||||
defer self.sessionsMux.Unlock()
|
||||
for i, ss := range self.sessions {
|
||||
if ss.eventStart.GetUUID() == uuid {
|
||||
self.sessions = append(self.sessions[:i], self.sessions[i+1:]...)
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *Sessions) removeSession(s *Session, evStop engine.Event) error {
|
||||
_, err := self.guard.Guard(func() (interface{}, error) { // Lock it on UUID level
|
||||
if !self.unindexSession(s.eventStart.GetUUID()) { // Unreference it early so we avoid concurrency
|
||||
return nil, nil // Did not find the session so no need to close it anymore
|
||||
}
|
||||
if err := s.Close(evStop); err != nil { // Stop loop, refund advanced charges and save the costs deducted so far to database
|
||||
return nil, err
|
||||
}
|
||||
return nil, nil
|
||||
}, time.Duration(2)*time.Second, s.eventStart.GetUUID())
|
||||
return err
|
||||
}
|
||||
@@ -17,7 +17,7 @@ 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
|
||||
package sessions
|
||||
|
||||
import (
|
||||
"net/rpc/jsonrpc"
|
||||
@@ -16,7 +16,7 @@ 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
|
||||
package sessions
|
||||
|
||||
import (
|
||||
"errors"
|
||||
@@ -295,3 +295,30 @@ func (self *SMGSession) AsActiveSession(timezone string) *ActiveSession {
|
||||
}
|
||||
return aSession
|
||||
}
|
||||
|
||||
// Will be used when displaying active sessions via RPC
|
||||
type ActiveSession struct {
|
||||
CGRID string
|
||||
TOR string // type of record, meta-field, should map to one of the TORs hardcoded inside the server <*voice|*data|*sms|*generic>
|
||||
OriginID string // represents the unique accounting id given by the telecom switch generating the CDR
|
||||
CdrHost string // represents the IP address of the host generating the CDR (automatically populated by the server)
|
||||
CdrSource string // formally identifies the source of the CDR (free form field)
|
||||
ReqType string // matching the supported request types by the **CGRateS**, accepted values are hardcoded in the server <prepaid|postpaid|pseudoprepaid|rated>
|
||||
Tenant string // tenant whom this record belongs
|
||||
Category string // free-form filter for this record, matching the category defined in rating profiles.
|
||||
Account string // account id (accounting subsystem) the record should be attached to
|
||||
Subject string // rating subject (rating subsystem) this record should be attached to
|
||||
Destination string // destination to be charged
|
||||
SetupTime time.Time // set-up time of the event. Supported formats: datetime RFC3339 compatible, SQL datetime (eg: MySQL), unix timestamp.
|
||||
AnswerTime time.Time // answer time of the event. Supported formats: datetime RFC3339 compatible, SQL datetime (eg: MySQL), unix timestamp.
|
||||
Usage time.Duration // event usage information (eg: in case of tor=*voice this will represent the total duration of a call)
|
||||
ExtraFields map[string]string // Extra fields to be stored in CDR
|
||||
SMId string
|
||||
SMConnId string
|
||||
RunID string
|
||||
LoopIndex float64 // indicates the position of this segment in a cost request loop
|
||||
DurationIndex time.Duration // the call duration so far (till TimeEnd)
|
||||
MaxRate float64
|
||||
MaxRateUnit time.Duration
|
||||
MaxCostSoFar float64
|
||||
}
|
||||
@@ -16,7 +16,7 @@ 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
|
||||
package sessions
|
||||
|
||||
import (
|
||||
"errors"
|
||||
@@ -16,7 +16,7 @@ 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
|
||||
package sessions
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
@@ -15,7 +15,7 @@ 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
|
||||
package sessions
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
@@ -17,7 +17,7 @@ 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
|
||||
package sessions
|
||||
|
||||
import (
|
||||
"flag"
|
||||
@@ -18,7 +18,7 @@ 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
|
||||
package sessions
|
||||
|
||||
import (
|
||||
"net/rpc/jsonrpc"
|
||||
@@ -15,7 +15,7 @@ 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
|
||||
package sessions
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
@@ -17,7 +17,7 @@ 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
|
||||
package sessions
|
||||
|
||||
import (
|
||||
"net/rpc"
|
||||
Reference in New Issue
Block a user