storj/multinode/console/controllers/reputation.go
Yaroslav Vorobiov 68627e7d80 multinode/console: add reputation satellite api
Change-Id: I7cef6c1c271607f7485f604d5b61587558a31878
2021-07-05 15:32:22 +00:00

93 lines
2.4 KiB
Go

// Copyright (C) 2021 Storj Labs, Inc.
// See LICENSE for copying information.
package controllers
import (
"encoding/json"
"net/http"
"github.com/gorilla/mux"
"github.com/zeebo/errs"
"go.uber.org/zap"
"storj.io/common/storj"
"storj.io/storj/multinode/nodes"
"storj.io/storj/multinode/reputation"
)
var (
// ErrReputation is an error type for reputation web api controller.
ErrReputation = errs.Class("reputation web api controller")
)
// Reputation is a reputation web api controller.
type Reputation struct {
log *zap.Logger
service *reputation.Service
}
// NewReputation is a constructor of reputation controller.
func NewReputation(log *zap.Logger, service *reputation.Service) *Reputation {
return &Reputation{
log: log,
service: service,
}
}
// Stats handles retrieval of a node reputation for particular satellite.
func (controller *Reputation) Stats(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
var err error
defer mon.Task()(&ctx)(&err)
w.Header().Add("Content-Type", "application/json")
segments := mux.Vars(r)
satelliteIDEnc, ok := segments["satelliteID"]
if !ok {
controller.serveError(w, http.StatusBadRequest, ErrReputation.New("could not retrieve satellite id segment"))
return
}
satelliteID, err := storj.NodeIDFromString(satelliteIDEnc)
if err != nil {
controller.serveError(w, http.StatusBadRequest, ErrReputation.Wrap(err))
return
}
stats, err := controller.service.Stats(ctx, satelliteID)
if err != nil {
if nodes.ErrNoNode.Has(err) {
controller.serveError(w, http.StatusNotFound, ErrReputation.Wrap(err))
return
}
controller.log.Error("reputation stats internal error", zap.Error(ErrReputation.Wrap(err)))
controller.serveError(w, http.StatusInternalServerError, ErrReputation.Wrap(err))
return
}
if len(stats) == 0 {
stats = make([]reputation.Stats, 0)
}
if err = json.NewEncoder(w).Encode(stats); err != nil {
controller.log.Error("failed to write json response", zap.Error(ErrReputation.Wrap(err)))
return
}
}
// serveError set http statuses and send json error.
func (controller *Reputation) 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(err))
}
}