mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
@@ -829,6 +829,7 @@ func (cd *CallDescriptor) GetLCR(stats StatsInterface) (*LCRCost, error) {
|
||||
var tcdValues sort.Float64Slice
|
||||
var accValues sort.Float64Slice
|
||||
var tccValues sort.Float64Slice
|
||||
var ddcValues sort.Float64Slice
|
||||
// track if one value is never calculated
|
||||
asrNeverConsidered := true
|
||||
pddNeverConsidered := true
|
||||
@@ -836,6 +837,7 @@ func (cd *CallDescriptor) GetLCR(stats StatsInterface) (*LCRCost, error) {
|
||||
tcdNeverConsidered := true
|
||||
accNeverConsidered := true
|
||||
tccNeverConsidered := true
|
||||
ddcNeverConsidered := true
|
||||
if utils.IsSliceMember([]string{LCR_STRATEGY_QOS, LCR_STRATEGY_QOS_THRESHOLD}, lcrCost.Entry.Strategy) {
|
||||
if stats == nil {
|
||||
lcrCost.SupplierCosts = append(lcrCost.SupplierCosts, &LCRSupplierCost{
|
||||
@@ -909,6 +911,12 @@ func (cd *CallDescriptor) GetLCR(stats StatsInterface) (*LCRCost, error) {
|
||||
}
|
||||
tccNeverConsidered = false
|
||||
}
|
||||
if ddc, exists := statValues[TCC]; exists {
|
||||
if ddc > STATS_NA {
|
||||
ddcValues = append(ddcValues, ddc)
|
||||
}
|
||||
ddcNeverConsidered = false
|
||||
}
|
||||
}
|
||||
if statsErr { // Stats error in loop, to go next supplier
|
||||
continue
|
||||
@@ -919,6 +927,7 @@ func (cd *CallDescriptor) GetLCR(stats StatsInterface) (*LCRCost, error) {
|
||||
tcdValues.Sort()
|
||||
accValues.Sort()
|
||||
tccValues.Sort()
|
||||
ddcValues.Sort()
|
||||
|
||||
//log.Print(asrValues, acdValues)
|
||||
if utils.IsSliceMember([]string{LCR_STRATEGY_QOS_THRESHOLD, LCR_STRATEGY_QOS}, lcrCost.Entry.Strategy) {
|
||||
@@ -926,7 +935,7 @@ func (cd *CallDescriptor) GetLCR(stats StatsInterface) (*LCRCost, error) {
|
||||
}
|
||||
if lcrCost.Entry.Strategy == LCR_STRATEGY_QOS_THRESHOLD {
|
||||
// filter suppliers by qos thresholds
|
||||
asrMin, asrMax, pddMin, pddMax, acdMin, acdMax, tcdMin, tcdMax, accMin, accMax, tccMin, tccMax := lcrCost.Entry.GetQOSLimits()
|
||||
asrMin, asrMax, pddMin, pddMax, acdMin, acdMax, tcdMin, tcdMax, accMin, accMax, tccMin, tccMax, ddcMin, ddcMax := lcrCost.Entry.GetQOSLimits()
|
||||
//log.Print(asrMin, asrMax, acdMin, acdMax)
|
||||
// skip current supplier if off limits
|
||||
if asrMin > 0 && len(asrValues) != 0 && asrValues[0] < asrMin {
|
||||
@@ -965,6 +974,12 @@ func (cd *CallDescriptor) GetLCR(stats StatsInterface) (*LCRCost, error) {
|
||||
if tccMax > 0 && len(tccValues) != 0 && tccValues[len(tccValues)-1] > tccMax {
|
||||
continue
|
||||
}
|
||||
if ddcMin > 0 && len(ddcValues) != 0 && ddcValues[0] < ddcMin {
|
||||
continue
|
||||
}
|
||||
if ddcMax > 0 && len(ddcValues) != 0 && ddcValues[len(ddcValues)-1] > ddcMax {
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1019,6 +1034,9 @@ func (cd *CallDescriptor) GetLCR(stats StatsInterface) (*LCRCost, error) {
|
||||
if !tccNeverConsidered {
|
||||
qos[TCC] = utils.AvgNegative(tccValues)
|
||||
}
|
||||
if !ddcNeverConsidered {
|
||||
qos[DDC] = utils.AvgNegative(ddcValues)
|
||||
}
|
||||
if utils.IsSliceMember([]string{LCR_STRATEGY_QOS, LCR_STRATEGY_QOS_THRESHOLD}, lcrCost.Entry.Strategy) {
|
||||
supplCost.QOS = qos
|
||||
supplCost.qosSortParams = qosSortParams
|
||||
|
||||
@@ -162,11 +162,11 @@ func (lcr *LCR) Sort() {
|
||||
sort.Sort(lcr)
|
||||
}
|
||||
|
||||
func (le *LCREntry) GetQOSLimits() (minASR, maxASR float64, minPDD, maxPDD, minACD, maxACD, minTCD, maxTCD time.Duration, minACC, maxACC, minTCC, maxTCC float64) {
|
||||
// MIN_ASR;MAX_ASR;MIN_PDD;MAX_PDD;MIN_ACD;MAX_ACD;MIN_TCD;MAX_TCD;MIN_ACC;MAX_ACC;MIN_TCC;MAX_TCC
|
||||
minASR, maxASR, minPDD, maxPDD, minACD, maxACD, minTCD, maxTCD, minACC, maxACC, minTCC, maxTCC = -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
|
||||
func (le *LCREntry) GetQOSLimits() (minASR, maxASR float64, minPDD, maxPDD, minACD, maxACD, minTCD, maxTCD time.Duration, minACC, maxACC, minTCC, maxTCC, minDDC, maxDDC float64) {
|
||||
// MIN_ASR;MAX_ASR;MIN_PDD;MAX_PDD;MIN_ACD;MAX_ACD;MIN_TCD;MAX_TCD;MIN_ACC;MAX_ACC;MIN_TCC;MAX_TCC;MIN_DDC;MAX_DDC
|
||||
minASR, maxASR, minPDD, maxPDD, minACD, maxACD, minTCD, maxTCD, minACC, maxACC, minTCC, maxTCC, minDDC, maxDDC = -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
|
||||
params := strings.Split(le.StrategyParams, utils.INFIELD_SEP)
|
||||
if len(params) == 12 {
|
||||
if len(params) == 14 {
|
||||
var err error
|
||||
if minASR, err = strconv.ParseFloat(params[0], 64); err != nil {
|
||||
minASR = -1
|
||||
@@ -204,6 +204,12 @@ func (le *LCREntry) GetQOSLimits() (minASR, maxASR float64, minPDD, maxPDD, minA
|
||||
if maxTCC, err = strconv.ParseFloat(params[11], 64); err != nil {
|
||||
maxTCC = -1
|
||||
}
|
||||
if minDDC, err = strconv.ParseFloat(params[12], 64); err != nil {
|
||||
minDDC = -1
|
||||
}
|
||||
if maxDDC, err = strconv.ParseFloat(params[13], 64); err != nil {
|
||||
maxDDC = -1
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -220,7 +226,7 @@ func (le *LCREntry) GetParams() []string {
|
||||
}
|
||||
}
|
||||
if len(cleanParams) == 0 && le.Strategy == LCR_STRATEGY_QOS {
|
||||
return []string{ASR, PDD, ACD, TCD, ACC, TCC} // Default QoS stats if none configured
|
||||
return []string{ASR, PDD, ACD, TCD, ACC, TCC, DDC} // Default QoS stats if none configured
|
||||
}
|
||||
return cleanParams
|
||||
}
|
||||
|
||||
@@ -94,46 +94,49 @@ func TestLcrQOSSorterOACD(t *testing.T) {
|
||||
|
||||
func TestLcrGetQosLimitsAll(t *testing.T) {
|
||||
le := &LCREntry{
|
||||
StrategyParams: "1.2;2.3;4;7;45s;67m;16s;17m;8.9;10.11;12.13;14.15",
|
||||
StrategyParams: "1.2;2.3;4;7;45s;67m;16s;17m;8.9;10.11;12.13;14.15;2;3",
|
||||
}
|
||||
minAsr, maxAsr, minPdd, maxPdd, minAcd, maxAcd, minTcd, maxTcd, minAcc, maxAcc, minTcc, maxTcc := le.GetQOSLimits()
|
||||
minAsr, maxAsr, minPdd, maxPdd, minAcd, maxAcd, minTcd, maxTcd, minAcc, maxAcc, minTcc, maxTcc, minDdc, maxDdc := le.GetQOSLimits()
|
||||
if minAsr != 1.2 || maxAsr != 2.3 ||
|
||||
minPdd != 4*time.Second || maxPdd != 7*time.Second ||
|
||||
minAcd != 45*time.Second || maxAcd != 67*time.Minute ||
|
||||
minTcd != 16*time.Second || maxTcd != 17*time.Minute ||
|
||||
minAcc != 8.9 || maxAcc != 10.11 ||
|
||||
minTcc != 12.13 || maxTcc != 14.15 {
|
||||
t.Error("Wrong qos limits parsed: ", minAsr, maxAsr, minPdd, maxPdd, minAcd, maxAcd, minTcd, maxTcd, minAcc, maxAcc, minTcc, maxTcc)
|
||||
minTcc != 12.13 || maxTcc != 14.15 ||
|
||||
minDdc != 2 || maxDdc != 3 {
|
||||
t.Error("Wrong qos limits parsed: ", minAsr, maxAsr, minPdd, maxPdd, minAcd, maxAcd, minTcd, maxTcd, minAcc, maxAcc, minTcc, maxTcc, minDdc, maxDdc)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLcrGetQosLimitsSome(t *testing.T) {
|
||||
le := &LCREntry{
|
||||
StrategyParams: "1.2;;3;;;67m;;30m;1;;3;",
|
||||
StrategyParams: "1.2;;3;;;67m;;30m;1;;3;;;2",
|
||||
}
|
||||
minAsr, maxAsr, minPdd, maxPdd, minAcd, maxAcd, minTcd, maxTcd, minAcc, maxAcc, minTcc, maxTcc := le.GetQOSLimits()
|
||||
minAsr, maxAsr, minPdd, maxPdd, minAcd, maxAcd, minTcd, maxTcd, minAcc, maxAcc, minTcc, maxTcc, minDdc, maxDdc := le.GetQOSLimits()
|
||||
if minAsr != 1.2 || maxAsr != -1 ||
|
||||
minPdd != 3*time.Second || maxPdd != -1 ||
|
||||
minAcd != -1 || maxAcd != 67*time.Minute ||
|
||||
minTcd != -1 || maxTcd != 30*time.Minute ||
|
||||
minAcc != 1 || maxAcc != -1 ||
|
||||
minTcc != 3 || maxTcc != -1 {
|
||||
t.Error("Wrong qos limits parsed: ", minAsr, maxAsr, minAcd, maxAcd, minTcd, maxTcd)
|
||||
minTcc != 3 || maxTcc != -1 ||
|
||||
minDdc != -1 || maxDdc != 2 {
|
||||
t.Error("Wrong qos limits parsed: ", minAsr, maxAsr, minAcd, maxAcd, minTcd, maxTcd, minTcc, maxTcc, minDdc, maxDdc)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLcrGetQosLimitsNone(t *testing.T) {
|
||||
le := &LCREntry{
|
||||
StrategyParams: ";;;;;;;;;",
|
||||
StrategyParams: ";;;;;;;;;;;",
|
||||
}
|
||||
minAsr, maxAsr, minPdd, maxPdd, minAcd, maxAcd, minTcd, maxTcd, minAcc, maxAcc, minTcc, maxTcc := le.GetQOSLimits()
|
||||
minAsr, maxAsr, minPdd, maxPdd, minAcd, maxAcd, minTcd, maxTcd, minAcc, maxAcc, minTcc, maxTcc, minDdc, maxDdc := le.GetQOSLimits()
|
||||
if minAsr != -1 || maxAsr != -1 ||
|
||||
minPdd != -1 || maxPdd != -1 ||
|
||||
minAcd != -1 || maxAcd != -1 ||
|
||||
minTcd != -1 || maxTcd != -1 ||
|
||||
minAcc != -1 || maxAcc != -1 ||
|
||||
minTcc != -1 || maxTcc != -1 {
|
||||
t.Error("Wrong qos limits parsed: ", minAsr, maxAsr, minAcd, maxAcd)
|
||||
minTcc != -1 || maxTcc != -1 ||
|
||||
minDdc != -1 || maxDdc != -1 {
|
||||
t.Error("Wrong qos limits parsed: ", minAsr, maxAsr, minAcd, maxAcd, minDdc, maxDdc)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -284,7 +284,7 @@ func TestGetLCR(t *testing.T) {
|
||||
}
|
||||
}
|
||||
danStatsId := "dan12_stats"
|
||||
rsponder.Stats.AddQueue(&CdrStats{Id: danStatsId, Supplier: []string{"dan12"}, Metrics: []string{ASR, PDD, ACD, TCD, ACC, TCC}}, nil)
|
||||
rsponder.Stats.AddQueue(&CdrStats{Id: danStatsId, Supplier: []string{"dan12"}, Metrics: []string{ASR, PDD, ACD, TCD, ACC, TCC, DDC}}, nil)
|
||||
danRpfl := &RatingProfile{Id: "*out:tenant12:call:dan12",
|
||||
RatingPlanActivations: RatingPlanActivations{&RatingPlanActivation{
|
||||
ActivationTime: time.Date(2015, 01, 01, 8, 0, 0, 0, time.UTC),
|
||||
@@ -294,7 +294,7 @@ func TestGetLCR(t *testing.T) {
|
||||
}},
|
||||
}
|
||||
rifStatsId := "rif12_stats"
|
||||
rsponder.Stats.AddQueue(&CdrStats{Id: rifStatsId, Supplier: []string{"rif12"}, Metrics: []string{ASR, PDD, ACD, TCD, ACC, TCC}}, nil)
|
||||
rsponder.Stats.AddQueue(&CdrStats{Id: rifStatsId, Supplier: []string{"rif12"}, Metrics: []string{ASR, PDD, ACD, TCD, ACC, TCC, DDC}}, nil)
|
||||
rifRpfl := &RatingProfile{Id: "*out:tenant12:call:rif12",
|
||||
RatingPlanActivations: RatingPlanActivations{&RatingPlanActivation{
|
||||
ActivationTime: time.Date(2015, 01, 01, 8, 0, 0, 0, time.UTC),
|
||||
@@ -304,7 +304,7 @@ func TestGetLCR(t *testing.T) {
|
||||
}},
|
||||
}
|
||||
ivoStatsId := "ivo12_stats"
|
||||
rsponder.Stats.AddQueue(&CdrStats{Id: ivoStatsId, Supplier: []string{"ivo12"}, Metrics: []string{ASR, PDD, ACD, TCD, ACC, TCC}}, nil)
|
||||
rsponder.Stats.AddQueue(&CdrStats{Id: ivoStatsId, Supplier: []string{"ivo12"}, Metrics: []string{ASR, PDD, ACD, TCD, ACC, TCC, DDC}}, nil)
|
||||
ivoRpfl := &RatingProfile{Id: "*out:tenant12:call:ivo12",
|
||||
RatingPlanActivations: RatingPlanActivations{&RatingPlanActivation{
|
||||
ActivationTime: time.Date(2015, 01, 01, 8, 0, 0, 0, time.UTC),
|
||||
@@ -341,7 +341,7 @@ func TestGetLCR(t *testing.T) {
|
||||
&LCRActivation{
|
||||
ActivationTime: time.Date(2015, 01, 01, 8, 0, 0, 0, time.UTC),
|
||||
Entries: []*LCREntry{
|
||||
&LCREntry{DestinationId: utils.ANY, RPCategory: "call", Strategy: LCR_STRATEGY_QOS_THRESHOLD, StrategyParams: "35;;;;4m;;;;;;;", Weight: 10.0}},
|
||||
&LCREntry{DestinationId: utils.ANY, RPCategory: "call", Strategy: LCR_STRATEGY_QOS_THRESHOLD, StrategyParams: "35;;;;4m;;;;;;;;;", Weight: 10.0}},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -459,11 +459,11 @@ func TestGetLCR(t *testing.T) {
|
||||
Subject: "dan",
|
||||
}
|
||||
eQTLcr := &LCRCost{
|
||||
Entry: &LCREntry{DestinationId: utils.ANY, RPCategory: "call", Strategy: LCR_STRATEGY_QOS_THRESHOLD, StrategyParams: "35;;;;4m;;;;;;;", Weight: 10.0},
|
||||
Entry: &LCREntry{DestinationId: utils.ANY, RPCategory: "call", Strategy: LCR_STRATEGY_QOS_THRESHOLD, StrategyParams: "35;;;;4m;;;;;;;;;", Weight: 10.0},
|
||||
SupplierCosts: []*LCRSupplierCost{
|
||||
&LCRSupplierCost{Supplier: "*out:tenant12:call:ivo12", Cost: 0, Duration: 60 * time.Second, QOS: map[string]float64{TCD: -1, ACC: -1, TCC: -1, ASR: -1, ACD: -1, PDD: -1}, qosSortParams: []string{"35", "4m"}},
|
||||
&LCRSupplierCost{Supplier: "*out:tenant12:call:rif12", Cost: 0.4, Duration: 60 * time.Second, QOS: map[string]float64{TCD: -1, ACC: -1, TCC: -1, ASR: -1, ACD: -1, PDD: -1}, qosSortParams: []string{"35", "4m"}},
|
||||
&LCRSupplierCost{Supplier: "*out:tenant12:call:dan12", Cost: 0.6, Duration: 60 * time.Second, QOS: map[string]float64{TCD: -1, ACC: -1, TCC: -1, ASR: -1, ACD: -1, PDD: -1}, qosSortParams: []string{"35", "4m"}},
|
||||
&LCRSupplierCost{Supplier: "*out:tenant12:call:ivo12", Cost: 0, Duration: 60 * time.Second, QOS: map[string]float64{TCD: -1, ACC: -1, TCC: -1, ASR: -1, ACD: -1, PDD: -1, DDC: -1}, qosSortParams: []string{"35", "4m"}},
|
||||
&LCRSupplierCost{Supplier: "*out:tenant12:call:rif12", Cost: 0.4, Duration: 60 * time.Second, QOS: map[string]float64{TCD: -1, ACC: -1, TCC: -1, ASR: -1, ACD: -1, PDD: -1, DDC: -1}, qosSortParams: []string{"35", "4m"}},
|
||||
&LCRSupplierCost{Supplier: "*out:tenant12:call:dan12", Cost: 0.6, Duration: 60 * time.Second, QOS: map[string]float64{TCD: -1, ACC: -1, TCC: -1, ASR: -1, ACD: -1, PDD: -1, DDC: -1}, qosSortParams: []string{"35", "4m"}},
|
||||
},
|
||||
}
|
||||
var lcrQT LCRCost
|
||||
@@ -480,10 +480,10 @@ func TestGetLCR(t *testing.T) {
|
||||
cdr = &StoredCdr{Supplier: "dan12", AnswerTime: time.Now(), Usage: 5 * time.Minute, Cost: 2}
|
||||
rsponder.Stats.AppendCDR(cdr, nil)
|
||||
eQTLcr = &LCRCost{
|
||||
Entry: &LCREntry{DestinationId: utils.ANY, RPCategory: "call", Strategy: LCR_STRATEGY_QOS_THRESHOLD, StrategyParams: "35;;;;4m;;;;;;;", Weight: 10.0},
|
||||
Entry: &LCREntry{DestinationId: utils.ANY, RPCategory: "call", Strategy: LCR_STRATEGY_QOS_THRESHOLD, StrategyParams: "35;;;;4m;;;;;;;;;", Weight: 10.0},
|
||||
SupplierCosts: []*LCRSupplierCost{
|
||||
&LCRSupplierCost{Supplier: "*out:tenant12:call:ivo12", Cost: 0, Duration: 60 * time.Second, QOS: map[string]float64{PDD: -1, TCD: -1, ACC: -1, TCC: -1, ASR: -1, ACD: -1}, qosSortParams: []string{"35", "4m"}},
|
||||
&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}, qosSortParams: []string{"35", "4m"}},
|
||||
&LCRSupplierCost{Supplier: "*out:tenant12:call:ivo12", Cost: 0, Duration: 60 * time.Second, QOS: map[string]float64{PDD: -1, TCD: -1, ACC: -1, TCC: -1, ASR: -1, ACD: -1, DDC: -1}, qosSortParams: []string{"35", "4m"}},
|
||||
&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 {
|
||||
@@ -492,7 +492,7 @@ func TestGetLCR(t *testing.T) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", eQTLcr.Entry, lcrQT.Entry)
|
||||
|
||||
} else if !reflect.DeepEqual(eQTLcr.SupplierCosts, lcrQT.SupplierCosts) {
|
||||
t.Errorf("Expecting: %+v, received: %+v", eQTLcr.SupplierCosts[0], lcrQT.SupplierCosts[0])
|
||||
t.Errorf("Expecting: %+v, received: %+v", eQTLcr.SupplierCosts[1], lcrQT.SupplierCosts[1])
|
||||
}
|
||||
|
||||
// Test *qos strategy here
|
||||
@@ -509,9 +509,9 @@ func TestGetLCR(t *testing.T) {
|
||||
eQosLcr := &LCRCost{
|
||||
Entry: &LCREntry{DestinationId: utils.ANY, RPCategory: "call", Strategy: LCR_STRATEGY_QOS, Weight: 10.0},
|
||||
SupplierCosts: []*LCRSupplierCost{
|
||||
&LCRSupplierCost{Supplier: "*out:tenant12:call:ivo12", Cost: 0, Duration: 60 * time.Second, QOS: map[string]float64{ACD: -1, PDD: -1, TCD: -1, ASR: -1, ACC: -1, TCC: -1}, qosSortParams: []string{ASR, PDD, ACD, TCD, ACC, TCC}},
|
||||
&LCRSupplierCost{Supplier: "*out:tenant12:call:dan12", Cost: 0.6, Duration: 60 * time.Second, QOS: map[string]float64{ACD: 300, PDD: -1, TCD: 300, ASR: 100, ACC: 2, TCC: 2}, qosSortParams: []string{ASR, PDD, ACD, TCD, ACC, TCC}},
|
||||
&LCRSupplierCost{Supplier: "*out:tenant12:call:rif12", Cost: 0.4, Duration: 60 * time.Second, QOS: map[string]float64{ACD: 180, PDD: -1, TCD: 180, ASR: 100, ACC: 1, TCC: 1}, qosSortParams: []string{ASR, PDD, ACD, TCD, ACC, TCC}},
|
||||
&LCRSupplierCost{Supplier: "*out:tenant12:call:ivo12", Cost: 0, Duration: 60 * time.Second, QOS: map[string]float64{ACD: -1, PDD: -1, TCD: -1, ASR: -1, ACC: -1, TCC: -1, DDC: -1}, qosSortParams: []string{ASR, PDD, ACD, TCD, ACC, TCC, DDC}},
|
||||
&LCRSupplierCost{Supplier: "*out:tenant12:call:dan12", Cost: 0.6, Duration: 60 * time.Second, QOS: map[string]float64{ACD: 300, PDD: -1, TCD: 300, ASR: 100, ACC: 2, TCC: 2, DDC: 2}, qosSortParams: []string{ASR, PDD, ACD, TCD, ACC, TCC, DDC}},
|
||||
&LCRSupplierCost{Supplier: "*out:tenant12:call:rif12", Cost: 0.4, Duration: 60 * time.Second, QOS: map[string]float64{ACD: 180, PDD: -1, TCD: 180, ASR: 100, ACC: 1, TCC: 1, DDC: 1}, qosSortParams: []string{ASR, PDD, ACD, TCD, ACC, TCC, DDC}},
|
||||
},
|
||||
}
|
||||
var lcrQ LCRCost
|
||||
|
||||
@@ -36,6 +36,7 @@ const TCD = "TCD"
|
||||
const ACC = "ACC"
|
||||
const TCC = "TCC"
|
||||
const PDD = "PDD"
|
||||
const DDC = "DDC"
|
||||
const STATS_NA = -1
|
||||
|
||||
func CreateMetric(metric string) Metric {
|
||||
@@ -52,6 +53,8 @@ func CreateMetric(metric string) Metric {
|
||||
return &ACCMetric{}
|
||||
case TCC:
|
||||
return &TCCMetric{}
|
||||
case DDC:
|
||||
return NewDccMetric()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -230,37 +233,37 @@ func (tcc *TCCMetric) GetValue() float64 {
|
||||
return utils.Round(tcc.sum, globalRoundingDecimals, utils.ROUNDING_MIDDLE)
|
||||
}
|
||||
|
||||
// DIC - Destination ID Counter
|
||||
// DDC - Destination Distinct Count
|
||||
//
|
||||
type DICMetric struct {
|
||||
type DCCMetric struct {
|
||||
destinations map[string]int64
|
||||
}
|
||||
|
||||
func (dic *DICMetric) AddCdr(cdr *QCdr) {
|
||||
if dic.destinations == nil {
|
||||
dic.destinations = make(map[string]int64)
|
||||
}
|
||||
if count, exists := dic.destinations[cdr.Dest]; exists {
|
||||
dic.destinations[cdr.Dest] = count + 1
|
||||
} else {
|
||||
dic.destinations[cdr.Dest] = 0
|
||||
func NewDccMetric() *DCCMetric {
|
||||
return &DCCMetric{
|
||||
destinations: make(map[string]int64),
|
||||
}
|
||||
}
|
||||
|
||||
func (dic *DICMetric) RemoveCdr(cdr *QCdr) {
|
||||
if dic.destinations == nil {
|
||||
dic.destinations = make(map[string]int64)
|
||||
}
|
||||
if count, exists := dic.destinations[cdr.Dest]; exists && count > 1 {
|
||||
dic.destinations[cdr.Dest] = count - 1
|
||||
func (dcc *DCCMetric) AddCdr(cdr *QCdr) {
|
||||
if count, exists := dcc.destinations[cdr.Dest]; exists {
|
||||
dcc.destinations[cdr.Dest] = count + 1
|
||||
} else {
|
||||
dic.destinations[cdr.Dest] = 0
|
||||
dcc.destinations[cdr.Dest] = 0
|
||||
}
|
||||
}
|
||||
|
||||
func (dic *DICMetric) GetValue() float64 {
|
||||
if len(dic.destinations) == 0 {
|
||||
func (dcc *DCCMetric) RemoveCdr(cdr *QCdr) {
|
||||
if count, exists := dcc.destinations[cdr.Dest]; exists && count > 1 {
|
||||
dcc.destinations[cdr.Dest] = count - 1
|
||||
} else {
|
||||
dcc.destinations[cdr.Dest] = 0
|
||||
}
|
||||
}
|
||||
|
||||
func (dcc *DCCMetric) GetValue() float64 {
|
||||
if len(dcc.destinations) == 0 {
|
||||
return STATS_NA
|
||||
}
|
||||
return float64(len(dic.destinations))
|
||||
return float64(len(dcc.destinations))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user