Renaming sessionmanager package into sessions

This commit is contained in:
DanB
2018-01-28 12:27:25 +01:00
parent 681ba8f616
commit 1a85fa64b2
35 changed files with 176 additions and 1275 deletions

View File

@@ -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:

View File

@@ -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",

View File

@@ -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",

View File

@@ -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 {

View File

@@ -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),

View File

@@ -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(

View File

@@ -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],

View File

@@ -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 {

View File

@@ -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) {

View File

@@ -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

View File

@@ -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",

View File

@@ -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)
}

View File

@@ -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)
}

View File

@@ -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)
}

View File

@@ -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
}

View File

@@ -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)
}

View File

@@ -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))

View File

@@ -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)

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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)
}
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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"

View File

@@ -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
}

View File

@@ -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"

View File

@@ -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"

View File

@@ -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"

View File

@@ -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"

View File

@@ -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"

View File

@@ -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"

View File

@@ -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"