diff --git a/engine/libstats.go b/engine/libstats.go
index 08d6b3354..96c22cbad 100644
--- a/engine/libstats.go
+++ b/engine/libstats.go
@@ -19,9 +19,12 @@ along with this program. If not, see
package engine
import (
+ "bytes"
+ "encoding/gob"
"encoding/json"
"fmt"
"sort"
+ "strings"
"sync"
"time"
@@ -343,18 +346,20 @@ func (sis StatQueues) Sort() {
sort.Slice(sis, func(i, j int) bool { return sis[i].sqPrfl.Weight > sis[j].sqPrfl.Weight })
}
+type encStatQueue struct {
+ Tenant string
+ ID string
+ SQItems []SQItem
+ SQMetrics map[string]StatMetric
+}
+
func (sq *StatQueue) MarshalJSON() (rply []byte, err error) {
if sq == nil {
return []byte("null"), nil
}
guardian.Guardian.Guard(context.Background(), func(*context.Context) (_ interface{}, _ error) {
sq.RLock()
- rply, err = json.Marshal(struct {
- Tenant string
- ID string
- SQItems []SQItem
- SQMetrics map[string]StatMetric
- }{
+ rply, err = json.Marshal(&encStatQueue{
Tenant: sq.Tenant,
ID: sq.ID,
SQItems: sq.SQItems,
@@ -366,4 +371,69 @@ func (sq *StatQueue) MarshalJSON() (rply []byte, err error) {
return
}
-// func (sq *StatQueue) GobEncode() ([]byte, error)
+// UnmarshalJSON here only to fully support json for StatQueue
+func (sq *StatQueue) UnmarshalJSON(data []byte) (err error) {
+ var tmp struct {
+ Tenant string
+ ID string
+ SQItems []SQItem
+ SQMetrics map[string]json.RawMessage
+ }
+ if err = json.Unmarshal(data, &tmp); err != nil {
+ return
+ }
+ sq.Tenant = tmp.Tenant
+ sq.ID = tmp.ID
+ sq.SQItems = tmp.SQItems
+ sq.SQMetrics = make(map[string]StatMetric)
+ for metricID, val := range tmp.SQMetrics {
+ metricSplit := strings.Split(metricID, utils.HashtagSep)
+ var metric StatMetric
+ switch metricSplit[0] {
+ case utils.MetaASR:
+ metric = new(StatASR)
+ case utils.MetaACD:
+ metric = new(StatACD)
+ case utils.MetaTCD:
+ metric = new(StatTCD)
+ case utils.MetaACC:
+ metric = new(StatACC)
+ case utils.MetaTCC:
+ metric = new(StatTCC)
+ case utils.MetaPDD:
+ metric = new(StatPDD)
+ case utils.MetaDDC:
+ metric = new(StatDDC)
+ case utils.MetaSum:
+ metric = new(StatSum)
+ case utils.MetaAverage:
+ metric = new(StatAverage)
+ case utils.MetaDistinct:
+ metric = new(StatDistinct)
+ default:
+ return fmt.Errorf("unsupported metric type <%s>", metricSplit[0])
+ }
+ if err = json.Unmarshal([]byte(val), metric); err != nil {
+ fmt.Println(1)
+ return
+ }
+ sq.SQMetrics[metricID] = metric
+ }
+ return
+}
+
+func (sq *StatQueue) GobEncode() (rply []byte, err error) {
+ buf := bytes.NewBuffer(rply)
+ guardian.Guardian.Guard(context.Background(), func(*context.Context) (_ interface{}, _ error) {
+ sq.RLock()
+ err = gob.NewEncoder(buf).Encode(&encStatQueue{
+ Tenant: sq.Tenant,
+ ID: sq.ID,
+ SQItems: sq.SQItems,
+ SQMetrics: sq.SQMetrics,
+ })
+ sq.RUnlock()
+ return
+ }, config.CgrConfig().GeneralCfg().LockingTimeout, utils.StatQueuePrefix+sq.TenantID())
+ return buf.Bytes(), nil
+}
diff --git a/engine/libstats_test.go b/engine/libstats_test.go
index 697dc6196..4d60fbc7e 100644
--- a/engine/libstats_test.go
+++ b/engine/libstats_test.go
@@ -18,6 +18,7 @@ along with this program. If not, see
package engine
import (
+ "encoding/json"
"reflect"
"testing"
"time"
@@ -694,3 +695,20 @@ func TestStatRemoveExpiredQueue(t *testing.T) {
t.Errorf("Expecting: 2, received: %+v", len(sq.SQItems))
}
}
+
+func TestStatQueueJSONMarshall(t *testing.T) {
+ rply := new(StatQueue)
+ exp, err := NewStatQueue("cgrates.org", "STS", []*MetricWithFilters{
+ {MetricID: utils.MetaASR},
+ {MetricID: utils.MetaTCD},
+ }, 1)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if err = json.Unmarshal([]byte(utils.ToJSON(exp)), rply); err != nil {
+ t.Fatal(err)
+ } else if !reflect.DeepEqual(rply, exp) {
+ t.Errorf("Expected: %s , received: %s", utils.ToJSON(exp), utils.ToJSON(rply))
+ }
+
+}