package transport import ( "fmt" "net/http" "time" "github.com/go-chi/chi" "github.com/go-chi/chi/middleware" "github.com/influxdata/influxdb/v2" "github.com/influxdata/influxdb/v2/kit/platform/errors" kithttp "github.com/influxdata/influxdb/v2/kit/transport/http" "go.uber.org/zap" ) const ( // this is the base api prefix, since the annotations system mounts handlers at // both the ../annotations and ../streams paths. prefixAnnotations = "/api/v2private" ) var ( errBadOrg = &errors.Error{ Code: errors.EInvalid, Msg: "invalid or missing org id", } errBadAnnotationId = &errors.Error{ Code: errors.EInvalid, Msg: "annotation id is invalid", } errBadStreamId = &errors.Error{ Code: errors.EInvalid, Msg: "stream id is invalid", } errBadStreamName = &errors.Error{ Code: errors.EInvalid, Msg: "invalid stream name", } ) func invalidStickerError(s string) error { return &errors.Error{ Code: errors.EInternal, Msg: fmt.Sprintf("invalid sticker: %q", s), } } // AnnotationsHandler is the handler for the annotation service type AnnotationHandler struct { chi.Router log *zap.Logger api *kithttp.API annotationService influxdb.AnnotationService } func NewAnnotationHandler(log *zap.Logger, annotationService influxdb.AnnotationService) *AnnotationHandler { h := &AnnotationHandler{ log: log, api: kithttp.NewAPI(kithttp.WithLog(log)), annotationService: annotationService, } r := chi.NewRouter() r.Use( middleware.Recoverer, middleware.RequestID, middleware.RealIP, ) r.Mount("/annotations", h.annotationsRouter()) r.Mount("/streams", h.streamsRouter()) h.Router = r return h } func (h *AnnotationHandler) Prefix() string { return prefixAnnotations } // tFromReq and tStringToPointer are used in handlers to extract time values from query parameters. // pointers to time.Time structs are used, since the JSON responses may omit empty (nil pointer) times. func tFromReq(r *http.Request) (*time.Time, *time.Time, error) { st, err := tStringToPointer(r.URL.Query().Get("startTime")) if err != nil { return nil, nil, err } et, err := tStringToPointer(r.URL.Query().Get("endTime")) if err != nil { return nil, nil, err } return st, et, nil } func tStringToPointer(s string) (*time.Time, error) { if s == "" { return nil, nil } t, err := time.Parse(time.RFC3339, s) if err != nil { return nil, err } return &t, nil }