multinode/console: operators controller added
Change-Id: I170371baec3c6996bd2af3c332620bd6fee3ed63
This commit is contained in:
parent
0b3ee4bda7
commit
4af0037a67
95
multinode/console/controllers/operators.go
Normal file
95
multinode/console/controllers/operators.go
Normal file
@ -0,0 +1,95 @@
|
||||
// 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)))
|
||||
}
|
||||
}
|
@ -17,6 +17,7 @@ import (
|
||||
|
||||
"storj.io/storj/multinode/console/controllers"
|
||||
"storj.io/storj/multinode/nodes"
|
||||
"storj.io/storj/multinode/operators"
|
||||
"storj.io/storj/multinode/payouts"
|
||||
)
|
||||
|
||||
@ -37,9 +38,10 @@ type Config struct {
|
||||
type Server struct {
|
||||
log *zap.Logger
|
||||
|
||||
config Config
|
||||
nodes *nodes.Service
|
||||
payouts *payouts.Service
|
||||
config Config
|
||||
nodes *nodes.Service
|
||||
payouts *payouts.Service
|
||||
operators *operators.Service
|
||||
|
||||
listener net.Listener
|
||||
http http.Server
|
||||
@ -48,13 +50,14 @@ type Server struct {
|
||||
}
|
||||
|
||||
// NewServer returns new instance of Multinode Dashboard http server.
|
||||
func NewServer(log *zap.Logger, config Config, nodes *nodes.Service, payouts *payouts.Service, listener net.Listener) (*Server, error) {
|
||||
func NewServer(log *zap.Logger, config Config, nodes *nodes.Service, payouts *payouts.Service, operators *operators.Service, listener net.Listener) (*Server, error) {
|
||||
server := Server{
|
||||
log: log,
|
||||
config: config,
|
||||
nodes: nodes,
|
||||
listener: listener,
|
||||
payouts: payouts,
|
||||
log: log,
|
||||
config: config,
|
||||
nodes: nodes,
|
||||
operators: operators,
|
||||
payouts: payouts,
|
||||
listener: listener,
|
||||
}
|
||||
|
||||
router := mux.NewRouter()
|
||||
@ -73,6 +76,10 @@ func NewServer(log *zap.Logger, config Config, nodes *nodes.Service, payouts *pa
|
||||
nodesRouter.HandleFunc("/{id}", nodesController.UpdateName).Methods(http.MethodPatch)
|
||||
nodesRouter.HandleFunc("/{id}", nodesController.Delete).Methods(http.MethodDelete)
|
||||
|
||||
operatorsController := controllers.NewOperators(server.log, server.operators)
|
||||
operatorsRouter := apiRouter.PathPrefix("/operators").Subrouter()
|
||||
operatorsRouter.HandleFunc("", operatorsController.ListPaginated).Methods(http.MethodGet)
|
||||
|
||||
payoutsController := controllers.NewPayouts(server.log, server.payouts)
|
||||
payoutsRouter := apiRouter.PathPrefix("/payouts").Subrouter()
|
||||
payoutsRouter.HandleFunc("/summaries", payoutsController.Summary).Methods(http.MethodGet)
|
||||
|
@ -21,6 +21,8 @@ type DB interface {
|
||||
// List returns all connected nodes.
|
||||
List(ctx context.Context) ([]Node, error)
|
||||
// ListPaged returns paginated nodes list.
|
||||
// TODO: rename to ListPaginated, because pagination is to divide up copy into pages,
|
||||
// because paging doesn't necessarily mean pagination in computing.
|
||||
ListPaged(ctx context.Context, cursor Cursor) (page Page, err error)
|
||||
// Add creates new node in NodesDB.
|
||||
// TODO: pass Node entity instead of set of a parameters.
|
||||
|
@ -43,8 +43,8 @@ func NewService(log *zap.Logger, dialer rpc.Dialer, nodes nodes.DB) *Service {
|
||||
}
|
||||
}
|
||||
|
||||
// ListOperatorsPaginated returns paginated list of operators.
|
||||
func (service *Service) ListOperatorsPaginated(ctx context.Context, cursor Cursor) (_ Page, err error) {
|
||||
// ListPaginated returns paginated list of operators.
|
||||
func (service *Service) ListPaginated(ctx context.Context, cursor Cursor) (_ Page, err error) {
|
||||
defer mon.Task()(&ctx)(&err)
|
||||
if cursor.Limit > MaxOperatorsOnPage {
|
||||
cursor.Limit = MaxOperatorsOnPage
|
||||
|
@ -17,6 +17,7 @@ import (
|
||||
"storj.io/private/debug"
|
||||
"storj.io/storj/multinode/console/server"
|
||||
"storj.io/storj/multinode/nodes"
|
||||
"storj.io/storj/multinode/operators"
|
||||
"storj.io/storj/multinode/payouts"
|
||||
"storj.io/storj/private/lifecycle"
|
||||
)
|
||||
@ -62,6 +63,11 @@ type Peer struct {
|
||||
Service *nodes.Service
|
||||
}
|
||||
|
||||
// exposes operators related logic.
|
||||
Operators struct {
|
||||
Service *operators.Service
|
||||
}
|
||||
|
||||
// contains logic of payouts domain.
|
||||
Payouts struct {
|
||||
Service *payouts.Service
|
||||
@ -105,6 +111,14 @@ func New(log *zap.Logger, full *identity.FullIdentity, config Config, db DB) (_
|
||||
)
|
||||
}
|
||||
|
||||
{ // operators setup
|
||||
peer.Operators.Service = operators.NewService(
|
||||
peer.Log.Named("operators:service"),
|
||||
peer.Dialer,
|
||||
peer.DB.Nodes(),
|
||||
)
|
||||
}
|
||||
|
||||
{ // payouts setup
|
||||
peer.Payouts.Service = payouts.NewService(
|
||||
peer.Log.Named("payouts:service"),
|
||||
@ -124,6 +138,7 @@ func New(log *zap.Logger, full *identity.FullIdentity, config Config, db DB) (_
|
||||
config.Console,
|
||||
peer.Nodes.Service,
|
||||
peer.Payouts.Service,
|
||||
peer.Operators.Service,
|
||||
peer.Console.Listener,
|
||||
)
|
||||
if err != nil {
|
||||
|
Loading…
Reference in New Issue
Block a user