Plugins: Core plugins register via backend factory provider (#43171)
* refactoring store interface and init flow * fix import * fix linter * refactor resource calling * load with class * re-order args * fix tests * fix linter * remove old creator * add custom config struct * fix some tests * cleanup * fix * tackle plugins * fix linter * refactor and fix test * add connect failure error * add fix for azure, cloud monitoring and test data * restructure * remove unused err * add fake tracer for test * fix grafana ds plugin
This commit is contained in:
@@ -85,7 +85,7 @@ func writeResponse(rw http.ResponseWriter, code int, msg string) {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) resourceHandler(subDataSource string) func(rw http.ResponseWriter, req *http.Request) {
|
||||
func (s *Service) handleResourceReq(subDataSource string) func(rw http.ResponseWriter, req *http.Request) {
|
||||
return func(rw http.ResponseWriter, req *http.Request) {
|
||||
azlog.Debug("Received resource call", "url", req.URL.String(), "method", req.Method)
|
||||
|
||||
@@ -115,11 +115,13 @@ func (s *Service) resourceHandler(subDataSource string) func(rw http.ResponseWri
|
||||
}
|
||||
}
|
||||
|
||||
// registerRoutes provides route definitions shared with the frontend.
|
||||
// newResourceMux provides route definitions shared with the frontend.
|
||||
// Check: /public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/common.ts <routeNames>
|
||||
func (s *Service) registerRoutes(mux *http.ServeMux) {
|
||||
mux.HandleFunc("/azuremonitor/", s.resourceHandler(azureMonitor))
|
||||
mux.HandleFunc("/appinsights/", s.resourceHandler(appInsights))
|
||||
mux.HandleFunc("/loganalytics/", s.resourceHandler(azureLogAnalytics))
|
||||
mux.HandleFunc("/resourcegraph/", s.resourceHandler(azureResourceGraph))
|
||||
func (s *Service) newResourceMux() *http.ServeMux {
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("/azuremonitor/", s.handleResourceReq(azureMonitor))
|
||||
mux.HandleFunc("/appinsights/", s.handleResourceReq(appInsights))
|
||||
mux.HandleFunc("/loganalytics/", s.handleResourceReq(azureLogAnalytics))
|
||||
mux.HandleFunc("/resourcegraph/", s.handleResourceReq(azureResourceGraph))
|
||||
return mux
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ func (s *fakeProxy) Do(rw http.ResponseWriter, req *http.Request, cli *http.Clie
|
||||
return nil
|
||||
}
|
||||
|
||||
func Test_resourceHandler(t *testing.T) {
|
||||
func Test_handleResourceReq(t *testing.T) {
|
||||
proxy := &fakeProxy{}
|
||||
s := Service{
|
||||
im: &fakeInstance{
|
||||
@@ -102,7 +102,6 @@ func Test_resourceHandler(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
Cfg: &setting.Cfg{},
|
||||
executors: map[string]azDatasourceExecutor{
|
||||
azureMonitor: &AzureMonitorDatasource{
|
||||
proxy: proxy,
|
||||
@@ -114,7 +113,7 @@ func Test_resourceHandler(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error %v", err)
|
||||
}
|
||||
s.resourceHandler(azureMonitor)(rw, req)
|
||||
s.handleResourceReq(azureMonitor)(rw, req)
|
||||
expectedURL := "https://management.azure.com/subscriptions/44693801"
|
||||
if proxy.requestedURL != expectedURL {
|
||||
t.Errorf("Unexpected result URL. Got %s, expecting %s", proxy.requestedURL, expectedURL)
|
||||
|
||||
@@ -12,18 +12,16 @@ import (
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend/instancemgmt"
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend/resource/httpadapter"
|
||||
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/plugins/backendplugin/coreplugin"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/tsdb/azuremonitor/azcredentials"
|
||||
)
|
||||
|
||||
const (
|
||||
timeSeries = "time_series"
|
||||
pluginID = "grafana-azure-monitor-datasource"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -31,7 +29,7 @@ var (
|
||||
legendKeyFormat = regexp.MustCompile(`\{\{\s*(.+?)\s*\}\}`)
|
||||
)
|
||||
|
||||
func ProvideService(cfg *setting.Cfg, httpClientProvider *httpclient.Provider, pluginStore plugins.Store, tracer tracing.Tracer) *Service {
|
||||
func ProvideService(cfg *setting.Cfg, httpClientProvider *httpclient.Provider, tracer tracing.Tracer) *Service {
|
||||
proxy := &httpServiceProxy{}
|
||||
executors := map[string]azDatasourceExecutor{
|
||||
azureMonitor: &AzureMonitorDatasource{proxy: proxy},
|
||||
@@ -43,37 +41,36 @@ func ProvideService(cfg *setting.Cfg, httpClientProvider *httpclient.Provider, p
|
||||
im := datasource.NewInstanceManager(NewInstanceSettings(cfg, *httpClientProvider, executors))
|
||||
|
||||
s := &Service{
|
||||
Cfg: cfg,
|
||||
im: im,
|
||||
executors: executors,
|
||||
tracer: tracer,
|
||||
}
|
||||
|
||||
mux := s.newMux()
|
||||
resourceMux := http.NewServeMux()
|
||||
s.registerRoutes(resourceMux)
|
||||
factory := coreplugin.New(backend.ServeOpts{
|
||||
QueryDataHandler: mux,
|
||||
CallResourceHandler: httpadapter.New(resourceMux),
|
||||
})
|
||||
|
||||
resolver := plugins.CoreDataSourcePathResolver(cfg, pluginID)
|
||||
if err := pluginStore.AddWithFactory(context.Background(), pluginID, factory, resolver); err != nil {
|
||||
azlog.Error("Failed to register plugin", "error", err)
|
||||
}
|
||||
s.queryMux = s.newQueryMux()
|
||||
s.resourceHandler = httpadapter.New(s.newResourceMux())
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *Service) QueryData(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) {
|
||||
return s.queryMux.QueryData(ctx, req)
|
||||
}
|
||||
|
||||
func (s *Service) CallResource(ctx context.Context, req *backend.CallResourceRequest, sender backend.CallResourceResponseSender) error {
|
||||
return s.resourceHandler.CallResource(ctx, req, sender)
|
||||
}
|
||||
|
||||
type serviceProxy interface {
|
||||
Do(rw http.ResponseWriter, req *http.Request, cli *http.Client) http.ResponseWriter
|
||||
}
|
||||
|
||||
type Service struct {
|
||||
Cfg *setting.Cfg
|
||||
im instancemgmt.InstanceManager
|
||||
executors map[string]azDatasourceExecutor
|
||||
tracer tracing.Tracer
|
||||
|
||||
queryMux *datasource.QueryTypeMux
|
||||
resourceHandler backend.CallResourceHandler
|
||||
tracer tracing.Tracer
|
||||
}
|
||||
|
||||
type azureMonitorSettings struct {
|
||||
@@ -182,7 +179,7 @@ func (s *Service) getDataSourceFromPluginReq(req *backend.QueryDataRequest) (dat
|
||||
return dsInfo, nil
|
||||
}
|
||||
|
||||
func (s *Service) newMux() *datasource.QueryTypeMux {
|
||||
func (s *Service) newQueryMux() *datasource.QueryTypeMux {
|
||||
mux := datasource.NewQueryTypeMux()
|
||||
for dsType := range s.executors {
|
||||
// Make a copy of the string to keep the reference after the iterator
|
||||
|
||||
@@ -99,10 +99,6 @@ func (f *fakeExecutor) executeTimeSeriesQuery(ctx context.Context, originalQueri
|
||||
}
|
||||
|
||||
func Test_newMux(t *testing.T) {
|
||||
cfg := &setting.Cfg{
|
||||
Azure: setting.AzureSettings{},
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
queryType string
|
||||
@@ -126,7 +122,6 @@ func Test_newMux(t *testing.T) {
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
s := &Service{
|
||||
Cfg: cfg,
|
||||
im: &fakeInstance{
|
||||
routes: routes[azureMonitorPublic],
|
||||
services: map[string]datasourceService{
|
||||
@@ -144,7 +139,7 @@ func Test_newMux(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
mux := s.newMux()
|
||||
mux := s.newQueryMux()
|
||||
res, err := mux.QueryData(context.Background(), &backend.QueryDataRequest{
|
||||
PluginContext: backend.PluginContext{},
|
||||
Queries: []backend.DataQuery{
|
||||
|
||||
Reference in New Issue
Block a user