Merge branch 'master' into aliases

This commit is contained in:
Radu Ioan Fericean
2015-08-06 17:23:41 +03:00
15 changed files with 72 additions and 73 deletions

View File

@@ -486,7 +486,7 @@ func mailAsync(ub *Account, sq *StatsQueueTriggered, a *Action, acs Actions) err
message = []byte(fmt.Sprintf("To: %s\r\nSubject: [CGR Notification] Threshold hit on Balance: %s\r\n\r\nTime: \r\n\t%s\r\n\r\nBalance:\r\n\t%s\r\n\r\nYours faithfully,\r\nCGR Balance Monitor\r\n", toAddrStr, ub.Id, time.Now(), balJsn))
} else if sq != nil {
message = []byte(fmt.Sprintf("To: %s\r\nSubject: [CGR Notification] Threshold hit on StatsQueueId: %s\r\n\r\nTime: \r\n\t%s\r\n\r\nStatsQueueId:\r\n\t%s\r\n\r\nMetrics:\r\n\t%+v\r\n\r\nTrigger:\r\n\t%+v\r\n\r\nYours faithfully,\r\nCGR CDR Stats Monitor\r\n",
toAddrStr, sq.Id, time.Now(), sq.Id, sq.metrics, sq.Trigger))
toAddrStr, sq.Id, time.Now(), sq.Id, sq.Metrics, sq.Trigger))
}
auth := smtp.PlainAuth("", cgrCfg.MailerAuthUser, cgrCfg.MailerAuthPass, strings.Split(cgrCfg.MailerServer, ":")[0]) // We only need host part, so ignore port
go func() {

View File

@@ -348,22 +348,6 @@ func (cd *CallDescriptor) splitInTimeSpans() (timespans []*TimeSpan) {
}
}
}
// split on days
/*for i := 0; i < len(timespans); i++ {
if timespans[i].TimeStart.Day() != timespans[i].TimeEnd.Day() {
//log.Print("TS: ", timespans[i].TimeStart, timespans[i].TimeEnd)
start := timespans[i].TimeStart
newTs := timespans[i].SplitByTime(time.Date(start.Year(), start.Month(), start.Day(), 0, 0, 0, 0, start.Location()).Add(24 * time.Hour))
if newTs != nil {
//log.Print("NEW TS: ", newTs.TimeStart, newTs.TimeEnd)
// insert the new timespan
index := i + 1
timespans = append(timespans, nil)
copy(timespans[index+1:], timespans[index:])
timespans[index] = newTs
}
}
}*/
// Logger.Debug(fmt.Sprintf("After SplitByRatingPlan: %+v", timespans))
// split on rate intervals
for i := 0; i < len(timespans); i++ {
@@ -795,7 +779,7 @@ func (cd *CallDescriptor) GetLCRFromStorage() (*LCR, error) {
return nil, utils.ErrNotFound
}
func (cd *CallDescriptor) GetLCR(stats StatsInterface) (*LCRCost, error) {
func (cd *CallDescriptor) GetLCR(stats StatsInterface, p *utils.Paginator) (*LCRCost, error) {
cd.account = nil // make sure it's not cached
lcr, err := cd.GetLCRFromStorage()
if err != nil {
@@ -831,12 +815,13 @@ func (cd *CallDescriptor) GetLCR(stats StatsInterface) (*LCRCost, error) {
lcrCD.Account = supplier
lcrCD.Subject = supplier
lcrCD.Category = lcrCost.Entry.RPCategory
fullSupplier := utils.ConcatenatedKey(lcrCD.Direction, lcrCD.Tenant, lcrCD.Category, lcrCD.Subject)
var cc *CallCost
var err error
if cd.account, err = accountingStorage.GetAccount(lcrCD.GetAccountKey()); err == nil {
if cd.account.Disabled {
lcrCost.SupplierCosts = append(lcrCost.SupplierCosts, &LCRSupplierCost{
Supplier: supplier,
Supplier: fullSupplier,
Error: fmt.Sprintf("supplier %s is disabled", supplier),
})
continue
@@ -846,16 +831,15 @@ func (cd *CallDescriptor) GetLCR(stats StatsInterface) (*LCRCost, error) {
cc, err = lcrCD.GetCost()
}
supplier = utils.ConcatenatedKey(lcrCD.Direction, lcrCD.Tenant, lcrCD.Category, lcrCD.Subject)
//log.Printf("CC: %+v", cc.Timespans[0].ratingInfo.RateIntervals[0].Rating.Rates[0])
if err != nil || cc == nil {
lcrCost.SupplierCosts = append(lcrCost.SupplierCosts, &LCRSupplierCost{
Supplier: supplier,
Supplier: fullSupplier,
Error: err.Error(),
})
} else {
lcrCost.SupplierCosts = append(lcrCost.SupplierCosts, &LCRSupplierCost{
Supplier: supplier,
Supplier: fullSupplier,
Cost: cc.Cost,
Duration: cc.GetDuration(),
})
@@ -878,6 +862,7 @@ func (cd *CallDescriptor) GetLCR(stats StatsInterface) (*LCRCost, error) {
lcrCD.Category = category
lcrCD.Account = supplier
lcrCD.Subject = supplier
fullSupplier := utils.ConcatenatedKey(lcrCD.Direction, lcrCD.Tenant, lcrCD.Category, lcrCD.Subject)
var qosSortParams []string
var asrValues sort.Float64Slice
var pddValues sort.Float64Slice
@@ -897,7 +882,7 @@ func (cd *CallDescriptor) GetLCR(stats StatsInterface) (*LCRCost, error) {
if utils.IsSliceMember([]string{LCR_STRATEGY_QOS, LCR_STRATEGY_QOS_THRESHOLD, LCR_STRATEGY_LOAD}, lcrCost.Entry.Strategy) {
if stats == nil {
lcrCost.SupplierCosts = append(lcrCost.SupplierCosts, &LCRSupplierCost{
Supplier: supplier,
Supplier: fullSupplier,
Error: fmt.Sprintf("Cdr stats service not configured"),
})
continue
@@ -905,7 +890,7 @@ func (cd *CallDescriptor) GetLCR(stats StatsInterface) (*LCRCost, error) {
rpfKey := utils.ConcatenatedKey(ratingProfileSearchKey, supplier)
if rpf, err := ratingStorage.GetRatingProfile(rpfKey, false); err != nil {
lcrCost.SupplierCosts = append(lcrCost.SupplierCosts, &LCRSupplierCost{
Supplier: supplier,
Supplier: fullSupplier,
Error: fmt.Sprintf("Rating plan error: %s", err.Error()),
})
continue
@@ -937,7 +922,7 @@ func (cd *CallDescriptor) GetLCR(stats StatsInterface) (*LCRCost, error) {
statValues := make(map[string]float64)
if err := stats.GetValues(qId, &statValues); err != nil {
lcrCost.SupplierCosts = append(lcrCost.SupplierCosts, &LCRSupplierCost{
Supplier: supplier,
Supplier: fullSupplier,
Error: fmt.Sprintf("Get stats values for queue id %s, error %s", qId, err.Error()),
})
statsErr = true
@@ -991,7 +976,7 @@ func (cd *CallDescriptor) GetLCR(stats StatsInterface) (*LCRCost, error) {
if lcrCost.Entry.Strategy == LCR_STRATEGY_LOAD {
if len(supplierQueues) > 0 {
lcrCost.SupplierCosts = append(lcrCost.SupplierCosts, &LCRSupplierCost{
Supplier: supplier,
Supplier: fullSupplier,
supplierQueues: supplierQueues,
})
}
@@ -1071,7 +1056,7 @@ func (cd *CallDescriptor) GetLCR(stats StatsInterface) (*LCRCost, error) {
//log.Print("ACCCOUNT")
if cd.account.Disabled {
lcrCost.SupplierCosts = append(lcrCost.SupplierCosts, &LCRSupplierCost{
Supplier: supplier,
Supplier: fullSupplier,
Error: fmt.Sprintf("supplier %s is disabled", supplier),
})
continue
@@ -1082,16 +1067,15 @@ func (cd *CallDescriptor) GetLCR(stats StatsInterface) (*LCRCost, error) {
cc, err = lcrCD.GetCost()
}
//log.Printf("CC: %+v", cc)
supplier = utils.ConcatenatedKey(lcrCD.Direction, lcrCD.Tenant, lcrCD.Category, lcrCD.Subject)
if err != nil || cc == nil {
lcrCost.SupplierCosts = append(lcrCost.SupplierCosts, &LCRSupplierCost{
Supplier: supplier,
Supplier: fullSupplier,
Error: err.Error(),
})
continue
} else {
supplCost := &LCRSupplierCost{
Supplier: supplier,
Supplier: fullSupplier,
Cost: cc.Cost,
Duration: cc.GetDuration(),
}
@@ -1127,5 +1111,13 @@ func (cd *CallDescriptor) GetLCR(stats StatsInterface) (*LCRCost, error) {
// sort according to strategy
lcrCost.Sort()
}
if p != nil {
if p.Offset != nil && *p.Offset > 0 && *p.Offset < len(lcrCost.SupplierCosts) {
lcrCost.SupplierCosts = lcrCost.SupplierCosts[*p.Offset:]
}
if p.Limit != nil && *p.Limit > 0 && *p.Limit < len(lcrCost.SupplierCosts) {
lcrCost.SupplierCosts = lcrCost.SupplierCosts[:*p.Limit]
}
}
return lcrCost, nil
}

View File

@@ -56,6 +56,7 @@ type LcrRequest struct {
Destination string
StartTime string
Duration string
*utils.Paginator
}
func (self *LcrRequest) AsCallDescriptor() (*CallDescriptor, error) {

View File

@@ -204,7 +204,7 @@ func TestLcrGet(t *testing.T) {
Account: "rif",
Subject: "rif",
}
lcr, err := cd.GetLCR(nil)
lcr, err := cd.GetLCR(nil, nil)
//jsn, _ := json.Marshal(lcr)
//log.Print("LCR: ", string(jsn))
if err != nil || lcr == nil {

View File

@@ -40,6 +40,11 @@ type SessionRun struct {
CallCosts []*CallCost
}
type AttrGetLcr struct {
*CallDescriptor
*utils.Paginator
}
type Responder struct {
Bal *balancer2go.Balancer
ExitChan chan bool
@@ -325,20 +330,25 @@ func (rs *Responder) LogCallCost(ccl *CallCostLog, reply *string) error {
return nil
}
func (rs *Responder) GetLCR(cd *CallDescriptor, reply *LCRCost) error {
if cd.Subject == "" {
cd.Subject = cd.Account
func (rs *Responder) GetLCR(attrs *AttrGetLcr, reply *LCRCost) error {
if attrs.CallDescriptor.Subject == "" {
attrs.CallDescriptor.Subject = attrs.CallDescriptor.Account
}
if upData, err := LoadUserProfile(cd, "ExtraFields"); err != nil {
if upData, err := LoadUserProfile(attrs.CallDescriptor, "ExtraFields"); err != nil {
return err
} else {
udRcv := upData.(*CallDescriptor)
*cd = *udRcv
*attrs.CallDescriptor = *udRcv
}
lcrCost, err := cd.GetLCR(rs.Stats)
lcrCost, err := attrs.CallDescriptor.GetLCR(rs.Stats, attrs.Paginator)
if err != nil {
return err
}
if lcrCost.Entry.Strategy == LCR_STRATEGY_LOAD {
for _, suppl := range lcrCost.SupplierCosts {
suppl.Cost = -1 // In case of load distribution we don't calculate costs
}
}
*reply = *lcrCost
return nil
}
@@ -505,7 +515,7 @@ type Connector interface {
GetSessionRuns(*StoredCdr, *[]*SessionRun) error
ProcessCdr(*StoredCdr, *string) error
LogCallCost(*CallCostLog, *string) error
GetLCR(*CallDescriptor, *LCRCost) error
GetLCR(*AttrGetLcr, *LCRCost) error
}
type RPCClientConnector struct {
@@ -552,6 +562,6 @@ func (rcc *RPCClientConnector) LogCallCost(ccl *CallCostLog, reply *string) erro
return rcc.Client.Call("CDRSV1.LogCallCost", ccl, reply)
}
func (rcc *RPCClientConnector) GetLCR(cd *CallDescriptor, reply *LCRCost) error {
return rcc.Client.Call("Responder.GetLCR", cd, reply)
func (rcc *RPCClientConnector) GetLCR(attrs *AttrGetLcr, reply *LCRCost) error {
return rcc.Client.Call("Responder.GetLCR", attrs, reply)
}

View File

@@ -395,7 +395,7 @@ func TestGetLCR(t *testing.T) {
},
}
var lcr LCRCost
if err := rsponder.GetLCR(cdStatic, &lcr); err != nil {
if err := rsponder.GetLCR(&AttrGetLcr{CallDescriptor: cdStatic}, &lcr); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(eStLcr.Entry, lcr.Entry) {
t.Errorf("Expecting: %+v, received: %+v", eStLcr.Entry, lcr.Entry)
@@ -422,7 +422,7 @@ func TestGetLCR(t *testing.T) {
},
}
var lcrLc LCRCost
if err := rsponder.GetLCR(cdLowestCost, &lcrLc); err != nil {
if err := rsponder.GetLCR(&AttrGetLcr{CallDescriptor: cdLowestCost}, &lcrLc); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(eLcLcr.Entry, lcrLc.Entry) {
t.Errorf("Expecting: %+v, received: %+v", eLcLcr.Entry, lcrLc.Entry)
@@ -447,7 +447,7 @@ func TestGetLCR(t *testing.T) {
&LCRSupplierCost{Supplier: "*out:tenant12:call:dan12", Cost: 0.6, Duration: 60 * time.Second},
},
}
if err := rsponder.GetLCR(cdLowestCost, &lcrLc); err != nil {
if err := rsponder.GetLCR(&AttrGetLcr{CallDescriptor: cdLowestCost}, &lcrLc); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(eLcLcr.Entry, lcrLc.Entry) {
t.Errorf("Expecting: %+v, received: %+v", eLcLcr.Entry, lcrLc.Entry)
@@ -476,7 +476,7 @@ func TestGetLCR(t *testing.T) {
},
}
var lcrQT LCRCost
if err := rsponder.GetLCR(cdQosThreshold, &lcrQT); err != nil {
if err := rsponder.GetLCR(&AttrGetLcr{CallDescriptor: cdQosThreshold}, &lcrQT); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(eQTLcr.Entry, lcrQT.Entry) {
t.Errorf("Expecting: %+v, received: %+v", eQTLcr.Entry, lcrQT.Entry)
@@ -495,7 +495,7 @@ func TestGetLCR(t *testing.T) {
&LCRSupplierCost{Supplier: "*out:tenant12:call:dan12", Cost: 0.6, Duration: 60 * time.Second, QOS: map[string]float64{PDD: -1, ACD: 300, TCD: 300, ASR: 100, ACC: 2, TCC: 2, DDC: 2}, qosSortParams: []string{"35", "4m"}},
},
}
if err := rsponder.GetLCR(cdQosThreshold, &lcrQT); err != nil {
if err := rsponder.GetLCR(&AttrGetLcr{CallDescriptor: cdQosThreshold}, &lcrQT); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(eQTLcr.Entry, lcrQT.Entry) {
t.Errorf("Expecting: %+v, received: %+v", eQTLcr.Entry, lcrQT.Entry)
@@ -524,7 +524,7 @@ func TestGetLCR(t *testing.T) {
},
}
var lcrQ LCRCost
if err := rsponder.GetLCR(cdQos, &lcrQ); err != nil {
if err := rsponder.GetLCR(&AttrGetLcr{CallDescriptor: cdQos}, &lcrQ); err != nil {
t.Error(err)
} else if !reflect.DeepEqual(eQosLcr.Entry, lcrQ.Entry) {
t.Errorf("Expecting: %+v, received: %+v", eQosLcr.Entry, lcrQ.Entry)

View File

@@ -215,12 +215,12 @@ func (sq *StatsQueue) GetId() string {
// Convert data into a struct which can be used in actions based on triggers hit
func (sq *StatsQueue) Triggered(at *ActionTrigger) *StatsQueueTriggered {
return &StatsQueueTriggered{Id: sq.conf.Id, metrics: sq.getStats(), Trigger: at}
return &StatsQueueTriggered{Id: sq.conf.Id, Metrics: sq.getStats(), Trigger: at}
}
// Struct to be passed to triggered actions
type StatsQueueTriggered struct {
Id string // StatsQueueId
metrics map[string]float64
Metrics map[string]float64
Trigger *ActionTrigger
}

View File

@@ -416,22 +416,6 @@ func (ts *TimeSpan) SplitByRateInterval(i *RateInterval, data bool) (nts *TimeSp
return
}
/*func (ts *TimeSpan) SplitByTime(splitTime time.Time) (nts *TimeSpan) {
if splitTime.Equal(ts.TimeEnd) {
return
}
nts = &TimeSpan{
TimeStart: splitTime,
TimeEnd: ts.TimeEnd,
}
nts.copyRatingInfo(ts)
ts.TimeEnd = splitTime
nts.SetRateInterval(ts.RateInterval)
nts.DurationIndex = ts.DurationIndex
ts.SetNewDurationIndex(nts)
return
}*/
// Split the timespan at the given increment start
func (ts *TimeSpan) SplitByIncrement(index int) *TimeSpan {
if index <= 0 || index >= len(ts.Increments) {