mirror of https://github.com/grafana/grafana
Chore: Refactor Prometheus HTTP client middleware (#34473)
Following #33439 this refactors the Prometheus HTTP transport which is replaced by HTTP client middleware.pull/34814/head
parent
1ded9a37c1
commit
f76f426da3
@ -0,0 +1,48 @@ |
||||
package prometheus |
||||
|
||||
import ( |
||||
"fmt" |
||||
"net/http" |
||||
"net/url" |
||||
"strings" |
||||
|
||||
sdkhttpclient "github.com/grafana/grafana-plugin-sdk-go/backend/httpclient" |
||||
) |
||||
|
||||
const ( |
||||
customQueryParametersMiddlewareName = "prom-custom-query-parameters" |
||||
customQueryParametersKey = "customQueryParameters" |
||||
) |
||||
|
||||
func customQueryParametersMiddleware() sdkhttpclient.Middleware { |
||||
return sdkhttpclient.NamedMiddlewareFunc(customQueryParametersMiddlewareName, func(opts sdkhttpclient.Options, next http.RoundTripper) http.RoundTripper { |
||||
customQueryParamsVal, exists := opts.CustomOptions[customQueryParametersKey] |
||||
if !exists { |
||||
return next |
||||
} |
||||
customQueryParams, ok := customQueryParamsVal.(string) |
||||
if !ok || customQueryParams == "" { |
||||
return next |
||||
} |
||||
|
||||
return sdkhttpclient.RoundTripperFunc(func(req *http.Request) (*http.Response, error) { |
||||
params := url.Values{} |
||||
for _, param := range strings.Split(customQueryParams, "&") { |
||||
parts := strings.Split(param, "=") |
||||
if len(parts) == 1 { |
||||
// This is probably a mistake on the users part in defining the params but we don't want to crash.
|
||||
params.Add(parts[0], "") |
||||
} else { |
||||
params.Add(parts[0], parts[1]) |
||||
} |
||||
} |
||||
if req.URL.RawQuery != "" { |
||||
req.URL.RawQuery = fmt.Sprintf("%s&%s", req.URL.RawQuery, params.Encode()) |
||||
} else { |
||||
req.URL.RawQuery = params.Encode() |
||||
} |
||||
|
||||
return next.RoundTrip(req) |
||||
}) |
||||
}) |
||||
} |
||||
@ -0,0 +1,109 @@ |
||||
package prometheus |
||||
|
||||
import ( |
||||
"net/http" |
||||
"testing" |
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/backend/httpclient" |
||||
"github.com/stretchr/testify/require" |
||||
) |
||||
|
||||
func TestCustomQueryParametersMiddleware(t *testing.T) { |
||||
require.Equal(t, "customQueryParameters", customQueryParametersKey) |
||||
|
||||
finalRoundTripper := httpclient.RoundTripperFunc(func(req *http.Request) (*http.Response, error) { |
||||
return &http.Response{StatusCode: http.StatusOK}, nil |
||||
}) |
||||
|
||||
t.Run("Without custom query parameters set should not apply middleware", func(t *testing.T) { |
||||
mw := customQueryParametersMiddleware() |
||||
rt := mw.CreateMiddleware(httpclient.Options{}, finalRoundTripper) |
||||
require.NotNil(t, rt) |
||||
middlewareName, ok := mw.(httpclient.MiddlewareName) |
||||
require.True(t, ok) |
||||
require.Equal(t, customQueryParametersMiddlewareName, middlewareName.MiddlewareName()) |
||||
|
||||
req, err := http.NewRequest(http.MethodGet, "http://test.com/query?hello=name", nil) |
||||
require.NoError(t, err) |
||||
res, err := rt.RoundTrip(req) |
||||
require.NoError(t, err) |
||||
require.NotNil(t, res) |
||||
if res.Body != nil { |
||||
require.NoError(t, res.Body.Close()) |
||||
} |
||||
|
||||
require.Equal(t, "http://test.com/query?hello=name", req.URL.String()) |
||||
}) |
||||
|
||||
t.Run("Without custom query parameters set as string should not apply middleware", func(t *testing.T) { |
||||
mw := customQueryParametersMiddleware() |
||||
rt := mw.CreateMiddleware(httpclient.Options{ |
||||
CustomOptions: map[string]interface{}{ |
||||
customQueryParametersKey: 64, |
||||
}, |
||||
}, finalRoundTripper) |
||||
require.NotNil(t, rt) |
||||
middlewareName, ok := mw.(httpclient.MiddlewareName) |
||||
require.True(t, ok) |
||||
require.Equal(t, customQueryParametersMiddlewareName, middlewareName.MiddlewareName()) |
||||
|
||||
req, err := http.NewRequest(http.MethodGet, "http://test.com/query?hello=name", nil) |
||||
require.NoError(t, err) |
||||
res, err := rt.RoundTrip(req) |
||||
require.NoError(t, err) |
||||
require.NotNil(t, res) |
||||
if res.Body != nil { |
||||
require.NoError(t, res.Body.Close()) |
||||
} |
||||
|
||||
require.Equal(t, "http://test.com/query?hello=name", req.URL.String()) |
||||
}) |
||||
|
||||
t.Run("With custom query parameters set as empty string should not apply middleware", func(t *testing.T) { |
||||
mw := customQueryParametersMiddleware() |
||||
rt := mw.CreateMiddleware(httpclient.Options{ |
||||
CustomOptions: map[string]interface{}{ |
||||
customQueryParametersKey: "", |
||||
}, |
||||
}, finalRoundTripper) |
||||
require.NotNil(t, rt) |
||||
middlewareName, ok := mw.(httpclient.MiddlewareName) |
||||
require.True(t, ok) |
||||
require.Equal(t, customQueryParametersMiddlewareName, middlewareName.MiddlewareName()) |
||||
|
||||
req, err := http.NewRequest(http.MethodGet, "http://test.com/query?hello=name", nil) |
||||
require.NoError(t, err) |
||||
res, err := rt.RoundTrip(req) |
||||
require.NoError(t, err) |
||||
require.NotNil(t, res) |
||||
if res.Body != nil { |
||||
require.NoError(t, res.Body.Close()) |
||||
} |
||||
|
||||
require.Equal(t, "http://test.com/query?hello=name", req.URL.String()) |
||||
}) |
||||
|
||||
t.Run("With custom query parameters set as string should apply middleware", func(t *testing.T) { |
||||
mw := customQueryParametersMiddleware() |
||||
rt := mw.CreateMiddleware(httpclient.Options{ |
||||
CustomOptions: map[string]interface{}{ |
||||
customQueryParametersKey: "custom=par/am&second=f oo", |
||||
}, |
||||
}, finalRoundTripper) |
||||
require.NotNil(t, rt) |
||||
middlewareName, ok := mw.(httpclient.MiddlewareName) |
||||
require.True(t, ok) |
||||
require.Equal(t, customQueryParametersMiddlewareName, middlewareName.MiddlewareName()) |
||||
|
||||
req, err := http.NewRequest(http.MethodGet, "http://test.com/query?hello=name", nil) |
||||
require.NoError(t, err) |
||||
res, err := rt.RoundTrip(req) |
||||
require.NoError(t, err) |
||||
require.NotNil(t, res) |
||||
if res.Body != nil { |
||||
require.NoError(t, res.Body.Close()) |
||||
} |
||||
|
||||
require.Equal(t, "http://test.com/query?hello=name&custom=par%2Fam&second=f+oo", req.URL.String()) |
||||
}) |
||||
} |
||||
Loading…
Reference in new issue