mirror of https://github.com/grafana/grafana
Plugins: Remove support for deprecated backend plugin protocol version (#34127)
* 33959: Remove support for deprecated backend plugin protocol (v1) * 33959: Remove unused methods * 33959: Remove some additional unused code * 33959: Remove some additional unused code * 33959: Remove datasource plugin wrapper with test * 33959:Remove DefaultProtocolVersionpull/34357/head
parent
5042dc3b52
commit
1e8e7e34f1
@ -1,97 +0,0 @@ |
||||
package grpcplugin |
||||
|
||||
import ( |
||||
"context" |
||||
|
||||
datasourceV1 "github.com/grafana/grafana-plugin-model/go/datasource" |
||||
rendererV1 "github.com/grafana/grafana-plugin-model/go/renderer" |
||||
"github.com/grafana/grafana-plugin-sdk-go/backend" |
||||
"github.com/grafana/grafana/pkg/infra/log" |
||||
"github.com/grafana/grafana/pkg/plugins/backendplugin" |
||||
"github.com/grafana/grafana/pkg/plugins/backendplugin/instrumentation" |
||||
"github.com/hashicorp/go-plugin" |
||||
) |
||||
|
||||
type clientV1 struct { |
||||
logger log.Logger |
||||
datasourceV1.DatasourcePlugin |
||||
rendererV1.RendererPlugin |
||||
} |
||||
|
||||
func newClientV1(descriptor PluginDescriptor, logger log.Logger, rpcClient plugin.ClientProtocol) (pluginClient, error) { |
||||
logger.Warn("Plugin uses a deprecated version of Grafana's backend plugin system which will be removed in a future release. " + |
||||
"Consider upgrading to a newer plugin version or reach out to the plugin repository/developer and request an upgrade.") |
||||
|
||||
raw, err := rpcClient.Dispense(descriptor.pluginID) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
c := clientV1{ |
||||
logger: logger, |
||||
} |
||||
if plugin, ok := raw.(datasourceV1.DatasourcePlugin); ok { |
||||
c.DatasourcePlugin = instrumentDatasourcePluginV1(plugin) |
||||
} |
||||
|
||||
if plugin, ok := raw.(rendererV1.RendererPlugin); ok { |
||||
c.RendererPlugin = plugin |
||||
} |
||||
|
||||
if descriptor.startFns.OnLegacyStart != nil { |
||||
legacyClient := &LegacyClient{ |
||||
DatasourcePlugin: c.DatasourcePlugin, |
||||
RendererPlugin: c.RendererPlugin, |
||||
} |
||||
if err := descriptor.startFns.OnLegacyStart(descriptor.pluginID, legacyClient, logger); err != nil { |
||||
return nil, err |
||||
} |
||||
} |
||||
|
||||
return &c, nil |
||||
} |
||||
|
||||
func (c *clientV1) CollectMetrics(ctx context.Context) (*backend.CollectMetricsResult, error) { |
||||
return nil, backendplugin.ErrMethodNotImplemented |
||||
} |
||||
|
||||
func (c *clientV1) CheckHealth(ctx context.Context, req *backend.CheckHealthRequest) (*backend.CheckHealthResult, error) { |
||||
return nil, backendplugin.ErrMethodNotImplemented |
||||
} |
||||
|
||||
func (c *clientV1) CallResource(ctx context.Context, req *backend.CallResourceRequest, sender backend.CallResourceResponseSender) error { |
||||
return backendplugin.ErrMethodNotImplemented |
||||
} |
||||
|
||||
func (c *clientV1) SubscribeStream(ctx context.Context, request *backend.SubscribeStreamRequest) (*backend.SubscribeStreamResponse, error) { |
||||
return nil, backendplugin.ErrMethodNotImplemented |
||||
} |
||||
|
||||
func (c *clientV1) PublishStream(ctx context.Context, request *backend.PublishStreamRequest) (*backend.PublishStreamResponse, error) { |
||||
return nil, backendplugin.ErrMethodNotImplemented |
||||
} |
||||
|
||||
func (c *clientV1) RunStream(ctx context.Context, request *backend.RunStreamRequest, sender backend.StreamPacketSender) error { |
||||
return backendplugin.ErrMethodNotImplemented |
||||
} |
||||
|
||||
type datasourceV1QueryFunc func(ctx context.Context, req *datasourceV1.DatasourceRequest) (*datasourceV1.DatasourceResponse, error) |
||||
|
||||
func (fn datasourceV1QueryFunc) Query(ctx context.Context, req *datasourceV1.DatasourceRequest) (*datasourceV1.DatasourceResponse, error) { |
||||
return fn(ctx, req) |
||||
} |
||||
|
||||
func instrumentDatasourcePluginV1(plugin datasourceV1.DatasourcePlugin) datasourceV1.DatasourcePlugin { |
||||
if plugin == nil { |
||||
return nil |
||||
} |
||||
|
||||
return datasourceV1QueryFunc(func(ctx context.Context, req *datasourceV1.DatasourceRequest) (*datasourceV1.DatasourceResponse, error) { |
||||
var resp *datasourceV1.DatasourceResponse |
||||
err := instrumentation.InstrumentQueryDataRequest(req.Datasource.Type, func() (innerErr error) { |
||||
resp, innerErr = plugin.Query(ctx, req) |
||||
return |
||||
}) |
||||
return resp, err |
||||
}) |
||||
} |
||||
@ -1,172 +0,0 @@ |
||||
package plugins |
||||
|
||||
import ( |
||||
"context" |
||||
"errors" |
||||
"fmt" |
||||
|
||||
"github.com/grafana/grafana-plugin-model/go/datasource" |
||||
"github.com/grafana/grafana/pkg/components/null" |
||||
"github.com/grafana/grafana/pkg/components/simplejson" |
||||
"github.com/grafana/grafana/pkg/infra/log" |
||||
"github.com/grafana/grafana/pkg/models" |
||||
) |
||||
|
||||
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 DataQuery) (DataResponse, error) { |
||||
jsonData, err := ds.JsonData.MarshalJSON() |
||||
if err != nil { |
||||
return DataResponse{}, err |
||||
} |
||||
|
||||
pbQuery := &datasource.DatasourceRequest{ |
||||
Datasource: &datasource.DatasourceInfo{ |
||||
Name: ds.Name, |
||||
Type: ds.Type, |
||||
Url: ds.Url, |
||||
Id: ds.Id, |
||||
OrgId: ds.OrgId, |
||||
JsonData: string(jsonData), |
||||
DecryptedSecureJsonData: ds.SecureJsonData.Decrypt(), |
||||
}, |
||||
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, err := q.Model.MarshalJSON() |
||||
if err != nil { |
||||
return DataResponse{}, err |
||||
} |
||||
|
||||
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 DataResponse{}, err |
||||
} |
||||
|
||||
res := DataResponse{ |
||||
Results: map[string]DataQueryResult{}, |
||||
} |
||||
|
||||
for _, r := range pbres.Results { |
||||
qr := DataQueryResult{ |
||||
RefID: r.RefId, |
||||
Series: []DataTimeSeries{}, |
||||
Tables: []DataTable{}, |
||||
} |
||||
|
||||
if r.Error != "" { |
||||
qr.Error = errors.New(r.Error) |
||||
qr.ErrorString = r.Error |
||||
} |
||||
|
||||
if r.MetaJson != "" { |
||||
metaJson, err := simplejson.NewJson([]byte(r.MetaJson)) |
||||
if err != nil { |
||||
tw.logger.Error("Error parsing JSON Meta field: " + err.Error()) |
||||
} |
||||
qr.Meta = metaJson |
||||
} |
||||
|
||||
for _, s := range r.GetSeries() { |
||||
points := DataTimeSeriesPoints{} |
||||
|
||||
for _, p := range s.Points { |
||||
po := DataTimePoint{null.FloatFrom(p.Value), null.FloatFrom(float64(p.Timestamp))} |
||||
points = append(points, po) |
||||
} |
||||
|
||||
qr.Series = append(qr.Series, DataTimeSeries{ |
||||
Name: s.Name, |
||||
Tags: s.Tags, |
||||
Points: points, |
||||
}) |
||||
} |
||||
|
||||
mappedTables, err := tw.mapTables(r) |
||||
if err != nil { |
||||
return DataResponse{}, err |
||||
} |
||||
qr.Tables = mappedTables |
||||
|
||||
res.Results[r.RefId] = qr |
||||
} |
||||
|
||||
return res, nil |
||||
} |
||||
|
||||
func (tw *DatasourcePluginWrapper) mapTables(r *datasource.QueryResult) ([]DataTable, error) { |
||||
var tables []DataTable |
||||
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) (DataTable, error) { |
||||
table := DataTable{} |
||||
for _, c := range t.GetColumns() { |
||||
table.Columns = append(table.Columns, DataTableColumn{ |
||||
Text: c.Name, |
||||
}) |
||||
} |
||||
|
||||
table.Rows = make([]DataRowValues, 0) |
||||
for _, r := range t.GetRows() { |
||||
row := DataRowValues{} |
||||
for _, rv := range r.Values { |
||||
mappedRw, err := tw.mapRowValue(rv) |
||||
if err != nil { |
||||
return table, 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) |
||||
} |
||||
} |
||||
@ -1,86 +0,0 @@ |
||||
package plugins |
||||
|
||||
import ( |
||||
"testing" |
||||
|
||||
"github.com/grafana/grafana-plugin-model/go/datasource" |
||||
"github.com/grafana/grafana/pkg/infra/log" |
||||
"github.com/stretchr/testify/require" |
||||
) |
||||
|
||||
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, |
||||
}) |
||||
|
||||
have, err := dpw.mapTables(qr) |
||||
require.NoError(t, err) |
||||
require.Len(t, have, 1) |
||||
} |
||||
|
||||
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 := DataTable{ |
||||
Columns: []DataTableColumn{{Text: "column1"}, {Text: "column2"}}, |
||||
} |
||||
have, err := dpw.mapTable(source) |
||||
require.NoError(t, err) |
||||
|
||||
require.Equal(t, want.Columns, have.Columns) |
||||
require.Len(t, have.Rows, 1) |
||||
require.Len(t, have.Rows[0], 2) |
||||
} |
||||
|
||||
func TestMappingRowValue(t *testing.T) { |
||||
dpw := newDataSourcePluginWrapper(log.New("test-logger"), nil) |
||||
|
||||
boolRowValue, err := dpw.mapRowValue(&datasource.RowValue{Kind: datasource.RowValue_TYPE_BOOL, BoolValue: true}) |
||||
require.NoError(t, err) |
||||
haveBool, ok := boolRowValue.(bool) |
||||
require.True(t, ok) |
||||
require.True(t, haveBool) |
||||
|
||||
intRowValue, _ := dpw.mapRowValue(&datasource.RowValue{Kind: datasource.RowValue_TYPE_INT64, Int64Value: 42}) |
||||
haveInt, ok := intRowValue.(int64) |
||||
require.True(t, ok) |
||||
require.Equal(t, int64(42), haveInt) |
||||
|
||||
stringRowValue, _ := dpw.mapRowValue(&datasource.RowValue{Kind: datasource.RowValue_TYPE_STRING, StringValue: "grafana"}) |
||||
haveString, ok := stringRowValue.(string) |
||||
require.True(t, ok) |
||||
require.Equal(t, "grafana", haveString) |
||||
|
||||
doubleRowValue, _ := dpw.mapRowValue(&datasource.RowValue{Kind: datasource.RowValue_TYPE_DOUBLE, DoubleValue: 1.5}) |
||||
haveDouble, ok := doubleRowValue.(float64) |
||||
require.True(t, ok) |
||||
require.Equal(t, 1.5, haveDouble) |
||||
|
||||
bytesRowValue, _ := dpw.mapRowValue(&datasource.RowValue{Kind: datasource.RowValue_TYPE_BYTES, BytesValue: []byte{66}}) |
||||
haveBytes, ok := bytesRowValue.([]byte) |
||||
require.True(t, ok) |
||||
require.Equal(t, []byte{66}, haveBytes) |
||||
|
||||
haveNil, err := dpw.mapRowValue(&datasource.RowValue{Kind: datasource.RowValue_TYPE_NULL}) |
||||
require.NoError(t, err) |
||||
require.Nil(t, haveNil) |
||||
} |
||||
Loading…
Reference in new issue