mirror of
https://github.com/prometheus/prometheus
synced 2024-12-24 23:42:32 +00:00
API_V1: Extract time param parsing logic (#6860)
* extract API time param parsing logic in a func Signed-off-by: blalov <boiskila@gmail.com>
This commit is contained in:
parent
1dbd799354
commit
84b00564f4
@ -318,18 +318,10 @@ func (api *API) options(r *http.Request) apiFuncResult {
|
||||
}
|
||||
|
||||
func (api *API) query(r *http.Request) apiFuncResult {
|
||||
var ts time.Time
|
||||
if t := r.FormValue("time"); t != "" {
|
||||
var err error
|
||||
ts, err = parseTime(t)
|
||||
if err != nil {
|
||||
err = errors.Wrapf(err, "invalid parameter 'time'")
|
||||
return apiFuncResult{nil, &apiError{errorBadData, err}, nil, nil}
|
||||
}
|
||||
} else {
|
||||
ts = api.now()
|
||||
ts, err := parseTimeParam(r, "time", api.now())
|
||||
if err != nil {
|
||||
return apiFuncResult{nil, &apiError{errorBadData, err}, nil, nil}
|
||||
}
|
||||
|
||||
ctx := r.Context()
|
||||
if to := r.FormValue("timeout"); to != "" {
|
||||
var cancel context.CancelFunc
|
||||
@ -512,26 +504,13 @@ func (api *API) series(r *http.Request) apiFuncResult {
|
||||
return apiFuncResult{nil, &apiError{errorBadData, errors.New("no match[] parameter provided")}, nil, nil}
|
||||
}
|
||||
|
||||
var start time.Time
|
||||
if t := r.FormValue("start"); t != "" {
|
||||
var err error
|
||||
start, err = parseTime(t)
|
||||
if err != nil {
|
||||
return apiFuncResult{nil, &apiError{errorBadData, err}, nil, nil}
|
||||
}
|
||||
} else {
|
||||
start = minTime
|
||||
start, err := parseTimeParam(r, "start", minTime)
|
||||
if err != nil {
|
||||
return apiFuncResult{nil, &apiError{errorBadData, err}, nil, nil}
|
||||
}
|
||||
|
||||
var end time.Time
|
||||
if t := r.FormValue("end"); t != "" {
|
||||
var err error
|
||||
end, err = parseTime(t)
|
||||
if err != nil {
|
||||
return apiFuncResult{nil, &apiError{errorBadData, err}, nil, nil}
|
||||
}
|
||||
} else {
|
||||
end = maxTime
|
||||
end, err := parseTimeParam(r, "end", maxTime)
|
||||
if err != nil {
|
||||
return apiFuncResult{nil, &apiError{errorBadData, err}, nil, nil}
|
||||
}
|
||||
|
||||
var matcherSets [][]*labels.Matcher
|
||||
@ -1320,26 +1299,13 @@ func (api *API) deleteSeries(r *http.Request) apiFuncResult {
|
||||
return apiFuncResult{nil, &apiError{errorBadData, errors.New("no match[] parameter provided")}, nil, nil}
|
||||
}
|
||||
|
||||
var start time.Time
|
||||
if t := r.FormValue("start"); t != "" {
|
||||
var err error
|
||||
start, err = parseTime(t)
|
||||
if err != nil {
|
||||
return apiFuncResult{nil, &apiError{errorBadData, err}, nil, nil}
|
||||
}
|
||||
} else {
|
||||
start = minTime
|
||||
start, err := parseTimeParam(r, "start", minTime)
|
||||
if err != nil {
|
||||
return apiFuncResult{nil, &apiError{errorBadData, err}, nil, nil}
|
||||
}
|
||||
|
||||
var end time.Time
|
||||
if t := r.FormValue("end"); t != "" {
|
||||
var err error
|
||||
end, err = parseTime(t)
|
||||
if err != nil {
|
||||
return apiFuncResult{nil, &apiError{errorBadData, err}, nil, nil}
|
||||
}
|
||||
} else {
|
||||
end = maxTime
|
||||
end, err := parseTimeParam(r, "end", maxTime)
|
||||
if err != nil {
|
||||
return apiFuncResult{nil, &apiError{errorBadData, err}, nil, nil}
|
||||
}
|
||||
|
||||
for _, s := range r.Form["match[]"] {
|
||||
@ -1474,6 +1440,18 @@ func (api *API) respondError(w http.ResponseWriter, apiErr *apiError, data inter
|
||||
}
|
||||
}
|
||||
|
||||
func parseTimeParam(r *http.Request, paramName string, defaultValue time.Time) (time.Time, error) {
|
||||
val := r.FormValue(paramName)
|
||||
if val == "" {
|
||||
return defaultValue, nil
|
||||
}
|
||||
result, err := parseTime(val)
|
||||
if err != nil {
|
||||
return time.Time{}, errors.Wrapf(err, "Invalid time value for '%s'", paramName)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func parseTime(s string) (time.Time, error) {
|
||||
if t, err := strconv.ParseFloat(s, 64); err == nil {
|
||||
s, ns := math.Modf(t)
|
||||
|
@ -17,7 +17,6 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
@ -41,6 +40,7 @@ import (
|
||||
"github.com/prometheus/common/promlog"
|
||||
"github.com/prometheus/common/route"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/prometheus/prometheus/config"
|
||||
"github.com/prometheus/prometheus/pkg/gate"
|
||||
"github.com/prometheus/prometheus/pkg/labels"
|
||||
@ -2172,6 +2172,68 @@ func TestRespondError(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseTimeParam(t *testing.T) {
|
||||
type resultType struct {
|
||||
asTime time.Time
|
||||
asError func() error
|
||||
}
|
||||
|
||||
ts, err := parseTime("1582468023986")
|
||||
testutil.Ok(t, err)
|
||||
|
||||
var tests = []struct {
|
||||
paramName string
|
||||
paramValue string
|
||||
defaultValue time.Time
|
||||
result resultType
|
||||
}{
|
||||
{ // When data is valid.
|
||||
paramName: "start",
|
||||
paramValue: "1582468023986",
|
||||
defaultValue: minTime,
|
||||
result: resultType{
|
||||
asTime: ts,
|
||||
asError: nil,
|
||||
},
|
||||
},
|
||||
{ // When data is empty string.
|
||||
paramName: "end",
|
||||
paramValue: "",
|
||||
defaultValue: maxTime,
|
||||
result: resultType{
|
||||
asTime: maxTime,
|
||||
asError: nil,
|
||||
},
|
||||
},
|
||||
{ // When data is not valid.
|
||||
paramName: "foo",
|
||||
paramValue: "baz",
|
||||
defaultValue: maxTime,
|
||||
result: resultType{
|
||||
asTime: time.Time{},
|
||||
asError: func() error {
|
||||
_, err := parseTime("baz")
|
||||
return errors.Wrapf(err, "Invalid time value for '%s'", "foo")
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
req, err := http.NewRequest("GET", "localhost:42/foo?"+test.paramName+"="+test.paramValue, nil)
|
||||
testutil.Ok(t, err)
|
||||
|
||||
result := test.result
|
||||
asTime, err := parseTimeParam(req, test.paramName, test.defaultValue)
|
||||
|
||||
if err != nil {
|
||||
testutil.ErrorEqual(t, result.asError(), err)
|
||||
} else {
|
||||
testutil.Assert(t, asTime.Equal(result.asTime), "time as return value: %s not parsed correctly. Expected %s. Actual %s", test.paramValue, result.asTime, asTime)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseTime(t *testing.T) {
|
||||
ts, err := time.Parse(time.RFC3339Nano, "2015-06-03T13:21:58.555Z")
|
||||
if err != nil {
|
||||
|
Loading…
Reference in New Issue
Block a user