| 17 | ) |
| 18 | |
| 19 | func (s *Server) ResolveTemplatedString(ctx context.Context, req *runtimev1.ResolveTemplatedStringRequest) (*runtimev1.ResolveTemplatedStringResponse, error) { |
| 20 | s.addInstanceRequestAttributes(ctx, req.InstanceId) |
| 21 | observability.AddRequestAttributes(ctx, |
| 22 | attribute.String("args.instance_id", req.InstanceId), |
| 23 | attribute.Bool("args.use_format_tokens", req.UseFormatTokens), |
| 24 | ) |
| 25 | |
| 26 | claims := auth.GetClaims(ctx, req.InstanceId) |
| 27 | if !claims.Can(runtime.ReadAPI) { |
| 28 | return nil, status.Error(codes.PermissionDenied, "does not have access to query data") |
| 29 | } |
| 30 | |
| 31 | additionalWhereByMetricsView := map[string]map[string]any{} |
| 32 | for mv, expr := range req.AdditionalWhereByMetricsView { |
| 33 | var err error |
| 34 | additionalWhereByMetricsView[mv], err = metricsview.NewExpressionFromProto(expr).AsMap() |
| 35 | if err != nil { |
| 36 | return nil, fmt.Errorf("failed to convert additional where expression for metrics view %q: %w", mv, err) |
| 37 | } |
| 38 | } |
| 39 | |
| 40 | var additionalTimeRange map[string]any |
| 41 | var timeZone string |
| 42 | if req.AdditionalTimeRange != nil { |
| 43 | var err error |
| 44 | additionalTimeRange, err = metricsview.NewTimeRangeFromProto(req.AdditionalTimeRange).AsMap() |
| 45 | if err != nil { |
| 46 | return nil, fmt.Errorf("failed to convert additional time range: %w", err) |
| 47 | } |
| 48 | timeZone = req.AdditionalTimeRange.TimeZone |
| 49 | } |
| 50 | |
| 51 | resolveRes, _, err := s.runtime.Resolve(ctx, &runtime.ResolveOptions{ |
| 52 | InstanceID: req.InstanceId, |
| 53 | Resolver: "text", |
| 54 | ResolverProperties: map[string]any{ |
| 55 | "text": req.Body, |
| 56 | "use_format_tokens": req.UseFormatTokens, |
| 57 | "additional_where_by_metrics_view": additionalWhereByMetricsView, |
| 58 | "additional_time_range": additionalTimeRange, |
| 59 | "time_zone": timeZone, |
| 60 | }, |
| 61 | Claims: claims, |
| 62 | }) |
| 63 | if err != nil { |
| 64 | return nil, mapGRPCErrorWithFallback(err, codes.InvalidArgument) |
| 65 | } |
| 66 | defer resolveRes.Close() |
| 67 | |
| 68 | row, err := resolveRes.Next() |
| 69 | if err != nil { |
| 70 | if errors.Is(err, io.EOF) { |
| 71 | return nil, status.Errorf(codes.Internal, "text resolver returned no rows") |
| 72 | } |
| 73 | return nil, err |
| 74 | } |
| 75 | |
| 76 | body, _ := row["text"].(string) |