96 lines
2.4 KiB
Go
96 lines
2.4 KiB
Go
|
// Copyright (C) 2021 Storj Labs, Inc.
|
||
|
// See LICENSE for copying information.
|
||
|
|
||
|
package controllers
|
||
|
|
||
|
import (
|
||
|
"encoding/json"
|
||
|
"net/http"
|
||
|
"strconv"
|
||
|
|
||
|
"github.com/zeebo/errs"
|
||
|
"go.uber.org/zap"
|
||
|
|
||
|
"storj.io/storj/multinode/operators"
|
||
|
)
|
||
|
|
||
|
var (
|
||
|
// ErrOperators is an internal error type for operators web api controller.
|
||
|
ErrOperators = errs.Class("nodes web api controller")
|
||
|
)
|
||
|
|
||
|
const (
|
||
|
defaultLimit = 5
|
||
|
)
|
||
|
|
||
|
// Operators is a web api controller.
|
||
|
type Operators struct {
|
||
|
log *zap.Logger
|
||
|
service *operators.Service
|
||
|
}
|
||
|
|
||
|
// NewOperators is a constructor for Operators.
|
||
|
func NewOperators(log *zap.Logger, service *operators.Service) *Operators {
|
||
|
return &Operators{
|
||
|
log: log,
|
||
|
service: service,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// ListPaginated handles retrieval of operators.
|
||
|
func (controller *Operators) ListPaginated(w http.ResponseWriter, r *http.Request) {
|
||
|
ctx := r.Context()
|
||
|
var err error
|
||
|
defer mon.Task()(&ctx)(&err)
|
||
|
|
||
|
w.Header().Add("Content-Type", "application/json")
|
||
|
|
||
|
limit := int64(defaultLimit)
|
||
|
if limitParam := r.URL.Query().Get("limit"); limitParam != "" {
|
||
|
limit, err = strconv.ParseInt(limitParam, 10, 64)
|
||
|
if err != nil {
|
||
|
controller.serveError(w, http.StatusBadRequest, ErrOperators.Wrap(err))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pageParam := r.URL.Query().Get("page")
|
||
|
if pageParam == "" {
|
||
|
controller.serveError(w, http.StatusBadRequest, ErrOperators.Wrap(errs.New("page is missing")))
|
||
|
return
|
||
|
}
|
||
|
pageNumber, err := strconv.ParseInt(pageParam, 10, 64)
|
||
|
if err != nil {
|
||
|
controller.serveError(w, http.StatusBadRequest, ErrOperators.Wrap(err))
|
||
|
return
|
||
|
}
|
||
|
|
||
|
cursor := operators.Cursor{
|
||
|
Limit: limit,
|
||
|
Page: pageNumber,
|
||
|
}
|
||
|
page, err := controller.service.ListPaginated(ctx, cursor)
|
||
|
if err != nil {
|
||
|
controller.log.Error("could not get operators page", zap.Error(ErrOperators.Wrap(err)))
|
||
|
controller.serveError(w, http.StatusInternalServerError, ErrOperators.Wrap(err))
|
||
|
return
|
||
|
}
|
||
|
|
||
|
if err = json.NewEncoder(w).Encode(page); err != nil {
|
||
|
controller.log.Error("failed to write json response", zap.Error(ErrOperators.Wrap(err)))
|
||
|
return
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// serveError set http statuses and send json error.
|
||
|
func (controller *Operators) serveError(w http.ResponseWriter, status int, err error) {
|
||
|
w.WriteHeader(status)
|
||
|
var response struct {
|
||
|
Error string `json:"error"`
|
||
|
}
|
||
|
response.Error = err.Error()
|
||
|
err = json.NewEncoder(w).Encode(response)
|
||
|
if err != nil {
|
||
|
controller.log.Error("failed to write json error response", zap.Error(ErrOperators.Wrap(err)))
|
||
|
}
|
||
|
}
|