Graphite: Migrate query endpoint entirely to backend (#111138)
* Update query type * Support metric tank queries - Update tests - Appropriately set URL parameter * Support queries via the backend - Add the filterQuery and applyTemplateVariables methods - Separate the frontend query path into its own function - Ensure format is always json - Add method for building backend query objects (maintain the existing template replacement logic) - Fix a bug in metric find queries * Update tests * Fix lint * Update types
This commit is contained in:
@@ -123,11 +123,11 @@ func (s *Service) RunQuery(ctx context.Context, req *backend.QueryDataRequest, d
|
||||
|
||||
// processQuery converts a Graphite data source query to a Graphite query target. It returns the target,
|
||||
// and the model if the target is invalid
|
||||
func (s *Service) processQuery(query backend.DataQuery) (string, *GraphiteQuery, error) {
|
||||
func (s *Service) processQuery(query backend.DataQuery) (string, *GraphiteQuery, bool, error) {
|
||||
queryJSON := GraphiteQuery{}
|
||||
err := json.Unmarshal(query.JSON, &queryJSON)
|
||||
if err != nil {
|
||||
return "", &queryJSON, fmt.Errorf("failed to decode the Graphite query: %w", err)
|
||||
return "", &queryJSON, false, fmt.Errorf("failed to decode the Graphite query: %w", err)
|
||||
}
|
||||
s.logger.Debug("Graphite", "query", queryJSON)
|
||||
currTarget := queryJSON.TargetFull
|
||||
@@ -137,11 +137,11 @@ func (s *Service) processQuery(query backend.DataQuery) (string, *GraphiteQuery,
|
||||
}
|
||||
if currTarget == "" {
|
||||
s.logger.Debug("Graphite", "empty query target", queryJSON)
|
||||
return "", &queryJSON, nil
|
||||
return "", &queryJSON, false, nil
|
||||
}
|
||||
target := fixIntervalFormat(currTarget)
|
||||
|
||||
return target, nil, nil
|
||||
return target, nil, queryJSON.IsMetricTank, nil
|
||||
}
|
||||
|
||||
func (s *Service) createGraphiteRequest(ctx context.Context, query backend.DataQuery, dsInfo *datasourceInfo) (*http.Request, url.Values, *GraphiteQuery, error) {
|
||||
@@ -158,7 +158,7 @@ func (s *Service) createGraphiteRequest(ctx context.Context, query backend.DataQ
|
||||
"target": []string{},
|
||||
}
|
||||
|
||||
target, emptyQuery, err := s.processQuery(query)
|
||||
target, emptyQuery, isMetricTank, err := s.processQuery(query)
|
||||
if err != nil {
|
||||
return nil, formData, nil, err
|
||||
}
|
||||
@@ -172,11 +172,17 @@ func (s *Service) createGraphiteRequest(ctx context.Context, query backend.DataQ
|
||||
|
||||
s.logger.Debug("Graphite request", "params", formData)
|
||||
|
||||
params := map[string][]string{}
|
||||
if isMetricTank {
|
||||
params["meta"] = []string{"true"}
|
||||
}
|
||||
|
||||
graphiteReq, err := s.createRequest(ctx, dsInfo, URLParams{
|
||||
SubPath: "render",
|
||||
Method: http.MethodPost,
|
||||
Body: strings.NewReader(formData.Encode()),
|
||||
Headers: map[string]string{"Content-Type": "application/x-www-form-urlencoded"},
|
||||
SubPath: "render",
|
||||
Method: http.MethodPost,
|
||||
Body: strings.NewReader(formData.Encode()),
|
||||
Headers: map[string]string{"Content-Type": "application/x-www-form-urlencoded"},
|
||||
QueryParams: params,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, formData, nil, err
|
||||
|
||||
@@ -32,10 +32,11 @@ func TestProcessQuery(t *testing.T) {
|
||||
}`),
|
||||
},
|
||||
}
|
||||
target, jsonModel, err := service.processQuery(queries[0])
|
||||
target, jsonModel, isMetricTank, err := service.processQuery(queries[0])
|
||||
assert.NoError(t, err)
|
||||
assert.Nil(t, jsonModel)
|
||||
assert.Equal(t, "app.grafana.*.dashboards.views.1M.count", target)
|
||||
assert.False(t, isMetricTank)
|
||||
})
|
||||
|
||||
t.Run("Returns if target is empty", func(t *testing.T) {
|
||||
@@ -48,10 +49,26 @@ func TestProcessQuery(t *testing.T) {
|
||||
},
|
||||
}
|
||||
emptyQuery := GraphiteQuery{Target: ""}
|
||||
target, jsonModel, err := service.processQuery(queries[0])
|
||||
target, jsonModel, isMetricTank, err := service.processQuery(queries[0])
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, &emptyQuery, jsonModel)
|
||||
assert.Equal(t, "", target)
|
||||
assert.False(t, isMetricTank)
|
||||
})
|
||||
|
||||
t.Run("Returns isMetricTank value", func(t *testing.T) {
|
||||
queries := []backend.DataQuery{
|
||||
{
|
||||
RefID: "A",
|
||||
JSON: []byte(`{
|
||||
"target": "app.grafana.*.dashboards.views.1M.count",
|
||||
"isMetricTank": true
|
||||
}`),
|
||||
},
|
||||
}
|
||||
_, _, isMetricTank, err := service.processQuery(queries[0])
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, isMetricTank)
|
||||
})
|
||||
|
||||
t.Run("QueryData with no valid queries returns bad request response", func(t *testing.T) {
|
||||
|
||||
@@ -27,6 +27,7 @@ type GraphiteQuery struct {
|
||||
TargetFull string `json:"targetFull,omitempty"`
|
||||
Tags []string `json:"tags,omitempty"`
|
||||
FromAnnotations *bool `json:"fromAnnotations,omitempty"`
|
||||
IsMetricTank bool `json:"isMetricTank,omitempty"`
|
||||
}
|
||||
|
||||
type GraphiteEventsRequest struct {
|
||||
|
||||
Reference in New Issue
Block a user