moves datasource plugin model to grafana/grafana_plugin_model

This commit is contained in:
bergquist
2018-01-17 13:21:42 +01:00
parent af9d1cc577
commit a183ea97bb
10 changed files with 418 additions and 320 deletions
@@ -0,0 +1,150 @@
package wrapper
import (
"context"
"fmt"
"github.com/grafana/grafana/pkg/components/null"
"github.com/grafana/grafana/pkg/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/tsdb"
"github.com/grafana/grafana_plugin_model/go/datasource"
)
func NewDatasourcePluginWrapper(log log.Logger, plugin datasource.DatasourcePlugin) *DatasourcePluginWrapper {
return &DatasourcePluginWrapper{DatasourcePlugin: plugin, logger: log}
}
type DatasourcePluginWrapper struct {
datasource.DatasourcePlugin
logger log.Logger
}
func (tw *DatasourcePluginWrapper) Query(ctx context.Context, ds *models.DataSource, query *tsdb.TsdbQuery) (*tsdb.Response, error) {
jsonData, err := ds.JsonData.MarshalJSON()
if err != nil {
return nil, err
}
pbQuery := &datasource.DatasourceRequest{
Datasource: &datasource.DatasourceInfo{
JsonData: string(jsonData),
Name: ds.Name,
Type: ds.Type,
Url: ds.Url,
Id: ds.Id,
OrgId: ds.OrgId,
},
TimeRange: &datasource.TimeRange{
FromRaw: query.TimeRange.From,
ToRaw: query.TimeRange.To,
ToEpochMs: query.TimeRange.GetToAsMsEpoch(),
FromEpochMs: query.TimeRange.GetFromAsMsEpoch(),
},
Queries: []*datasource.Query{},
}
for _, q := range query.Queries {
modelJson, _ := q.Model.MarshalJSON()
pbQuery.Queries = append(pbQuery.Queries, &datasource.Query{
ModelJson: string(modelJson),
IntervalMs: q.IntervalMs,
RefId: q.RefId,
MaxDataPoints: q.MaxDataPoints,
})
}
pbres, err := tw.DatasourcePlugin.Query(ctx, pbQuery)
if err != nil {
return nil, err
}
res := &tsdb.Response{
Results: map[string]*tsdb.QueryResult{},
}
for _, r := range pbres.Results {
res.Results[r.RefId] = &tsdb.QueryResult{
RefId: r.RefId,
Series: []*tsdb.TimeSeries{},
}
for _, s := range r.GetSeries() {
points := tsdb.TimeSeriesPoints{}
for _, p := range s.Points {
po := tsdb.NewTimePoint(null.FloatFrom(p.Value), float64(p.Timestamp))
points = append(points, po)
}
res.Results[r.RefId].Series = append(res.Results[r.RefId].Series, &tsdb.TimeSeries{
Name: s.Name,
Tags: s.Tags,
Points: points,
})
}
mappedTables, err := tw.mapTables(r)
if err != nil {
return nil, err
}
res.Results[r.RefId].Tables = mappedTables
}
return res, nil
}
func (tw *DatasourcePluginWrapper) mapTables(r *datasource.QueryResult) ([]*tsdb.Table, error) {
var tables []*tsdb.Table
for _, t := range r.GetTables() {
mappedTable, err := tw.mapTable(t)
if err != nil {
return nil, err
}
tables = append(tables, mappedTable)
}
return tables, nil
}
func (tw *DatasourcePluginWrapper) mapTable(t *datasource.Table) (*tsdb.Table, error) {
table := &tsdb.Table{}
for _, c := range t.GetColumns() {
table.Columns = append(table.Columns, tsdb.TableColumn{
Text: c.Name,
})
}
for _, r := range t.GetRows() {
row := tsdb.RowValues{}
for _, rv := range r.Values {
mappedRw, err := tw.mapRowValue(rv)
if err != nil {
return nil, err
}
row = append(row, mappedRw)
}
table.Rows = append(table.Rows, row)
}
return table, nil
}
func (tw *DatasourcePluginWrapper) mapRowValue(rv *datasource.RowValue) (interface{}, error) {
switch rv.Kind {
case datasource.RowValue_TYPE_NULL:
return nil, nil
case datasource.RowValue_TYPE_INT64:
return rv.Int64Value, nil
case datasource.RowValue_TYPE_BOOL:
return rv.BoolValue, nil
case datasource.RowValue_TYPE_STRING:
return rv.StringValue, nil
case datasource.RowValue_TYPE_DOUBLE:
return rv.DoubleValue, nil
case datasource.RowValue_TYPE_BYTES:
return rv.BytesValue, nil
default:
return nil, fmt.Errorf("Unsupported row value %v from plugin", rv.Kind)
}
}
@@ -0,0 +1,109 @@
package wrapper
import (
"testing"
"github.com/grafana/grafana/pkg/log"
"github.com/grafana/grafana/pkg/tsdb"
"github.com/grafana/grafana_plugin_model/go/datasource"
)
func TestMapTables(t *testing.T) {
dpw := NewDatasourcePluginWrapper(log.New("test-logger"), nil)
var qr = &datasource.QueryResult{}
qr.Tables = append(qr.Tables, &datasource.Table{
Columns: []*datasource.TableColumn{},
Rows: nil,
})
want := []*tsdb.Table{{}}
have, err := dpw.mapTables(qr)
if err != nil {
t.Errorf("failed to map tables. error: %v", err)
}
if len(want) != len(have) {
t.Errorf("could not map all tables")
}
}
func TestMapTable(t *testing.T) {
dpw := NewDatasourcePluginWrapper(log.New("test-logger"), nil)
source := &datasource.Table{
Columns: []*datasource.TableColumn{{Name: "column1"}, {Name: "column2"}},
Rows: []*datasource.TableRow{{
Values: []*datasource.RowValue{
{
Kind: datasource.RowValue_TYPE_BOOL,
BoolValue: true,
},
{
Kind: datasource.RowValue_TYPE_INT64,
Int64Value: 42,
},
},
}},
}
want := &tsdb.Table{
Columns: []tsdb.TableColumn{{Text: "column1"}, {Text: "column2"}},
}
have, err := dpw.mapTable(source)
if err != nil {
t.Fatalf("failed to map table. error: %v", err)
}
for i := range have.Columns {
if want.Columns[i] != have.Columns[i] {
t.Fatalf("have column: %s, want %s", have, want)
}
}
if len(have.Rows) != 1 {
t.Fatalf("Expects one row but got %d", len(have.Rows))
}
rowValuesCount := len(have.Rows[0])
if rowValuesCount != 2 {
t.Fatalf("Expects two row values, got %d", rowValuesCount)
}
}
func TestMappingRowValue(t *testing.T) {
dpw := NewDatasourcePluginWrapper(log.New("test-logger"), nil)
boolRowValue, _ := dpw.mapRowValue(&datasource.RowValue{Kind: datasource.RowValue_TYPE_BOOL, BoolValue: true})
haveBool, ok := boolRowValue.(bool)
if !ok || haveBool != true {
t.Fatalf("Expected true, was %s", haveBool)
}
intRowValue, _ := dpw.mapRowValue(&datasource.RowValue{Kind: datasource.RowValue_TYPE_INT64, Int64Value: 42})
haveInt, ok := intRowValue.(int64)
if !ok || haveInt != 42 {
t.Fatalf("Expected %d, was %d", 42, haveInt)
}
stringRowValue, _ := dpw.mapRowValue(&datasource.RowValue{Kind: datasource.RowValue_TYPE_STRING, StringValue: "grafana"})
haveString, ok := stringRowValue.(string)
if !ok || haveString != "grafana" {
t.Fatalf("Expected %s, was %s", "grafana", haveString)
}
doubleRowValue, _ := dpw.mapRowValue(&datasource.RowValue{Kind: datasource.RowValue_TYPE_DOUBLE, DoubleValue: 1.5})
haveDouble, ok := doubleRowValue.(float64)
if !ok || haveDouble != 1.5 {
t.Fatalf("Expected %v, was %v", 1.5, haveDouble)
}
bytesRowValue, _ := dpw.mapRowValue(&datasource.RowValue{Kind: datasource.RowValue_TYPE_BYTES, BytesValue: []byte{66}})
haveBytes, ok := bytesRowValue.([]byte)
if !ok || len(haveBytes) != 1 || haveBytes[0] != 66 {
t.Fatalf("Expected %v, was %v", []byte{66}, haveBytes)
}
haveNil, _ := dpw.mapRowValue(&datasource.RowValue{Kind: datasource.RowValue_TYPE_NULL})
if haveNil != nil {
t.Fatalf("Expected %v, was %v", nil, haveNil)
}
}