From fd4fc106d98d8d40b56230a560af887d0c312b3b Mon Sep 17 00:00:00 2001 From: Andreas Christou Date: Fri, 25 Oct 2024 13:25:00 +0100 Subject: [PATCH] Azure: Improve handling of deprecated query types (#95363) * Add logic for handling deprecated query types * Test * Improve documentation --- pkg/tsdb/azuremonitor/azuremonitor.go | 23 ++++ pkg/tsdb/azuremonitor/azuremonitor_test.go | 144 +++++++++++++++++++++ 2 files changed, 167 insertions(+) diff --git a/pkg/tsdb/azuremonitor/azuremonitor.go b/pkg/tsdb/azuremonitor/azuremonitor.go index b5bf3dcd5a0..442ef4d2cea 100644 --- a/pkg/tsdb/azuremonitor/azuremonitor.go +++ b/pkg/tsdb/azuremonitor/azuremonitor.go @@ -54,7 +54,30 @@ func ProvideService(httpClientProvider *httpclient.Provider) *Service { return s } +func handleDeprecatedQueryTypes(req *backend.QueryDataRequest) *backend.QueryDataResponse { + // Logic to handle deprecated query types that haven't been migrated + responses := backend.Responses{} + for _, q := range req.Queries { + if q.QueryType == "Application Insights" || q.QueryType == "Insights Analytics" { + responses[q.RefID] = backend.DataResponse{ + Error: fmt.Errorf("query type: '%s' is no longer supported. Please migrate this query (see https://grafana.com/docs/grafana/v9.0/datasources/azuremonitor/deprecated-application-insights/ for details)", q.QueryType), + ErrorSource: backend.ErrorSourceDownstream, + } + } + } + + return &backend.QueryDataResponse{ + Responses: responses, + } +} + func (s *Service) QueryData(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) { + responses := handleDeprecatedQueryTypes(req) + + if len(responses.Responses) > 0 { + return responses, nil + } + return s.queryMux.QueryData(azusercontext.WithUserFromQueryReq(ctx, req), req) } diff --git a/pkg/tsdb/azuremonitor/azuremonitor_test.go b/pkg/tsdb/azuremonitor/azuremonitor_test.go index 6cde8cb6792..992c5b76db2 100644 --- a/pkg/tsdb/azuremonitor/azuremonitor_test.go +++ b/pkg/tsdb/azuremonitor/azuremonitor_test.go @@ -5,6 +5,7 @@ import ( "context" "encoding/json" "errors" + "fmt" "io" "net/http" "strings" @@ -499,3 +500,146 @@ func TestCheckHealth(t *testing.T) { }) } } + +func Test_QueryData(t *testing.T) { + tests := []struct { + name string + queryType string + expectedURL string + Err require.ErrorAssertionFunc + ExpectedError error + }{ + { + name: "Azure Monitor query type", + queryType: azureMonitor, + expectedURL: testRoutes[azureMonitor].URL, + Err: require.NoError, + ExpectedError: nil, + }, + { + name: "Azure Log Analytics query type", + queryType: azureLogAnalytics, + expectedURL: testRoutes[azureLogAnalytics].URL, + Err: require.NoError, + ExpectedError: nil, + }, + { + name: "Azure Resource Graph query type", + queryType: azureResourceGraph, + expectedURL: testRoutes[azureResourceGraph].URL, + Err: require.NoError, + ExpectedError: nil, + }, + { + name: "Azure Traces query type", + queryType: azureTraces, + expectedURL: testRoutes[azureLogAnalytics].URL, + Err: require.NoError, + ExpectedError: nil, + }, + { + name: "traceExemplar query type", + queryType: traceExemplar, + expectedURL: testRoutes[traceExemplar].URL, + Err: require.NoError, + ExpectedError: nil, + }, + { + name: "Deprecated Application Insights query type", + queryType: "Application Insights", + expectedURL: "", + Err: require.Error, + ExpectedError: fmt.Errorf("query type: '%s' is no longer supported. Please migrate this query (see https://grafana.com/docs/grafana/v9.0/datasources/azuremonitor/deprecated-application-insights/ for details)", "Application Insights"), + }, + { + name: "Deprecated Insights Analytics query type", + queryType: "Insights Analytics", + expectedURL: "", + Err: require.Error, + ExpectedError: fmt.Errorf("query type: '%s' is no longer supported. Please migrate this query (see https://grafana.com/docs/grafana/v9.0/datasources/azuremonitor/deprecated-application-insights/ for details)", "Insights Analytics"), + }, + } + + service := &Service{ + im: &fakeInstance{ + routes: testRoutes, + services: map[string]types.DatasourceService{ + azureMonitor: { + URL: testRoutes[azureMonitor].URL, + HTTPClient: &http.Client{}, + }, + azureLogAnalytics: { + URL: testRoutes[azureLogAnalytics].URL, + HTTPClient: &http.Client{}, + }, + azureResourceGraph: { + URL: testRoutes[azureResourceGraph].URL, + HTTPClient: &http.Client{}, + }, + azureTraces: { + URL: testRoutes[azureTraces].URL, + HTTPClient: &http.Client{}, + }, + traceExemplar: { + URL: testRoutes[traceExemplar].URL, + HTTPClient: &http.Client{}, + }, + }, + }, + executors: map[string]azDatasourceExecutor{ + azureMonitor: &fakeExecutor{ + t: t, + queryType: azureMonitor, + expectedURL: testRoutes[azureMonitor].URL, + }, + azureLogAnalytics: &fakeExecutor{ + t: t, + queryType: azureMonitor, + expectedURL: testRoutes[azureLogAnalytics].URL, + }, + azureResourceGraph: &fakeExecutor{ + t: t, + queryType: azureMonitor, + expectedURL: testRoutes[azureResourceGraph].URL, + }, + azureTraces: &fakeExecutor{ + t: t, + queryType: azureMonitor, + expectedURL: testRoutes[azureTraces].URL, + }, + traceExemplar: &fakeExecutor{ + t: t, + queryType: azureMonitor, + expectedURL: testRoutes[traceExemplar].URL, + }, + }, + } + service.queryMux = service.newQueryMux() + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + res, _ := service.QueryData(context.Background(), &backend.QueryDataRequest{ + PluginContext: backend.PluginContext{ + DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{ + Name: "datasource_name", + UID: "datasource_UID", + }, + }, + Queries: []backend.DataQuery{ + {QueryType: tt.queryType, + RefID: "test"}, + }, + }) + + if res == nil { + t.Errorf("Expecting a response") + } + + if res != nil { + tt.Err(t, res.Responses["test"].Error) + if tt.ExpectedError != nil { + assert.EqualError(t, res.Responses["test"].Error, tt.ExpectedError.Error()) + } + } + }) + } +}