diff --git a/sessionmanager/event.go b/sessionmanager/event.go index afe20c469..9e0137e05 100644 --- a/sessionmanager/event.go +++ b/sessionmanager/event.go @@ -32,6 +32,15 @@ var ( eventBodyRE = regexp.MustCompile(`"(.*?)":\s+"(.*?)"`) ) +const ( + CALL_DIRECTION = "Call-Direction" + SUBJECT = "variable_sip_full_from" + DESTINATION = "variable_sip_full_to" + UUID = "Unique-ID" + CSTMID = "Caller-Dialplan" + START_TIME = "Event-Date-GMT" +) + //eventBodyRE *regexp.Regexp func NewEvent(body string) (ev *Event) { diff --git a/sessionmanager/session.go b/sessionmanager/session.go index b7cdd9df0..0a4c09c91 100644 --- a/sessionmanager/session.go +++ b/sessionmanager/session.go @@ -26,24 +26,25 @@ import ( ) type Session struct { - id, cstmId, subject string - callsMap map[string]time.Time + uuid, cstmId, subject, destination string + startTime time.Time // destination: startTime } -func NewSession(cstmId, subject string) *Session { - return &Session{cstmId: cstmId, subject: subject, callsMap: make(map[string]time.Time)} -} - -func (s *Session) AddCallToSession(destination string, startTime time.Time) { - s.callsMap[destination] = startTime +func NewSession(ev *Event) *Session { + startTime, err := time.Parse(time.RFC1123, ev.Fields[START_TIME]) + if err != nil { + log.Print("Error parsing answer event start time, using time.Now!") + startTime = time.Now() + } + return &Session{uuid: ev.Fields[UUID], + cstmId: ev.Fields[CSTMID], + subject: ev.Fields[SUBJECT], + destination: ev.Fields[DESTINATION], + startTime: startTime} } func (s *Session) GetSessionDurationFrom(now time.Time) (d time.Duration) { - seconds := 0.0 - - for _, st := range s.callsMap { - seconds += now.Sub(st).Seconds() - } + seconds := now.Sub(s.startTime).Seconds() d, err := time.ParseDuration(fmt.Sprintf("%ds", int(seconds))) if err != nil { log.Printf("Cannot parse session duration %v", seconds) @@ -55,19 +56,16 @@ func (s *Session) GetSessionDuration() time.Duration { return s.GetSessionDurationFrom(time.Now()) } -func (s *Session) GetSessionCostFrom(now time.Time) (callCosts []*timespans.CallCost, err error) { - for dest, st := range s.callsMap { - cd := ×pans.CallDescriptor{TOR: 1, CstmId: s.cstmId, Subject: s.subject, DestinationPrefix: dest, TimeStart: st, TimeEnd: now} - cd.SetStorageGetter(storageGetter) - if cc, err := cd.GetCost(); err == nil { - callCosts = append(callCosts, cc) - } else { - break - } +func (s *Session) GetSessionCostFrom(now time.Time) (callCosts *timespans.CallCost, err error) { + cd := ×pans.CallDescriptor{TOR: 1, CstmId: s.cstmId, Subject: s.subject, DestinationPrefix: s.destination, TimeStart: s.startTime, TimeEnd: now} + cd.SetStorageGetter(storageGetter) + callCosts, err = cd.GetCost() + if err != nil { + log.Printf("Error getting call cost for session %v", s) } return } -func (s *Session) GetSessionCost() (callCosts []*timespans.CallCost, err error) { +func (s *Session) GetSessionCost() (callCosts *timespans.CallCost, err error) { return s.GetSessionCostFrom(time.Now()) } diff --git a/sessionmanager/session_test.go b/sessionmanager/session_test.go index 744725345..c89c5773c 100644 --- a/sessionmanager/session_test.go +++ b/sessionmanager/session_test.go @@ -23,58 +23,50 @@ import ( "time" ) -func TestSessionDurationSingle(t *testing.T) { - s := NewSession("", "") - start := time.Date(2012, 5, 3, 14, 30, 0, 0, time.UTC) - s.AddCallToSession("", start) - twoSeconds, _ := time.ParseDuration("2s") - if d := s.GetSessionDurationFrom(start.Add(twoSeconds)); d.Seconds() < 2 || d.Seconds() > 3 { - t.Errorf("Wrong session duration %v", d) - } -} +var ( + newEvent = NewEvent(` +"Event-Name": "HEARTBEAT", +"Core-UUID": "d5abc5b0-95c6-11e1-be05-43c90197c914", +"FreeSWITCH-Hostname": "grace", +"FreeSWITCH-Switchname": "grace", +"FreeSWITCH-IPv4": "172.17.77.126", +"variable_sip_full_from": "rif", +"variable_sip_full_to": "0723045326", +"Caller-Dialplan": "vdf", +"FreeSWITCH-IPv6": "::1", +"Event-Date-Local": "2012-05-04 14:38:23", +"Event-Date-GMT": "Fri, 03 May 2012 11:38:23 GMT", +"Event-Date-Timestamp": "1336131503218867", +"Event-Calling-File": "switch_core.c", +"Event-Calling-Function": "send_heartbeat", +"Event-Calling-Line-Number": "68", +"Event-Sequence": "4171", +"Event-Info": "System Ready", +"Up-Time": "0 years, 0 days, 2 hours, 43 minutes, 21 seconds, 349 milliseconds, 683 microseconds", +"Session-Count": "0", +"Max-Sessions": "1000", +"Session-Per-Sec": "30", +"Session-Since-Startup": "122", +"Idle-CPU": "100.000000" +`) +) -func TestSessionDurationMultiple(t *testing.T) { - s := NewSession("", "") - start := time.Date(2012, 5, 3, 14, 30, 0, 0, time.UTC) - s.AddCallToSession("", start) - s.AddCallToSession("", start) - s.AddCallToSession("", start) +func TestSessionDurationSingle(t *testing.T) { + s := NewSession(newEvent) twoSeconds, _ := time.ParseDuration("2s") - if d := s.GetSessionDurationFrom(start.Add(twoSeconds)); d.Seconds() < 2 || d.Seconds() > 3 { + if d := s.GetSessionDurationFrom(s.startTime.Add(twoSeconds)); d.Seconds() < 2 || d.Seconds() > 3 { t.Errorf("Wrong session duration %v", d) } } func TestSessionCostSingle(t *testing.T) { - s := NewSession("vdf", "rif") - start := time.Date(2012, 5, 3, 14, 30, 0, 0, time.UTC) - s.AddCallToSession("0723", start) + s := NewSession(newEvent) twoSeconds, _ := time.ParseDuration("60s") - if ccs, err := s.GetSessionCostFrom(start.Add(twoSeconds)); err != nil { + if cc, err := s.GetSessionCostFrom(s.startTime.Add(twoSeconds)); err != nil { t.Errorf("Get cost returned error %v", err) } else { - if len(ccs) != 1 || ccs[0].Cost < 1 || ccs[0].Cost > 1.1 { - t.Errorf("Expected %v got %v", "between 1 and 1.1", ccs[0].Cost) - } - } -} - -func TestSessionCostMultiple(t *testing.T) { - s := NewSession("vdf", "rif") - start := time.Date(2012, 5, 3, 14, 30, 0, 0, time.UTC) - s.AddCallToSession("0723", start) - s.AddCallToSession("0257", start) - s.AddCallToSession("0256", start) - twoSeconds, _ := time.ParseDuration("60s") - if ccs, err := s.GetSessionCostFrom(start.Add(twoSeconds)); err != nil { - t.Errorf("Get cost returned error %v", err) - } else { - sum := 0.0 - for _, cc := range ccs { - sum += cc.Cost - } - if len(ccs) != 3 || sum < 23 || sum > 23.1 { - t.Errorf("Expected %v got %v", "between 23 and 23.1", sum) + if cc.Cost < 1 || cc.Cost > 1.1 { + t.Errorf("Expected %v got %v", "between 1 and 1.1", cc.Cost) } } } diff --git a/sessionmanager/sessionmanager.go b/sessionmanager/sessionmanager.go index 57ce8d628..4dfc3e0ed 100644 --- a/sessionmanager/sessionmanager.go +++ b/sessionmanager/sessionmanager.go @@ -64,16 +64,35 @@ func (sm *SessionManager) ReadNextEvent() (ev *Event) { return } +func (sm *SessionManager) GetSessionByUUID(uuid string) *Session { + for _, s := range sm.sessions { + if s.uuid == uuid { + return s + } + } + return nil +} + +func (sm *SessionManager) GetSessionBySubject(subj string) (s *Session) { + for _, s := range sm.sessions { + if s.subject == subj { + return s + } + } + return +} + func (sm *SessionManager) OnHeartBeat(ev *Event) { log.Print("heartbeat") } func (sm *SessionManager) OnChannelAnswer(ev *Event) { - log.Printf("answer") + s := NewSession(ev) + log.Printf("answer: %v", s) } func (sm *SessionManager) OnChannelHangupComplete(ev *Event) { - log.Print("hangup") + //s := GetSessionByUUID(ev.Fields[UUID]) } func (sm *SessionManager) OnOther(ev *Event) {