mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
refactor(): refactoring json usage
This commit is contained in:
parent
40b2f00dc5
commit
3fb0b71822
@ -4,7 +4,6 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"log"
|
"log"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -51,6 +50,11 @@ func New() *Json {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// New returns a pointer to a new, empty `Json` object
|
||||||
|
func NewFromAny(data interface{}) *Json {
|
||||||
|
return &Json{data: data}
|
||||||
|
}
|
||||||
|
|
||||||
// Interface returns the underlying data
|
// Interface returns the underlying data
|
||||||
func (j *Json) Interface() interface{} {
|
func (j *Json) Interface() interface{} {
|
||||||
return j.data
|
return j.data
|
||||||
@ -68,7 +72,6 @@ func (j *Json) EncodePretty() ([]byte, error) {
|
|||||||
|
|
||||||
// Implements the json.Marshaler interface.
|
// Implements the json.Marshaler interface.
|
||||||
func (j *Json) MarshalJSON() ([]byte, error) {
|
func (j *Json) MarshalJSON() ([]byte, error) {
|
||||||
fmt.Printf("MarshalJSON")
|
|
||||||
return json.Marshal(&j.data)
|
return json.Marshal(&j.data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gosimple/slug"
|
"github.com/gosimple/slug"
|
||||||
|
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Typed errors
|
// Typed errors
|
||||||
@ -37,14 +38,14 @@ type Dashboard struct {
|
|||||||
CreatedBy int64
|
CreatedBy int64
|
||||||
|
|
||||||
Title string
|
Title string
|
||||||
Data map[string]interface{}
|
Data *simplejson.Json
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDashboard creates a new dashboard
|
// NewDashboard creates a new dashboard
|
||||||
func NewDashboard(title string) *Dashboard {
|
func NewDashboard(title string) *Dashboard {
|
||||||
dash := &Dashboard{}
|
dash := &Dashboard{}
|
||||||
dash.Data = make(map[string]interface{})
|
dash.Data = simplejson.New()
|
||||||
dash.Data["title"] = title
|
dash.Data.Set("title", title)
|
||||||
dash.Title = title
|
dash.Title = title
|
||||||
dash.Created = time.Now()
|
dash.Created = time.Now()
|
||||||
dash.Updated = time.Now()
|
dash.Updated = time.Now()
|
||||||
@ -54,34 +55,24 @@ func NewDashboard(title string) *Dashboard {
|
|||||||
|
|
||||||
// GetTags turns the tags in data json into go string array
|
// GetTags turns the tags in data json into go string array
|
||||||
func (dash *Dashboard) GetTags() []string {
|
func (dash *Dashboard) GetTags() []string {
|
||||||
jsonTags := dash.Data["tags"]
|
return dash.Data.Get("tags").MustStringArray()
|
||||||
if jsonTags == nil || jsonTags == "" {
|
|
||||||
return []string{}
|
|
||||||
}
|
|
||||||
|
|
||||||
arr := jsonTags.([]interface{})
|
|
||||||
b := make([]string, len(arr))
|
|
||||||
for i := range arr {
|
|
||||||
b[i] = arr[i].(string)
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDashboardFromJson(data map[string]interface{}) *Dashboard {
|
func NewDashboardFromJson(data *simplejson.Json) *Dashboard {
|
||||||
dash := &Dashboard{}
|
dash := &Dashboard{}
|
||||||
dash.Data = data
|
dash.Data = data
|
||||||
dash.Title = dash.Data["title"].(string)
|
dash.Title = dash.Data.Get("title").MustString()
|
||||||
dash.UpdateSlug()
|
dash.UpdateSlug()
|
||||||
|
|
||||||
if dash.Data["id"] != nil {
|
if id, err := dash.Data.Get("id").Float64(); err == nil {
|
||||||
dash.Id = int64(dash.Data["id"].(float64))
|
dash.Id = int64(id)
|
||||||
|
|
||||||
if dash.Data["version"] != nil {
|
if version, err := dash.Data.Get("version").Float64(); err == nil {
|
||||||
dash.Version = int(dash.Data["version"].(float64))
|
dash.Version = int(version)
|
||||||
dash.Updated = time.Now()
|
dash.Updated = time.Now()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
dash.Data["version"] = 0
|
dash.Data.Set("version", 0)
|
||||||
dash.Created = time.Now()
|
dash.Created = time.Now()
|
||||||
dash.Updated = time.Now()
|
dash.Updated = time.Now()
|
||||||
}
|
}
|
||||||
@ -92,9 +83,11 @@ func NewDashboardFromJson(data map[string]interface{}) *Dashboard {
|
|||||||
// GetDashboardModel turns the command into the savable model
|
// GetDashboardModel turns the command into the savable model
|
||||||
func (cmd *SaveDashboardCommand) GetDashboardModel() *Dashboard {
|
func (cmd *SaveDashboardCommand) GetDashboardModel() *Dashboard {
|
||||||
dash := NewDashboardFromJson(cmd.Dashboard)
|
dash := NewDashboardFromJson(cmd.Dashboard)
|
||||||
if dash.Data["version"] == 0 {
|
|
||||||
|
if dash.Data.Get("version").MustInt(0) == 0 {
|
||||||
dash.CreatedBy = cmd.UserId
|
dash.CreatedBy = cmd.UserId
|
||||||
}
|
}
|
||||||
|
|
||||||
dash.UpdatedBy = cmd.UserId
|
dash.UpdatedBy = cmd.UserId
|
||||||
dash.OrgId = cmd.OrgId
|
dash.OrgId = cmd.OrgId
|
||||||
dash.UpdateSlug()
|
dash.UpdateSlug()
|
||||||
@ -103,15 +96,12 @@ func (cmd *SaveDashboardCommand) GetDashboardModel() *Dashboard {
|
|||||||
|
|
||||||
// GetString a
|
// GetString a
|
||||||
func (dash *Dashboard) GetString(prop string, defaultValue string) string {
|
func (dash *Dashboard) GetString(prop string, defaultValue string) string {
|
||||||
if val, exists := dash.Data[prop]; exists {
|
return dash.Data.Get(prop).MustString(defaultValue)
|
||||||
return val.(string)
|
|
||||||
}
|
|
||||||
return defaultValue
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateSlug updates the slug
|
// UpdateSlug updates the slug
|
||||||
func (dash *Dashboard) UpdateSlug() {
|
func (dash *Dashboard) UpdateSlug() {
|
||||||
title := strings.ToLower(dash.Data["title"].(string))
|
title := strings.ToLower(dash.Data.Get("title").MustString())
|
||||||
dash.Slug = slug.Make(title)
|
dash.Slug = slug.Make(title)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,10 +110,10 @@ func (dash *Dashboard) UpdateSlug() {
|
|||||||
//
|
//
|
||||||
|
|
||||||
type SaveDashboardCommand struct {
|
type SaveDashboardCommand struct {
|
||||||
Dashboard map[string]interface{} `json:"dashboard" binding:"Required"`
|
Dashboard *simplejson.Json `json:"dashboard" binding:"Required"`
|
||||||
UserId int64 `json:"userId"`
|
UserId int64 `json:"userId"`
|
||||||
OrgId int64 `json:"-"`
|
OrgId int64 `json:"-"`
|
||||||
Overwrite bool `json:"overwrite"`
|
Overwrite bool `json:"overwrite"`
|
||||||
|
|
||||||
Result *Dashboard
|
Result *Dashboard
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package models
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||||
. "github.com/smartystreets/goconvey/convey"
|
. "github.com/smartystreets/goconvey/convey"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -16,12 +17,11 @@ func TestDashboardModel(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
Convey("Given a dashboard json", t, func() {
|
Convey("Given a dashboard json", t, func() {
|
||||||
json := map[string]interface{}{
|
json := simplejson.New()
|
||||||
"title": "test dash",
|
json.Set("title", "test dash")
|
||||||
}
|
|
||||||
|
|
||||||
Convey("With tags as string value", func() {
|
Convey("With tags as string value", func() {
|
||||||
json["tags"] = ""
|
json.Set("tags", "")
|
||||||
dash := NewDashboardFromJson(json)
|
dash := NewDashboardFromJson(json)
|
||||||
|
|
||||||
So(len(dash.GetTags()), ShouldEqual, 0)
|
So(len(dash.GetTags()), ShouldEqual, 0)
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
"regexp"
|
"regexp"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/bus"
|
"github.com/grafana/grafana/pkg/bus"
|
||||||
"github.com/grafana/grafana/pkg/components/dynmap"
|
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||||
"github.com/grafana/grafana/pkg/log"
|
"github.com/grafana/grafana/pkg/log"
|
||||||
m "github.com/grafana/grafana/pkg/models"
|
m "github.com/grafana/grafana/pkg/models"
|
||||||
)
|
)
|
||||||
@ -54,9 +54,8 @@ func ImportDashboard(cmd *ImportDashboardCommand) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
template := dynmap.NewFromMap(dashboard.Data)
|
|
||||||
evaluator := &DashTemplateEvaluator{
|
evaluator := &DashTemplateEvaluator{
|
||||||
template: template,
|
template: dashboard.Data,
|
||||||
inputs: cmd.Inputs,
|
inputs: cmd.Inputs,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,7 +65,7 @@ func ImportDashboard(cmd *ImportDashboardCommand) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
saveCmd := m.SaveDashboardCommand{
|
saveCmd := m.SaveDashboardCommand{
|
||||||
Dashboard: generatedDash.StringMap(),
|
Dashboard: generatedDash,
|
||||||
OrgId: cmd.OrgId,
|
OrgId: cmd.OrgId,
|
||||||
UserId: cmd.UserId,
|
UserId: cmd.UserId,
|
||||||
}
|
}
|
||||||
@ -89,15 +88,15 @@ func ImportDashboard(cmd *ImportDashboardCommand) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type DashTemplateEvaluator struct {
|
type DashTemplateEvaluator struct {
|
||||||
template *dynmap.Object
|
template *simplejson.Json
|
||||||
inputs []ImportDashboardInput
|
inputs []ImportDashboardInput
|
||||||
variables map[string]string
|
variables map[string]string
|
||||||
result *dynmap.Object
|
result *simplejson.Json
|
||||||
varRegex *regexp.Regexp
|
varRegex *regexp.Regexp
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *DashTemplateEvaluator) findInput(varName string, varDef *dynmap.Object) *ImportDashboardInput {
|
func (this *DashTemplateEvaluator) findInput(varName string, varDef *simplejson.Json) *ImportDashboardInput {
|
||||||
inputType, _ := varDef.GetString("type")
|
inputType := varDef.Get("type").MustString()
|
||||||
|
|
||||||
for _, input := range this.inputs {
|
for _, input := range this.inputs {
|
||||||
if inputType == input.Type && (input.Name == varName || input.Name == "*") {
|
if inputType == input.Type && (input.Name == varName || input.Name == "*") {
|
||||||
@ -108,16 +107,15 @@ func (this *DashTemplateEvaluator) findInput(varName string, varDef *dynmap.Obje
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *DashTemplateEvaluator) Eval() (*dynmap.Object, error) {
|
func (this *DashTemplateEvaluator) Eval() (*simplejson.Json, error) {
|
||||||
this.result = dynmap.NewObject()
|
this.result = simplejson.New()
|
||||||
this.variables = make(map[string]string)
|
this.variables = make(map[string]string)
|
||||||
this.varRegex, _ = regexp.Compile("\\$__(\\w+)")
|
this.varRegex, _ = regexp.Compile("\\$__(\\w+)")
|
||||||
|
|
||||||
// check that we have all inputs we need
|
// check that we have all inputs we need
|
||||||
if requiredInputs, err := this.template.GetObject("__inputs"); err == nil {
|
if inputDefs := this.template.Get("__inputs"); inputDefs != nil {
|
||||||
for varName, value := range requiredInputs.Map() {
|
for varName, value := range inputDefs.MustMap() {
|
||||||
varDef, _ := value.Object()
|
input := this.findInput(varName, simplejson.NewFromAny(value))
|
||||||
input := this.findInput(varName, varDef)
|
|
||||||
|
|
||||||
if input == nil {
|
if input == nil {
|
||||||
return nil, &DashboardInputMissingError{VariableName: varName}
|
return nil, &DashboardInputMissingError{VariableName: varName}
|
||||||
@ -133,28 +131,28 @@ func (this *DashTemplateEvaluator) Eval() (*dynmap.Object, error) {
|
|||||||
return this.result, nil
|
return this.result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *DashTemplateEvaluator) EvalObject(source *dynmap.Object, writer *dynmap.Object) {
|
func (this *DashTemplateEvaluator) EvalObject(source *simplejson.Json, writer *simplejson.Json) {
|
||||||
|
|
||||||
for key, value := range source.Map() {
|
for key, value := range source.MustMap() {
|
||||||
if key == "__inputs" {
|
if key == "__inputs" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
goValue := value.Interface()
|
switch v := value.(type) {
|
||||||
|
|
||||||
switch v := goValue.(type) {
|
|
||||||
case string:
|
case string:
|
||||||
interpolated := this.varRegex.ReplaceAllStringFunc(v, func(match string) string {
|
interpolated := this.varRegex.ReplaceAllStringFunc(v, func(match string) string {
|
||||||
return this.variables[match]
|
return this.variables[match]
|
||||||
})
|
})
|
||||||
writer.SetValue(key, interpolated)
|
writer.Set(key, interpolated)
|
||||||
case map[string]interface{}:
|
case map[string]interface{}:
|
||||||
childSource, _ := value.Object()
|
childSource := simplejson.NewFromAny(value)
|
||||||
childWriter, _ := writer.SetValue(key, map[string]interface{}{}).Object()
|
childWriter := simplejson.New()
|
||||||
|
writer.Set(key, childWriter.Interface())
|
||||||
this.EvalObject(childSource, childWriter)
|
this.EvalObject(childSource, childWriter)
|
||||||
|
case []interface{}:
|
||||||
default:
|
default:
|
||||||
log.Info("type: %v", reflect.TypeOf(goValue))
|
log.Info("type: %v", reflect.TypeOf(value))
|
||||||
log.Error(3, "Unknown json type key: %v , type: %v", key, goValue)
|
log.Error(3, "Unknown json type key: %v , type: %v", key, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/bus"
|
"github.com/grafana/grafana/pkg/bus"
|
||||||
"github.com/grafana/grafana/pkg/components/dynmap"
|
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||||
m "github.com/grafana/grafana/pkg/models"
|
m "github.com/grafana/grafana/pkg/models"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
. "github.com/smartystreets/goconvey/convey"
|
. "github.com/smartystreets/goconvey/convey"
|
||||||
@ -44,21 +44,16 @@ func TestDashboardImport(t *testing.T) {
|
|||||||
Convey("should install dashboard", func() {
|
Convey("should install dashboard", func() {
|
||||||
So(importedDash, ShouldNotBeNil)
|
So(importedDash, ShouldNotBeNil)
|
||||||
|
|
||||||
dashData := dynmap.NewFromMap(importedDash.Data)
|
dashStr, _ := importedDash.Data.EncodePretty()
|
||||||
So(dashData.String(), ShouldEqual, "")
|
So(string(dashStr), ShouldEqual, "")
|
||||||
|
|
||||||
rows := importedDash.Data["rows"].([]interface{})
|
// So(panel["datasource"], ShouldEqual, "graphite")
|
||||||
row1 := rows[0].(map[string]interface{})
|
// So(importedDash.Data["__inputs"], ShouldBeNil)
|
||||||
panels := row1["panels"].([]interface{})
|
|
||||||
panel := panels[0].(map[string]interface{})
|
|
||||||
|
|
||||||
So(panel["datasource"], ShouldEqual, "graphite")
|
|
||||||
So(importedDash.Data["__inputs"], ShouldBeNil)
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
Convey("When evaling dashboard template", t, func() {
|
Convey("When evaling dashboard template", t, func() {
|
||||||
template, _ := dynmap.NewObjectFromBytes([]byte(`{
|
template, _ := simplejson.NewJson([]byte(`{
|
||||||
"__inputs": {
|
"__inputs": {
|
||||||
"graphite": {
|
"graphite": {
|
||||||
"type": "datasource"
|
"type": "datasource"
|
||||||
@ -80,12 +75,12 @@ func TestDashboardImport(t *testing.T) {
|
|||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
|
|
||||||
Convey("should render template", func() {
|
Convey("should render template", func() {
|
||||||
So(res.MustGetString("test.prop", ""), ShouldEqual, "my-server")
|
So(res.GetPath("test", "prop").MustString(), ShouldEqual, "my-server")
|
||||||
})
|
})
|
||||||
|
|
||||||
Convey("should not include inputs in output", func() {
|
Convey("should not include inputs in output", func() {
|
||||||
_, err := res.GetObject("__inputs")
|
inputs := res.Get("__inputs")
|
||||||
So(err, ShouldNotBeNil)
|
So(inputs.Interface(), ShouldBeNil)
|
||||||
})
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
package plugins
|
package plugins
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/bus"
|
"github.com/grafana/grafana/pkg/bus"
|
||||||
|
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||||
m "github.com/grafana/grafana/pkg/models"
|
m "github.com/grafana/grafana/pkg/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -52,10 +52,8 @@ func loadPluginDashboard(plugin *PluginBase, path string) (*m.Dashboard, error)
|
|||||||
|
|
||||||
defer reader.Close()
|
defer reader.Close()
|
||||||
|
|
||||||
jsonParser := json.NewDecoder(reader)
|
data, err := simplejson.NewFromReader(reader)
|
||||||
var data map[string]interface{}
|
if err != nil {
|
||||||
|
|
||||||
if err := jsonParser.Decode(&data); err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ func TestPluginDashboards(t *testing.T) {
|
|||||||
bus.AddHandler("test", func(query *m.GetDashboardQuery) error {
|
bus.AddHandler("test", func(query *m.GetDashboardQuery) error {
|
||||||
if query.Slug == "nginx-connections" {
|
if query.Slug == "nginx-connections" {
|
||||||
dash := m.NewDashboard("Nginx Connections")
|
dash := m.NewDashboard("Nginx Connections")
|
||||||
dash.Data["revision"] = "1.1"
|
dash.Data.Set("revision", "1.1")
|
||||||
query.Result = dash
|
query.Result = dash
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
package search
|
package search
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||||
"github.com/grafana/grafana/pkg/log"
|
"github.com/grafana/grafana/pkg/log"
|
||||||
m "github.com/grafana/grafana/pkg/models"
|
m "github.com/grafana/grafana/pkg/models"
|
||||||
)
|
)
|
||||||
@ -120,10 +120,8 @@ func loadDashboardFromFile(filename string) (*JsonDashIndexItem, error) {
|
|||||||
}
|
}
|
||||||
defer reader.Close()
|
defer reader.Close()
|
||||||
|
|
||||||
jsonParser := json.NewDecoder(reader)
|
data, err := simplejson.NewFromReader(reader)
|
||||||
var data map[string]interface{}
|
if err != nil {
|
||||||
|
|
||||||
if err := jsonParser.Decode(&data); err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user