Commit ed661767 by bergquist

follow go idiom and return error as second param

parent 79b873e4
......@@ -43,7 +43,7 @@ func QueryMetrics(c *middleware.Context, reqDto dtos.MetricRequest) Response {
})
}
resp, err := tsdb.HandleRequest(context.Background(), request)
resp, err := tsdb.HandleRequest(context.Background(), dsQuery.Result, request)
if err != nil {
return ApiError(500, "Metric request error", err)
}
......@@ -100,16 +100,17 @@ func GetTestDataRandomWalk(c *middleware.Context) Response {
timeRange := tsdb.NewTimeRange(from, to)
request := &tsdb.TsdbQuery{TimeRange: timeRange}
dsInfo := &models.DataSource{Type: "grafana-testdata-datasource"}
request.Queries = append(request.Queries, &tsdb.Query{
RefId: "A",
IntervalMs: intervalMs,
Model: simplejson.NewFromAny(&util.DynMap{
"scenario": "random_walk",
}),
DataSource: &models.DataSource{Type: "grafana-testdata-datasource"},
DataSource: dsInfo,
})
resp, err := tsdb.HandleRequest(context.Background(), request)
resp, err := tsdb.HandleRequest(context.Background(), dsInfo, request)
if err != nil {
return ApiError(500, "Metric request error", err)
}
......
......@@ -112,7 +112,7 @@ func (c *QueryCondition) executeQuery(context *alerting.EvalContext, timeRange *
req := c.getRequestForAlertRule(getDsInfo.Result, timeRange)
result := make(tsdb.TimeSeriesSlice, 0)
resp, err := c.HandleRequest(context.Ctx, req)
resp, err := c.HandleRequest(context.Ctx, getDsInfo.Result, req)
if err != nil {
if err == gocontext.DeadlineExceeded {
return nil, fmt.Errorf("Alert execution exceeded the timeout")
......
......@@ -168,7 +168,7 @@ func (ctx *queryConditionTestContext) exec() (*alerting.ConditionResult, error)
ctx.condition = condition
condition.HandleRequest = func(context context.Context, req *tsdb.TsdbQuery) (*tsdb.Response, error) {
condition.HandleRequest = func(context context.Context, dsInfo *m.DataSource, req *tsdb.TsdbQuery) (*tsdb.Response, error) {
return &tsdb.Response{
Results: map[string]*tsdb.QueryResult{
"A": {Series: ctx.series},
......
......@@ -20,18 +20,18 @@ func NewFakeExecutor(dsInfo *models.DataSource) (*FakeExecutor, error) {
}, nil
}
func (e *FakeExecutor) Query(ctx context.Context, dsInfo *models.DataSource, context *TsdbQuery) *BatchResult {
result := &BatchResult{QueryResults: make(map[string]*QueryResult)}
func (e *FakeExecutor) Query(ctx context.Context, dsInfo *models.DataSource, context *TsdbQuery) (*Response, error) {
result := &Response{Results: make(map[string]*QueryResult)}
for _, query := range context.Queries {
if results, has := e.results[query.RefId]; has {
result.QueryResults[query.RefId] = results
result.Results[query.RefId] = results
}
if testFunc, has := e.resultsFn[query.RefId]; has {
result.QueryResults[query.RefId] = testFunc(context)
result.Results[query.RefId] = testFunc(context)
}
}
return result
return result, nil
}
func (e *FakeExecutor) Return(refId string, series TimeSeriesSlice) {
......
......@@ -37,8 +37,8 @@ func init() {
tsdb.RegisterTsdbQueryEndpoint("graphite", NewGraphiteExecutor)
}
func (e *GraphiteExecutor) Query(ctx context.Context, dsInfo *models.DataSource, tsdbQuery *tsdb.TsdbQuery) *tsdb.BatchResult {
result := &tsdb.BatchResult{}
func (e *GraphiteExecutor) Query(ctx context.Context, dsInfo *models.DataSource, tsdbQuery *tsdb.TsdbQuery) (*tsdb.Response, error) {
result := &tsdb.Response{}
from := "-" + formatTimeRange(tsdbQuery.TimeRange.From)
until := formatTimeRange(tsdbQuery.TimeRange.To)
......@@ -67,14 +67,12 @@ func (e *GraphiteExecutor) Query(ctx context.Context, dsInfo *models.DataSource,
req, err := e.createRequest(dsInfo, formData)
if err != nil {
result.Error = err
return result
return nil, err
}
httpClient, err := dsInfo.GetHttpClient()
if err != nil {
result.Error = err
return result
return nil, err
}
span, ctx := opentracing.StartSpanFromContext(ctx, "graphite query")
......@@ -90,17 +88,15 @@ func (e *GraphiteExecutor) Query(ctx context.Context, dsInfo *models.DataSource,
res, err := ctxhttp.Do(ctx, httpClient, req)
if err != nil {
result.Error = err
return result
return nil, err
}
data, err := e.parseResponse(res)
if err != nil {
result.Error = err
return result
return nil, err
}
result.QueryResults = make(map[string]*tsdb.QueryResult)
result.Results = make(map[string]*tsdb.QueryResult)
queryRes := tsdb.NewQueryResult()
for _, series := range data {
......@@ -114,8 +110,8 @@ func (e *GraphiteExecutor) Query(ctx context.Context, dsInfo *models.DataSource,
}
}
result.QueryResults["A"] = queryRes
return result
result.Results["A"] = queryRes
return result, nil
}
func (e *GraphiteExecutor) parseResponse(res *http.Response) ([]TargetResponseDTO, error) {
......
......@@ -39,17 +39,17 @@ func init() {
tsdb.RegisterTsdbQueryEndpoint("influxdb", NewInfluxDBExecutor)
}
func (e *InfluxDBExecutor) Query(ctx context.Context, dsInfo *models.DataSource, tsdbQuery *tsdb.TsdbQuery) *tsdb.BatchResult {
result := &tsdb.BatchResult{}
func (e *InfluxDBExecutor) Query(ctx context.Context, dsInfo *models.DataSource, tsdbQuery *tsdb.TsdbQuery) (*tsdb.Response, error) {
result := &tsdb.Response{}
query, err := e.getQuery(dsInfo, tsdbQuery.Queries, tsdbQuery)
if err != nil {
return result.WithError(err)
return nil, err
}
rawQuery, err := query.Build(tsdbQuery)
if err != nil {
return result.WithError(err)
return nil, err
}
if setting.Env == setting.DEV {
......@@ -58,21 +58,21 @@ func (e *InfluxDBExecutor) Query(ctx context.Context, dsInfo *models.DataSource,
req, err := e.createRequest(dsInfo, rawQuery)
if err != nil {
return result.WithError(err)
return nil, err
}
httpClient, err := dsInfo.GetHttpClient()
if err != nil {
return result.WithError(err)
return nil, err
}
resp, err := ctxhttp.Do(ctx, httpClient, req)
if err != nil {
return result.WithError(err)
return nil, err
}
if resp.StatusCode/100 != 2 {
return result.WithError(fmt.Errorf("Influxdb returned statuscode invalid status code: %v", resp.Status))
return nil, fmt.Errorf("Influxdb returned statuscode invalid status code: %v", resp.Status)
}
var response Response
......@@ -82,17 +82,17 @@ func (e *InfluxDBExecutor) Query(ctx context.Context, dsInfo *models.DataSource,
err = dec.Decode(&response)
if err != nil {
return result.WithError(err)
return nil, err
}
if response.Err != nil {
return result.WithError(response.Err)
return nil, response.Err
}
result.QueryResults = make(map[string]*tsdb.QueryResult)
result.QueryResults["A"] = e.ResponseParser.Parse(&response, query)
result.Results = make(map[string]*tsdb.QueryResult)
result.Results["A"] = e.ResponseParser.Parse(&response, query)
return result
return result, nil
}
func (e *InfluxDBExecutor) getQuery(dsInfo *models.DataSource, queries []*tsdb.Query, context *tsdb.TsdbQuery) (*Query, error) {
......
......@@ -22,24 +22,8 @@ type Query struct {
}
type Response struct {
BatchTimings []*BatchTiming `json:"timings"`
Results map[string]*QueryResult `json:"results"`
Message string `json:"message,omitempty"`
}
type BatchTiming struct {
TimeElapsed int64
}
type BatchResult struct {
Error error
QueryResults map[string]*QueryResult
Timings *BatchTiming
}
func (br *BatchResult) WithError(err error) *BatchResult {
br.Error = err
return br
Results map[string]*QueryResult `json:"results"`
Message string `json:"message,omitempty"`
}
type QueryResult struct {
......
......@@ -85,9 +85,9 @@ func (e *MysqlExecutor) initEngine(dsInfo *models.DataSource) error {
return nil
}
func (e *MysqlExecutor) Query(ctx context.Context, dsInfo *models.DataSource, tsdbQuery *tsdb.TsdbQuery) *tsdb.BatchResult {
result := &tsdb.BatchResult{
QueryResults: make(map[string]*tsdb.QueryResult),
func (e *MysqlExecutor) Query(ctx context.Context, dsInfo *models.DataSource, tsdbQuery *tsdb.TsdbQuery) (*tsdb.Response, error) {
result := &tsdb.Response{
Results: make(map[string]*tsdb.QueryResult),
}
macroEngine := NewMysqlMacroEngine(tsdbQuery.TimeRange)
......@@ -102,7 +102,7 @@ func (e *MysqlExecutor) Query(ctx context.Context, dsInfo *models.DataSource, ts
}
queryResult := &tsdb.QueryResult{Meta: simplejson.New(), RefId: query.RefId}
result.QueryResults[query.RefId] = queryResult
result.Results[query.RefId] = queryResult
rawSql, err := macroEngine.Interpolate(rawSql)
if err != nil {
......@@ -138,7 +138,7 @@ func (e *MysqlExecutor) Query(ctx context.Context, dsInfo *models.DataSource, ts
}
}
return result
return result, nil
}
func (e MysqlExecutor) TransformToTable(query *tsdb.Query, rows *core.Rows, result *tsdb.QueryResult) error {
......
......@@ -50,8 +50,8 @@ func init() {
tsdb.RegisterTsdbQueryEndpoint("opentsdb", NewOpenTsdbExecutor)
}
func (e *OpenTsdbExecutor) Query(ctx context.Context, dsInfo *models.DataSource, queryContext *tsdb.TsdbQuery) *tsdb.BatchResult {
result := &tsdb.BatchResult{}
func (e *OpenTsdbExecutor) Query(ctx context.Context, dsInfo *models.DataSource, queryContext *tsdb.TsdbQuery) (*tsdb.Response, error) {
result := &tsdb.Response{}
var tsdbQuery OpenTsdbQuery
......@@ -69,29 +69,26 @@ func (e *OpenTsdbExecutor) Query(ctx context.Context, dsInfo *models.DataSource,
req, err := e.createRequest(dsInfo, tsdbQuery)
if err != nil {
result.Error = err
return result
return nil, err
}
httpClient, err := dsInfo.GetHttpClient()
if err != nil {
result.Error = err
return result
return nil, err
}
res, err := ctxhttp.Do(ctx, httpClient, req)
if err != nil {
result.Error = err
return result
return nil, err
}
queryResult, err := e.parseResponse(tsdbQuery, res)
if err != nil {
return result.WithError(err)
return nil, err
}
result.QueryResults = queryResult
return result
result.Results = queryResult
return result, nil
}
func (e *OpenTsdbExecutor) createRequest(dsInfo *models.DataSource, data OpenTsdbQuery) (*http.Request, error) {
......
......@@ -80,17 +80,17 @@ func (e *PrometheusExecutor) getClient(dsInfo *models.DataSource) (apiv1.API, er
return apiv1.NewAPI(client), nil
}
func (e *PrometheusExecutor) Query(ctx context.Context, dsInfo *models.DataSource, tsdbQuery *tsdb.TsdbQuery) *tsdb.BatchResult {
result := &tsdb.BatchResult{}
func (e *PrometheusExecutor) Query(ctx context.Context, dsInfo *models.DataSource, tsdbQuery *tsdb.TsdbQuery) (*tsdb.Response, error) {
result := &tsdb.Response{}
client, err := e.getClient(dsInfo)
if err != nil {
return result.WithError(err)
return nil, err
}
query, err := parseQuery(tsdbQuery.Queries, tsdbQuery)
if err != nil {
return result.WithError(err)
return nil, err
}
timeRange := apiv1.Range{
......@@ -108,15 +108,15 @@ func (e *PrometheusExecutor) Query(ctx context.Context, dsInfo *models.DataSourc
value, err := client.QueryRange(ctx, query.Expr, timeRange)
if err != nil {
return result.WithError(err)
return nil, err
}
queryResult, err := parseResponse(value, query)
if err != nil {
return result.WithError(err)
return nil, err
}
result.QueryResults = queryResult
return result
result.Results = queryResult
return result, nil
}
func formatLegend(metric model.Metric, query *PrometheusQuery) string {
......
......@@ -8,7 +8,7 @@ import (
)
type TsdbQueryEndpoint interface {
Query(ctx context.Context, ds *models.DataSource, query *TsdbQuery) *BatchResult
Query(ctx context.Context, ds *models.DataSource, query *TsdbQuery) (*Response, error)
}
var registry map[string]GetTsdbQueryEndpointFn
......
......@@ -2,25 +2,17 @@ package tsdb
import (
"context"
"github.com/grafana/grafana/pkg/models"
)
type HandleRequestFunc func(ctx context.Context, req *TsdbQuery) (*Response, error)
type HandleRequestFunc func(ctx context.Context, dsInfo *models.DataSource, req *TsdbQuery) (*Response, error)
func HandleRequest(ctx context.Context, req *TsdbQuery) (*Response, error) {
//TODO niceify
ds := req.Queries[0].DataSource
endpoint, err := getTsdbQueryEndpointFor(ds)
func HandleRequest(ctx context.Context, dsInfo *models.DataSource, req *TsdbQuery) (*Response, error) {
endpoint, err := getTsdbQueryEndpointFor(dsInfo)
if err != nil {
return nil, err
}
res := endpoint.Query(ctx, ds, req)
if res.Error != nil {
return nil, res.Error
}
return &Response{
Results: res.QueryResults,
BatchTimings: []*BatchTiming{res.Timings},
}, nil
return endpoint.Query(ctx, dsInfo, req)
}
......@@ -24,19 +24,19 @@ func init() {
tsdb.RegisterTsdbQueryEndpoint("grafana-testdata-datasource", NewTestDataExecutor)
}
func (e *TestDataExecutor) Query(ctx context.Context, dsInfo *models.DataSource, tsdbQuery *tsdb.TsdbQuery) *tsdb.BatchResult {
result := &tsdb.BatchResult{}
result.QueryResults = make(map[string]*tsdb.QueryResult)
func (e *TestDataExecutor) Query(ctx context.Context, dsInfo *models.DataSource, tsdbQuery *tsdb.TsdbQuery) (*tsdb.Response, error) {
result := &tsdb.Response{}
result.Results = make(map[string]*tsdb.QueryResult)
for _, query := range tsdbQuery.Queries {
scenarioId := query.Model.Get("scenarioId").MustString("random_walk")
if scenario, exist := ScenarioRegistry[scenarioId]; exist {
result.QueryResults[query.RefId] = scenario.Handler(query, tsdbQuery)
result.QueryResults[query.RefId].RefId = query.RefId
result.Results[query.RefId] = scenario.Handler(query, tsdbQuery)
result.Results[query.RefId].RefId = query.RefId
} else {
e.log.Error("Scenario not found", "scenarioId", scenarioId)
}
}
return result
return result, nil
}
......@@ -19,7 +19,7 @@ func TestMetricQuery(t *testing.T) {
fakeExecutor := registerFakeExecutor()
fakeExecutor.Return("A", TimeSeriesSlice{&TimeSeries{Name: "argh"}})
res, err := HandleRequest(context.TODO(), req)
res, err := HandleRequest(context.TODO(), &models.DataSource{Id: 1, Type: "test"}, req)
So(err, ShouldBeNil)
Convey("Should return query results", func() {
......@@ -40,18 +40,13 @@ func TestMetricQuery(t *testing.T) {
fakeExecutor.Return("A", TimeSeriesSlice{&TimeSeries{Name: "argh"}})
fakeExecutor.Return("B", TimeSeriesSlice{&TimeSeries{Name: "barg"}})
res, err := HandleRequest(context.TODO(), req)
res, err := HandleRequest(context.TODO(), &models.DataSource{Id: 1, Type: "test"}, req)
So(err, ShouldBeNil)
Convey("Should return query results", func() {
So(len(res.Results), ShouldEqual, 2)
So(res.Results["B"].Series[0].Name, ShouldEqual, "barg")
})
Convey("Should have been batched in one request", func() {
So(len(res.BatchTimings), ShouldEqual, 1)
})
})
Convey("When query uses data source of unknown type", t, func() {
......@@ -61,7 +56,7 @@ func TestMetricQuery(t *testing.T) {
},
}
_, err := HandleRequest(context.TODO(), req)
_, err := HandleRequest(context.TODO(), &models.DataSource{Id: 12, Type: "testjughjgjg"}, req)
So(err, ShouldNotBeNil)
})
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment