2020-03-15 18:30:23 +00:00
// Copyright (C) 2020 Storj Labs, Inc.
// See LICENSE for copying information.
package consoleapi
import (
"encoding/json"
"net/http"
2020-03-16 01:32:52 +00:00
"github.com/gorilla/mux"
2020-03-15 18:30:23 +00:00
"github.com/zeebo/errs"
"go.uber.org/zap"
2020-05-29 09:52:10 +01:00
"storj.io/common/storj"
2020-03-15 18:30:23 +00:00
"storj.io/storj/storagenode/heldamount"
)
2020-03-26 14:53:15 +00:00
// ErrHeldAmountAPI - console heldAmount api error type.
var ErrHeldAmountAPI = errs . Class ( "heldAmount console web error" )
2020-03-15 18:30:23 +00:00
// HeldAmount is an api controller that exposes all held amount related api.
type HeldAmount struct {
service * heldamount . Service
log * zap . Logger
}
// NewHeldAmount is a constructor for heldAmount controller.
func NewHeldAmount ( log * zap . Logger , service * heldamount . Service ) * HeldAmount {
return & HeldAmount {
log : log ,
service : service ,
}
}
2020-03-26 14:53:15 +00:00
// PayStubMonthly returns heldamount, storage holding and prices data for specific month from all satellites or specified satellite by query parameter id.
func ( heldAmount * HeldAmount ) PayStubMonthly ( w http . ResponseWriter , r * http . Request ) {
2020-03-15 18:30:23 +00:00
ctx := r . Context ( )
var err error
defer mon . Task ( ) ( & ctx ) ( & err )
w . Header ( ) . Set ( contentType , applicationJSON )
2020-03-26 14:53:15 +00:00
segmentParams := mux . Vars ( r )
queryParams := r . URL . Query ( )
2020-03-16 04:28:03 +00:00
2020-03-26 14:53:15 +00:00
period , ok := segmentParams [ "period" ]
2020-03-16 04:28:03 +00:00
if ! ok {
heldAmount . serveJSONError ( w , http . StatusBadRequest , ErrNotificationsAPI . Wrap ( err ) )
return
}
2020-03-26 14:53:15 +00:00
id := queryParams . Get ( "id" )
if id == "" {
payStubs , err := heldAmount . service . AllPayStubsMonthlyCached ( ctx , period )
if err != nil {
heldAmount . serveJSONError ( w , http . StatusInternalServerError , ErrHeldAmountAPI . Wrap ( err ) )
return
}
if err := json . NewEncoder ( w ) . Encode ( payStubs ) ; err != nil {
heldAmount . log . Error ( "failed to encode json response" , zap . Error ( ErrHeldAmountAPI . Wrap ( err ) ) )
return
}
} else {
satelliteID , err := storj . NodeIDFromString ( id )
if err != nil {
heldAmount . serveJSONError ( w , http . StatusBadRequest , ErrHeldAmountAPI . Wrap ( err ) )
return
}
payStub , err := heldAmount . service . SatellitePayStubMonthlyCached ( ctx , satelliteID , period )
if err != nil {
if heldamount . ErrNoPayStubForPeriod . Has ( err ) {
heldAmount . serveJSONError ( w , http . StatusNotFound , ErrHeldAmountAPI . Wrap ( err ) )
return
}
heldAmount . serveJSONError ( w , http . StatusInternalServerError , ErrHeldAmountAPI . Wrap ( err ) )
return
}
2020-04-20 14:03:42 +01:00
if err := json . NewEncoder ( w ) . Encode ( [ ] * heldamount . PayStub { payStub } ) ; err != nil {
2020-03-26 14:53:15 +00:00
heldAmount . log . Error ( "failed to encode json response" , zap . Error ( ErrHeldAmountAPI . Wrap ( err ) ) )
return
}
2020-03-16 04:28:03 +00:00
}
}
2020-03-26 14:53:15 +00:00
// PayStubPeriod retrieves held amount for selected range of months from storagenode database for all satellites or specified satellite by query parameter id.
func ( heldAmount * HeldAmount ) PayStubPeriod ( w http . ResponseWriter , r * http . Request ) {
2020-03-16 04:28:03 +00:00
ctx := r . Context ( )
var err error
defer mon . Task ( ) ( & ctx ) ( & err )
w . Header ( ) . Set ( contentType , applicationJSON )
2020-03-26 14:53:15 +00:00
segmentParams := mux . Vars ( r )
queryParams := r . URL . Query ( )
2020-03-16 04:28:03 +00:00
2020-03-26 14:53:15 +00:00
start , ok := segmentParams [ "start" ]
2020-03-16 04:28:03 +00:00
if ! ok {
heldAmount . serveJSONError ( w , http . StatusBadRequest , ErrNotificationsAPI . Wrap ( err ) )
return
}
2020-03-26 14:53:15 +00:00
end , ok := segmentParams [ "end" ]
2020-03-16 04:28:03 +00:00
if ! ok {
heldAmount . serveJSONError ( w , http . StatusBadRequest , ErrNotificationsAPI . Wrap ( err ) )
return
}
2020-03-26 14:53:15 +00:00
id := queryParams . Get ( "id" )
if id == "" {
payStubs , err := heldAmount . service . AllPayStubsPeriodCached ( ctx , start , end )
if err != nil {
if heldamount . ErrBadPeriod . Has ( err ) {
heldAmount . serveJSONError ( w , http . StatusBadRequest , ErrHeldAmountAPI . Wrap ( err ) )
return
}
heldAmount . serveJSONError ( w , http . StatusInternalServerError , ErrHeldAmountAPI . Wrap ( err ) )
return
}
if err := json . NewEncoder ( w ) . Encode ( payStubs ) ; err != nil {
heldAmount . log . Error ( "failed to encode json response" , zap . Error ( ErrHeldAmountAPI . Wrap ( err ) ) )
return
}
} else {
satelliteID , err := storj . NodeIDFromString ( id )
if err != nil {
heldAmount . serveJSONError ( w , http . StatusBadRequest , ErrHeldAmountAPI . Wrap ( err ) )
return
}
payStubs , err := heldAmount . service . SatellitePayStubPeriodCached ( ctx , satelliteID , start , end )
if err != nil {
if heldamount . ErrBadPeriod . Has ( err ) {
heldAmount . serveJSONError ( w , http . StatusBadRequest , ErrHeldAmountAPI . Wrap ( err ) )
return
}
heldAmount . serveJSONError ( w , http . StatusInternalServerError , ErrHeldAmountAPI . Wrap ( err ) )
return
}
if err := json . NewEncoder ( w ) . Encode ( payStubs ) ; err != nil {
heldAmount . log . Error ( "failed to encode json response" , zap . Error ( ErrHeldAmountAPI . Wrap ( err ) ) )
return
}
2020-03-16 04:28:03 +00:00
}
}
2020-05-27 17:27:28 +01:00
// HeldHistory returns held amount for each % period for all satellites.
func ( heldAmount * HeldAmount ) HeldHistory ( w http . ResponseWriter , r * http . Request ) {
2020-04-28 14:07:50 +01:00
ctx := r . Context ( )
var err error
defer mon . Task ( ) ( & ctx ) ( & err )
w . Header ( ) . Set ( contentType , applicationJSON )
2020-05-27 17:27:28 +01:00
heldbackHistory , err := heldAmount . service . AllHeldbackHistory ( ctx )
2020-04-28 14:07:50 +01:00
if err != nil {
heldAmount . serveJSONError ( w , http . StatusInternalServerError , ErrHeldAmountAPI . Wrap ( err ) )
return
}
if err := json . NewEncoder ( w ) . Encode ( heldbackHistory ) ; err != nil {
heldAmount . log . Error ( "failed to encode json response" , zap . Error ( ErrHeldAmountAPI . Wrap ( err ) ) )
return
}
}
2020-05-18 19:37:16 +01:00
// HeldAmountPeriods retrieves all periods in which we have some heldamount data.
// Have optional parameter - satelliteID.
// If satelliteID specified - will retrieve periods only for concrete satellite.
func ( heldAmount * HeldAmount ) HeldAmountPeriods ( w http . ResponseWriter , r * http . Request ) {
ctx := r . Context ( )
var err error
defer mon . Task ( ) ( & ctx ) ( & err )
w . Header ( ) . Set ( contentType , applicationJSON )
queryParams := r . URL . Query ( )
id := queryParams . Get ( "id" )
if id == "" {
payStubs , err := heldAmount . service . AllPeriods ( ctx )
if err != nil {
heldAmount . serveJSONError ( w , http . StatusInternalServerError , ErrHeldAmountAPI . Wrap ( err ) )
return
}
if err := json . NewEncoder ( w ) . Encode ( payStubs ) ; err != nil {
heldAmount . log . Error ( "failed to encode json response" , zap . Error ( ErrHeldAmountAPI . Wrap ( err ) ) )
return
}
} else {
satelliteID , err := storj . NodeIDFromString ( id )
if err != nil {
heldAmount . serveJSONError ( w , http . StatusBadRequest , ErrHeldAmountAPI . Wrap ( err ) )
return
}
payStubs , err := heldAmount . service . SatellitePeriods ( ctx , satelliteID )
if err != nil {
heldAmount . serveJSONError ( w , http . StatusInternalServerError , ErrHeldAmountAPI . Wrap ( err ) )
return
}
if err := json . NewEncoder ( w ) . Encode ( payStubs ) ; err != nil {
heldAmount . log . Error ( "failed to encode json response" , zap . Error ( ErrHeldAmountAPI . Wrap ( err ) ) )
return
}
}
}
2020-03-15 18:30:23 +00:00
// serveJSONError writes JSON error to response output stream.
2020-03-16 01:32:52 +00:00
func ( heldAmount * HeldAmount ) serveJSONError ( w http . ResponseWriter , status int , err error ) {
2020-03-15 18:30:23 +00:00
w . WriteHeader ( status )
var response struct {
Error string ` json:"error" `
}
response . Error = err . Error ( )
err = json . NewEncoder ( w ) . Encode ( response )
if err != nil {
2020-03-26 14:53:15 +00:00
heldAmount . log . Error ( "failed to write json error response" , zap . Error ( ErrHeldAmountAPI . Wrap ( err ) ) )
2020-03-15 18:30:23 +00:00
return
}
}