mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
Merge branch 'master' of https://github.com/cgrates/cgrates
This commit is contained in:
@@ -43,6 +43,7 @@ information, please see the [`CONTRIBUTING.md`](CONTRIBUTING.md) file.
|
||||
| @noahmehl | Noah Mehl |
|
||||
| @elfranne | Tom Braarup Cuykens |
|
||||
| @rbarrabe | Régis Barrabé |
|
||||
| @J0hnSteel | John Koce Steel |
|
||||
<!-- to sign, include a single line above this comment containing the following text:
|
||||
| @username | First Last |
|
||||
-->
|
||||
|
||||
@@ -387,7 +387,8 @@ func (self *ApierV1) LoadTariffPlanFromStorDb(attrs AttrLoadTpFromStorDb, reply
|
||||
}
|
||||
|
||||
if len(cstKeys) != 0 && self.CdrStatsSrv != nil {
|
||||
if err := self.CdrStatsSrv.Call("CDRStatsV1.ReloadQueues", cstKeys, nil); err != nil {
|
||||
var out int
|
||||
if err := self.CdrStatsSrv.Call("CDRStatsV1.ReloadQueues", cstKeys, &out); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
#Tag,DestinationsTag,RatesTag,RoundingMethod,RoundingDecimals,MaxCost,MaxCostStrategy
|
||||
DR_RETAIL,GERMANY,RT_1CENT,*up,4,0,
|
||||
DR_SMS_1,EUROPE,RT_SMS_5c,*up,4,0,
|
||||
|
||||
|
@@ -0,0 +1,4 @@
|
||||
#Tag,Prefix
|
||||
GERMANY,+49
|
||||
EUROPE,+40
|
||||
EUROPE,+49
|
||||
|
3
data/tariffplans/test/destinations/multiid/Rates.csv
Normal file
3
data/tariffplans/test/destinations/multiid/Rates.csv
Normal file
@@ -0,0 +1,3 @@
|
||||
#Tag,ConnectFee,Rate,RateUnit,RateIncrement,GroupIntervalStart
|
||||
RT_1CENT,0,1,1s,1s,0s
|
||||
RT_SMS_5c,0,0.005,1,1,0
|
||||
|
@@ -0,0 +1,3 @@
|
||||
#Tag,DestinationRatesTag,TimingTag,Weight
|
||||
RP_RETAIL,DR_RETAIL,ALWAYS,20
|
||||
RP_RETAIL,DR_SMS_1,ALWAYS,10
|
||||
|
@@ -0,0 +1,2 @@
|
||||
#Direction,Tenant,Category,Subject,ActivationTime,RatingPlanId,RatesFallbackSubject,CdrStatQueueIds
|
||||
*out,cgrates.org,call,*any,2012-01-01T00:00:00Z,RP_RETAIL,,
|
||||
|
2
data/tariffplans/test/destinations/multiid/Timings.csv
Normal file
2
data/tariffplans/test/destinations/multiid/Timings.csv
Normal file
@@ -0,0 +1,2 @@
|
||||
#Tag,Years,Months,MonthDays,WeekDays,Time
|
||||
ALWAYS,*any,*any,*any,*any,00:00:00
|
||||
|
@@ -98,6 +98,7 @@ modparam("acc", "evi_extra", "cgr_reqtype=$avp(cgr_reqtype);
|
||||
cgr_account=$avp(cgr_account);
|
||||
cgr_destination=$avp(cgr_destination);
|
||||
cgr_supplier=$avp(cgr_supplier);
|
||||
cgr_answertime=$dlg_val(atime);
|
||||
dialog_id=$DLG_did")
|
||||
#modparam("acc", "db_url", "flatstore:/tmp")
|
||||
#modparam("acc", "db_flag", "CDR")
|
||||
@@ -344,6 +345,7 @@ route{
|
||||
route[relay] {
|
||||
# for INVITEs enable some additional helper routes
|
||||
if (is_method("INVITE") && !has_totag()) {
|
||||
t_on_reply("MSG_REPLY"); #added for completeness not tested
|
||||
t_on_failure("missed_call");
|
||||
}
|
||||
if (!t_relay()) {
|
||||
@@ -367,3 +369,11 @@ failure_route[missed_call] {
|
||||
}
|
||||
}
|
||||
|
||||
onreply_route[MSG_REPLY]{
|
||||
if (t_check_status("200") && !$dlg_val(atime)){#so we set it ONLY ONCE
|
||||
$dlg_val(atime)=$Ts;
|
||||
}
|
||||
if (t_check_status("4..")){#CAPTURE ALL ERROR CODES NEGATIVE ASR record
|
||||
$dlg_val(atime)=NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,9 +19,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
package engine
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"net/smtp"
|
||||
"path"
|
||||
"reflect"
|
||||
@@ -638,6 +640,24 @@ type RPCRequest struct {
|
||||
}
|
||||
|
||||
func cgrRPCAction(account *Account, sq *StatsQueueTriggered, a *Action, acs Actions) error {
|
||||
// parse template
|
||||
tmpl := template.New("extra_params")
|
||||
t, err := tmpl.Parse(a.ExtraParameters)
|
||||
if err != nil {
|
||||
utils.Logger.Err(fmt.Sprintf("error parsing *cgr_rpc template: %s", err.Error()))
|
||||
return err
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
if err = t.Execute(&buf, map[string]interface{}{
|
||||
"account": account,
|
||||
"action": a,
|
||||
"actions": acs,
|
||||
"sq": sq,
|
||||
}); err != nil {
|
||||
utils.Logger.Err(fmt.Sprintf("error executing *cgr_rpc template %s:", err.Error()))
|
||||
return err
|
||||
}
|
||||
a.ExtraParameters = buf.String()
|
||||
req := RPCRequest{}
|
||||
if err := json.Unmarshal([]byte(a.ExtraParameters), &req); err != nil {
|
||||
return err
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package: github.com/cgrates/cgrates
|
||||
import:
|
||||
- package: github.com/DisposaBoy/JsonConfigReader
|
||||
- package: github.com/cenk/hub
|
||||
- package: github.com/cenkalti/rpc2
|
||||
- package: github.com/cgrates/fsock
|
||||
- package: github.com/cgrates/kamevapi
|
||||
|
||||
@@ -151,11 +151,11 @@ func (osipsev *OsipsEvent) GetSetupTime(fieldName, timezone string) (time.Time,
|
||||
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[TIME])
|
||||
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[TIME]
|
||||
aTimeStr = osipsev.osipsEvent.AttrValues[CGR_ANSWERTIME]
|
||||
}
|
||||
return utils.ParseTimeDetectLayout(aTimeStr, timezone)
|
||||
}
|
||||
@@ -250,7 +250,7 @@ func (osipsev *OsipsEvent) PassesFieldFilter(*utils.RSRField) (bool, string) {
|
||||
}
|
||||
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_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) {
|
||||
|
||||
@@ -33,7 +33,7 @@ import (
|
||||
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", "time": "1406370499", "cgr_reqtype": utils.META_PREPAID, "cgr_subject": "dan", "cgr_destination": "+4986517174963", "cgr_tenant": "itsyscom.com", "sip_code": "200",
|
||||
"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) {
|
||||
@@ -158,7 +158,7 @@ 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_reqtype": utils.META_PSEUDOPREPAID,
|
||||
"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,
|
||||
}}
|
||||
@@ -176,7 +176,7 @@ func TestOsipsAccMissedToStoredCdr(t *testing.T) {
|
||||
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_reqtype": utils.META_PREPAID,
|
||||
"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,
|
||||
}}
|
||||
@@ -188,7 +188,7 @@ func TestOsipsUpdateDurationFromEvent(t *testing.T) {
|
||||
}}
|
||||
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_reqtype": utils.META_PREPAID,
|
||||
"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,
|
||||
}}
|
||||
|
||||
Reference in New Issue
Block a user