func TestPSQLRemStoredCdrs(t *testing.T) {
	if !*testLocal {
		return
	}
	cgrIdB1 := utils.Sha1("bbb1", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String())
	if err := psqlDb.RemStoredCdrs([]string{cgrIdB1}); err != nil {
		t.Error(err.Error())
	}
	if storedCdrs, _, err := psqlDb.GetStoredCdrs(new(utils.CdrsFilter)); err != nil {
		t.Error(err.Error())
	} else if len(storedCdrs) != 7 {
		t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
	}
	tm, _ := utils.ParseTimeDetectLayout("2013-11-08T08:42:20Z", "")
	cgrIdA1 := utils.Sha1("aaa1", tm.String())
	tm, _ = utils.ParseTimeDetectLayout("2013-11-08T08:42:22Z", "")
	cgrIdA2 := utils.Sha1("aaa2", tm.String())
	tm, _ = utils.ParseTimeDetectLayout("2013-11-07T08:42:24Z", "")
	cgrIdA3 := utils.Sha1("aaa3", tm.String())
	tm, _ = utils.ParseTimeDetectLayout("2013-11-07T08:42:21Z", "")
	cgrIdA4 := utils.Sha1("aaa4", tm.String())
	tm, _ = utils.ParseTimeDetectLayout("2013-11-07T08:42:25Z", "")
	cgrIdA5 := utils.Sha1("aaa5", tm.String())
	cgrIdB2 := utils.Sha1("bbb2", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String())
	cgrIdB3 := utils.Sha1("bbb3", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String())
	if err := psqlDb.RemStoredCdrs([]string{cgrIdA1, cgrIdA2, cgrIdA3, cgrIdA4, cgrIdA5,
		cgrIdB2, cgrIdB3}); err != nil {
		t.Error(err.Error())
	}
	if storedCdrs, _, err := psqlDb.GetStoredCdrs(new(utils.CdrsFilter)); err != nil {
		t.Error(err.Error())
	} else if len(storedCdrs) != 0 {
		t.Error("Unexpected number of StoredCdrs returned: ", storedCdrs)
	}
}
Beispiel #2
0
func NewCDRFromExternalCDR(extCdr *ExternalCDR, timezone string) (*CDR, error) {
	var err error
	cdr := &CDR{CGRID: extCdr.CGRID, RunID: extCdr.RunID, OrderID: extCdr.OrderID, ToR: extCdr.ToR, OriginID: extCdr.OriginID, OriginHost: extCdr.OriginHost,
		Source: extCdr.Source, RequestType: extCdr.RequestType, Direction: extCdr.Direction, Tenant: extCdr.Tenant, Category: extCdr.Category,
		Account: extCdr.Account, Subject: extCdr.Subject, Destination: extCdr.Destination, Supplier: extCdr.Supplier,
		DisconnectCause: extCdr.DisconnectCause, CostSource: extCdr.CostSource, Cost: extCdr.Cost, Rated: extCdr.Rated}
	if cdr.SetupTime, err = utils.ParseTimeDetectLayout(extCdr.SetupTime, timezone); err != nil {
		return nil, err
	}
	if len(cdr.CGRID) == 0 { // Populate CGRID if not present
		cdr.CGRID = utils.Sha1(cdr.OriginID, cdr.SetupTime.UTC().String())
	}
	if cdr.AnswerTime, err = utils.ParseTimeDetectLayout(extCdr.AnswerTime, timezone); err != nil {
		return nil, err
	}
	if cdr.Usage, err = utils.ParseDurationWithSecs(extCdr.Usage); err != nil {
		return nil, err
	}
	if cdr.PDD, err = utils.ParseDurationWithSecs(extCdr.PDD); err != nil {
		return nil, err
	}
	if len(extCdr.CostDetails) != 0 {
		if err = json.Unmarshal([]byte(extCdr.CostDetails), cdr.CostDetails); err != nil {
			return nil, err
		}
	}
	if extCdr.ExtraFields != nil {
		cdr.ExtraFields = make(map[string]string)
	}
	for k, v := range extCdr.ExtraFields {
		cdr.ExtraFields[k] = v
	}
	return cdr, nil
}
Beispiel #3
0
// Populates the field with id from value; strings are appended to original one
func (cdr *CDR) ParseFieldValue(fieldId, fieldVal, timezone string) error {
	var err error
	switch fieldId {
	case utils.ORDERID:
		if cdr.OrderID, err = strconv.ParseInt(fieldVal, 10, 64); err != nil {
			return err
		}
	case utils.TOR:
		cdr.ToR += fieldVal
	case utils.MEDI_RUNID:
		cdr.RunID += fieldVal
	case utils.ACCID:
		cdr.OriginID += fieldVal
	case utils.REQTYPE:
		cdr.RequestType += fieldVal
	case utils.DIRECTION:
		cdr.Direction += fieldVal
	case utils.TENANT:
		cdr.Tenant += fieldVal
	case utils.CATEGORY:
		cdr.Category += fieldVal
	case utils.ACCOUNT:
		cdr.Account += fieldVal
	case utils.SUBJECT:
		cdr.Subject += fieldVal
	case utils.DESTINATION:
		cdr.Destination += fieldVal
	case utils.RATED_FLD:
		cdr.Rated, _ = strconv.ParseBool(fieldVal)
	case utils.SETUP_TIME:
		if cdr.SetupTime, err = utils.ParseTimeDetectLayout(fieldVal, timezone); err != nil {
			return fmt.Errorf("Cannot parse answer time field with value: %s, err: %s", fieldVal, err.Error())
		}
	case utils.PDD:
		if cdr.PDD, err = utils.ParseDurationWithSecs(fieldVal); err != nil {
			return fmt.Errorf("Cannot parse answer time field with value: %s, err: %s", fieldVal, err.Error())
		}
	case utils.ANSWER_TIME:
		if cdr.AnswerTime, err = utils.ParseTimeDetectLayout(fieldVal, timezone); err != nil {
			return fmt.Errorf("Cannot parse answer time field with value: %s, err: %s", fieldVal, err.Error())
		}
	case utils.USAGE:
		if cdr.Usage, err = utils.ParseDurationWithSecs(fieldVal); err != nil {
			return fmt.Errorf("Cannot parse duration field with value: %s, err: %s", fieldVal, err.Error())
		}
	case utils.SUPPLIER:
		cdr.Supplier += fieldVal
	case utils.DISCONNECT_CAUSE:
		cdr.DisconnectCause += fieldVal
	case utils.COST:
		if cdr.Cost, err = strconv.ParseFloat(fieldVal, 64); err != nil {
			return fmt.Errorf("Cannot parse cost field with value: %s, err: %s", fieldVal, err.Error())
		}
	case utils.PartialField:
		cdr.Partial, _ = strconv.ParseBool(fieldVal)
	default: // Extra fields will not match predefined so they all show up here
		cdr.ExtraFields[fieldId] += fieldVal
	}
	return nil
}
Beispiel #4
0
// Remotely start mediation with specific runid, runs asynchronously, it's status will be displayed in syslog
func (self *MediatorV1) RateCdrs(attrs utils.AttrRateCdrs, reply *string) error {
	if self.Medi == nil {
		return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, "MediatorNotRunning")
	}
	var tStart, tEnd time.Time
	var err error
	if len(attrs.TimeStart) != 0 {
		if tStart, err = utils.ParseTimeDetectLayout(attrs.TimeStart); err != nil {
			return err
		}
	}
	if len(attrs.TimeEnd) != 0 {
		if tEnd, err = utils.ParseTimeDetectLayout(attrs.TimeEnd); err != nil {
			return err
		}
	}
	//RateCdrs(cgrIds, runIds, tors, cdrHosts, cdrSources, reqTypes, directions, tenants, categories, accounts, subjects, destPrefixes []string,
	//orderIdStart, orderIdEnd int64, timeStart, timeEnd time.Time, rerateErrors, rerateRated bool)
	if err := self.Medi.RateCdrs(attrs.CgrIds, attrs.MediationRunIds, attrs.TORs, attrs.CdrHosts, attrs.CdrSources, attrs.ReqTypes, attrs.Directions,
		attrs.Tenants, attrs.Categories, attrs.Accounts, attrs.Subjects, attrs.DestinationPrefixes, attrs.RatedAccounts, attrs.RatedSubjects,
		attrs.OrderIdStart, attrs.OrderIdEnd, tStart, tEnd, attrs.RerateErrors, attrs.RerateRated, attrs.SendToStats); err != nil {
		return fmt.Errorf("%s:%s", utils.ERR_SERVER_ERROR, err.Error())
	}
	*reply = utils.OK
	return nil
}
Beispiel #5
0
// handlerUsageDiff will calculate the usage as difference between timeEnd and timeStart
// Expects the 2 arguments in template separated by |
func handlerSubstractUsage(xmlElmnt tree.Res, argsTpl utils.RSRFields, cdrPath utils.HierarchyPath, timezone string) (time.Duration, error) {
	var argsStr string
	for _, rsrArg := range argsTpl {
		if rsrArg.Id == utils.HandlerArgSep {
			argsStr += rsrArg.Id
			continue
		}
		absolutePath := utils.ParseHierarchyPath(rsrArg.Id, "")
		relPath := utils.HierarchyPath(absolutePath[len(cdrPath)-1:]) // Need relative path to the xmlElmnt
		argStr, _ := elementText(xmlElmnt, relPath.AsString("/", true))
		argsStr += argStr
	}
	handlerArgs := strings.Split(argsStr, utils.HandlerArgSep)
	if len(handlerArgs) != 2 {
		return time.Duration(0), errors.New("Unexpected number of arguments")
	}
	tEnd, err := utils.ParseTimeDetectLayout(handlerArgs[0], timezone)
	if err != nil {
		return time.Duration(0), err
	}
	tStart, err := utils.ParseTimeDetectLayout(handlerArgs[1], timezone)
	if err != nil {
		return time.Duration(0), err
	}
	return tEnd.Sub(tStart), nil
}
Beispiel #6
0
func (cgrCdr CgrCdr) AsStoredCdr(timezone string) *CDR {
	storCdr := new(CDR)
	storCdr.CGRID = cgrCdr.getCGRID(timezone)
	storCdr.ToR = cgrCdr[utils.TOR]
	storCdr.OriginID = cgrCdr[utils.ACCID]
	storCdr.OriginHost = cgrCdr[utils.CDRHOST]
	storCdr.Source = cgrCdr[utils.CDRSOURCE]
	storCdr.RequestType = cgrCdr[utils.REQTYPE]
	storCdr.Direction = utils.OUT
	storCdr.Tenant = cgrCdr[utils.TENANT]
	storCdr.Category = cgrCdr[utils.CATEGORY]
	storCdr.Account = cgrCdr[utils.ACCOUNT]
	storCdr.Subject = cgrCdr[utils.SUBJECT]
	storCdr.Destination = cgrCdr[utils.DESTINATION]
	storCdr.SetupTime, _ = utils.ParseTimeDetectLayout(cgrCdr[utils.SETUP_TIME], timezone) // Not interested to process errors, should do them if necessary in a previous step
	storCdr.PDD, _ = utils.ParseDurationWithSecs(cgrCdr[utils.PDD])
	storCdr.AnswerTime, _ = utils.ParseTimeDetectLayout(cgrCdr[utils.ANSWER_TIME], timezone)
	storCdr.Usage, _ = utils.ParseDurationWithSecs(cgrCdr[utils.USAGE])
	storCdr.Supplier = cgrCdr[utils.SUPPLIER]
	storCdr.DisconnectCause = cgrCdr[utils.DISCONNECT_CAUSE]
	storCdr.ExtraFields = cgrCdr.getExtraFields()
	storCdr.Cost = -1
	if costStr, hasIt := cgrCdr[utils.COST]; hasIt {
		storCdr.Cost, _ = strconv.ParseFloat(costStr, 64)
	}
	if ratedStr, hasIt := cgrCdr[utils.RATED]; hasIt {
		storCdr.Rated, _ = strconv.ParseBool(ratedStr)
	}
	return storCdr
}
Beispiel #7
0
func NewStoredCdrFromExternalCdr(extCdr *ExternalCdr, timezone string) (*StoredCdr, error) {
	var err error
	storedCdr := &StoredCdr{CgrId: extCdr.CgrId, OrderId: extCdr.OrderId, TOR: extCdr.TOR, AccId: extCdr.AccId, CdrHost: extCdr.CdrHost, CdrSource: extCdr.CdrSource,
		ReqType: extCdr.ReqType, Direction: extCdr.Direction, Tenant: extCdr.Tenant, Category: extCdr.Category, Account: extCdr.Account, Subject: extCdr.Subject,
		Destination: extCdr.Destination, Supplier: extCdr.Supplier, DisconnectCause: extCdr.DisconnectCause,
		MediationRunId: extCdr.MediationRunId, RatedAccount: extCdr.RatedAccount, RatedSubject: extCdr.RatedSubject, Cost: extCdr.Cost, Rated: extCdr.Rated}
	if storedCdr.SetupTime, err = utils.ParseTimeDetectLayout(extCdr.SetupTime, timezone); err != nil {
		return nil, err
	}
	if len(storedCdr.CgrId) == 0 { // Populate CgrId if not present
		storedCdr.CgrId = utils.Sha1(storedCdr.AccId, storedCdr.SetupTime.UTC().String())
	}
	if storedCdr.AnswerTime, err = utils.ParseTimeDetectLayout(extCdr.AnswerTime, timezone); err != nil {
		return nil, err
	}
	if storedCdr.Usage, err = utils.ParseDurationWithSecs(extCdr.Usage); err != nil {
		return nil, err
	}
	if storedCdr.Pdd, err = utils.ParseDurationWithSecs(extCdr.Pdd); err != nil {
		return nil, err
	}
	if len(extCdr.CostDetails) != 0 {
		if err = json.Unmarshal([]byte(extCdr.CostDetails), storedCdr.CostDetails); err != nil {
			return nil, err
		}
	}
	if extCdr.ExtraFields != nil {
		storedCdr.ExtraFields = make(map[string]string)
	}
	for k, v := range extCdr.ExtraFields {
		storedCdr.ExtraFields[k] = v
	}
	return storedCdr, nil
}
Beispiel #8
0
func (fsCdr FSCdr) AsStoredCdr(timezone string) *CDR {
	storCdr := new(CDR)
	storCdr.CGRID = fsCdr.getCGRID(timezone)
	storCdr.ToR = utils.VOICE
	storCdr.OriginID = fsCdr.vars[FS_UUID]
	storCdr.OriginHost = fsCdr.vars[FS_IP]
	storCdr.Source = FS_CDR_SOURCE
	storCdr.RequestType = utils.FirstNonEmpty(fsCdr.vars[utils.CGR_REQTYPE], fsCdr.cgrCfg.DefaultReqType)
	storCdr.Direction = utils.OUT
	storCdr.Tenant = utils.FirstNonEmpty(fsCdr.vars[utils.CGR_TENANT], fsCdr.cgrCfg.DefaultTenant)
	storCdr.Category = utils.FirstNonEmpty(fsCdr.vars[utils.CGR_CATEGORY], fsCdr.cgrCfg.DefaultCategory)
	storCdr.Account = utils.FirstNonEmpty(fsCdr.vars[utils.CGR_ACCOUNT], fsCdr.vars[FS_USERNAME])
	storCdr.Subject = utils.FirstNonEmpty(fsCdr.vars[utils.CGR_SUBJECT], fsCdr.vars[utils.CGR_ACCOUNT], fsCdr.vars[FS_USERNAME])
	storCdr.Destination = utils.FirstNonEmpty(fsCdr.vars[utils.CGR_DESTINATION], fsCdr.vars[FS_CALL_DEST_NR], fsCdr.vars[FS_SIP_REQUSER])
	storCdr.SetupTime, _ = utils.ParseTimeDetectLayout(fsCdr.vars[FS_SETUP_TIME], timezone) // Not interested to process errors, should do them if necessary in a previous step
	pddStr := utils.FirstNonEmpty(fsCdr.vars[FS_PROGRESS_MEDIAMSEC], fsCdr.vars[FS_PROGRESSMS])
	pddStr += "ms"
	storCdr.PDD, _ = time.ParseDuration(pddStr)
	storCdr.AnswerTime, _ = utils.ParseTimeDetectLayout(fsCdr.vars[FS_ANSWER_TIME], timezone)
	storCdr.Usage, _ = utils.ParseDurationWithSecs(fsCdr.vars[FS_DURATION])
	storCdr.Supplier = fsCdr.vars[utils.CGR_SUPPLIER]
	storCdr.DisconnectCause = utils.FirstNonEmpty(fsCdr.vars[utils.CGR_DISCONNECT_CAUSE], fsCdr.vars["hangup_cause"])
	storCdr.ExtraFields = fsCdr.getExtraFields()
	storCdr.Cost = -1
	return storCdr
}
Beispiel #9
0
// Takes the record out of csv and turns it into http form which can be posted
func (self *Cdrc) recordToStoredCdr(record []string) (*utils.StoredCdr, error) {
	storedCdr := &utils.StoredCdr{CdrHost: "0.0.0.0", CdrSource: self.cdrSourceId, ExtraFields: make(map[string]string), Cost: -1}
	var err error
	for cfgFieldName, cfgFieldRSRs := range self.cdrFields {
		var fieldVal string
		if utils.IsSliceMember([]string{CSV, FS_CSV}, self.cdrType) {
			for _, cfgFieldRSR := range cfgFieldRSRs {
				if strings.HasPrefix(cfgFieldRSR.Id, utils.STATIC_VALUE_PREFIX) {
					fieldVal += cfgFieldRSR.ParseValue("PLACEHOLDER")
				} else { // Dynamic value extracted using index
					if cfgFieldIdx, _ := strconv.Atoi(cfgFieldRSR.Id); len(record) <= cfgFieldIdx {
						return nil, fmt.Errorf("Ignoring record: %v - cannot extract field %s", record, cfgFieldName)
					} else {
						fieldVal += cfgFieldRSR.ParseValue(record[cfgFieldIdx])
					}
				}
			}
		} else { // Modify here when we add more supported cdr formats
			fieldVal = "UNKNOWN"
		}
		switch cfgFieldName {
		case utils.TOR:
			storedCdr.TOR = fieldVal
		case utils.ACCID:
			storedCdr.AccId = fieldVal
		case utils.REQTYPE:
			storedCdr.ReqType = fieldVal
		case utils.DIRECTION:
			storedCdr.Direction = fieldVal
		case utils.TENANT:
			storedCdr.Tenant = fieldVal
		case utils.CATEGORY:
			storedCdr.Category = fieldVal
		case utils.ACCOUNT:
			storedCdr.Account = fieldVal
		case utils.SUBJECT:
			storedCdr.Subject = fieldVal
		case utils.DESTINATION:
			storedCdr.Destination = fieldVal
		case utils.SETUP_TIME:
			if storedCdr.SetupTime, err = utils.ParseTimeDetectLayout(fieldVal); err != nil {
				return nil, fmt.Errorf("Cannot parse answer time field with value: %s, err: %s", fieldVal, err.Error())
			}
		case utils.ANSWER_TIME:
			if storedCdr.AnswerTime, err = utils.ParseTimeDetectLayout(fieldVal); err != nil {
				return nil, fmt.Errorf("Cannot parse answer time field with value: %s, err: %s", fieldVal, err.Error())
			}
		case utils.USAGE:
			if storedCdr.Usage, err = utils.ParseDurationWithNanosecs(fieldVal); err != nil {
				return nil, fmt.Errorf("Cannot parse duration field with value: %s, err: %s", fieldVal, err.Error())
			}
		default: // Extra fields will not match predefined so they all show up here
			storedCdr.ExtraFields[cfgFieldName] = fieldVal
		}

	}
	storedCdr.CgrId = utils.Sha1(storedCdr.AccId, storedCdr.SetupTime.String())
	return storedCdr, nil
}
// Connect rpc client to rater
func TestCdrsHttpCdrReplication(t *testing.T) {
	if !*testIntegration {
		return
	}
	cdrsMasterRpc, err := rpcclient.NewRpcClient("tcp", cdrsMasterCfg.RPCJSONListen, 1, 1, "json", nil)
	if err != nil {
		t.Fatal("Could not connect to rater: ", err.Error())
	}
	testCdr1 := &engine.CDR{CGRID: utils.Sha1("httpjsonrpc1", time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC).String()),
		ToR: utils.VOICE, OriginID: "httpjsonrpc1", OriginHost: "192.168.1.1", Source: "UNKNOWN", RequestType: utils.META_PSEUDOPREPAID,
		Direction: "*out", Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001", Destination: "1002",
		SetupTime: time.Date(2013, 12, 7, 8, 42, 24, 0, time.UTC), AnswerTime: time.Date(2013, 12, 7, 8, 42, 26, 0, time.UTC),
		Usage: time.Duration(10) * time.Second, ExtraFields: map[string]string{"field_extr1": "val_extr1", "fieldextr2": "valextr2"},
		RunID: utils.DEFAULT_RUNID, Cost: 1.201, Rated: true}
	var reply string
	if err := cdrsMasterRpc.Call("CdrsV2.ProcessCdr", testCdr1, &reply); err != nil {
		t.Error("Unexpected error: ", err.Error())
	} else if reply != utils.OK {
		t.Error("Unexpected reply received: ", reply)
	}
	time.Sleep(time.Duration(*waitRater) * time.Millisecond)
	cdrsSlaveRpc, err := rpcclient.NewRpcClient("tcp", "127.0.0.1:12012", 1, 1, "json", nil)
	if err != nil {
		t.Fatal("Could not connect to rater: ", err.Error())
	}
	// ToDo: Fix cdr_http to be compatible with rest of processCdr methods
	var rcvedCdrs []*engine.ExternalCDR
	if err := cdrsSlaveRpc.Call("ApierV2.GetCdrs", utils.RPCCDRsFilter{CGRIDs: []string{testCdr1.CGRID}, RunIDs: []string{utils.META_DEFAULT}}, &rcvedCdrs); err != nil {
		t.Error("Unexpected error: ", err.Error())
	} else if len(rcvedCdrs) != 1 {
		t.Error("Unexpected number of CDRs returned: ", len(rcvedCdrs))
	} else {
		rcvSetupTime, _ := utils.ParseTimeDetectLayout(rcvedCdrs[0].SetupTime, "")
		rcvAnswerTime, _ := utils.ParseTimeDetectLayout(rcvedCdrs[0].AnswerTime, "")
		//rcvUsage, _ := utils.ParseDurationWithSecs(rcvedCdrs[0].Usage)
		if rcvedCdrs[0].CGRID != testCdr1.CGRID ||
			rcvedCdrs[0].ToR != testCdr1.ToR ||
			rcvedCdrs[0].OriginHost != testCdr1.OriginHost ||
			rcvedCdrs[0].Source != testCdr1.Source ||
			rcvedCdrs[0].RequestType != testCdr1.RequestType ||
			rcvedCdrs[0].Direction != testCdr1.Direction ||
			rcvedCdrs[0].Tenant != testCdr1.Tenant ||
			rcvedCdrs[0].Category != testCdr1.Category ||
			rcvedCdrs[0].Account != testCdr1.Account ||
			rcvedCdrs[0].Subject != testCdr1.Subject ||
			rcvedCdrs[0].Destination != testCdr1.Destination ||
			!rcvSetupTime.Equal(testCdr1.SetupTime) ||
			!rcvAnswerTime.Equal(testCdr1.AnswerTime) ||
			//rcvUsage != 10 ||
			rcvedCdrs[0].RunID != testCdr1.RunID {
			//rcvedCdrs[0].Cost != testCdr1.Cost ||
			//!reflect.DeepEqual(rcvedCdrs[0].ExtraFields, testCdr1.ExtraFields) {
			t.Errorf("Expected: %+v, received: %+v", testCdr1, rcvedCdrs[0])
		}
	}
}
Beispiel #11
0
func TestOsipsEventAsStoredCdr(t *testing.T) {
	setupTime, _ := utils.ParseTimeDetectLayout("1406370492")
	answerTime, _ := utils.ParseTimeDetectLayout("1406370499")
	eStoredCdr := &utils.StoredCdr{CgrId: utils.Sha1("ODVkMDI2Mzc2MDY5N2EzODhjNTAzNTdlODhiZjRlYWQ;eb082607;4ea9687f", setupTime.UTC().String()),
		TOR: utils.VOICE, AccId: "ODVkMDI2Mzc2MDY5N2EzODhjNTAzNTdlODhiZjRlYWQ;eb082607;4ea9687f", CdrHost: "172.16.254.77", CdrSource: "OSIPS_E_ACC_CDR", ReqType: "prepaid",
		Direction: utils.OUT, 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.AsStoredCdr(); !reflect.DeepEqual(eStoredCdr, storedCdr) {
		t.Errorf("Expecting: %+v, received: %+v", eStoredCdr, storedCdr)
	}
}
Beispiel #12
0
func TestOsipsEventAsStoredCdr(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,
		Direction:   utils.OUT, Tenant: "itsyscom.com", Category: "call", Account: "dan", Subject: "dan",
		Destination: "+4986517174963", SetupTime: setupTime, AnswerTime: answerTime,
		Usage: time.Duration(20) * time.Second, PDD: time.Duration(3) * time.Second, Supplier: "supplier3", DisconnectCause: "200", ExtraFields: map[string]string{"extra1": "val1", "extra2": "val2"}, Cost: -1}
	if storedCdr := osipsEv.AsStoredCdr(""); !reflect.DeepEqual(eStoredCdr, storedCdr) {
		t.Errorf("Expecting: %+v, received: %+v", eStoredCdr, storedCdr)
	}
}
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",
		)
	}
}
Beispiel #14
0
func TestFsEvAsStoredCdr(t *testing.T) {
	cfg, _ := config.NewDefaultCGRConfig()
	config.SetCgrConfig(cfg)
	ev := new(FSEvent).AsEvent(hangupEv)
	setupTime, _ := utils.ParseTimeDetectLayout("1436280728", "")
	aTime, _ := utils.ParseTimeDetectLayout("1436280728", "")
	eStoredCdr := &engine.StoredCdr{CgrId: "164b0422fdc6a5117031b427439482c6a4f90e41",
		TOR: utils.VOICE, AccId: "e3133bf7-dcde-4daf-9663-9a79ffcef5ad", CdrHost: "10.0.3.15", CdrSource: "FS_CHANNEL_HANGUP_COMPLETE", ReqType: utils.META_PREPAID,
		Direction: utils.OUT, Tenant: "cgrates.org", Category: "call", Account: "1001", Subject: "1001",
		Destination: "1003", SetupTime: setupTime, AnswerTime: aTime,
		Usage: time.Duration(66) * time.Second, Pdd: time.Duration(28) * time.Millisecond, Supplier: "supplier1", DisconnectCause: "NORMAL_CLEARING", ExtraFields: make(map[string]string), Cost: -1}
	if storedCdr := ev.AsStoredCdr(""); !reflect.DeepEqual(eStoredCdr, storedCdr) {
		t.Errorf("Expecting: %+v, received: %+v", eStoredCdr, storedCdr)
	}
}
Beispiel #15
0
func TestFsEvAsStoredCdr(t *testing.T) {
	cfg, _ = config.NewDefaultCGRConfig()
	config.SetCgrConfig(cfg)
	ev := new(FSEvent).New(hangupEv)
	setupTime, _ := utils.ParseTimeDetectLayout("1398442107")
	aTime, _ := utils.ParseTimeDetectLayout("1398442120")
	eStoredCdr := &utils.StoredCdr{CgrId: utils.Sha1("37e9b766-5256-4e4b-b1ed-3767b930fec8", setupTime.UTC().String()),
		TOR: utils.VOICE, AccId: "37e9b766-5256-4e4b-b1ed-3767b930fec8", CdrHost: "10.0.2.15", CdrSource: "FS_CHANNEL_HANGUP_COMPLETE", ReqType: utils.PSEUDOPREPAID,
		Direction: utils.OUT, Tenant: "cgrates.org", Category: "call", Account: "1003", Subject: "1003",
		Destination: "1002", SetupTime: setupTime, AnswerTime: aTime,
		Usage: time.Duration(5) * time.Second, ExtraFields: make(map[string]string), Cost: -1}
	if storedCdr := ev.AsStoredCdr(); !reflect.DeepEqual(eStoredCdr, storedCdr) {
		t.Errorf("Expecting: %+v, received: %+v", eStoredCdr, storedCdr)
	}
}
Beispiel #16
0
// Populates the
func populateStoredCdrField(cdr *engine.StoredCdr, fieldId, fieldVal, timezone string) error {
	var err error
	switch fieldId {
	case utils.TOR:
		cdr.TOR += fieldVal
	case utils.ACCID:
		cdr.AccId += fieldVal
	case utils.REQTYPE:
		cdr.ReqType += fieldVal
	case utils.DIRECTION:
		cdr.Direction += fieldVal
	case utils.TENANT:
		cdr.Tenant += fieldVal
	case utils.CATEGORY:
		cdr.Category += fieldVal
	case utils.ACCOUNT:
		cdr.Account += fieldVal
	case utils.SUBJECT:
		cdr.Subject += fieldVal
	case utils.DESTINATION:
		cdr.Destination += fieldVal
	case utils.RATED:
		cdr.Rated, _ = strconv.ParseBool(fieldVal)
	case utils.SETUP_TIME:
		if cdr.SetupTime, err = utils.ParseTimeDetectLayout(fieldVal, timezone); err != nil {
			return fmt.Errorf("Cannot parse answer time field with value: %s, err: %s", fieldVal, err.Error())
		}
	case utils.PDD:
		if cdr.Pdd, err = utils.ParseDurationWithSecs(fieldVal); err != nil {
			return fmt.Errorf("Cannot parse answer time field with value: %s, err: %s", fieldVal, err.Error())
		}
	case utils.ANSWER_TIME:
		if cdr.AnswerTime, err = utils.ParseTimeDetectLayout(fieldVal, timezone); err != nil {
			return fmt.Errorf("Cannot parse answer time field with value: %s, err: %s", fieldVal, err.Error())
		}
	case utils.USAGE:
		if cdr.Usage, err = utils.ParseDurationWithSecs(fieldVal); err != nil {
			return fmt.Errorf("Cannot parse duration field with value: %s, err: %s", fieldVal, err.Error())
		}
	case utils.SUPPLIER:
		cdr.Supplier += fieldVal
	case utils.DISCONNECT_CAUSE:
		cdr.DisconnectCause += fieldVal
	default: // Extra fields will not match predefined so they all show up here
		cdr.ExtraFields[fieldId] += fieldVal
	}
	return nil
}
Beispiel #17
0
func (self SMGenericEvent) GetAnswerTime(fieldName, timezone string) (time.Time, error) {
	if fieldName == utils.META_DEFAULT {
		fieldName = utils.ANSWER_TIME
	}
	result, _ := utils.ConvertIfaceToString(self[fieldName])
	return utils.ParseTimeDetectLayout(result, timezone)
}
Beispiel #18
0
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)
}
Beispiel #19
0
func (self *UsageRecord) AsCallDescriptor(timezone string) (*CallDescriptor, error) {
	var err error
	cd := &CallDescriptor{
		CgrID:       self.GetId(),
		TOR:         self.ToR,
		Direction:   self.Direction,
		Tenant:      self.Tenant,
		Category:    self.Category,
		Subject:     self.Subject,
		Account:     self.Account,
		Destination: self.Destination,
	}
	timeStr := self.AnswerTime
	if len(timeStr) == 0 { // In case of auth, answer time will not be defined, so take it out of setup one
		timeStr = self.SetupTime
	}
	if cd.TimeStart, err = utils.ParseTimeDetectLayout(timeStr, timezone); err != nil {
		return nil, err
	}
	if usage, err := utils.ParseDurationWithSecs(self.Usage); err != nil {
		return nil, err
	} else {
		cd.TimeEnd = cd.TimeStart.Add(usage)
	}
	if self.ExtraFields != nil {
		cd.ExtraFields = make(map[string]string)
	}
	for k, v := range self.ExtraFields {
		cd.ExtraFields[k] = v
	}
	return cd, nil
}
func TestAPItoResourceLimit(t *testing.T) {
	tpRL := &utils.TPResourceLimit{
		TPID: testTPID,
		ID:   "ResGroup1",
		Filters: []*utils.TPRequestFilter{
			&utils.TPRequestFilter{Type: MetaString, FieldName: "Account", Values: []string{"1001", "1002"}},
			&utils.TPRequestFilter{Type: MetaStringPrefix, FieldName: "Destination", Values: []string{"10", "20"}},
			&utils.TPRequestFilter{Type: MetaCDRStats, Values: []string{"CDRST1:*min_ASR:34", "CDRST_1001:*min_ASR:20"}},
			&utils.TPRequestFilter{Type: MetaRSRFields, Values: []string{"Subject(~^1.*1$)", "Destination(1002)"}},
		},
		ActivationTime: "2014-07-29T15:00:00Z",
		Weight:         10,
		Limit:          "2",
	}
	eRL := &ResourceLimit{ID: tpRL.ID, Weight: tpRL.Weight, Filters: make([]*RequestFilter, len(tpRL.Filters)), Usage: make(map[string]*ResourceUsage)}
	eRL.Filters[0] = &RequestFilter{Type: MetaString, FieldName: "Account", Values: []string{"1001", "1002"}}
	eRL.Filters[1] = &RequestFilter{Type: MetaStringPrefix, FieldName: "Destination", Values: []string{"10", "20"}}
	eRL.Filters[2] = &RequestFilter{Type: MetaCDRStats, Values: []string{"CDRST1:*min_ASR:34", "CDRST_1001:*min_ASR:20"},
		cdrStatSThresholds: []*RFStatSThreshold{
			&RFStatSThreshold{QueueID: "CDRST1", ThresholdType: "*MIN_ASR", ThresholdValue: 34},
			&RFStatSThreshold{QueueID: "CDRST_1001", ThresholdType: "*MIN_ASR", ThresholdValue: 20},
		}}
	eRL.Filters[3] = &RequestFilter{Type: MetaRSRFields, Values: []string{"Subject(~^1.*1$)", "Destination(1002)"},
		rsrFields: utils.ParseRSRFieldsMustCompile("Subject(~^1.*1$);Destination(1002)", utils.INFIELD_SEP),
	}
	eRL.ActivationTime, _ = utils.ParseTimeDetectLayout("2014-07-29T15:00:00Z", "UTC")
	eRL.Limit = 2
	if rl, err := APItoResourceLimit(tpRL, "UTC"); err != nil {
		t.Error(err)
	} else if !reflect.DeepEqual(eRL, rl) {
		t.Errorf("Expecting: %+v, received: %+v", eRL, rl)
	}
}
Beispiel #21
0
func (cgrCdr CgrCdr) getCGRID(timezone string) string {
	if CGRID, hasIt := cgrCdr[utils.CGRID]; hasIt {
		return CGRID
	}
	setupTime, _ := utils.ParseTimeDetectLayout(cgrCdr[utils.SETUP_TIME], timezone)
	return utils.Sha1(cgrCdr[utils.ACCID], setupTime.UTC().String())
}
Beispiel #22
0
func (dbr *DbReader) LoadActionTriggers() (err error) {
	atrsMap, err := dbr.storDb.GetTpActionTriggers(dbr.tpid, "")
	if err != nil {
		return err
	}
	for key, atrsLst := range atrsMap {
		atrs := make([]*ActionTrigger, len(atrsLst))
		for idx, apiAtr := range atrsLst {
			balance_expiration_date, _ := utils.ParseTimeDetectLayout(apiAtr.BalanceExpirationDate)
			atrs[idx] = &ActionTrigger{
				Id:                    utils.GenUUID(),
				BalanceType:           apiAtr.BalanceType,
				Direction:             apiAtr.Direction,
				ThresholdType:         apiAtr.ThresholdType,
				ThresholdValue:        apiAtr.ThresholdValue,
				Recurrent:             apiAtr.Recurrent,
				MinSleep:              apiAtr.MinSleep,
				DestinationId:         apiAtr.DestinationId,
				BalanceWeight:         apiAtr.BalanceWeight,
				BalanceExpirationDate: balance_expiration_date,
				BalanceRatingSubject:  apiAtr.BalanceRatingSubject,
				BalanceCategory:       apiAtr.BalanceCategory,
				BalanceSharedGroup:    apiAtr.BalanceSharedGroup,
				Weight:                apiAtr.Weight,
				ActionsId:             apiAtr.ActionsId,
				MinQueuedItems:        apiAtr.MinQueuedItems,
			}
		}
		dbr.actionsTriggers[key] = atrs
	}
	return err
}
Beispiel #23
0
func TestCDRFields(t *testing.T) {
	fsCdrCfg.CDRSExtraFields = []*utils.RSRField{&utils.RSRField{Id: "sip_user_agent"}}
	fsCdr, err := NewFSCdr(body, fsCdrCfg)
	if err != nil {
		t.Errorf("Error loading cdr: %v", err)
	}
	setupTime, _ := utils.ParseTimeDetectLayout("1436280728", "")
	answerTime, _ := utils.ParseTimeDetectLayout("1436280728", "")
	expctCDR := &CDR{CGRID: "164b0422fdc6a5117031b427439482c6a4f90e41", ToR: utils.VOICE, OriginID: "e3133bf7-dcde-4daf-9663-9a79ffcef5ad",
		OriginHost: "127.0.0.1", Source: "freeswitch_json", Direction: utils.OUT, Category: "call", RequestType: utils.META_PREPAID, Tenant: "cgrates.org", Account: "1001", Subject: "1001",
		Destination: "1003", SetupTime: setupTime, PDD: time.Duration(28) * time.Millisecond, AnswerTime: answerTime, Usage: time.Duration(66) * time.Second, Supplier: "supplier1",
		DisconnectCause: "NORMAL_CLEARING", ExtraFields: map[string]string{"sip_user_agent": "PJSUA v2.3 Linux-3.2.0.4/x86_64/glibc-2.13"}, Cost: -1}
	if CDR := fsCdr.AsStoredCdr(""); !reflect.DeepEqual(expctCDR, CDR) {
		t.Errorf("Expecting: %v, received: %v", expctCDR, CDR)
	}
}
Beispiel #24
0
func (kev KamEvent) GetSetupTime(fieldName, timezone string) (time.Time, error) {
	sTimeStr := utils.FirstNonEmpty(kev[fieldName], kev[CGR_SETUPTIME], kev[CGR_ANSWERTIME])
	if strings.HasPrefix(fieldName, utils.STATIC_VALUE_PREFIX) { // Static value
		sTimeStr = fieldName[len(utils.STATIC_VALUE_PREFIX):]
	}
	return utils.ParseTimeDetectLayout(sTimeStr, timezone)
}
Beispiel #25
0
func (self *ApierV1) RemoveBalances(attr *utils.AttrSetBalance, reply *string) error {
	if missing := utils.MissingStructFields(attr, []string{"Tenant", "Account", "BalanceType"}); len(missing) != 0 {
		return utils.NewErrMandatoryIeMissing(missing...)
	}
	var expTime *time.Time
	if attr.ExpiryTime != nil {
		expTimeVal, err := utils.ParseTimeDetectLayout(*attr.ExpiryTime, self.Config.DefaultTimezone)
		if err != nil {
			*reply = err.Error()
			return err
		}
		expTime = &expTimeVal
	}
	accID := utils.AccountKey(attr.Tenant, attr.Account)
	if _, err := self.AccountDb.GetAccount(accID); err != nil {
		return utils.ErrNotFound
	}

	at := &engine.ActionTiming{}
	at.SetAccountIDs(utils.StringMap{accID: true})
	a := &engine.Action{
		ActionType: engine.REMOVE_BALANCE,
		Balance: &engine.BalanceFilter{
			Uuid:           attr.BalanceUUID,
			ID:             attr.BalanceID,
			Type:           utils.StringPointer(attr.BalanceType),
			ExpirationDate: expTime,
			RatingSubject:  attr.RatingSubject,
			Weight:         attr.Weight,
			Blocker:        attr.Blocker,
			Disabled:       attr.Disabled,
		},
	}
	if attr.Value != nil {
		a.Balance.Value = &utils.ValueFormula{Static: *attr.Value}
	}
	if attr.Directions != nil {
		a.Balance.Directions = utils.StringMapPointer(utils.ParseStringMap(*attr.Directions))
	}
	if attr.DestinationIds != nil {
		a.Balance.DestinationIDs = utils.StringMapPointer(utils.ParseStringMap(*attr.DestinationIds))
	}
	if attr.Categories != nil {
		a.Balance.Categories = utils.StringMapPointer(utils.ParseStringMap(*attr.Categories))
	}
	if attr.SharedGroups != nil {
		a.Balance.SharedGroups = utils.StringMapPointer(utils.ParseStringMap(*attr.SharedGroups))
	}
	if attr.TimingIds != nil {
		a.Balance.TimingIDs = utils.StringMapPointer(utils.ParseStringMap(*attr.TimingIds))
	}
	at.SetActions(engine.Actions{a})
	if err := at.Execute(); err != nil {
		*reply = err.Error()
		return err
	}
	*reply = OK
	return nil
}
Beispiel #26
0
func TestCDRFields(t *testing.T) {
	cfg, _ = config.NewDefaultCGRConfig()
	cfg.CDRSExtraFields = []*utils.RSRField{&utils.RSRField{Id: "sip_user_agent"}}
	fsCdr, err := NewFSCdr(body)
	if err != nil {
		t.Errorf("Error loading cdr: %v", err)
	}
	setupTime, _ := utils.ParseTimeDetectLayout(fsCdr.vars[FS_SETUP_TIME])
	answerTime, _ := utils.ParseTimeDetectLayout(fsCdr.vars[FS_ANSWER_TIME])
	expctStoredCdr := &utils.StoredCdr{CgrId: utils.Sha1("01df56f4-d99a-4ef6-b7fe-b924b2415b7f", setupTime.UTC().String()), TOR: utils.VOICE, AccId: "01df56f4-d99a-4ef6-b7fe-b924b2415b7f",
		CdrHost: "127.0.0.1", CdrSource: "freeswitch_json", Direction: "*out", Category: "call", ReqType: utils.RATED, Tenant: "ipbx.itsyscom.com", Account: "dan", Subject: "dan",
		Destination: "+4986517174963", SetupTime: setupTime, AnswerTime: answerTime, Usage: time.Duration(4) * time.Second,
		ExtraFields: map[string]string{"sip_user_agent": "Jitsi2.2.4603.9615Linux"}, Cost: -1}
	if storedCdr := fsCdr.AsStoredCdr(); !reflect.DeepEqual(expctStoredCdr, storedCdr) {
		t.Errorf("Expecting: %v, received: %v", expctStoredCdr, storedCdr)
	}
}
Beispiel #27
0
// Deprecated in rc8, replaced by AddAccountActionTriggers
func (self *ApierV1) AddTriggeredAction(attr AttrAddActionTrigger, reply *string) error {
	if missing := utils.MissingStructFields(&attr, []string{"Tenant", "Account"}); len(missing) != 0 {
		return utils.NewErrMandatoryIeMissing(missing...)
	}
	at := &engine.ActionTrigger{
		ID:             attr.ActionTriggersId,
		ThresholdType:  attr.ThresholdType,
		ThresholdValue: attr.ThresholdValue,
		Balance:        new(engine.BalanceFilter),
		Weight:         attr.Weight,
		ActionsID:      attr.ActionsId,
	}
	if attr.BalanceId != "" {
		at.Balance.ID = utils.StringPointer(attr.BalanceId)
	}
	if attr.BalanceType != "" {
		at.Balance.Type = utils.StringPointer(attr.BalanceType)
	}
	if attr.BalanceDirection != "" {
		at.Balance.Directions = &utils.StringMap{attr.BalanceDirection: true}
	}
	if attr.BalanceDestinationIds != "" {
		dstIDsMp := utils.StringMapFromSlice(strings.Split(attr.BalanceDestinationIds, utils.INFIELD_SEP))
		at.Balance.DestinationIDs = &dstIDsMp
	}
	if attr.BalanceRatingSubject != "" {
		at.Balance.RatingSubject = utils.StringPointer(attr.BalanceRatingSubject)
	}
	if attr.BalanceWeight != 0.0 {
		at.Balance.Weight = utils.Float64Pointer(attr.BalanceWeight)
	}
	if balExpiryTime, err := utils.ParseTimeDetectLayout(attr.BalanceExpiryTime, self.Config.DefaultTimezone); err != nil {
		return utils.NewErrServerError(err)
	} else {
		at.Balance.ExpirationDate = &balExpiryTime
	}
	if attr.BalanceSharedGroup != "" {
		at.Balance.SharedGroups = &utils.StringMap{attr.BalanceSharedGroup: true}
	}
	acntID := utils.AccountKey(attr.Tenant, attr.Account)
	_, err := engine.Guardian.Guard(func() (interface{}, error) {
		acnt, err := self.AccountDb.GetAccount(acntID)
		if err != nil {
			return 0, err
		}
		acnt.ActionTriggers = append(acnt.ActionTriggers, at)

		if err = self.AccountDb.SetAccount(acnt); err != nil {
			return 0, err
		}
		return 0, nil
	}, 0, acntID)
	if err != nil {
		return err
	}
	*reply = OK
	return nil
}
Beispiel #28
0
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)
}
Beispiel #29
0
func (self *ApierV1) AddAccountActionTriggers(attr AttrAddAccountActionTriggers, reply *string) error {
	if missing := utils.MissingStructFields(&attr, []string{"Tenant", "Account"}); len(missing) != 0 {
		return utils.NewErrMandatoryIeMissing(missing...)
	}
	actTime, err := utils.ParseTimeDetectLayout(attr.ActivationDate, self.Config.DefaultTimezone)
	if err != nil {
		*reply = err.Error()
		return err
	}
	accID := utils.AccountKey(attr.Tenant, attr.Account)
	var account *engine.Account
	_, err = engine.Guardian.Guard(func() (interface{}, error) {
		if acc, err := self.AccountDb.GetAccount(accID); err == nil {
			account = acc
		} else {
			return 0, err
		}
		if attr.ActionTriggerIDs != nil {
			if attr.ActionTriggerOverwrite {
				account.ActionTriggers = make(engine.ActionTriggers, 0)
			}
			for _, actionTriggerID := range *attr.ActionTriggerIDs {
				atrs, err := self.RatingDb.GetActionTriggers(actionTriggerID, false, utils.NonTransactional)
				if err != nil {

					return 0, err
				}
				for _, at := range atrs {
					var found bool
					for _, existingAt := range account.ActionTriggers {
						if existingAt.Equals(at) {
							found = true
							break
						}
					}
					at.ActivationDate = actTime
					at.Executed = attr.Executed
					if !found {
						account.ActionTriggers = append(account.ActionTriggers, at)
					}
				}
			}
		}
		account.InitCounters()
		if err := self.AccountDb.SetAccount(account); err != nil {
			return 0, err
		}
		return 0, nil
	}, 0, accID)
	if err != nil {
		*reply = err.Error()
		return err
	}
	*reply = utils.OK
	return nil
}
Beispiel #30
0
func TestCosts1GetCost1(t *testing.T) {
	tStart, _ := utils.ParseTimeDetectLayout("2013-08-07T17:30:00Z", "")
	tEnd, _ := utils.ParseTimeDetectLayout("2013-08-07T17:31:30Z", "")
	cd := &engine.CallDescriptor{
		Direction:   "*out",
		Category:    "call",
		Tenant:      "cgrates.org",
		Subject:     "1001",
		Account:     "1001",
		Destination: "+4986517174963",
		TimeStart:   tStart,
		TimeEnd:     tEnd,
	}
	if cc, err := cd.GetCost(); err != nil {
		t.Error(err)
	} else if cc.Cost != 90 {
		t.Error("Wrong cost returned: ", cc.Cost)
	}
}