storagenode/console/api period payment api extended
Change-Id: I18ec331c6a684e3a9351e3c917bacdb8b8f18c28
This commit is contained in:
parent
0df586c3a8
commit
8597e6b512
@ -179,8 +179,8 @@ func (heldAmount *HeldAmount) AllPayStubsPeriod(w http.ResponseWriter, r *http.R
|
||||
}
|
||||
}
|
||||
|
||||
// GetMonthlyPayment returns payment data from satellite for specific month.
|
||||
func (heldAmount *HeldAmount) GetMonthlyPayment(w http.ResponseWriter, r *http.Request) {
|
||||
// SatellitePaymentMonthly returns payment data from satellite for specific month.
|
||||
func (heldAmount *HeldAmount) SatellitePaymentMonthly(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
var err error
|
||||
defer mon.Task()(&ctx)(&err)
|
||||
@ -206,7 +206,7 @@ func (heldAmount *HeldAmount) GetMonthlyPayment(w http.ResponseWriter, r *http.R
|
||||
return
|
||||
}
|
||||
|
||||
paymentData, err := heldAmount.service.GetPayment(ctx, satelliteID, period)
|
||||
paymentData, err := heldAmount.service.SatellitePaymentMonthlyCached(ctx, satelliteID, period)
|
||||
if err != nil {
|
||||
heldAmount.serveJSONError(w, http.StatusInternalServerError, ErrHeldAmountPI.Wrap(err))
|
||||
return
|
||||
@ -218,6 +218,113 @@ func (heldAmount *HeldAmount) GetMonthlyPayment(w http.ResponseWriter, r *http.R
|
||||
}
|
||||
}
|
||||
|
||||
// AllPaymentsMonthly returns payments for specific month from all satellites.
|
||||
func (heldAmount *HeldAmount) AllPaymentsMonthly(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
var err error
|
||||
defer mon.Task()(&ctx)(&err)
|
||||
|
||||
w.Header().Set(contentType, applicationJSON)
|
||||
|
||||
params := mux.Vars(r)
|
||||
|
||||
period, ok := params["period"]
|
||||
if !ok {
|
||||
heldAmount.serveJSONError(w, http.StatusBadRequest, ErrNotificationsAPI.Wrap(err))
|
||||
return
|
||||
}
|
||||
|
||||
payStubs, err := heldAmount.service.AllPaymentsMonthlyCached(ctx, period)
|
||||
if err != nil {
|
||||
heldAmount.serveJSONError(w, http.StatusInternalServerError, ErrHeldAmountPI.Wrap(err))
|
||||
return
|
||||
}
|
||||
|
||||
if err := json.NewEncoder(w).Encode(payStubs); err != nil {
|
||||
heldAmount.log.Error("failed to encode json response", zap.Error(ErrHeldAmountPI.Wrap(err)))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// SatellitePaymentPeriod retrieves payment for selected satellite for selected period from storagenode database.
|
||||
func (heldAmount *HeldAmount) SatellitePaymentPeriod(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
var err error
|
||||
defer mon.Task()(&ctx)(&err)
|
||||
|
||||
w.Header().Set(contentType, applicationJSON)
|
||||
|
||||
params := mux.Vars(r)
|
||||
|
||||
id, ok := params["satelliteID"]
|
||||
if !ok {
|
||||
heldAmount.serveJSONError(w, http.StatusBadRequest, ErrNotificationsAPI.Wrap(err))
|
||||
return
|
||||
}
|
||||
satelliteID, err := storj.NodeIDFromString(id)
|
||||
if err != nil {
|
||||
heldAmount.serveJSONError(w, http.StatusBadRequest, ErrHeldAmountPI.Wrap(err))
|
||||
return
|
||||
}
|
||||
|
||||
start, ok := params["start"]
|
||||
if !ok {
|
||||
heldAmount.serveJSONError(w, http.StatusBadRequest, ErrNotificationsAPI.Wrap(err))
|
||||
return
|
||||
}
|
||||
|
||||
end, ok := params["end"]
|
||||
if !ok {
|
||||
heldAmount.serveJSONError(w, http.StatusBadRequest, ErrNotificationsAPI.Wrap(err))
|
||||
return
|
||||
}
|
||||
|
||||
payments, err := heldAmount.service.SatellitePaymentPeriodCached(ctx, satelliteID, start, end)
|
||||
if err != nil {
|
||||
heldAmount.serveJSONError(w, http.StatusInternalServerError, ErrHeldAmountPI.Wrap(err))
|
||||
return
|
||||
}
|
||||
|
||||
if err := json.NewEncoder(w).Encode(payments); err != nil {
|
||||
heldAmount.log.Error("failed to encode json response", zap.Error(ErrHeldAmountPI.Wrap(err)))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// AllPaymentsPeriod retrieves payment for all satellites for selected range of months from storagenode database.
|
||||
func (heldAmount *HeldAmount) AllPaymentsPeriod(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
var err error
|
||||
defer mon.Task()(&ctx)(&err)
|
||||
|
||||
w.Header().Set(contentType, applicationJSON)
|
||||
|
||||
params := mux.Vars(r)
|
||||
|
||||
start, ok := params["start"]
|
||||
if !ok {
|
||||
heldAmount.serveJSONError(w, http.StatusBadRequest, ErrNotificationsAPI.Wrap(err))
|
||||
return
|
||||
}
|
||||
|
||||
end, ok := params["end"]
|
||||
if !ok {
|
||||
heldAmount.serveJSONError(w, http.StatusBadRequest, ErrNotificationsAPI.Wrap(err))
|
||||
return
|
||||
}
|
||||
|
||||
payStubs, err := heldAmount.service.AllPaymentsPeriodCached(ctx, start, end)
|
||||
if err != nil {
|
||||
heldAmount.serveJSONError(w, http.StatusInternalServerError, ErrHeldAmountPI.Wrap(err))
|
||||
return
|
||||
}
|
||||
|
||||
if err := json.NewEncoder(w).Encode(payStubs); err != nil {
|
||||
heldAmount.log.Error("failed to encode json response", zap.Error(ErrHeldAmountPI.Wrap(err)))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// serveJSONError writes JSON error to response output stream.
|
||||
func (heldAmount *HeldAmount) serveJSONError(w http.ResponseWriter, status int, err error) {
|
||||
w.WriteHeader(status)
|
||||
|
@ -81,7 +81,10 @@ func NewServer(logger *zap.Logger, assets http.FileSystem, notifications *notifi
|
||||
heldAmountRouter.HandleFunc("/paystub/{period}", heldAmountController.AllPayStubsMonthly).Methods(http.MethodGet)
|
||||
heldAmountRouter.HandleFunc("/paystub/{start}/{end}/{satelliteID}", heldAmountController.SatellitePayStubPeriod).Methods(http.MethodGet)
|
||||
heldAmountRouter.HandleFunc("/paystub/{start}/{end}", heldAmountController.AllPayStubsPeriod).Methods(http.MethodGet)
|
||||
heldAmountRouter.HandleFunc("/payment/{period}/{satelliteID}", heldAmountController.GetMonthlyPayment).Methods(http.MethodGet)
|
||||
heldAmountRouter.HandleFunc("/payment/{period}/{satelliteID}", heldAmountController.SatellitePaymentMonthly).Methods(http.MethodGet)
|
||||
heldAmountRouter.HandleFunc("/payment/{period}", heldAmountController.AllPaymentsMonthly).Methods(http.MethodGet)
|
||||
heldAmountRouter.HandleFunc("/payment/{start}/{end}/{satelliteID}", heldAmountController.SatellitePaymentPeriod).Methods(http.MethodGet)
|
||||
heldAmountRouter.HandleFunc("/payment/{start}/{end}", heldAmountController.AllPaymentsPeriod).Methods(http.MethodGet)
|
||||
|
||||
if assets != nil {
|
||||
fs := http.FileServer(assets)
|
||||
|
@ -149,10 +149,12 @@ func TestHeldAmountDB(t *testing.T) {
|
||||
|
||||
paym, err = heldAmount.GetPayment(ctx, satelliteID, "")
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, true, heldamount.ErrNoPayStubForPeriod.Has(err))
|
||||
assert.Nil(t, paym)
|
||||
|
||||
paym, err = heldAmount.GetPayment(ctx, storj.NodeID{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, period)
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, true, heldamount.ErrNoPayStubForPeriod.Has(err))
|
||||
assert.Nil(t, paym)
|
||||
})
|
||||
|
||||
@ -174,6 +176,81 @@ func TestHeldAmountDB(t *testing.T) {
|
||||
})
|
||||
})
|
||||
}
|
||||
func TestSatellitePaymentPeriodCached(t *testing.T) {
|
||||
storagenodedbtest.Run(t, func(ctx *testcontext.Context, t *testing.T, db storagenode.DB) {
|
||||
heldAmountDB := db.HeldAmount()
|
||||
service := heldamount.NewService(nil, heldAmountDB, rpc.Dialer{}, nil)
|
||||
|
||||
payment := heldamount.Payment{
|
||||
Created: time.Now().UTC(),
|
||||
SatelliteID: storj.NodeID{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
|
||||
Amount: 228,
|
||||
Receipt: "receipt_test",
|
||||
Notes: "notes_test",
|
||||
}
|
||||
|
||||
for i := 1; i < 4; i++ {
|
||||
payment.Period = fmt.Sprintf("2020-0%d", i)
|
||||
payment.ID = int64(i)
|
||||
err := heldAmountDB.StorePayment(ctx, payment)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
payments, err := service.SatellitePaymentPeriodCached(ctx, payment.SatelliteID, "2020-01", "2020-03")
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 3, len(payments))
|
||||
|
||||
payments, err = service.SatellitePaymentPeriodCached(ctx, payment.SatelliteID, "2019-01", "2021-03")
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 3, len(payments))
|
||||
|
||||
payments, err = service.SatellitePaymentPeriodCached(ctx, payment.SatelliteID, "2019-01", "2020-01")
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 1, len(payments))
|
||||
})
|
||||
}
|
||||
|
||||
func TestAllPaymentPeriodCached(t *testing.T) {
|
||||
storagenodedbtest.Run(t, func(ctx *testcontext.Context, t *testing.T, db storagenode.DB) {
|
||||
heldAmountDB := db.HeldAmount()
|
||||
service := heldamount.NewService(nil, heldAmountDB, rpc.Dialer{}, nil)
|
||||
|
||||
payment := heldamount.Payment{
|
||||
ID: 1,
|
||||
Created: time.Now().UTC(),
|
||||
SatelliteID: storj.NodeID{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
|
||||
Amount: 228,
|
||||
Receipt: "receipt_test",
|
||||
Notes: "notes_test",
|
||||
}
|
||||
|
||||
for i := 1; i < 4; i++ {
|
||||
payment.SatelliteID[0] += byte(i)
|
||||
for j := 1; j < 4; j++ {
|
||||
payment.Period = fmt.Sprintf("2020-0%d", j)
|
||||
payment.ID = int64(12*i + 2*j + 1)
|
||||
err := heldAmountDB.StorePayment(ctx, payment)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
}
|
||||
|
||||
payments, err := service.AllPaymentsPeriodCached(ctx, "2020-01", "2020-03")
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 9, len(payments))
|
||||
|
||||
payments, err = service.AllPaymentsPeriodCached(ctx, "2019-01", "2021-03")
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 9, len(payments))
|
||||
|
||||
payments, err = service.AllPaymentsPeriodCached(ctx, "2019-01", "2020-01")
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 3, len(payments))
|
||||
|
||||
payments, err = service.AllPaymentsPeriodCached(ctx, "2019-01", "2019-01")
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 0, len(payments))
|
||||
})
|
||||
}
|
||||
|
||||
func TestSatellitePayStubPeriodCached(t *testing.T) {
|
||||
storagenodedbtest.Run(t, func(ctx *testcontext.Context, t *testing.T, db storagenode.DB) {
|
||||
|
@ -8,7 +8,6 @@ import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/spacemonkeygo/monkit/v3"
|
||||
"github.com/zeebo/errs"
|
||||
@ -17,6 +16,7 @@ import (
|
||||
"storj.io/common/pb"
|
||||
"storj.io/common/rpc"
|
||||
"storj.io/storj/pkg/storj"
|
||||
"storj.io/storj/private/date"
|
||||
"storj.io/storj/storagenode/trust"
|
||||
)
|
||||
|
||||
@ -74,7 +74,7 @@ func (service *Service) GetPaystubStats(ctx context.Context, satelliteID storj.N
|
||||
}
|
||||
defer func() { err = errs.Combine(err, client.Close()) }()
|
||||
|
||||
requestedPeriod, err := stringToTime(period)
|
||||
requestedPeriod, err := date.PeriodToTime(period)
|
||||
if err != nil {
|
||||
service.log.Error("stringToTime", zap.Error(err))
|
||||
return nil, ErrHeldAmountService.Wrap(err)
|
||||
@ -121,7 +121,7 @@ func (service *Service) GetPayment(ctx context.Context, satelliteID storj.NodeID
|
||||
}
|
||||
defer func() { err = errs.Combine(err, client.Close()) }()
|
||||
|
||||
requestedPeriod, err := stringToTime(period)
|
||||
requestedPeriod, err := date.PeriodToTime(period)
|
||||
if err != nil {
|
||||
return nil, ErrHeldAmountService.Wrap(err)
|
||||
}
|
||||
@ -235,6 +235,51 @@ func (service *Service) AllPaymentsMonthlyCached(ctx context.Context, period str
|
||||
return payments, nil
|
||||
}
|
||||
|
||||
// SatellitePaymentPeriodCached retrieves payment for all satellites for selected months from storagenode database.
|
||||
func (service *Service) SatellitePaymentPeriodCached(ctx context.Context, satelliteID storj.NodeID, periodStart, periodEnd string) (payments []*Payment, err error) {
|
||||
defer mon.Task()(&ctx, &satelliteID, &periodStart, &periodEnd)(&err)
|
||||
|
||||
periods, err := parsePeriodRange(periodStart, periodEnd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, period := range periods {
|
||||
payment, err := service.db.GetPayment(ctx, satelliteID, period)
|
||||
if err != nil {
|
||||
if ErrNoPayStubForPeriod.Has(err) {
|
||||
continue
|
||||
}
|
||||
return nil, ErrHeldAmountService.Wrap(err)
|
||||
}
|
||||
|
||||
payments = append(payments, payment)
|
||||
}
|
||||
|
||||
return payments, nil
|
||||
}
|
||||
|
||||
// AllPaymentsPeriodCached retrieves payment for all satellites for selected range of months from storagenode database.
|
||||
func (service *Service) AllPaymentsPeriodCached(ctx context.Context, periodStart, periodEnd string) (payments []Payment, err error) {
|
||||
defer mon.Task()(&ctx, &periodStart, &periodEnd)(&err)
|
||||
|
||||
periods, err := parsePeriodRange(periodStart, periodEnd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, period := range periods {
|
||||
payment, err := service.db.AllPayments(ctx, period)
|
||||
if err != nil {
|
||||
return nil, ErrHeldAmountService.Wrap(err)
|
||||
}
|
||||
|
||||
payments = append(payments, payment...)
|
||||
}
|
||||
|
||||
return payments, nil
|
||||
}
|
||||
|
||||
// dial dials the HeldAmount client for the satellite by id
|
||||
func (service *Service) dial(ctx context.Context, satelliteID storj.NodeID) (_ *Client, err error) {
|
||||
defer mon.Task()(&ctx)(&err)
|
||||
@ -255,17 +300,6 @@ func (service *Service) dial(ctx context.Context, satelliteID storj.NodeID) (_ *
|
||||
}, nil
|
||||
}
|
||||
|
||||
func stringToTime(period string) (_ time.Time, err error) {
|
||||
layout := "2006-01"
|
||||
per := period[0:7]
|
||||
result, err := time.Parse(layout, per)
|
||||
if err != nil {
|
||||
return time.Time{}, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// TODO: improve it.
|
||||
func parsePeriodRange(periodStart, periodEnd string) (periods []string, err error) {
|
||||
var yearStart, yearEnd, monthStart, monthEnd int
|
||||
|
@ -273,6 +273,9 @@ func (db *heldamountDB) GetPayment(ctx context.Context, satelliteID storj.NodeID
|
||||
&result.Notes,
|
||||
)
|
||||
if err != nil {
|
||||
if sql.ErrNoRows == err {
|
||||
return nil, heldamount.ErrNoPayStubForPeriod.Wrap(err)
|
||||
}
|
||||
return nil, ErrHeldAmount.Wrap(err)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user