Skip to content

Commit

Permalink
Convert adapter utils to middlewares (#1118)
Browse files Browse the repository at this point in the history
  • Loading branch information
marefr authored Oct 23, 2024
1 parent abcbdd9 commit 850229a
Show file tree
Hide file tree
Showing 20 changed files with 625 additions and 552 deletions.
173 changes: 0 additions & 173 deletions backend/adapter_utils.go

This file was deleted.

37 changes: 0 additions & 37 deletions backend/adapter_utils_test.go

This file was deleted.

18 changes: 2 additions & 16 deletions backend/admission_adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,8 @@ func newAdmissionSDKAdapter(handler AdmissionHandler) *admissionSDKAdapter {
}

func (a *admissionSDKAdapter) ValidateAdmission(ctx context.Context, req *pluginv2.AdmissionRequest) (*pluginv2.ValidationResponse, error) {
ctx = setupContext(ctx, EndpointValidateAdmission)
parsedReq := FromProto().AdmissionRequest(req)

var resp *ValidationResponse
err := wrapHandler(ctx, parsedReq.PluginContext, func(ctx context.Context) (RequestStatus, error) {
var innerErr error
resp, innerErr = a.handler.ValidateAdmission(ctx, parsedReq)
return RequestStatusFromError(innerErr), innerErr
})
resp, err := a.handler.ValidateAdmission(ctx, parsedReq)
if err != nil {
return nil, err
}
Expand All @@ -35,15 +28,8 @@ func (a *admissionSDKAdapter) ValidateAdmission(ctx context.Context, req *plugin
}

func (a *admissionSDKAdapter) MutateAdmission(ctx context.Context, req *pluginv2.AdmissionRequest) (*pluginv2.MutationResponse, error) {
ctx = setupContext(ctx, EndpointMutateAdmission)
parsedReq := FromProto().AdmissionRequest(req)

var resp *MutationResponse
err := wrapHandler(ctx, parsedReq.PluginContext, func(ctx context.Context) (RequestStatus, error) {
var innerErr error
resp, innerErr = a.handler.MutateAdmission(ctx, parsedReq)
return RequestStatusFromError(innerErr), innerErr
})
resp, err := a.handler.MutateAdmission(ctx, parsedReq)
if err != nil {
return nil, err
}
Expand Down
9 changes: 2 additions & 7 deletions backend/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -297,13 +297,6 @@ func SecureJSONDataFromHTTPClientOptions(opts httpclient.Options) (res map[strin
return secureJSONData
}

func propagateTenantIDIfPresent(ctx context.Context) context.Context {
if tid, exists := tenant.IDFromIncomingGRPCContext(ctx); exists {
ctx = tenant.WithTenant(ctx, tid)
}
return ctx
}

func (s *DataSourceInstanceSettings) ProxyOptionsFromContext(ctx context.Context) (*proxy.Options, error) {
cfg := GrafanaConfigFromContext(ctx)
p, err := cfg.proxy()
Expand Down Expand Up @@ -383,3 +376,5 @@ func (s *DataSourceInstanceSettings) ProxyClient(ctx context.Context) (proxy.Cli
func WithTenant(ctx context.Context, tenantID string) context.Context {
return tenant.WithTenant(ctx, tenantID)
}

type handlerWrapperFunc func(ctx context.Context) (RequestStatus, error)
27 changes: 13 additions & 14 deletions backend/conversion_adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,24 +64,23 @@ func (a *conversionSDKAdapter) convertQueryDataRequest(ctx context.Context, requ
}

func (a *conversionSDKAdapter) ConvertObjects(ctx context.Context, req *pluginv2.ConversionRequest) (*pluginv2.ConversionResponse, error) {
ctx = setupContext(ctx, EndpointConvertObjects)
parsedReq := FromProto().ConversionRequest(req)

resp := &ConversionResponse{}
err := wrapHandler(ctx, parsedReq.PluginContext, func(ctx context.Context) (RequestStatus, error) {
var innerErr error
if a.queryConversionHandler != nil {
// Try to parse it as a query data request
reqs, err := parseAsQueryRequest(parsedReq)
if err == nil {
resp, innerErr = a.convertQueryDataRequest(ctx, reqs)
return RequestStatusFromError(innerErr), innerErr
}
var resp *ConversionResponse
var err error
if a.queryConversionHandler != nil {
// Try to parse it as a query data request
var reqs []*QueryDataRequest
reqs, err = parseAsQueryRequest(parsedReq)
if err == nil {
resp, err = a.convertQueryDataRequest(ctx, reqs)
} else {
// The object cannot be parsed as a query data request, so we will try to convert it as a generic object
resp, err = a.handler.ConvertObjects(ctx, parsedReq)
}
resp, innerErr = a.handler.ConvertObjects(ctx, parsedReq)
return RequestStatusFromError(innerErr), innerErr
})
} else {
resp, err = a.handler.ConvertObjects(ctx, parsedReq)
}
if err != nil {
return nil, err
}
Expand Down
75 changes: 5 additions & 70 deletions backend/data_adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ package backend
import (
"context"
"errors"
"fmt"

"github.com/grafana/grafana-plugin-sdk-go/experimental/status"
"github.com/grafana/grafana-plugin-sdk-go/genproto/pluginv2"
)

Expand All @@ -21,78 +19,15 @@ func newDataSDKAdapter(handler QueryDataHandler) *dataSDKAdapter {
}

func (a *dataSDKAdapter) QueryData(ctx context.Context, req *pluginv2.QueryDataRequest) (*pluginv2.QueryDataResponse, error) {
ctx = setupContext(ctx, EndpointQueryData)
parsedReq := FromProto().QueryDataRequest(req)

var resp *QueryDataResponse
err := wrapHandler(ctx, parsedReq.PluginContext, func(ctx context.Context) (RequestStatus, error) {
ctx = withHeaderMiddleware(ctx, parsedReq.GetHTTPHeaders())
var innerErr error
resp, innerErr = a.queryDataHandler.QueryData(ctx, parsedReq)

requestStatus := RequestStatusFromQueryDataResponse(resp, innerErr)
if innerErr != nil {
return requestStatus, innerErr
} else if resp == nil {
return RequestStatusError, errors.New("both response and error are nil, but one must be provided")
}
ctxLogger := Logger.FromContext(ctx)

// Set downstream status source in the context if there's at least one response with downstream status source,
// and if there's no plugin error
var hasPluginError, hasDownstreamError bool
for refID, r := range resp.Responses {
if r.Error == nil || status.IsCancelledError(r.Error) {
continue
}

if !r.ErrorSource.IsValid() {
// if the error is a downstream error, set error source to downstream, otherwise plugin.
if IsDownstreamError(r.Error) {
r.ErrorSource = ErrorSourceDownstream
} else {
r.ErrorSource = ErrorSourcePlugin
}
resp.Responses[refID] = r
}

if !r.Status.IsValid() {
r.Status = statusFromError(r.Error)
resp.Responses[refID] = r
}

if r.ErrorSource == ErrorSourceDownstream {
hasDownstreamError = true
} else {
hasPluginError = true
}

logParams := []any{
"refID", refID,
"status", int(r.Status),
"error", r.Error,
"statusSource", string(r.ErrorSource),
}
ctxLogger.Error("Partial data response error", logParams...)
}

// A plugin error has higher priority than a downstream error,
// so set to downstream only if there's no plugin error
if hasPluginError {
if err := WithErrorSource(ctx, ErrorSourcePlugin); err != nil {
return RequestStatusError, fmt.Errorf("failed to set plugin status source: %w", errors.Join(innerErr, err))
}
} else if hasDownstreamError {
if err := WithDownstreamErrorSource(ctx); err != nil {
return RequestStatusError, fmt.Errorf("failed to set downstream status source: %w", errors.Join(innerErr, err))
}
}

return requestStatus, nil
})
resp, err := a.queryDataHandler.QueryData(ctx, parsedReq)
if err != nil {
return nil, err
}

if resp == nil {
return nil, errors.New("both response and error are nil, but one must be provided")
}

return ToProto().QueryDataResponse(resp)
}
Loading

0 comments on commit 850229a

Please sign in to comment.