Storage: Dashboard summary builder cleanup (#56665)

This commit is contained in:
Ryan McKinley 2022-10-13 09:29:19 -04:00 committed by GitHub
parent b8b25f7e31
commit 3b4b528993
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 571 additions and 294 deletions

View File

@ -15,23 +15,36 @@ const (
// Types: influx, prometheus, testdata, ...
StandardKindDataSource = "ds"
// StandardKindPanel: currently used in two ways :( in search it defines a panel within a dashboard
// This is also used to refer to a panel plugin with type: heatmap, timeseries, table, ...
// StandardKindPanel: only used for searchV2 right now
// Standalone panel is not an object kind yet -- library panel, or nested in dashboard
StandardKindPanel = "panel"
// StandardKindTransform: used to show that a dashboard depends on a set of transformations
// NOTE: this should likey be replaced with kind:system/type:transform/uid:joinByField or something like that
StandardKindTransform = "transform"
// StandardKindSVG SVG file support
StandardKindSVG = "svg"
// StandardKindPNG PNG file support
StandardKindPNG = "png"
// StandardKindGeoJSON represents spatial data
StandardKindGeoJSON = "geojson"
// StandardKindQuery early development on panel query library
// the kind may need to change to better encapsulate { targets:[], transforms:[] }
StandardKindQuery = "query"
//----------------------------------------
// References are referenced from objects
//----------------------------------------
// ExternalEntityReferencePlugin: requires a plugin to be installed
ExternalEntityReferencePlugin = "plugin"
// ExternalEntityReferenceRuntime: frontend runtime requirements
ExternalEntityReferenceRuntime = "runtime"
// ExternalEntityReferenceRuntime_Transformer is a "type" under runtime
// UIDs include: joinByField, organize, seriesToColumns, etc
ExternalEntityReferenceRuntime_Transformer = "transformer"
)
// ObjectKindInfo describes information needed from the object store

View File

@ -213,13 +213,13 @@ func getDashboardPanelDocs(dash dashboard, location string) []*bluge.Document {
Aggregatable().
SearchTermPositions())
}
case models.StandardKindPanel:
if ref.Type != "" {
doc.AddField(bluge.NewKeywordField(documentFieldPanelType, ref.Type).Aggregatable().StoreValue())
case models.ExternalEntityReferencePlugin:
if ref.Type == models.StandardKindPanel && ref.UID != "" {
doc.AddField(bluge.NewKeywordField(documentFieldPanelType, ref.UID).Aggregatable().StoreValue())
}
case models.StandardKindTransform:
if ref.Type != "" {
doc.AddField(bluge.NewKeywordField(documentFieldTransformer, ref.Type).Aggregatable())
case models.ExternalEntityReferenceRuntime:
if ref.Type == models.ExternalEntityReferenceRuntime_Transformer && ref.UID != "" {
doc.AddField(bluge.NewKeywordField(documentFieldTransformer, ref.UID).Aggregatable())
}
}
}

View File

@ -24,6 +24,21 @@ type DatasourceQueryResult struct {
IsDefault bool `xorm:"is_default"`
}
type directLookup struct{}
func (d *directLookup) ByRef(ref *DataSourceRef) *DataSourceRef {
if ref == nil {
return &DataSourceRef{} // indicates the default
}
return ref
}
func (d *directLookup) ByType(dsType string) []DataSourceRef {
return []DataSourceRef{
{Type: dsType, UID: "*"},
}
}
func CreateDatasourceLookup(rows []*DatasourceQueryResult) DatasourceLookup {
byUID := make(map[string]*DataSourceRef, 50)
byName := make(map[string]*DataSourceRef, 50)

View File

@ -7,8 +7,7 @@ import (
"strconv"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/store"
"github.com/grafana/grafana/pkg/plugins"
)
func GetObjectKindInfo() models.ObjectKindInfo {
@ -19,26 +18,15 @@ func GetObjectKindInfo() models.ObjectKindInfo {
}
}
func NewDashboardSummary(sql *sqlstore.SQLStore) models.ObjectSummaryBuilder {
// This summary does not resolve old name as UID
func GetObjectSummaryBuilder() models.ObjectSummaryBuilder {
builder := NewStaticDashboardSummaryBuilder(&directLookup{})
return func(ctx context.Context, uid string, body []byte) (*models.ObjectSummary, []byte, error) {
// This just gets the orgID (that will soon/eventually be encoded in a GRN and passed instead of a UID)
user := store.UserFromContext(ctx)
if user == nil {
return nil, nil, fmt.Errorf("can not find user in context")
}
// Totally inefficient to look this up every time, but for the current use case that is OK
// The lookup is currently structured to support searchV2, but I think should become a real fallback
// that is only executed when we find a legacy dashboard ref
lookup, err := LoadDatasourceLookup(ctx, user.OrgID, sql)
if err != nil {
return nil, nil, err
}
builder := NewStaticDashboardSummaryBuilder(lookup)
return builder(ctx, uid, body)
}
}
// This implementation moves datasources referenced by internal ID or name to UID
func NewStaticDashboardSummaryBuilder(lookup DatasourceLookup) models.ObjectSummaryBuilder {
return func(ctx context.Context, uid string, body []byte) (*models.ObjectSummary, []byte, error) {
summary := &models.ObjectSummary{
@ -77,18 +65,23 @@ func NewStaticDashboardSummaryBuilder(lookup DatasourceLookup) models.ObjectSumm
p.Description = panel.Description
p.URL = fmt.Sprintf("%s?viewPanel=%d", url, panel.ID)
p.Fields = make(map[string]interface{}, 0)
p.Fields["type"] = panel.Type
panelRefs.Add("panel", panel.Type, "")
if panel.Type != "row" {
panelRefs.Add(models.ExternalEntityReferencePlugin, string(plugins.Panel), panel.Type)
dashboardRefs.Add(models.ExternalEntityReferencePlugin, string(plugins.Panel), panel.Type)
}
for _, v := range panel.Datasource {
dashboardRefs.Add(models.StandardKindDataSource, v.Type, v.UID)
panelRefs.Add(models.StandardKindDataSource, v.Type, v.UID)
if v.Type != "" {
dashboardRefs.Add(models.ExternalEntityReferencePlugin, string(plugins.DataSource), v.Type)
}
}
for _, v := range panel.Transformer {
panelRefs.Add(models.StandardKindTransform, v, "")
panelRefs.Add(models.ExternalEntityReferenceRuntime, models.ExternalEntityReferenceRuntime_Transformer, v)
dashboardRefs.Add(models.ExternalEntityReferenceRuntime, models.ExternalEntityReferenceRuntime_Transformer, v)
}
dashboardRefs.Add(models.StandardKindPanel, panel.Type, "")
p.References = panelRefs.Get()
summary.Nested = append(summary.Nested, p)
}

View File

@ -16,7 +16,7 @@ func TestReadSummaries(t *testing.T) {
devdash := "../../../../../devenv/dev-dashboards/panel-graph/"
ctx := context.Background()
reader := NewStaticDashboardSummaryBuilder(dsLookupForTests())
reader := GetObjectSummaryBuilder()
failed := make([]string, 0, 10)
err := filepath.Walk(devdash,

View File

@ -15,15 +15,17 @@
"kind": "panel",
"name": "Req/s",
"URL": "/d/graph-gradient-area-fills.json/panel-tests-graph-gradient-area-fills?viewPanel=2",
"fields": {
"type": "graph"
},
"references": [
{
"kind": "ds",
"type": "default.type",
"UID": "default.uid"
"kind": "ds"
},
{
"kind": "panel",
"type": "graph"
"kind": "plugin",
"type": "panel",
"UID": "graph"
}
]
},
@ -32,15 +34,17 @@
"kind": "panel",
"name": "Req/s",
"URL": "/d/graph-gradient-area-fills.json/panel-tests-graph-gradient-area-fills?viewPanel=11",
"fields": {
"type": "graph"
},
"references": [
{
"kind": "ds",
"type": "default.type",
"UID": "default.uid"
"kind": "ds"
},
{
"kind": "panel",
"type": "graph"
"kind": "plugin",
"type": "panel",
"UID": "graph"
}
]
},
@ -49,15 +53,17 @@
"kind": "panel",
"name": "Memory",
"URL": "/d/graph-gradient-area-fills.json/panel-tests-graph-gradient-area-fills?viewPanel=7",
"fields": {
"type": "graph"
},
"references": [
{
"kind": "ds",
"type": "default.type",
"UID": "default.uid"
"kind": "ds"
},
{
"kind": "panel",
"type": "graph"
"kind": "plugin",
"type": "panel",
"UID": "graph"
}
]
},
@ -66,28 +72,29 @@
"kind": "panel",
"name": "Req/s",
"URL": "/d/graph-gradient-area-fills.json/panel-tests-graph-gradient-area-fills?viewPanel=10",
"fields": {
"type": "graph"
},
"references": [
{
"kind": "ds",
"type": "default.type",
"UID": "default.uid"
"kind": "ds"
},
{
"kind": "panel",
"type": "graph"
"kind": "plugin",
"type": "panel",
"UID": "graph"
}
]
}
],
"references": [
{
"kind": "ds",
"type": "default.type",
"UID": "default.uid"
"kind": "ds"
},
{
"kind": "panel",
"type": "graph"
"kind": "plugin",
"type": "panel",
"UID": "graph"
}
]
}

View File

@ -15,15 +15,17 @@
"kind": "panel",
"name": "two units",
"URL": "/d/graph-shared-tooltips.json/panel-tests-shared-tooltips?viewPanel=4",
"fields": {
"type": "timeseries"
},
"references": [
{
"kind": "ds",
"type": "default.type",
"UID": "default.uid"
"kind": "ds"
},
{
"kind": "panel",
"type": "timeseries"
"kind": "plugin",
"type": "panel",
"UID": "timeseries"
}
]
},
@ -32,23 +34,27 @@
"kind": "panel",
"name": "Speed vs Temperature (XY)",
"URL": "/d/graph-shared-tooltips.json/panel-tests-shared-tooltips?viewPanel=13",
"fields": {
"type": "xychart"
},
"references": [
{
"kind": "ds",
"type": "default.type",
"UID": "default.uid"
"kind": "ds"
},
{
"kind": "panel",
"type": "xychart"
"kind": "plugin",
"type": "panel",
"UID": "xychart"
},
{
"kind": "transform",
"type": "organize"
"kind": "runtime",
"type": "transformer",
"UID": "organize"
},
{
"kind": "transform",
"type": "seriesToColumns"
"kind": "runtime",
"type": "transformer",
"UID": "seriesToColumns"
}
]
},
@ -57,15 +63,17 @@
"kind": "panel",
"name": "Cursor info",
"URL": "/d/graph-shared-tooltips.json/panel-tests-shared-tooltips?viewPanel=2",
"fields": {
"type": "debug"
},
"references": [
{
"kind": "ds",
"type": "default.type",
"UID": "default.uid"
"kind": "ds"
},
{
"kind": "panel",
"type": "debug"
"kind": "plugin",
"type": "panel",
"UID": "debug"
}
]
},
@ -74,15 +82,17 @@
"kind": "panel",
"name": "Only temperature",
"URL": "/d/graph-shared-tooltips.json/panel-tests-shared-tooltips?viewPanel=5",
"fields": {
"type": "timeseries"
},
"references": [
{
"kind": "ds",
"type": "default.type",
"UID": "default.uid"
"kind": "ds"
},
{
"kind": "panel",
"type": "timeseries"
"kind": "plugin",
"type": "panel",
"UID": "timeseries"
}
]
},
@ -91,15 +101,17 @@
"kind": "panel",
"name": "Only Speed",
"URL": "/d/graph-shared-tooltips.json/panel-tests-shared-tooltips?viewPanel=9",
"fields": {
"type": "timeseries"
},
"references": [
{
"kind": "ds",
"type": "default.type",
"UID": "default.uid"
"kind": "ds"
},
{
"kind": "panel",
"type": "timeseries"
"kind": "plugin",
"type": "panel",
"UID": "timeseries"
}
]
},
@ -108,15 +120,17 @@
"kind": "panel",
"name": "Panel Title",
"URL": "/d/graph-shared-tooltips.json/panel-tests-shared-tooltips?viewPanel=11",
"fields": {
"type": "timeseries"
},
"references": [
{
"kind": "ds",
"type": "default.type",
"UID": "default.uid"
"kind": "ds"
},
{
"kind": "panel",
"type": "timeseries"
"kind": "plugin",
"type": "panel",
"UID": "timeseries"
}
]
},
@ -125,15 +139,17 @@
"kind": "panel",
"name": "flot panel (temperature)",
"URL": "/d/graph-shared-tooltips.json/panel-tests-shared-tooltips?viewPanel=8",
"fields": {
"type": "graph"
},
"references": [
{
"kind": "ds",
"type": "default.type",
"UID": "default.uid"
"kind": "ds"
},
{
"kind": "panel",
"type": "graph"
"kind": "plugin",
"type": "panel",
"UID": "graph"
}
]
},
@ -142,40 +158,54 @@
"kind": "panel",
"name": "flot panel (no units)",
"URL": "/d/graph-shared-tooltips.json/panel-tests-shared-tooltips?viewPanel=10",
"fields": {
"type": "graph"
},
"references": [
{
"kind": "ds",
"type": "default.type",
"UID": "default.uid"
"kind": "ds"
},
{
"kind": "panel",
"type": "graph"
"kind": "plugin",
"type": "panel",
"UID": "graph"
}
]
}
],
"references": [
{
"kind": "ds",
"type": "default.type",
"UID": "default.uid"
"kind": "ds"
},
{
"kind": "panel",
"type": "debug"
"kind": "plugin",
"type": "panel",
"UID": "debug"
},
{
"kind": "panel",
"type": "graph"
"kind": "plugin",
"type": "panel",
"UID": "graph"
},
{
"kind": "panel",
"type": "timeseries"
"kind": "plugin",
"type": "panel",
"UID": "timeseries"
},
{
"kind": "panel",
"type": "xychart"
"kind": "plugin",
"type": "panel",
"UID": "xychart"
},
{
"kind": "runtime",
"type": "transformer",
"UID": "organize"
},
{
"kind": "runtime",
"type": "transformer",
"UID": "seriesToColumns"
}
]
}

View File

@ -15,15 +15,18 @@
"kind": "panel",
"name": "Business Hours",
"URL": "/d/graph-time-regions.json/panel-tests-graph-time-regions?viewPanel=2",
"fields": {
"type": "graph"
},
"references": [
{
"kind": "ds",
"type": "testdata",
"UID": "PD8C576611E62080A"
"UID": "gdev-testdata"
},
{
"kind": "panel",
"type": "graph"
"kind": "plugin",
"type": "panel",
"UID": "graph"
}
]
},
@ -32,15 +35,18 @@
"kind": "panel",
"name": "Sunday's 20-23",
"URL": "/d/graph-time-regions.json/panel-tests-graph-time-regions?viewPanel=4",
"fields": {
"type": "graph"
},
"references": [
{
"kind": "ds",
"type": "testdata",
"UID": "PD8C576611E62080A"
"UID": "gdev-testdata"
},
{
"kind": "panel",
"type": "graph"
"kind": "plugin",
"type": "panel",
"UID": "graph"
}
]
},
@ -49,15 +55,18 @@
"kind": "panel",
"name": "Each day of week",
"URL": "/d/graph-time-regions.json/panel-tests-graph-time-regions?viewPanel=3",
"fields": {
"type": "graph"
},
"references": [
{
"kind": "ds",
"type": "testdata",
"UID": "PD8C576611E62080A"
"UID": "gdev-testdata"
},
{
"kind": "panel",
"type": "graph"
"kind": "plugin",
"type": "panel",
"UID": "graph"
}
]
},
@ -66,15 +75,18 @@
"kind": "panel",
"name": "05:00",
"URL": "/d/graph-time-regions.json/panel-tests-graph-time-regions?viewPanel=5",
"fields": {
"type": "graph"
},
"references": [
{
"kind": "ds",
"type": "testdata",
"UID": "PD8C576611E62080A"
"UID": "gdev-testdata"
},
{
"kind": "panel",
"type": "graph"
"kind": "plugin",
"type": "panel",
"UID": "graph"
}
]
},
@ -83,15 +95,18 @@
"kind": "panel",
"name": "From 22:00 to 00:30 (crossing midnight)",
"URL": "/d/graph-time-regions.json/panel-tests-graph-time-regions?viewPanel=7",
"fields": {
"type": "graph"
},
"references": [
{
"kind": "ds",
"type": "testdata",
"UID": "PD8C576611E62080A"
"UID": "gdev-testdata"
},
{
"kind": "panel",
"type": "graph"
"kind": "plugin",
"type": "panel",
"UID": "graph"
}
]
}
@ -99,12 +114,12 @@
"references": [
{
"kind": "ds",
"type": "testdata",
"UID": "PD8C576611E62080A"
"UID": "gdev-testdata"
},
{
"kind": "panel",
"type": "graph"
"kind": "plugin",
"type": "panel",
"UID": "graph"
}
]
}

View File

@ -15,15 +15,18 @@
"kind": "panel",
"name": "No Data Points Warning",
"URL": "/d/graph_tests.json/panel-tests-graph?viewPanel=1",
"fields": {
"type": "graph"
},
"references": [
{
"kind": "ds",
"type": "testdata",
"UID": "PD8C576611E62080A"
"UID": "gdev-testdata"
},
{
"kind": "panel",
"type": "graph"
"kind": "plugin",
"type": "panel",
"UID": "graph"
}
]
},
@ -32,15 +35,18 @@
"kind": "panel",
"name": "Datapoints Outside Range Warning",
"URL": "/d/graph_tests.json/panel-tests-graph?viewPanel=2",
"fields": {
"type": "graph"
},
"references": [
{
"kind": "ds",
"type": "testdata",
"UID": "PD8C576611E62080A"
"UID": "gdev-testdata"
},
{
"kind": "panel",
"type": "graph"
"kind": "plugin",
"type": "panel",
"UID": "graph"
}
]
},
@ -49,15 +55,18 @@
"kind": "panel",
"name": "Random walk series",
"URL": "/d/graph_tests.json/panel-tests-graph?viewPanel=3",
"fields": {
"type": "graph"
},
"references": [
{
"kind": "ds",
"type": "testdata",
"UID": "PD8C576611E62080A"
"UID": "gdev-testdata"
},
{
"kind": "panel",
"type": "graph"
"kind": "plugin",
"type": "panel",
"UID": "graph"
}
]
},
@ -66,15 +75,18 @@
"kind": "panel",
"name": "Millisecond res x-axis and tooltip",
"URL": "/d/graph_tests.json/panel-tests-graph?viewPanel=4",
"fields": {
"type": "graph"
},
"references": [
{
"kind": "ds",
"type": "testdata",
"UID": "PD8C576611E62080A"
"UID": "gdev-testdata"
},
{
"kind": "panel",
"type": "graph"
"kind": "plugin",
"type": "panel",
"UID": "graph"
}
]
},
@ -82,15 +94,17 @@
"uid": "graph_tests.json#6",
"kind": "panel",
"URL": "/d/graph_tests.json/panel-tests-graph?viewPanel=6",
"fields": {
"type": "text"
},
"references": [
{
"kind": "ds",
"type": "default.type",
"UID": "default.uid"
"kind": "ds"
},
{
"kind": "panel",
"type": "text"
"kind": "plugin",
"type": "panel",
"UID": "text"
}
]
},
@ -99,15 +113,18 @@
"kind": "panel",
"name": "2 yaxis and axis labels",
"URL": "/d/graph_tests.json/panel-tests-graph?viewPanel=5",
"fields": {
"type": "graph"
},
"references": [
{
"kind": "ds",
"type": "testdata",
"UID": "PD8C576611E62080A"
"UID": "gdev-testdata"
},
{
"kind": "panel",
"type": "graph"
"kind": "plugin",
"type": "panel",
"UID": "graph"
}
]
},
@ -115,15 +132,17 @@
"uid": "graph_tests.json#7",
"kind": "panel",
"URL": "/d/graph_tests.json/panel-tests-graph?viewPanel=7",
"fields": {
"type": "text"
},
"references": [
{
"kind": "ds",
"type": "default.type",
"UID": "default.uid"
"kind": "ds"
},
{
"kind": "panel",
"type": "text"
"kind": "plugin",
"type": "panel",
"UID": "text"
}
]
},
@ -132,15 +151,18 @@
"kind": "panel",
"name": "null value connected",
"URL": "/d/graph_tests.json/panel-tests-graph?viewPanel=8",
"fields": {
"type": "graph"
},
"references": [
{
"kind": "ds",
"type": "testdata",
"UID": "PD8C576611E62080A"
"UID": "gdev-testdata"
},
{
"kind": "panel",
"type": "graph"
"kind": "plugin",
"type": "panel",
"UID": "graph"
}
]
},
@ -149,15 +171,18 @@
"kind": "panel",
"name": "null value null as zero",
"URL": "/d/graph_tests.json/panel-tests-graph?viewPanel=10",
"fields": {
"type": "graph"
},
"references": [
{
"kind": "ds",
"type": "testdata",
"UID": "PD8C576611E62080A"
"UID": "gdev-testdata"
},
{
"kind": "panel",
"type": "graph"
"kind": "plugin",
"type": "panel",
"UID": "graph"
}
]
},
@ -165,15 +190,17 @@
"uid": "graph_tests.json#13",
"kind": "panel",
"URL": "/d/graph_tests.json/panel-tests-graph?viewPanel=13",
"fields": {
"type": "text"
},
"references": [
{
"kind": "ds",
"type": "default.type",
"UID": "default.uid"
"kind": "ds"
},
{
"kind": "panel",
"type": "text"
"kind": "plugin",
"type": "panel",
"UID": "text"
}
]
},
@ -182,15 +209,18 @@
"kind": "panel",
"name": "Stacking value ontop of nulls",
"URL": "/d/graph_tests.json/panel-tests-graph?viewPanel=9",
"fields": {
"type": "graph"
},
"references": [
{
"kind": "ds",
"type": "testdata",
"UID": "PD8C576611E62080A"
"UID": "gdev-testdata"
},
{
"kind": "panel",
"type": "graph"
"kind": "plugin",
"type": "panel",
"UID": "graph"
}
]
},
@ -198,15 +228,17 @@
"uid": "graph_tests.json#14",
"kind": "panel",
"URL": "/d/graph_tests.json/panel-tests-graph?viewPanel=14",
"fields": {
"type": "text"
},
"references": [
{
"kind": "ds",
"type": "default.type",
"UID": "default.uid"
"kind": "ds"
},
{
"kind": "panel",
"type": "text"
"kind": "plugin",
"type": "panel",
"UID": "text"
}
]
},
@ -215,15 +247,18 @@
"kind": "panel",
"name": "Stacking all series null segment",
"URL": "/d/graph_tests.json/panel-tests-graph?viewPanel=12",
"fields": {
"type": "graph"
},
"references": [
{
"kind": "ds",
"type": "testdata",
"UID": "PD8C576611E62080A"
"UID": "gdev-testdata"
},
{
"kind": "panel",
"type": "graph"
"kind": "plugin",
"type": "panel",
"UID": "graph"
}
]
},
@ -231,15 +266,17 @@
"uid": "graph_tests.json#15",
"kind": "panel",
"URL": "/d/graph_tests.json/panel-tests-graph?viewPanel=15",
"fields": {
"type": "text"
},
"references": [
{
"kind": "ds",
"type": "default.type",
"UID": "default.uid"
"kind": "ds"
},
{
"kind": "panel",
"type": "text"
"kind": "plugin",
"type": "panel",
"UID": "text"
}
]
},
@ -248,15 +285,18 @@
"kind": "panel",
"name": "Null between points",
"URL": "/d/graph_tests.json/panel-tests-graph?viewPanel=21",
"fields": {
"type": "graph"
},
"references": [
{
"kind": "ds",
"type": "testdata",
"UID": "PD8C576611E62080A"
"UID": "gdev-testdata"
},
{
"kind": "panel",
"type": "graph"
"kind": "plugin",
"type": "panel",
"UID": "graph"
}
]
},
@ -264,15 +304,17 @@
"uid": "graph_tests.json#22",
"kind": "panel",
"URL": "/d/graph_tests.json/panel-tests-graph?viewPanel=22",
"fields": {
"type": "text"
},
"references": [
{
"kind": "ds",
"type": "default.type",
"UID": "default.uid"
"kind": "ds"
},
{
"kind": "panel",
"type": "text"
"kind": "plugin",
"type": "panel",
"UID": "text"
}
]
},
@ -281,15 +323,18 @@
"kind": "panel",
"name": "Legend Table Single Series Should Take Minimum Height",
"URL": "/d/graph_tests.json/panel-tests-graph?viewPanel=20",
"fields": {
"type": "graph"
},
"references": [
{
"kind": "ds",
"type": "testdata",
"UID": "PD8C576611E62080A"
"UID": "gdev-testdata"
},
{
"kind": "panel",
"type": "graph"
"kind": "plugin",
"type": "panel",
"UID": "graph"
}
]
},
@ -298,15 +343,18 @@
"kind": "panel",
"name": "Legend Table No Scroll Visible",
"URL": "/d/graph_tests.json/panel-tests-graph?viewPanel=16",
"fields": {
"type": "graph"
},
"references": [
{
"kind": "ds",
"type": "testdata",
"UID": "PD8C576611E62080A"
"UID": "gdev-testdata"
},
{
"kind": "panel",
"type": "graph"
"kind": "plugin",
"type": "panel",
"UID": "graph"
}
]
},
@ -315,15 +363,18 @@
"kind": "panel",
"name": "Legend Table Should Scroll",
"URL": "/d/graph_tests.json/panel-tests-graph?viewPanel=17",
"fields": {
"type": "graph"
},
"references": [
{
"kind": "ds",
"type": "testdata",
"UID": "PD8C576611E62080A"
"UID": "gdev-testdata"
},
{
"kind": "panel",
"type": "graph"
"kind": "plugin",
"type": "panel",
"UID": "graph"
}
]
},
@ -332,15 +383,18 @@
"kind": "panel",
"name": "Legend Table No Scroll Visible",
"URL": "/d/graph_tests.json/panel-tests-graph?viewPanel=18",
"fields": {
"type": "graph"
},
"references": [
{
"kind": "ds",
"type": "testdata",
"UID": "PD8C576611E62080A"
"UID": "gdev-testdata"
},
{
"kind": "panel",
"type": "graph"
"kind": "plugin",
"type": "panel",
"UID": "graph"
}
]
},
@ -349,37 +403,39 @@
"kind": "panel",
"name": "Legend Table No Scroll Visible",
"URL": "/d/graph_tests.json/panel-tests-graph?viewPanel=19",
"fields": {
"type": "graph"
},
"references": [
{
"kind": "ds",
"type": "testdata",
"UID": "PD8C576611E62080A"
"UID": "gdev-testdata"
},
{
"kind": "panel",
"type": "graph"
"kind": "plugin",
"type": "panel",
"UID": "graph"
}
]
}
],
"references": [
{
"kind": "ds",
"type": "default.type",
"UID": "default.uid"
"kind": "ds"
},
{
"kind": "ds",
"type": "testdata",
"UID": "PD8C576611E62080A"
"UID": "gdev-testdata"
},
{
"kind": "panel",
"type": "graph"
"kind": "plugin",
"type": "panel",
"UID": "graph"
},
{
"kind": "panel",
"type": "text"
"kind": "plugin",
"type": "panel",
"UID": "text"
}
]
}

View File

@ -14,15 +14,17 @@
"kind": "panel",
"name": "Data from 0 - 10K (unit short)",
"URL": "/d/graph_y_axis.json/panel-tests-graph-y-axis-ticks?viewPanel=7",
"fields": {
"type": "graph"
},
"references": [
{
"kind": "ds",
"type": "default.type",
"UID": "default.uid"
"kind": "ds"
},
{
"kind": "panel",
"type": "graph"
"kind": "plugin",
"type": "panel",
"UID": "graph"
}
]
},
@ -31,15 +33,17 @@
"kind": "panel",
"name": "Data from 0 - 10K (unit bytes metric)",
"URL": "/d/graph_y_axis.json/panel-tests-graph-y-axis-ticks?viewPanel=5",
"fields": {
"type": "graph"
},
"references": [
{
"kind": "ds",
"type": "default.type",
"UID": "default.uid"
"kind": "ds"
},
{
"kind": "panel",
"type": "graph"
"kind": "plugin",
"type": "panel",
"UID": "graph"
}
]
},
@ -48,15 +52,17 @@
"kind": "panel",
"name": "Data from 0 - 10K (unit bytes IEC)",
"URL": "/d/graph_y_axis.json/panel-tests-graph-y-axis-ticks?viewPanel=4",
"fields": {
"type": "graph"
},
"references": [
{
"kind": "ds",
"type": "default.type",
"UID": "default.uid"
"kind": "ds"
},
{
"kind": "panel",
"type": "graph"
"kind": "plugin",
"type": "panel",
"UID": "graph"
}
]
},
@ -65,15 +71,17 @@
"kind": "panel",
"name": "Data from 0 - 10K (unit short)",
"URL": "/d/graph_y_axis.json/panel-tests-graph-y-axis-ticks?viewPanel=2",
"fields": {
"type": "graph"
},
"references": [
{
"kind": "ds",
"type": "default.type",
"UID": "default.uid"
"kind": "ds"
},
{
"kind": "panel",
"type": "graph"
"kind": "plugin",
"type": "panel",
"UID": "graph"
}
]
},
@ -82,15 +90,17 @@
"kind": "panel",
"name": "Data from 0.0002 - 0.001 (unit short)",
"URL": "/d/graph_y_axis.json/panel-tests-graph-y-axis-ticks?viewPanel=3",
"fields": {
"type": "graph"
},
"references": [
{
"kind": "ds",
"type": "default.type",
"UID": "default.uid"
"kind": "ds"
},
{
"kind": "panel",
"type": "graph"
"kind": "plugin",
"type": "panel",
"UID": "graph"
}
]
},
@ -99,15 +109,17 @@
"kind": "panel",
"name": "Data from 12000 - 30000 (unit ms)",
"URL": "/d/graph_y_axis.json/panel-tests-graph-y-axis-ticks?viewPanel=6",
"fields": {
"type": "graph"
},
"references": [
{
"kind": "ds",
"type": "default.type",
"UID": "default.uid"
"kind": "ds"
},
{
"kind": "panel",
"type": "graph"
"kind": "plugin",
"type": "panel",
"UID": "graph"
}
]
},
@ -116,15 +128,17 @@
"kind": "panel",
"name": "Data from 0 - 1B (unit short)",
"URL": "/d/graph_y_axis.json/panel-tests-graph-y-axis-ticks?viewPanel=9",
"fields": {
"type": "graph"
},
"references": [
{
"kind": "ds",
"type": "default.type",
"UID": "default.uid"
"kind": "ds"
},
{
"kind": "panel",
"type": "graph"
"kind": "plugin",
"type": "panel",
"UID": "graph"
}
]
},
@ -133,15 +147,17 @@
"kind": "panel",
"name": "Data from 0 - 1B (unit bytes)",
"URL": "/d/graph_y_axis.json/panel-tests-graph-y-axis-ticks?viewPanel=10",
"fields": {
"type": "graph"
},
"references": [
{
"kind": "ds",
"type": "default.type",
"UID": "default.uid"
"kind": "ds"
},
{
"kind": "panel",
"type": "graph"
"kind": "plugin",
"type": "panel",
"UID": "graph"
}
]
},
@ -150,28 +166,29 @@
"kind": "panel",
"name": "Data from 12000 - 30000 (unit ms)",
"URL": "/d/graph_y_axis.json/panel-tests-graph-y-axis-ticks?viewPanel=8",
"fields": {
"type": "graph"
},
"references": [
{
"kind": "ds",
"type": "default.type",
"UID": "default.uid"
"kind": "ds"
},
{
"kind": "panel",
"type": "graph"
"kind": "plugin",
"type": "panel",
"UID": "graph"
}
]
}
],
"references": [
{
"kind": "ds",
"type": "default.type",
"UID": "default.uid"
"kind": "ds"
},
{
"kind": "panel",
"type": "graph"
"kind": "plugin",
"type": "panel",
"UID": "graph"
}
]
}

View File

@ -0,0 +1,71 @@
package geojson
import (
"context"
"encoding/json"
"fmt"
"strings"
"github.com/grafana/grafana/pkg/models"
)
func GetObjectKindInfo() models.ObjectKindInfo {
return models.ObjectKindInfo{
ID: models.StandardKindGeoJSON,
Name: "GeoJSON",
Description: "JSON formatted spatial data",
FileExtension: ".geojson",
MimeType: "application/json",
}
}
// Very basic geojson validator
func GetObjectSummaryBuilder() models.ObjectSummaryBuilder {
return func(ctx context.Context, uid string, body []byte) (*models.ObjectSummary, []byte, error) {
var geojson map[string]interface{}
err := json.Unmarshal(body, &geojson)
if err != nil {
return nil, nil, err
}
ftype, ok := geojson["type"].(string)
if !ok {
return nil, nil, fmt.Errorf("missing type")
}
body, err = json.Marshal(geojson)
if err != nil {
return nil, nil, err
}
summary := &models.ObjectSummary{
Kind: models.StandardKindGeoJSON,
Name: guessNameFromUID(uid),
UID: uid,
Fields: map[string]interface{}{
"type": ftype,
},
}
if ftype == "FeatureCollection" {
features, ok := geojson["features"].([]interface{})
if ok {
summary.Fields["count"] = len(features)
}
}
return summary, body, nil
}
}
func guessNameFromUID(uid string) string {
sidx := strings.LastIndex(uid, "/") + 1
didx := strings.LastIndex(uid, ".")
if didx > sidx && didx != sidx {
return uid[sidx:didx]
}
if sidx > 0 {
return uid[sidx:]
}
return uid
}

View File

@ -0,0 +1,54 @@
package geojson
import (
"context"
"encoding/json"
"os"
"testing"
"github.com/stretchr/testify/require"
)
func TestGeoJSONSummary(t *testing.T) {
builder := GetObjectSummaryBuilder()
geo := []byte(`{"type":"FeatureCo`) // invalid
_, _, err := builder(context.Background(), "hello", geo)
require.Error(t, err)
geo = []byte(`{"type":"FeatureCollection","features":[]}`)
summary, out, err := builder(context.Background(), "hello", geo)
require.NoError(t, err)
require.NotEqual(t, geo, out) // wrote json
asjson, err := json.MarshalIndent(summary, "", " ")
//fmt.Printf(string(asjson))
require.NoError(t, err)
require.JSONEq(t, `{
"uid": "hello",
"kind": "geojson",
"name": "hello",
"fields": {
"type": "FeatureCollection",
"count": 0
}
}`, string(asjson))
// Ignore gosec warning G304 since it's a test
// nolint:gosec
airports, err := os.ReadFile("../../../../../public/gazetteer/airports.geojson")
require.NoError(t, err)
summary, _, err = builder(context.Background(), "gaz/airports.geojson", airports)
require.NoError(t, err)
asjson, err = json.MarshalIndent(summary, "", " ")
//fmt.Printf(string(asjson))
require.NoError(t, err)
require.JSONEq(t, `{
"uid": "gaz/airports.geojson",
"kind": "geojson",
"name": "airports",
"fields": {
"type": "FeatureCollection",
"count": 888
}
}`, string(asjson))
}

View File

@ -7,9 +7,9 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/rendering"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/store/kind/dashboard"
"github.com/grafana/grafana/pkg/services/store/kind/dummy"
"github.com/grafana/grafana/pkg/services/store/kind/geojson"
"github.com/grafana/grafana/pkg/services/store/kind/playlist"
"github.com/grafana/grafana/pkg/services/store/kind/png"
"github.com/grafana/grafana/pkg/services/store/kind/svg"
@ -29,10 +29,18 @@ func NewKindRegistry() KindRegistry {
info: playlist.GetObjectKindInfo(),
builder: playlist.GetObjectSummaryBuilder(),
}
kinds[models.StandardKindDashboard] = &kindValues{
info: dashboard.GetObjectKindInfo(),
builder: dashboard.GetObjectSummaryBuilder(),
}
kinds[models.StandardKindPNG] = &kindValues{
info: png.GetObjectKindInfo(),
builder: png.GetObjectSummaryBuilder(),
}
kinds[models.StandardKindGeoJSON] = &kindValues{
info: geojson.GetObjectKindInfo(),
builder: geojson.GetObjectSummaryBuilder(),
}
// FIXME -- these are registered because existing tests use them
for _, k := range []string{"dummy", "kind1", "kind2", "kind3"} {
@ -52,13 +60,9 @@ func NewKindRegistry() KindRegistry {
}
// TODO? This could be a zero dependency service that others are responsible for configuring
func ProvideService(cfg *setting.Cfg, renderer rendering.Service, sql *sqlstore.SQLStore) KindRegistry {
func ProvideService(cfg *setting.Cfg, renderer rendering.Service) KindRegistry {
reg := NewKindRegistry()
// Register Dashboard support
//-----------------------
_ = reg.Register(dashboard.GetObjectKindInfo(), dashboard.NewDashboardSummary(sql))
// Register SVG support
//-----------------------
info := svg.GetObjectKindInfo()

View File

@ -19,7 +19,9 @@ func TestKindRegistry(t *testing.T) {
ids = append(ids, k.ID)
}
require.Equal(t, []string{
"dashboard",
"dummy",
"geojson",
"kind1",
"kind2",
"kind3",