forked from grafana/grafana-plugin-sdk-go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
data.go
196 lines (161 loc) · 6.64 KB
/
data.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
package backend
import (
"context"
"encoding/json"
"errors"
"net/http"
"time"
"github.com/kosimas/grafana-plugin-sdk-go/data"
jsoniter "github.com/json-iterator/go"
)
// QueryDataHandler handles data queries.
type QueryDataHandler interface {
// QueryData handles multiple queries and returns multiple responses.
// req contains the queries []DataQuery (where each query contains RefID as a unique identifier).
// The QueryDataResponse contains a map of RefID to the response for each query, and each response
// contains Frames ([]*Frame).
//
// The Frames' RefID property, when it is an empty string, will be automatically set to
// the RefID in QueryDataResponse.Responses map. This is done before the QueryDataResponse is
// sent to Grafana. Therefore one does not need to be set that property on frames when using this method.
QueryData(ctx context.Context, req *QueryDataRequest) (*QueryDataResponse, error)
}
// QueryDataHandlerFunc is an adapter to allow the use of
// ordinary functions as backend.QueryDataHandler. If f is a function
// with the appropriate signature, QueryDataHandlerFunc(f) is a
// Handler that calls f.
type QueryDataHandlerFunc func(ctx context.Context, req *QueryDataRequest) (*QueryDataResponse, error)
// QueryData calls fn(ctx, req).
func (fn QueryDataHandlerFunc) QueryData(ctx context.Context, req *QueryDataRequest) (*QueryDataResponse, error) {
return fn(ctx, req)
}
// QueryDataRequest contains a single request which contains multiple queries.
// It is the input type for a QueryData call.
type QueryDataRequest struct {
// PluginContext the contextual information for the request.
PluginContext PluginContext
// Headers the environment/metadata information for the request.
//
// To access forwarded HTTP headers please use
// GetHTTPHeaders or GetHTTPHeader.
Headers map[string]string
// Queries the data queries for the request.
Queries []DataQuery
}
// SetHTTPHeader sets the header entries associated with key to the
// single element value. It replaces any existing values
// associated with key. The key is case insensitive; it is
// canonicalized by textproto.CanonicalMIMEHeaderKey.
func (req *QueryDataRequest) SetHTTPHeader(key, value string) {
if req.Headers == nil {
req.Headers = map[string]string{}
}
setHTTPHeaderInStringMap(req.Headers, key, value)
}
// DeleteHTTPHeader deletes the values associated with key.
// The key is case insensitive; it is canonicalized by
// CanonicalHeaderKey.
func (req *QueryDataRequest) DeleteHTTPHeader(key string) {
deleteHTTPHeaderInStringMap(req.Headers, key)
}
// GetHTTPHeader gets the first value associated with the given key. If
// there are no values associated with the key, Get returns "".
// It is case insensitive; textproto.CanonicalMIMEHeaderKey is
// used to canonicalize the provided key. Get assumes that all
// keys are stored in canonical form.
func (req *QueryDataRequest) GetHTTPHeader(key string) string {
return req.GetHTTPHeaders().Get(key)
}
// GetHTTPHeaders returns HTTP headers.
func (req *QueryDataRequest) GetHTTPHeaders() http.Header {
return getHTTPHeadersFromStringMap(req.Headers)
}
// DataQuery represents a single query as sent from the frontend.
// A slice of DataQuery makes up the Queries property of a QueryDataRequest.
type DataQuery struct {
// RefID is the unique identifier of the query, set by the frontend call.
RefID string
// QueryType is an optional identifier for the type of query.
// It can be used to distinguish different types of queries.
QueryType string
// MaxDataPoints is the maximum number of datapoints that should be returned from a time series query.
MaxDataPoints int64
// Interval is the suggested duration between time points in a time series query.
Interval time.Duration
// TimeRange is the Start and End of the query as sent by the frontend.
TimeRange TimeRange
// JSON is the raw JSON query and includes the above properties as well as custom properties.
JSON json.RawMessage
}
// QueryDataResponse contains the results from a QueryDataRequest.
// It is the return type of a QueryData call.
type QueryDataResponse struct {
// Responses is a map of RefIDs (Unique Query ID) to *DataResponse.
Responses Responses
}
// MarshalJSON writes the results as json
func (r QueryDataResponse) MarshalJSON() ([]byte, error) {
cfg := jsoniter.ConfigCompatibleWithStandardLibrary
stream := cfg.BorrowStream(nil)
defer cfg.ReturnStream(stream)
writeQueryDataResponseJSON(&r, stream)
return append([]byte(nil), stream.Buffer()...), stream.Error
}
// UnmarshalJSON will read JSON into a QueryDataResponse
func (r *QueryDataResponse) UnmarshalJSON(b []byte) error {
iter := jsoniter.ParseBytes(jsoniter.ConfigDefault, b)
readQueryDataResultsJSON(r, iter)
return iter.Error
}
// NewQueryDataResponse returns a QueryDataResponse with the Responses property initialized.
func NewQueryDataResponse() *QueryDataResponse {
return &QueryDataResponse{
Responses: make(Responses),
}
}
// Responses is a map of RefIDs (Unique Query ID) to DataResponses.
// The QueryData method the QueryDataHandler method will set the RefId
// property on the DataResponses' frames based on these RefIDs.
//
//swagger:model
type Responses map[string]DataResponse
// DataResponse contains the results from a DataQuery.
// A map of RefIDs (unique query identifiers) to this type makes up the Responses property of a QueryDataResponse.
// The Error property is used to allow for partial success responses from the containing QueryDataResponse.
//
//swagger:model
type DataResponse struct {
// The data returned from the Query. Each Frame repeats the RefID.
Frames data.Frames
// Error is a property to be set if the corresponding DataQuery has an error.
Error error
// Status codes map to HTTP status values
Status Status
}
// ErrDataResponse returns an error DataResponse given status and message.
func ErrDataResponse(status Status, message string) DataResponse {
return DataResponse{
Error: errors.New(message),
Status: status,
}
}
// MarshalJSON writes the results as json
func (r DataResponse) MarshalJSON() ([]byte, error) {
cfg := jsoniter.ConfigCompatibleWithStandardLibrary
stream := cfg.BorrowStream(nil)
defer cfg.ReturnStream(stream)
writeDataResponseJSON(&r, stream)
return append([]byte(nil), stream.Buffer()...), stream.Error
}
// TimeRange represents a time range for a query and is a property of DataQuery.
type TimeRange struct {
// From is the start time of the query.
From time.Time
// To is the end time of the query.
To time.Time
}
// Duration returns a time.Duration representing the amount of time between From and To.
func (tr TimeRange) Duration() time.Duration {
return tr.To.Sub(tr.From)
}
var _ ForwardHTTPHeaders = (*QueryDataRequest)(nil)