-
Notifications
You must be signed in to change notification settings - Fork 545
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Early Request Validation in Query Frontend (#10093)
* WIP sketch out validation roundtripper with existing metrics and labels query codecs * lint: license header * separate series request roundtrippers * introduce request validation roundtripper tests * lint import order * introduce & test cardinality query validation in frontend roundtripper; expand metrics query tests to cover instant queries * CHANGELOG
- Loading branch information
1 parent
a26eee3
commit 3251e86
Showing
6 changed files
with
387 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
// SPDX-License-Identifier: AGPL-3.0-only | ||
|
||
package querymiddleware | ||
|
||
import ( | ||
"context" | ||
"net/http" | ||
|
||
"github.com/grafana/dskit/cancellation" | ||
) | ||
|
||
const requestValidationFailedFmt = "request validation failed for " | ||
|
||
var errMetricsQueryRequestValidationFailed = cancellation.NewErrorf( | ||
requestValidationFailedFmt + "metrics query", | ||
) | ||
var errLabelsQueryRequestValidationFailed = cancellation.NewErrorf( | ||
requestValidationFailedFmt + "labels query", | ||
) | ||
var errCardinalityQueryRequestValidationFailed = cancellation.NewErrorf( | ||
requestValidationFailedFmt + "cardinality query", | ||
) | ||
|
||
type MetricsQueryRequestValidationRoundTripper struct { | ||
codec Codec | ||
next http.RoundTripper | ||
} | ||
|
||
func NewMetricsQueryRequestValidationRoundTripper(codec Codec, next http.RoundTripper) http.RoundTripper { | ||
return MetricsQueryRequestValidationRoundTripper{ | ||
codec: codec, | ||
next: next, | ||
} | ||
} | ||
|
||
func (rt MetricsQueryRequestValidationRoundTripper) RoundTrip(r *http.Request) (*http.Response, error) { | ||
ctx, cancel := context.WithCancelCause(r.Context()) | ||
defer cancel(errMetricsQueryRequestValidationFailed) | ||
r = r.WithContext(ctx) | ||
|
||
_, err := rt.codec.DecodeMetricsQueryRequest(ctx, r) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return rt.next.RoundTrip(r) | ||
} | ||
|
||
type LabelsQueryRequestValidationRoundTripper struct { | ||
codec Codec | ||
next http.RoundTripper | ||
} | ||
|
||
func NewLabelsQueryRequestValidationRoundTripper(codec Codec, next http.RoundTripper) http.RoundTripper { | ||
return LabelsQueryRequestValidationRoundTripper{ | ||
codec: codec, | ||
next: next, | ||
} | ||
} | ||
|
||
func (rt LabelsQueryRequestValidationRoundTripper) RoundTrip(r *http.Request) (*http.Response, error) { | ||
ctx, cancel := context.WithCancelCause(r.Context()) | ||
defer cancel(errLabelsQueryRequestValidationFailed) | ||
r = r.WithContext(ctx) | ||
|
||
_, err := rt.codec.DecodeLabelsQueryRequest(ctx, r) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return rt.next.RoundTrip(r) | ||
} | ||
|
||
type CardinalityQueryRequestValidationRoundTripper struct { | ||
next http.RoundTripper | ||
} | ||
|
||
func NewCardinalityQueryRequestValidationRoundTripper(next http.RoundTripper) http.RoundTripper { | ||
return CardinalityQueryRequestValidationRoundTripper{ | ||
next: next, | ||
} | ||
} | ||
|
||
func (rt CardinalityQueryRequestValidationRoundTripper) RoundTrip(r *http.Request) (*http.Response, error) { | ||
ctx, cancel := context.WithCancelCause(r.Context()) | ||
defer cancel(errCardinalityQueryRequestValidationFailed) | ||
r = r.WithContext(ctx) | ||
|
||
_, err := DecodeCardinalityQueryParams(r) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return rt.next.RoundTrip(r) | ||
} |
Oops, something went wrong.