datasources: querier: refactor (#108776)

datasources: querier: refactor types
This commit is contained in:
Gábor Farkas 2025-08-04 09:57:41 +02:00 committed by GitHub
parent 81f544e186
commit 6dc0dedc97
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 68 additions and 37 deletions

View File

@ -4,6 +4,7 @@ import (
"context"
data "github.com/grafana/grafana-plugin-sdk-go/experimental/apis/data/v0alpha1"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/registry/apis/query/clientapi"
"github.com/grafana/grafana/pkg/services/accesscontrol"
@ -18,7 +19,17 @@ type singleTenantClientSupplier struct {
cfg *setting.Cfg
}
func NewSingleTenantClientSupplier(cfg *setting.Cfg, features featuremgmt.FeatureToggles, p plugins.Client, ctxProv *plugincontext.Provider, accessControl accesscontrol.AccessControl) clientapi.DataSourceClientSupplier {
type singleTenantInstance struct {
client clientapi.QueryDataClient
features featuremgmt.FeatureToggles
cfg *setting.Cfg
}
func (t *singleTenantInstance) GetDataSourceClient(_ context.Context, _ data.DataSourceRef, _ map[string]string) (clientapi.QueryDataClient, error) {
return t.client, nil
}
func NewSingleTenantClientSupplier(cfg *setting.Cfg, features featuremgmt.FeatureToggles, p plugins.Client, ctxProv *plugincontext.Provider, accessControl accesscontrol.AccessControl) clientapi.InstanceProvider {
return &singleTenantClientSupplier{
cfg: cfg,
features: features,
@ -26,19 +37,29 @@ func NewSingleTenantClientSupplier(cfg *setting.Cfg, features featuremgmt.Featur
}
}
func (s *singleTenantClientSupplier) GetDataSourceClient(_ context.Context, _ data.DataSourceRef, _ map[string]string, _ clientapi.InstanceConfigurationSettings) (clientapi.QueryDataClient, error) {
func (s *singleTenantClientSupplier) GetDataSourceClient(_ context.Context, _ data.DataSourceRef, _ map[string]string) (clientapi.QueryDataClient, error) {
return s.client, nil
}
func (s *singleTenantClientSupplier) GetInstanceConfigurationSettings(ctx context.Context) (clientapi.InstanceConfigurationSettings, error) {
func (s *singleTenantClientSupplier) GetInstance(_ context.Context) (clientapi.Instance, error) {
return &singleTenantInstance{
client: s.client,
features: s.features,
cfg: s.cfg,
}, nil
}
func (s *singleTenantInstance) GetSettings() clientapi.InstanceConfigurationSettings {
return clientapi.InstanceConfigurationSettings{
StackID: 0,
FeatureToggles: s.features,
FullConfig: nil,
Options: nil,
SQLExpressionCellLimit: s.cfg.SQLExpressionCellLimit,
SQLExpressionOutputCellLimit: s.cfg.SQLExpressionOutputCellLimit,
SQLExpressionTimeout: s.cfg.SQLExpressionTimeout,
ExpressionsEnabled: s.cfg.ExpressionsEnabled,
}, nil
}
}
func (s *singleTenantInstance) GetLogger(parent log.Logger) log.Logger {
// currently we do not add any extra info
return parent.New()
}

View File

@ -7,6 +7,7 @@ import (
"github.com/grafana/grafana-plugin-sdk-go/backend"
data "github.com/grafana/grafana-plugin-sdk-go/experimental/apis/data/v0alpha1"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/services/featuremgmt"
)
@ -20,19 +21,20 @@ type QueryDataClient interface {
}
type InstanceConfigurationSettings struct {
StackID uint32
FeatureToggles featuremgmt.FeatureToggles
FullConfig map[string]map[string]string // configuration file settings
Options map[string]string // additional settings related to an instance as set by grafana
SQLExpressionCellLimit int64
SQLExpressionOutputCellLimit int64
SQLExpressionTimeout time.Duration
ExpressionsEnabled bool
}
type DataSourceClientSupplier interface {
// Get a client for a given datasource
GetDataSourceClient(ctx context.Context, ref data.DataSourceRef, headers map[string]string, instanceConfig InstanceConfigurationSettings) (QueryDataClient, error)
type Instance interface {
GetDataSourceClient(ctx context.Context, ref data.DataSourceRef, headers map[string]string) (QueryDataClient, error)
// fetch information on the grafana instance (e.g. feature toggles)
GetInstanceConfigurationSettings(ctx context.Context) (InstanceConfigurationSettings, error)
GetSettings() InstanceConfigurationSettings
GetLogger(parent log.Logger) log.Logger
}
type InstanceProvider interface {
GetInstance(ctx context.Context) (Instance, error)
}

View File

@ -246,20 +246,21 @@ func handleQuery(ctx context.Context, raw query.QueryDataRequest, b QueryAPIBuil
headers := ExtractKnownHeaders(httpreq.Header)
instanceConfig, err := b.clientSupplier.GetInstanceConfigurationSettings(ctx)
instance, err := b.clientSupplier.GetInstance(ctx)
if err != nil {
connectLogger.Error("failed to get instance configuration settings", "err", err)
responder.Error(err)
return nil, err
}
dsQuerierLoggerWithSlug := connectLogger.New("slug", instanceConfig.Options["slug"], "ruleuid", headers["X-Rule-Uid"])
instanceConfig := instance.GetSettings()
dsQuerierLoggerWithSlug := instance.GetLogger(connectLogger).New("ruleuid", headers["X-Rule-Uid"])
mtDsClientBuilder := mtdsclient.NewMtDatasourceClientBuilderWithClientSupplier(
b.clientSupplier,
instance,
ctx,
headers,
instanceConfig,
dsQuerierLoggerWithSlug,
)

View File

@ -250,7 +250,18 @@ type mockClient struct {
stubbedFrame *data.Frame
}
func (m mockClient) GetDataSourceClient(ctx context.Context, ref dataapi.DataSourceRef, headers map[string]string, instanceConfig clientapi.InstanceConfigurationSettings) (clientapi.QueryDataClient, error) {
func (m mockClient) GetInstance(ctx context.Context) (clientapi.Instance, error) {
mclient := mockClient{
stubbedFrame: m.stubbedFrame,
}
return mclient, nil
}
func (m mockClient) GetLogger(parent log.Logger) log.Logger {
return parent.New()
}
func (m mockClient) GetDataSourceClient(ctx context.Context, ref dataapi.DataSourceRef, headers map[string]string) (clientapi.QueryDataClient, error) {
mclient := mockClient{
stubbedFrame: m.stubbedFrame,
}
@ -281,11 +292,11 @@ func (m mockClient) CheckHealth(ctx context.Context, req *backend.CheckHealthReq
return nil, nil
}
func (m mockClient) GetInstanceConfigurationSettings(ctx context.Context) (clientapi.InstanceConfigurationSettings, error) {
func (m mockClient) GetSettings() clientapi.InstanceConfigurationSettings {
return clientapi.InstanceConfigurationSettings{
ExpressionsEnabled: true,
FeatureToggles: featuremgmt.WithFeatures(featuremgmt.FlagSqlExpressions),
}, nil
}
}
type mockLegacyDataSourceLookup struct{}

View File

@ -45,7 +45,7 @@ type QueryAPIBuilder struct {
tracer tracing.Tracer
metrics *metrics.ExprMetrics
clientSupplier clientapi.DataSourceClientSupplier
clientSupplier clientapi.InstanceProvider
registry query.DataSourceApiServerRegistry
converter *expr.ResultConverter
queryTypes *query.QueryTypeDefinitionList
@ -54,7 +54,7 @@ type QueryAPIBuilder struct {
func NewQueryAPIBuilder(
features featuremgmt.FeatureToggles,
clientSupplier clientapi.DataSourceClientSupplier,
clientSupplier clientapi.InstanceProvider,
ar authorizer.Authorizer,
registry query.DataSourceApiServerRegistry,
registerer prometheus.Registerer,

View File

@ -24,22 +24,20 @@ func NewNullMTDatasourceClientBuilder() MTDatasourceClientBuilder {
}
type MtDatasourceClientBuilderWithClientSupplier struct {
clientSupplier clientapi.DataSourceClientSupplier
ctx context.Context
headers map[string]string
instanceConfig clientapi.InstanceConfigurationSettings
logger log.Logger
instance clientapi.Instance
ctx context.Context
headers map[string]string
logger log.Logger
}
func (b *MtDatasourceClientBuilderWithClientSupplier) BuildClient(pluginId string, uid string) (clientapi.QueryDataClient, bool) {
dsClient, err := b.clientSupplier.GetDataSourceClient(
dsClient, err := b.instance.GetDataSourceClient(
b.ctx,
v0alpha1.DataSourceRef{
Type: pluginId,
UID: uid,
},
b.headers,
b.instanceConfig,
)
if err != nil {
b.logger.Debug("failed to get mt ds client", "error", err)
@ -50,18 +48,16 @@ func (b *MtDatasourceClientBuilderWithClientSupplier) BuildClient(pluginId strin
// TODO: I think we might be able to refactor this to just use the client supplier directly
func NewMtDatasourceClientBuilderWithClientSupplier(
clientSupplier clientapi.DataSourceClientSupplier,
instance clientapi.Instance,
ctx context.Context,
headers map[string]string,
instanceConfig clientapi.InstanceConfigurationSettings,
logger log.Logger,
) MTDatasourceClientBuilder {
return &MtDatasourceClientBuilderWithClientSupplier{
clientSupplier: clientSupplier,
ctx: ctx,
headers: headers,
instanceConfig: instanceConfig,
logger: logger,
instance: instance,
ctx: ctx,
headers: headers,
logger: logger,
}
}