Chore: Refactor usage of legacy data contracts (#41218)

Refactor usage of legacy data contracts. Moves legacy data contracts 
to pkg/tsdb/legacydata package.
Refactor pkg/expr to be a proper service/dependency that can be provided 
to wire to remove some unneeded dependencies to SSE in ngalert and other places.
Refactor pkg/expr to not use the legacydata,RequestHandler and use 
backend.QueryDataHandler instead.
This commit is contained in:
Marcus Efraimsson
2021-11-10 11:52:16 +01:00
committed by GitHub
parent d6ed5d295e
commit baab021fec
54 changed files with 732 additions and 951 deletions

View File

@@ -7,6 +7,7 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/services/encryption"
"github.com/grafana/grafana/pkg/setting"
)
@@ -35,15 +36,24 @@ func IsDataSource(uid string) bool {
// Service is service representation for expression handling.
type Service struct {
Cfg *setting.Cfg
DataService plugins.DataRequestHandler
cfg *setting.Cfg
dataService backend.QueryDataHandler
encryptionService encryption.Service
}
func ProvideService(cfg *setting.Cfg, pluginClient plugins.Client, encryptionService encryption.Service) *Service {
return &Service{
cfg: cfg,
dataService: pluginClient,
encryptionService: encryptionService,
}
}
func (s *Service) isDisabled() bool {
if s.Cfg == nil {
if s.cfg == nil {
return true
}
return !s.Cfg.ExpressionsEnabled
return !s.cfg.ExpressionsEnabled
}
// BuildPipeline builds a pipeline from a request.

View File

@@ -11,12 +11,13 @@ import (
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/data"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/services/encryption/ossencryption"
"github.com/grafana/grafana/pkg/setting"
"github.com/stretchr/testify/require"
)
// nolint:staticcheck // plugins.DataPlugin deprecated
func TestService(t *testing.T) {
dsDF := data.NewFrame("test",
data.NewField("time", nil, []time.Time{time.Unix(1, 0)}),
@@ -25,9 +26,13 @@ func TestService(t *testing.T) {
me := &mockEndpoint{
Frames: []*data.Frame{dsDF},
}
s := Service{DataService: me}
bus.AddHandler("test", func(query *models.GetDataSourceQuery) error {
query.Result = &models.DataSource{Id: 1, OrgId: 1, Type: "test"}
s := Service{
cfg: setting.NewCfg(),
dataService: me,
encryptionService: ossencryption.ProvideService(),
}
bus.AddHandlerCtx("test", func(_ context.Context, query *models.GetDataSourceQuery) error {
query.Result = &models.DataSource{Id: 1, OrgId: 1, Type: "test", JsonData: simplejson.New()}
return nil
})
@@ -88,18 +93,10 @@ type mockEndpoint struct {
Frames data.Frames
}
// nolint:staticcheck // plugins.DataQueryResponse deprecated
func (me *mockEndpoint) DataQuery(ctx context.Context, ds *models.DataSource, query plugins.DataQuery) (plugins.DataResponse, error) {
return plugins.DataResponse{
Results: map[string]plugins.DataQueryResult{
"A": {
Dataframes: plugins.NewDecodedDataFrames(me.Frames),
},
},
}, nil
}
// nolint:staticcheck // plugins.DataQueryResponse deprecated
func (me *mockEndpoint) HandleRequest(ctx context.Context, ds *models.DataSource, query plugins.DataQuery) (plugins.DataResponse, error) {
return me.DataQuery(ctx, ds, query)
func (me *mockEndpoint) QueryData(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) {
resp := backend.NewQueryDataResponse()
resp.Responses["A"] = backend.DataResponse{
Frames: me.Frames,
}
return resp, nil
}

View File

@@ -3,14 +3,14 @@ package expr
import (
"encoding/json"
"fmt"
"strconv"
"time"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/plugins/adapters"
"github.com/grafana/grafana/pkg/tsdb/legacydata"
"github.com/grafana/grafana/pkg/util/errutil"
"github.com/prometheus/client_golang/prometheus"
"golang.org/x/net/context"
)
@@ -33,7 +33,7 @@ func init() {
}
// WrapTransformData creates and executes transform requests
func (s *Service) WrapTransformData(ctx context.Context, query plugins.DataQuery) (*backend.QueryDataResponse, error) {
func (s *Service) WrapTransformData(ctx context.Context, query legacydata.DataQuery) (*backend.QueryDataResponse, error) {
req := Request{
OrgId: query.User.OrgId,
Queries: []Query{},
@@ -206,38 +206,23 @@ func (s *Service) queryData(ctx context.Context, req *backend.QueryDataRequest)
return nil, fmt.Errorf("could not find datasource: %w", err)
}
// Convert plugin-model (datasource) queries to tsdb queries
queries := make([]plugins.DataSubQuery, len(req.Queries))
for i, query := range req.Queries {
sj, err := simplejson.NewJson(query.JSON)
if err != nil {
return nil, err
}
queries[i] = plugins.DataSubQuery{
RefID: query.RefID,
IntervalMS: query.Interval.Milliseconds(),
MaxDataPoints: query.MaxDataPoints,
QueryType: query.QueryType,
DataSource: getDsInfo.Result,
Model: sj,
}
}
// For now take Time Range from first query.
timeRange := plugins.NewDataTimeRange(strconv.FormatInt(req.Queries[0].TimeRange.From.Unix()*1000, 10),
strconv.FormatInt(req.Queries[0].TimeRange.To.Unix()*1000, 10))
tQ := plugins.DataQuery{
TimeRange: &timeRange,
Queries: queries,
Headers: req.Headers,
}
// Execute the converted queries
tsdbRes, err := s.DataService.HandleRequest(ctx, getDsInfo.Result, tQ)
dsInstanceSettings, err := adapters.ModelToInstanceSettings(getDsInfo.Result, s.decryptSecureJsonDataFn(ctx))
if err != nil {
return nil, err
return nil, errutil.Wrap("failed to convert datasource instance settings", err)
}
return tsdbRes.ToBackendDataResponse()
req.PluginContext.DataSourceInstanceSettings = dsInstanceSettings
req.PluginContext.PluginID = getDsInfo.Result.Type
return s.dataService.QueryData(ctx, req)
}
func (s *Service) decryptSecureJsonDataFn(ctx context.Context) func(map[string][]byte) map[string]string {
return func(m map[string][]byte) map[string]string {
decryptedJsonData, err := s.encryptionService.DecryptJsonData(ctx, m, s.cfg.SecretKey)
if err != nil {
logger.Error("Failed to decrypt secure json data", "error", err)
}
return decryptedJsonData
}
}