| 
									
										
										
										
											2015-01-06 16:11:00 +08:00
										 |  |  | package api | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2020-07-24 18:34:56 +08:00
										 |  |  | 	"errors" | 
					
						
							| 
									
										
										
										
											2022-07-13 21:27:03 +08:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2021-02-04 03:47:45 +08:00
										 |  |  | 	"net/http" | 
					
						
							| 
									
										
										
										
											2016-06-03 21:06:57 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-31 23:35:03 +08:00
										 |  |  | 	"github.com/grafana/grafana-plugin-sdk-go/backend" | 
					
						
							| 
									
										
										
										
											2022-05-18 02:52:22 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-03 21:06:57 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/api/dtos" | 
					
						
							| 
									
										
										
										
											2021-01-15 21:43:20 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/api/response" | 
					
						
							| 
									
										
										
										
											2023-01-27 15:50:36 +08:00
										 |  |  | 	contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model" | 
					
						
							| 
									
										
										
										
											2022-06-28 00:23:15 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/datasources" | 
					
						
							| 
									
										
										
										
											2022-03-08 02:33:01 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/featuremgmt" | 
					
						
							| 
									
										
										
										
											2021-11-29 17:18:01 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/web" | 
					
						
							| 
									
										
										
										
											2015-01-06 16:11:00 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-29 18:08:40 +08:00
										 |  |  | func (hs *HTTPServer) handleQueryMetricsError(err error) *response.NormalResponse { | 
					
						
							| 
									
										
										
										
											2022-06-28 00:23:15 +08:00
										 |  |  | 	if errors.Is(err, datasources.ErrDataSourceAccessDenied) { | 
					
						
							| 
									
										
										
										
											2022-04-29 18:08:40 +08:00
										 |  |  | 		return response.Error(http.StatusForbidden, "Access denied to data source", err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-06-28 00:23:15 +08:00
										 |  |  | 	if errors.Is(err, datasources.ErrDataSourceNotFound) { | 
					
						
							| 
									
										
										
										
											2022-04-29 18:08:40 +08:00
										 |  |  | 		return response.Error(http.StatusNotFound, "Data source not found", err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-07-13 21:27:03 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	var secretsPlugin datasources.ErrDatasourceSecretsPluginUserFriendly | 
					
						
							|  |  |  | 	if errors.As(err, &secretsPlugin) { | 
					
						
							|  |  |  | 		return response.Error(http.StatusInternalServerError, fmt.Sprint("Secrets Plugin error: ", err.Error()), err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-15 00:19:57 +08:00
										 |  |  | 	return response.ErrOrFallback(http.StatusInternalServerError, "Query data error", err) | 
					
						
							| 
									
										
										
										
											2022-04-29 18:08:40 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-17 05:17:05 +08:00
										 |  |  | // QueryMetricsV2 returns query metrics.
 | 
					
						
							| 
									
										
										
										
											2022-07-27 21:54:37 +08:00
										 |  |  | // swagger:route POST /ds/query ds queryMetricsWithExpressions
 | 
					
						
							|  |  |  | //
 | 
					
						
							| 
									
										
										
										
											2022-09-12 15:40:35 +08:00
										 |  |  | // DataSource query metrics with expressions.
 | 
					
						
							| 
									
										
										
										
											2022-07-27 21:54:37 +08:00
										 |  |  | //
 | 
					
						
							|  |  |  | // If you are running Grafana Enterprise and have Fine-grained access control enabled
 | 
					
						
							|  |  |  | // you need to have a permission with action: `datasources:query`.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // Responses:
 | 
					
						
							|  |  |  | // 200: queryMetricsWithExpressionsRespons
 | 
					
						
							|  |  |  | // 207: queryMetricsWithExpressionsRespons
 | 
					
						
							|  |  |  | // 401: unauthorisedError
 | 
					
						
							|  |  |  | // 400: badRequestError
 | 
					
						
							|  |  |  | // 403: forbiddenError
 | 
					
						
							|  |  |  | // 500: internalServerError
 | 
					
						
							| 
									
										
										
										
											2023-01-27 15:50:36 +08:00
										 |  |  | func (hs *HTTPServer) QueryMetricsV2(c *contextmodel.ReqContext) response.Response { | 
					
						
							| 
									
										
										
										
											2022-03-08 02:33:01 +08:00
										 |  |  | 	reqDTO := dtos.MetricRequest{} | 
					
						
							|  |  |  | 	if err := web.Bind(c.Req, &reqDTO); err != nil { | 
					
						
							|  |  |  | 		return response.Error(http.StatusBadRequest, "bad request data", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-14 22:27:06 +08:00
										 |  |  | 	resp, err := hs.queryDataService.QueryData(c.Req.Context(), c.SignedInUser, c.SkipCache, reqDTO) | 
					
						
							| 
									
										
										
										
											2022-03-08 02:33:01 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return hs.handleQueryMetricsError(err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-05-04 00:02:20 +08:00
										 |  |  | 	return hs.toJsonStreamingResponse(resp) | 
					
						
							| 
									
										
										
										
											2022-03-08 02:33:01 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-04 00:02:20 +08:00
										 |  |  | func (hs *HTTPServer) toJsonStreamingResponse(qdr *backend.QueryDataResponse) response.Response { | 
					
						
							|  |  |  | 	statusWhenError := http.StatusBadRequest | 
					
						
							|  |  |  | 	if hs.Features.IsEnabled(featuremgmt.FlagDatasourceQueryMultiStatus) { | 
					
						
							|  |  |  | 		statusWhenError = http.StatusMultiStatus | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-05 23:12:55 +08:00
										 |  |  | 	statusCode := http.StatusOK | 
					
						
							|  |  |  | 	for _, res := range qdr.Responses { | 
					
						
							|  |  |  | 		if res.Error != nil { | 
					
						
							| 
									
										
										
										
											2022-05-04 00:02:20 +08:00
										 |  |  | 			statusCode = statusWhenError | 
					
						
							| 
									
										
										
										
											2021-11-05 23:12:55 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return response.JSONStreaming(statusCode, qdr) | 
					
						
							| 
									
										
										
										
											2019-10-25 21:28:26 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2022-07-27 21:54:37 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | // swagger:parameters queryMetricsWithExpressions
 | 
					
						
							|  |  |  | type QueryMetricsWithExpressionsBodyParams struct { | 
					
						
							|  |  |  | 	// in:body
 | 
					
						
							|  |  |  | 	// required:true
 | 
					
						
							|  |  |  | 	Body dtos.MetricRequest `json:"body"` | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // swagger:response queryMetricsWithExpressionsRespons
 | 
					
						
							|  |  |  | type QueryMetricsWithExpressionsRespons struct { | 
					
						
							|  |  |  | 	// The response message
 | 
					
						
							|  |  |  | 	// in: body
 | 
					
						
							|  |  |  | 	Body *backend.QueryDataResponse `json:"body"` | 
					
						
							|  |  |  | } |