diff --git a/cdrs/cdrs.go b/cdrs/cdrs.go
index c70703b14..1533741d1 100644
--- a/cdrs/cdrs.go
+++ b/cdrs/cdrs.go
@@ -19,41 +19,37 @@ along with this program. If not, see
package cdrs
import (
- "encoding/json"
"fmt"
- utils "github.com/cgrates/cgrates/cgrcoreutils"
+ "github.com/cgrates/cgrates/mediator"
+ "github.com/cgrates/cgrates/rater"
"io/ioutil"
- "log/syslog"
"net/http"
)
var (
- Logger utils.LoggerInterface
+ Logger = rater.Logger
)
-func init() {
- var err error
- Logger, err = syslog.New(syslog.LOG_INFO, "CGRateS")
- if err != nil {
- Logger = new(utils.StdLogger)
- }
+type CDRS struct {
+ loggerDb rater.DataStorage
+ medi *mediator.Mediator
}
-type CDRVars struct {
- FSCdr map[string]string
-}
-
-func cdrHandler(w http.ResponseWriter, r *http.Request) {
+func (cdrs *CDRS) cdrHandler(w http.ResponseWriter, r *http.Request) {
body, _ := ioutil.ReadAll(r.Body)
- cdr := CDRVars{}
- if err := json.Unmarshal(body, &cdr); err == nil {
- new(FSCdr).New(body)
+ if fsCdr, err := new(FSCdr).New(body); err == nil {
+ cdrs.loggerDb.SetCdr(fsCdr)
+ cdrs.medi.MediateCdrFromDB(fsCdr.GetAccount(), cdrs.loggerDb)
} else {
- Logger.Err(fmt.Sprintf("CDRCAPTOR: Could not unmarshal cdr: %v", err))
+ Logger.Err(fmt.Sprintf("Could not create CDR entry: %v", err))
}
}
-func startCaptiuringCDRs() {
- http.HandleFunc("/cdr", cdrHandler)
+func New(storage rater.DataStorage, mediator *mediator.Mediator) *CDRS {
+ return &CDRS{storage, mediator}
+}
+
+func (cdrs *CDRS) StartCaptiuringCDRs() {
+ http.HandleFunc("/cdr", cdrs.cdrHandler)
http.ListenAndServe(":8080", nil)
}
diff --git a/cdrs/fscdr.go b/cdrs/fscdr.go
index 643637f33..909e020e6 100644
--- a/cdrs/fscdr.go
+++ b/cdrs/fscdr.go
@@ -19,8 +19,10 @@ along with this program. If not, see
package cdrs
import (
- utils "github.com/cgrates/cgrates/cgrcoreutils"
+ "encoding/json"
"github.com/cgrates/cgrates/config"
+ "github.com/cgrates/cgrates/rater"
+ "github.com/cgrates/cgrates/utils"
"strconv"
"time"
)
@@ -29,6 +31,7 @@ var cfg *config.CGRConfig // Share the configuration with the rest of the packag
const (
// Freswitch event proprities names
+ CDR_MAP = "variables"
DIRECTION = "Call-Direction"
ORIG_ID = "variable_sip_call_id" //- originator_id - match cdrs
SUBJECT = "variable_cgr_subject"
@@ -48,64 +51,76 @@ const (
type FSCdr map[string]string
-func (fsev FSCdr) New(body []byte) CDR {
- //fsev = fsock.FSCdrStrToMap(body, nil)
- return fsev
+func (fsCdr FSCdr) New(body []byte) (rater.CDR, error) {
+ fsCdr = make(map[string]string)
+ var tmp map[string]interface{}
+ var err error
+ if err = json.Unmarshal(body, &tmp); err == nil {
+ if variables, ok := tmp[CDR_MAP]; ok {
+ if variables, ok := variables.(map[string]interface{}); ok {
+ for k, v := range variables {
+ fsCdr[k] = v.(string)
+ }
+ }
+ return fsCdr, nil
+ }
+ }
+ return nil, err
}
-func (fsev FSCdr) GetName() string {
- return fsev[NAME]
+func (fsCdr FSCdr) GetName() string {
+ return fsCdr[NAME]
}
-func (fsev FSCdr) GetDirection() string {
+func (fsCdr FSCdr) GetDirection() string {
//TODO: implement direction
return "OUT"
- //return fsev[DIRECTION]
+ //return fsCdr[DIRECTION]
}
-func (fsev FSCdr) GetOrigId() string {
- return fsev[ORIG_ID]
+func (fsCdr FSCdr) GetOrigId() string {
+ return fsCdr[ORIG_ID]
}
-func (fsev FSCdr) GetSubject() string {
- return utils.FirstNonEmpty(fsev[SUBJECT], fsev[USERNAME])
+func (fsCdr FSCdr) GetSubject() string {
+ return utils.FirstNonEmpty(fsCdr[SUBJECT], fsCdr[USERNAME])
}
-func (fsev FSCdr) GetAccount() string {
- return utils.FirstNonEmpty(fsev[ACCOUNT], fsev[USERNAME])
+func (fsCdr FSCdr) GetAccount() string {
+ return utils.FirstNonEmpty(fsCdr[ACCOUNT], fsCdr[USERNAME])
}
// Charging destination number
-func (fsev FSCdr) GetDestination() string {
- return utils.FirstNonEmpty(fsev[DESTINATION], fsev[CALL_DEST_NR])
+func (fsCdr FSCdr) GetDestination() string {
+ return utils.FirstNonEmpty(fsCdr[DESTINATION], fsCdr[CALL_DEST_NR])
}
// Original dialed destination number, useful in case of unpark
-func (fsev FSCdr) GetCallDestNr() string {
- return fsev[CALL_DEST_NR]
+func (fsCdr FSCdr) GetCallDestNr() string {
+ return fsCdr[CALL_DEST_NR]
}
-func (fsev FSCdr) GetTOR() string {
- return utils.FirstNonEmpty(fsev[TOR], cfg.SMDefaultTOR)
+func (fsCdr FSCdr) GetTOR() string {
+ return utils.FirstNonEmpty(fsCdr[TOR], cfg.SMDefaultTOR)
}
-func (fsev FSCdr) GetUUID() string {
- return fsev[UUID]
+func (fsCdr FSCdr) GetUUID() string {
+ return fsCdr[UUID]
}
-func (fsev FSCdr) GetTenant() string {
- return utils.FirstNonEmpty(fsev[CSTMID], cfg.SMDefaultTenant)
+func (fsCdr FSCdr) GetTenant() string {
+ return utils.FirstNonEmpty(fsCdr[CSTMID], cfg.SMDefaultTenant)
}
-func (fsev FSCdr) GetReqType() string {
- return utils.FirstNonEmpty(fsev[REQTYPE], cfg.SMDefaultReqType)
+func (fsCdr FSCdr) GetReqType() string {
+ return utils.FirstNonEmpty(fsCdr[REQTYPE], cfg.SMDefaultReqType)
}
-func (fsev FSCdr) GetExtraParameters() string {
+func (fsCdr FSCdr) GetExtraParameters() string {
return ""
}
-func (fsev FSCdr) GetFallbackSubj() string {
+func (fsCdr FSCdr) GetFallbackSubj() string {
return cfg.SMDefaultSubject
}
-func (fsev FSCdr) GetStartTime(field string) (t time.Time, err error) {
- st, err := strconv.ParseInt(fsev[field], 0, 64)
+func (fsCdr FSCdr) GetStartTime(field string) (t time.Time, err error) {
+ st, err := strconv.ParseInt(fsCdr[field], 0, 64)
t = time.Unix(0, st*1000)
return
}
-func (fsev FSCdr) GetEndTime() (t time.Time, err error) {
- st, err := strconv.ParseInt(fsev[END_TIME], 0, 64)
+func (fsCdr FSCdr) GetEndTime() (t time.Time, err error) {
+ st, err := strconv.ParseInt(fsCdr[END_TIME], 0, 64)
t = time.Unix(0, st*1000)
return
}
diff --git a/cdrs/fscdr_test.go b/cdrs/fscdr_test.go
new file mode 100644
index 000000000..69efa10f8
--- /dev/null
+++ b/cdrs/fscdr_test.go
@@ -0,0 +1,36 @@
+/*
+Rating system designed to be used in VoIP Carriers World
+Copyright (C) 2013 ITsysCOM
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see
+*/
+
+package cdrs
+
+import (
+ "testing"
+)
+
+var body = []byte(`{"core-uuid":"9b8ce609-6413-437b-8cf3-bbb92aaf720a","channel_data":{"state":"CS_REPORTING","direction":"inbound","state_number":"11","flags":"0=1;1=1;3=1;36=1;37=1;39=1;42=1;47=1;49=1;52=1;72=1;74=1","caps":"1=1;2=1;3=1;4=1;5=1;6=1"},"variables":{"direction":"inbound","uuid":"c8ccef5e-34c2-4fd2-9a2e-fa6f295f3a1e","session_id":"5","sip_from_user":"1001","sip_from_uri":"1001%40192.168.56.10","sip_from_host":"192.168.56.10","channel_name":"sofia/internal/1001%40192.168.56.10","sip_local_network_addr":"192.168.56.10","sip_network_ip":"192.168.56.1","sip_network_port":"5060","sip_received_ip":"192.168.56.1","sip_received_port":"5060","sip_via_protocol":"udp","sip_authorized":"true","sip_number_alias":"1001","sip_auth_username":"1001","sip_auth_realm":"192.168.56.10","number_alias":"1001","user_name":"1001","domain_name":"192.168.56.10","record_stereo":"true","default_gateway":"example.com","default_areacode":"918","transfer_fallback_extension":"operator","toll_allow":"domestic,international,local","accountcode":"1001","user_context":"default","effective_caller_id_name":"Extension%201001","effective_caller_id_number":"1001","outbound_caller_id_name":"FreeSWITCH","outbound_caller_id_number":"0000000000","callgroup":"techsupport","sip_from_user_stripped":"1001","sofia_profile_name":"internal","recovery_profile_name":"internal","sip_req_user":"1002","sip_req_uri":"1002%40192.168.56.10","sip_req_host":"192.168.56.10","sip_to_user":"1002","sip_to_uri":"1002%40192.168.56.10","sip_to_host":"192.168.56.10","sip_contact_params":"transport%3Dudp%3Bregistering_acc%3D192_168_56_10","sip_contact_user":"1001","sip_contact_port":"5060","sip_contact_uri":"1001%40192.168.56.1%3A5060","sip_contact_host":"192.168.56.1","sip_user_agent":"Jitsi2.2.4603.9615Linux","sip_via_host":"192.168.56.1","sip_via_port":"5060","max_forwards":"70","presence_id":"1001%40192.168.56.10","ep_codec_string":"PCMA%408000h%4020i%4064000b,PCMU%408000h%4020i%4064000b","DP_MATCH":"ARRAY%3A%3A1002%7C%3A1002","call_uuid":"c8ccef5e-34c2-4fd2-9a2e-fa6f295f3a1e","open":"true","RFC2822_DATE":"Thu,%2016%20May%202013%2014%3A33%3A28%20%2B0200","dialed_extension":"1002","export_vars":"RFC2822_DATE,dialed_extension","ringback":"%25(2000,4000,440,480)","transfer_ringback":"local_stream%3A//moh","call_timeout":"30","hangup_after_bridge":"true","continue_on_fail":"true","called_party_callgroup":"techsupport","current_application_data":"user/1002%40192.168.56.10","current_application":"bridge","dialed_user":"1002","dialed_domain":"192.168.56.10","inherit_codec":"true","originated_legs":"ARRAY%3A%3A28262ed6-9d57-4dac-8f0b-9cad38cc5183%3BOutbound%20Call%3B1002%7C%3A28262ed6-9d57-4dac-8f0b-9cad38cc5183%3BOutbound%20Call%3B1002","sip_use_codec_name":"PCMA","sip_use_codec_rate":"8000","sip_use_codec_ptime":"20","write_codec":"PCMA","write_rate":"8000","video_possible":"true","local_media_ip":"192.168.56.10","local_media_port":"23158","advertised_media_ip":"192.168.56.10","sip_use_pt":"8","rtp_use_ssrc":"1387666080","zrtp_secure_media_confirmed_audio":"true","zrtp_sas1_string_audio":"xyhx","switch_m_sdp":"v%3D0%0D%0Ao%3D1002%200%200%20IN%20IP4%20192.168.56.1%0D%0As%3D-%0D%0Ac%3DIN%20IP4%20192.168.56.1%0D%0At%3D0%200%0D%0Am%3Daudio%205022%20RTP/AVP%208%200%0D%0Aa%3Drtpmap%3A8%20PCMA/8000%0D%0Aa%3Drtpmap%3A0%20PCMU/8000%0D%0A","read_codec":"PCMA","read_rate":"8000","endpoint_disposition":"ANSWER","originate_causes":"ARRAY%3A%3A28262ed6-9d57-4dac-8f0b-9cad38cc5183%3BNONE%7C%3A28262ed6-9d57-4dac-8f0b-9cad38cc5183%3BNONE","originate_disposition":"SUCCESS","DIALSTATUS":"SUCCESS","last_bridge_to":"28262ed6-9d57-4dac-8f0b-9cad38cc5183","bridge_channel":"sofia/internal/sip%3A1002%40192.168.56.1%3A5060","bridge_uuid":"28262ed6-9d57-4dac-8f0b-9cad38cc5183","signal_bond":"28262ed6-9d57-4dac-8f0b-9cad38cc5183","last_sent_callee_id_name":"Outbound%20Call","last_sent_callee_id_number":"1002","sip_reinvite_sdp":"v%3D0%0D%0Ao%3D1001%200%201%20IN%20IP4%20192.168.56.1%0D%0As%3D-%0D%0Ac%3DIN%20IP4%20192.168.56.1%0D%0At%3D0%200%0D%0Am%3Daudio%205018%20RTP/AVP%2096%208%200%0D%0Aa%3Dsendonly%0D%0Aa%3Drtpmap%3A96%20opus/48000%0D%0Aa%3Dfmtp%3A96%20usedtx%3D1%0D%0Aa%3Drtpmap%3A8%20PCMA/8000%0D%0Aa%3Drtpmap%3A0%20PCMU/8000%0D%0Aa%3Dextmap%3A1%20urn%3Aietf%3Aparams%3Artp-hdrext%3Acsrc-audio-level%0D%0Aa%3Dzrtp-hash%3A1.10%2038d673831a623b1f80d4fe539ab9e2199ac7d5aa2c9dc2822940f8a016beac94%0D%0Am%3Dvideo%200%20RTP/AVP%2097%2099%0D%0A","switch_r_sdp":"v%3D0%0D%0Ao%3D1001%200%201%20IN%20IP4%20192.168.56.1%0D%0As%3D-%0D%0Ac%3DIN%20IP4%20192.168.56.1%0D%0At%3D0%200%0D%0Am%3Daudio%205018%20RTP/AVP%2096%208%200%0D%0Aa%3Drtpmap%3A96%20opus/48000%0D%0Aa%3Dfmtp%3A96%20usedtx%3D1%0D%0Aa%3Drtpmap%3A8%20PCMA/8000%0D%0Aa%3Drtpmap%3A0%20PCMU/8000%0D%0Aa%3Dsendonly%0D%0Aa%3Dextmap%3A1%20urn%3Aietf%3Aparams%3Artp-hdrext%3Acsrc-audio-level%0D%0Aa%3Dzrtp-hash%3A1.10%2038d673831a623b1f80d4fe539ab9e2199ac7d5aa2c9dc2822940f8a016beac94%0D%0Am%3Dvideo%200%20RTP/AVP%2097%2099%0D%0A","r_sdp_audio_zrtp_hash":"1.10%2038d673831a623b1f80d4fe539ab9e2199ac7d5aa2c9dc2822940f8a016beac94","remote_media_ip":"192.168.56.1","remote_media_port":"5018","sip_audio_recv_pt":"8","dtmf_type":"info","sip_local_sdp_str":"v%3D0%0Ao%3DFreeSWITCH%201368684450%201368684453%20IN%20IP4%20192.168.56.10%0As%3DFreeSWITCH%0Ac%3DIN%20IP4%20192.168.56.10%0At%3D0%200%0Am%3Daudio%2023158%20RTP/AVP%208%0Aa%3Drtpmap%3A8%20PCMA/8000%0Aa%3DsilenceSupp%3Aoff%20-%20-%20-%20-%0Aa%3Dptime%3A20%0Aa%3Dsendrecv%0A","sip_to_tag":"4yBBm5aFZ22vN","sip_from_tag":"d62e0dad","sip_cseq":"3","sip_call_id":"774f3a8a01222f664e6edebd372eef3d%400%3A0%3A0%3A0%3A0%3A0%3A0%3A0","sip_full_via":"SIP/2.0/UDP%20192.168.56.1%3A5060%3Bbranch%3Dz9hG4bK-343439-77113007fa4585ae040b5845fa11d4e8","sip_from_display":"1001","sip_full_from":"%221001%22%20%3Csip%3A1001%40192.168.56.10%3E%3Btag%3Dd62e0dad","sip_full_to":"%3Csip%3A1002%40192.168.56.10%3E%3Btag%3D4yBBm5aFZ22vN","sip_hangup_phrase":"OK","last_bridge_hangup_cause":"NORMAL_CLEARING","last_bridge_proto_specific_hangup_cause":"sip%3A200","bridge_hangup_cause":"NORMAL_CLEARING","hangup_cause":"NORMAL_CLEARING","hangup_cause_q850":"16","digits_dialed":"none","start_stamp":"2013-05-16%2014%3A33%3A28","profile_start_stamp":"2013-05-16%2014%3A33%3A28","answer_stamp":"2013-05-16%2014%3A33%3A31","bridge_stamp":"2013-05-16%2014%3A33%3A31","hold_stamp":"2013-05-16%2014%3A33%3A31","progress_stamp":"2013-05-16%2014%3A33%3A28","progress_media_stamp":"2013-05-16%2014%3A33%3A28","hold_events":"%7B%7B1368707611507967,1368707632287684%7D%7D","end_stamp":"2013-05-16%2014%3A33%3A52","start_epoch":"1368707608","start_uepoch":"1368707608847154","profile_start_epoch":"1368707608","profile_start_uepoch":"1368707608847154","answer_epoch":"1368707611","answer_uepoch":"1368707611310737","bridge_epoch":"1368707611","bridge_uepoch":"1368707611310737","last_hold_epoch":"1368707611","last_hold_uepoch":"1368707611507966","hold_accum_seconds":"0","hold_accum_usec":"0","hold_accum_ms":"0","resurrect_epoch":"0","resurrect_uepoch":"0","progress_epoch":"1368707608","progress_uepoch":"1368707608927201","progress_media_epoch":"1368707608","progress_media_uepoch":"1368707608947168","end_epoch":"1368707632","end_uepoch":"1368707632287198","last_app":"bridge","last_arg":"user/1002%40192.168.56.10","caller_id":"%221001%22%20%3C1001%3E","duration":"24","billsec":"21","progresssec":"0","answersec":"3","waitsec":"3","progress_mediasec":"0","flow_billsec":"24","mduration":"23440","billmsec":"20977","progressmsec":"80","answermsec":"2463","waitmsec":"2463","progress_mediamsec":"100","flow_billmsec":"23440","uduration":"23440044","billusec":"20976461","progressusec":"80047","answerusec":"2463583","waitusec":"2463583","progress_mediausec":"100014","flow_billusec":"23440044","sip_hangup_disposition":"send_bye","rtp_audio_in_raw_bytes":"202404","rtp_audio_in_media_bytes":"201524","rtp_audio_in_packet_count":"1150","rtp_audio_in_media_packet_count":"1145","rtp_audio_in_skip_packet_count":"36","rtp_audio_in_jb_packet_count":"0","rtp_audio_in_dtmf_packet_count":"0","rtp_audio_in_cng_packet_count":"0","rtp_audio_in_flush_packet_count":"5","rtp_audio_in_largest_jb_size":"0","rtp_audio_out_raw_bytes":"193228","rtp_audio_out_media_bytes":"193228","rtp_audio_out_packet_count":"1098","rtp_audio_out_media_packet_count":"1098","rtp_audio_out_skip_packet_count":"0","rtp_audio_out_dtmf_packet_count":"0","rtp_audio_out_cng_packet_count":"0","rtp_audio_rtcp_packet_count":"0","rtp_audio_rtcp_octet_count":"0"},"app_log":{"applications":[{"app_name":"set","app_data":"open=true"},{"app_name":"hash","app_data":"insert/192.168.56.10-spymap/1001/c8ccef5e-34c2-4fd2-9a2e-fa6f295f3a1e"},{"app_name":"hash","app_data":"insert/192.168.56.10-last_dial/1001/1002"},{"app_name":"hash","app_data":"insert/192.168.56.10-last_dial/global/c8ccef5e-34c2-4fd2-9a2e-fa6f295f3a1e"},{"app_name":"export","app_data":"RFC2822_DATE=Thu, 16 May 2013 14:33:28 +0200"},{"app_name":"export","app_data":"dialed_extension=1002"},{"app_name":"bind_meta_app","app_data":"1 b s execute_extension::dx XML features"},{"app_name":"bind_meta_app","app_data":"2 b s record_session::/var/lib/freeswitch/recordings/1001.2013-05-16-14-33-28.wav"},{"app_name":"bind_meta_app","app_data":"3 b s execute_extension::cf XML features"},{"app_name":"bind_meta_app","app_data":"4 b s execute_extension::att_xfer XML features"},{"app_name":"set","app_data":"ringback=%(2000,4000,440,480)"},{"app_name":"set","app_data":"transfer_ringback=local_stream://moh"},{"app_name":"set","app_data":"call_timeout=30"},{"app_name":"set","app_data":"hangup_after_bridge=true"},{"app_name":"set","app_data":"continue_on_fail=true"},{"app_name":"hash","app_data":"insert/192.168.56.10-call_return/1002/1001"},{"app_name":"hash","app_data":"insert/192.168.56.10-last_dial_ext/1002/c8ccef5e-34c2-4fd2-9a2e-fa6f295f3a1e"},{"app_name":"set","app_data":"called_party_callgroup=techsupport"},{"app_name":"hash","app_data":"insert/192.168.56.10-last_dial_ext/techsupport/c8ccef5e-34c2-4fd2-9a2e-fa6f295f3a1e"},{"app_name":"hash","app_data":"insert/192.168.56.10-last_dial_ext/global/c8ccef5e-34c2-4fd2-9a2e-fa6f295f3a1e"},{"app_name":"hash","app_data":"insert/192.168.56.10-last_dial/techsupport/c8ccef5e-34c2-4fd2-9a2e-fa6f295f3a1e"},{"app_name":"bridge","app_data":"user/1002@192.168.56.10"}]},"callflow":{"dialplan":"XML","profile_index":"1","extension":{"name":"tod_example","number":"1002","applications":[{"app_name":"set","app_data":"open=true"},{"app_name":"hash","app_data":"insert/${domain_name}-spymap/${caller_id_number}/${uuid}"},{"app_name":"hash","app_data":"insert/${domain_name}-last_dial/${caller_id_number}/${destination_number}"},{"app_name":"hash","app_data":"insert/${domain_name}-last_dial/global/${uuid}"},{"app_name":"export","app_data":"RFC2822_DATE=${strftime(%a, %d %b %Y %T %z)}"},{"app_name":"export","app_data":"dialed_extension=1002"},{"app_name":"bind_meta_app","app_data":"1 b s execute_extension::dx XML features"},{"app_name":"bind_meta_app","app_data":"2 b s record_session::/var/lib/freeswitch/recordings/${caller_id_number}.${strftime(%Y-%m-%d-%H-%M-%S)}.wav"},{"app_name":"bind_meta_app","app_data":"3 b s execute_extension::cf XML features"},{"app_name":"bind_meta_app","app_data":"4 b s execute_extension::att_xfer XML features"},{"app_name":"set","app_data":"ringback=${us-ring}"},{"app_name":"set","app_data":"transfer_ringback=local_stream://moh"},{"app_name":"set","app_data":"call_timeout=30"},{"app_name":"set","app_data":"hangup_after_bridge=true"},{"app_name":"set","app_data":"continue_on_fail=true"},{"app_name":"hash","app_data":"insert/${domain_name}-call_return/${dialed_extension}/${caller_id_number}"},{"app_name":"hash","app_data":"insert/${domain_name}-last_dial_ext/${dialed_extension}/${uuid}"},{"app_name":"set","app_data":"called_party_callgroup=${user_data(${dialed_extension}@${domain_name} var callgroup)}"},{"app_name":"hash","app_data":"insert/${domain_name}-last_dial_ext/${called_party_callgroup}/${uuid}"},{"app_name":"hash","app_data":"insert/${domain_name}-last_dial_ext/global/${uuid}"},{"app_name":"hash","app_data":"insert/${domain_name}-last_dial/${called_party_callgroup}/${uuid}"},{"app_name":"bridge","app_data":"user/${dialed_extension}@${domain_name}"},{"last_executed":"true","app_name":"answer","app_data":""},{"app_name":"sleep","app_data":"1000"},{"app_name":"bridge","app_data":"loopback/app=voicemail:default ${domain_name} ${dialed_extension}"}],"current_app":"answer"},"caller_profile":{"username":"1001","dialplan":"XML","caller_id_name":"1001","ani":"1001","aniii":"","caller_id_number":"1001","network_addr":"192.168.56.1","rdnis":"","destination_number":"1002","uuid":"c8ccef5e-34c2-4fd2-9a2e-fa6f295f3a1e","source":"mod_sofia","context":"default","chan_name":"sofia/internal/1001@192.168.56.10","originatee":{"originatee_caller_profiles":[{"username":"1001","dialplan":"XML","caller_id_name":"Extension 1001","ani":"1001","aniii":"","caller_id_number":"1001","network_addr":"192.168.56.1","rdnis":"","destination_number":"1002","uuid":"28262ed6-9d57-4dac-8f0b-9cad38cc5183","source":"mod_sofia","context":"default","chan_name":"sofia/internal/sip:1002@192.168.56.1:5060"},{"username":"1001","dialplan":"XML","caller_id_name":"Extension 1001","ani":"1001","aniii":"","caller_id_number":"1001","network_addr":"192.168.56.1","rdnis":"","destination_number":"1002","uuid":"28262ed6-9d57-4dac-8f0b-9cad38cc5183","source":"mod_sofia","context":"default","chan_name":"sofia/internal/sip:1002@192.168.56.1:5060"}]}},"times":{"created_time":"1368707608847154","profile_created_time":"1368707608847154","progress_time":"1368707608927201","progress_media_time":"1368707608947168","answered_time":"1368707611310737","hangup_time":"1368707632287198","resurrect_time":"0","transfer_time":"0"}}}`)
+
+func TestFirstNonEmpty(t *testing.T) {
+ fsCdr, err := new(FSCdr).New(body)
+ if err != nil {
+ t.Errorf("Error loading cdr: %v", err)
+ }
+ fsc := fsCdr.(FSCdr)
+ if _, ok := fsc["dialed_user"]; !ok {
+ t.Error("Error parsing cdr: ", fsCdr)
+ }
+}
diff --git a/mediator/mediator.go b/mediator/mediator.go
index e808e314b..a92cbcf06 100644
--- a/mediator/mediator.go
+++ b/mediator/mediator.go
@@ -224,3 +224,7 @@ func (m *Mediator) getCostsFromRater(record []string, runIdx int) (cc *rater.Cal
}
return
}
+
+func (m *Mediator) MediateCdrFromDB(cdrID string, db rater.DataStorage) error {
+ return nil
+}
diff --git a/rater/actions_test.go b/rater/actions_test.go
index b656a1771..2ebd6b131 100644
--- a/rater/actions_test.go
+++ b/rater/actions_test.go
@@ -748,7 +748,6 @@ func TestUUID(t *testing.T) {
if len(uuid) == 0 {
t.Fatalf("GenUUID error %s", uuid)
}
- t.Logf("uuid[%s]\n", uuid)
}
func TestActionTriggerLogging(t *testing.T) {
@@ -770,7 +769,8 @@ func TestActionTriggerLogging(t *testing.T) {
var key string
atMap, _ := storageGetter.GetAllActionTimings()
for k, v := range atMap {
- t.Logf("%v %v", k, v)
+ _ = k
+ _ = v
/*if strings.Contains(k, LOG_ACTION_TRIGGER_PREFIX) && strings.Contains(v, expected) {
key = k
break
@@ -811,7 +811,6 @@ func TestActionTimingLogging(t *testing.T) {
var key string
atMap, _ := storageGetter.GetAllActionTimings()
for k, v := range atMap {
- t.Logf("OOOOOOOOOO: %v %v", k, v)
/*if strings.Contains(k, LOG_ACTION_TIMMING_PREFIX) && strings.Contains(string(v), expected) {
key = k
}*/
diff --git a/rater/calldesc.go b/rater/calldesc.go
index fec25695d..d5c4f5807 100644
--- a/rater/calldesc.go
+++ b/rater/calldesc.go
@@ -22,7 +22,7 @@ import (
"errors"
"fmt"
"github.com/cgrates/cgrates/cache2go"
- utils "github.com/cgrates/cgrates/cgrcoreutils"
+ "github.com/cgrates/cgrates/utils"
"log/syslog"
"math"
"time"
diff --git a/cdrs/cdr.go b/rater/cdr.go
similarity index 96%
rename from cdrs/cdr.go
rename to rater/cdr.go
index b719356c9..0424db5d2 100644
--- a/cdrs/cdr.go
+++ b/rater/cdr.go
@@ -16,14 +16,14 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see
*/
-package cdrs
+package rater
import (
"time"
)
type CDR interface {
- New([]byte) CDR
+ New([]byte) (CDR, error)
GetName() string
GetDirection() string
GetOrigId() string
diff --git a/rater/rater.test b/rater/rater.test
new file mode 100755
index 000000000..30ff67882
Binary files /dev/null and b/rater/rater.test differ
diff --git a/rater/storage_gosexy.go b/rater/storage_gosexy.go
index 4a540ceee..7787ae754 100644
--- a/rater/storage_gosexy.go
+++ b/rater/storage_gosexy.go
@@ -20,7 +20,6 @@ package rater
import (
"fmt"
- "github.com/cgrates/cgrates/cdrs"
"menteslibres.net/gosexy/redis"
//"log"
"strconv"
@@ -219,9 +218,9 @@ func (rs *GosexyStorage) LogError(uuid, source, errstr string) (err error) {
return
}
-func (rs *GosexyStorage) GetCdr(string) (cdrs.CDR, error) {
+func (rs *GosexyStorage) GetCdr(string) (CDR, error) {
return nil, nil
}
-func (rs *GosexyStorage) SetCdr(string, cdrs.CDR) error {
+func (rs *GosexyStorage) SetCdr(CDR) error {
return nil
}
diff --git a/rater/storage_interface.go b/rater/storage_interface.go
index 18a787588..d13d2c66b 100644
--- a/rater/storage_interface.go
+++ b/rater/storage_interface.go
@@ -22,7 +22,6 @@ import (
"bytes"
"encoding/gob"
"encoding/json"
- "github.com/cgrates/cgrates/cdrs"
gmsgpack "github.com/ugorji/go-msgpack"
"github.com/vmihailenco/msgpack"
"strings"
@@ -62,8 +61,8 @@ type DataStorage interface {
GetActionTimings(string) ([]*ActionTiming, error)
SetActionTimings(string, []*ActionTiming) error
GetAllActionTimings() (map[string][]*ActionTiming, error)
- GetCdr(string) (cdrs.CDR, error)
- SetCdr(string, cdrs.CDR) error
+ GetCdr(string) (CDR, error)
+ SetCdr(CDR) error
//GetAllActionTimingsLogs() (map[string][]*ActionTiming, error)
LogCallCost(uuid, source string, cc *CallCost) error
LogError(uuid, source, errstr string) error
diff --git a/rater/storage_map.go b/rater/storage_map.go
index 7f96742c8..5203b9253 100644
--- a/rater/storage_map.go
+++ b/rater/storage_map.go
@@ -21,7 +21,6 @@ package rater
import (
"errors"
"fmt"
- "github.com/cgrates/cgrates/cdrs"
"strings"
"time"
)
@@ -184,9 +183,9 @@ func (ms *MapStorage) LogError(uuid, source, errstr string) (err error) {
return nil
}
-func (ms *MapStorage) GetCdr(string) (cdrs.CDR, error) {
+func (ms *MapStorage) GetCdr(string) (CDR, error) {
return nil, nil
}
-func (ms *MapStorage) SetCdr(string, cdrs.CDR) error {
+func (ms *MapStorage) SetCdr(CDR) error {
return nil
}
diff --git a/rater/storage_mongo.go b/rater/storage_mongo.go
index c3430a165..43e7726eb 100644
--- a/rater/storage_mongo.go
+++ b/rater/storage_mongo.go
@@ -20,7 +20,6 @@ package rater
import (
"fmt"
- "github.com/cgrates/cgrates/cdrs"
"labix.org/v2/mgo"
"labix.org/v2/mgo/bson"
"log"
@@ -209,9 +208,9 @@ func (ms *MongoStorage) LogError(uuid, source, errstr string) (err error) {
return ms.db.C("errlog").Insert(&LogErrEntry{uuid, errstr, source})
}
-func (ms *MongoStorage) GetCdr(string) (cdrs.CDR, error) {
+func (ms *MongoStorage) GetCdr(string) (CDR, error) {
return nil, nil
}
-func (ms *MongoStorage) SetCdr(string, cdrs.CDR) error {
+func (ms *MongoStorage) SetCdr(CDR) error {
return nil
}
diff --git a/rater/storage_mysql.go b/rater/storage_mysql.go
index c6c77a2b8..a30822965 100644
--- a/rater/storage_mysql.go
+++ b/rater/storage_mysql.go
@@ -22,7 +22,6 @@ import (
"database/sql"
"encoding/json"
"fmt"
- "github.com/cgrates/cgrates/cdrs"
_ "github.com/go-sql-driver/mysql"
)
@@ -222,9 +221,9 @@ func (mys *MySQLStorage) LogActionTiming(source string, at *ActionTiming, as []*
}
func (mys *MySQLStorage) LogError(uuid, source, errstr string) (err error) { return }
-func (mys *MySQLStorage) GetCdr(string) (cdrs.CDR, error) {
+func (mys *MySQLStorage) GetCdr(string) (CDR, error) {
return nil, nil
}
-func (mys *MySQLStorage) SetCdr(string, cdrs.CDR) error {
+func (mys *MySQLStorage) SetCdr(CDR) error {
return nil
}
diff --git a/rater/storage_postgres.go b/rater/storage_postgres.go
index 840fbc0ec..54822171a 100644
--- a/rater/storage_postgres.go
+++ b/rater/storage_postgres.go
@@ -23,7 +23,6 @@ import (
"encoding/json"
"fmt"
_ "github.com/bmizerany/pq"
- "github.com/cgrates/cgrates/cdrs"
)
type PostgresStorage struct {
@@ -222,9 +221,9 @@ func (psl *PostgresStorage) LogActionTiming(source string, at *ActionTiming, as
}
func (psl *PostgresStorage) LogError(uuid, source, errstr string) (err error) { return }
-func (psl *PostgresStorage) GetCdr(string) (cdrs.CDR, error) {
+func (psl *PostgresStorage) GetCdr(string) (CDR, error) {
return nil, nil
}
-func (psl *PostgresStorage) SetCdr(string, cdrs.CDR) error {
+func (psl *PostgresStorage) SetCdr(CDR) error {
return nil
}
diff --git a/rater/storage_redigo.go b/rater/storage_redigo.go
index 3e5612332..25051761e 100644
--- a/rater/storage_redigo.go
+++ b/rater/storage_redigo.go
@@ -20,7 +20,6 @@ package rater
import (
"fmt"
- "github.com/cgrates/cgrates/cdrs"
"github.com/garyburd/redigo/redis"
//"log"
"time"
@@ -216,9 +215,9 @@ func (rs *RedigoStorage) LogError(uuid, source, errstr string) (err error) {
return
}
-func (rs *RedigoStorage) GetCdr(string) (cdrs.CDR, error) {
+func (rs *RedigoStorage) GetCdr(string) (CDR, error) {
return nil, nil
}
-func (rs *RedigoStorage) SetCdr(string, cdrs.CDR) error {
+func (rs *RedigoStorage) SetCdr(CDR) error {
return nil
}
diff --git a/rater/storage_redis.go b/rater/storage_redis.go
index 030f25ceb..e503c74a4 100644
--- a/rater/storage_redis.go
+++ b/rater/storage_redis.go
@@ -20,7 +20,6 @@ package rater
import (
"fmt"
- "github.com/cgrates/cgrates/cdrs"
"github.com/fzzy/radix/redis"
//"log"
"time"
@@ -242,9 +241,9 @@ func (rs *RedisStorage) LogError(uuid, source, errstr string) (err error) {
}
return
}
-func (rs *RedisStorage) GetCdr(string) (cdrs.CDR, error) {
+func (rs *RedisStorage) GetCdr(string) (CDR, error) {
return nil, nil
}
-func (rs *RedisStorage) SetCdr(string, cdrs.CDR) error {
+func (rs *RedisStorage) SetCdr(CDR) error {
return nil
}
diff --git a/sessionmanager/fsevent.go b/sessionmanager/fsevent.go
index 20f559510..6559d6c68 100644
--- a/sessionmanager/fsevent.go
+++ b/sessionmanager/fsevent.go
@@ -20,7 +20,7 @@ package sessionmanager
import (
"fmt"
- utils "github.com/cgrates/cgrates/cgrcoreutils"
+ "github.com/cgrates/cgrates/utils"
"github.com/cgrates/fsock"
"strconv"
"strings"
diff --git a/test.sh b/test.sh
index 557a4a1f7..06be8cda1 100755
--- a/test.sh
+++ b/test.sh
@@ -7,7 +7,8 @@ go test -i github.com/cgrates/cgrates/cmd/cgr-rater
go test -i github.com/cgrates/cgrates/inotify
go test -i github.com/cgrates/cgrates/mediator
go test -i github.com/cgrates/fsock
-
+go test -i github.com/cgrates/cgrates/cdrs
+go test -i github.com/cgrates/cgrates/utils
go test github.com/cgrates/cgrates/rater
ts=$?
@@ -21,7 +22,11 @@ go test github.com/cgrates/cgrates/inotify
it=$?
go test github.com/cgrates/cgrates/mediator
md=$?
-go test github.com/cgrates/fsock
+go test github.com/cgrates/cgrates/cdrs
+cdr=$?
+go test github.com/cgrates/cgrates/utils
+ut=$?
+go test github.com/cgrates//fsock
fs=$?
-exit $ts && $sm && $cfg && $bl && $cr && $it && $md && $fs
+exit $ts && $sm && $cfg && $bl && $cr && $it && $md && $cdr && $fs && $ut
diff --git a/cgrcoreutils/cgrcoreutils.go b/utils/coreutils.go
similarity index 97%
rename from cgrcoreutils/cgrcoreutils.go
rename to utils/coreutils.go
index ee51c9e9f..721069bbd 100644
--- a/cgrcoreutils/cgrcoreutils.go
+++ b/utils/coreutils.go
@@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see
*/
-package cgrcoreutils
+package utils
// Returns first non empty string out of vals. Useful to extract defaults
func FirstNonEmpty(vals ...string) string {
diff --git a/cgrcoreutils/logger.go b/utils/logger.go
similarity index 98%
rename from cgrcoreutils/logger.go
rename to utils/logger.go
index b294822b5..33c0809f3 100644
--- a/cgrcoreutils/logger.go
+++ b/utils/logger.go
@@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see
*/
-package cgrcoreutils
+package utils
import (
"log"
diff --git a/sessionmanager/event_test.go b/utils/utils_test.go
similarity index 84%
rename from sessionmanager/event_test.go
rename to utils/utils_test.go
index 888dfd030..b7fc82cda 100644
--- a/sessionmanager/event_test.go
+++ b/utils/utils_test.go
@@ -16,10 +16,9 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see
*/
-package sessionmanager
+package utils
import (
- utils "github.com/cgrates/cgrates/cgrcoreutils"
"testing"
)
@@ -28,7 +27,7 @@ func TestFirstNonEmpty(t *testing.T) {
sampleMap := make(map[string]string)
sampleMap["Third"] = "third"
fourthElmnt := "fourth"
- winnerElmnt := utils.FirstNonEmpty(firstElmnt, sampleMap["second"], sampleMap["Third"], fourthElmnt)
+ winnerElmnt := FirstNonEmpty(firstElmnt, sampleMap["second"], sampleMap["Third"], fourthElmnt)
if winnerElmnt != sampleMap["Third"] {
t.Error("Wrong elemnt returned: ", winnerElmnt)
}