[#33] Add route to get NeoFS balance

Signed-off-by: Denis Kirillov <denis@nspcc.ru>
This commit is contained in:
Denis Kirillov 2022-07-28 19:57:40 +03:00 committed by Alex Vanin
parent aaf7433c7b
commit 6e01a0ead7
9 changed files with 530 additions and 0 deletions

105
gen/models/balance.go Normal file
View file

@ -0,0 +1,105 @@
// Code generated by go-swagger; DO NOT EDIT.
package models
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"context"
"github.com/go-openapi/errors"
"github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
"github.com/go-openapi/validate"
)
// Balance balance
//
// swagger:model Balance
type Balance struct {
// address
// Required: true
Address *string `json:"address"`
// precision
// Required: true
Precision *int64 `json:"precision"`
// value
// Required: true
Value *string `json:"value"`
}
// Validate validates this balance
func (m *Balance) Validate(formats strfmt.Registry) error {
var res []error
if err := m.validateAddress(formats); err != nil {
res = append(res, err)
}
if err := m.validatePrecision(formats); err != nil {
res = append(res, err)
}
if err := m.validateValue(formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
func (m *Balance) validateAddress(formats strfmt.Registry) error {
if err := validate.Required("address", "body", m.Address); err != nil {
return err
}
return nil
}
func (m *Balance) validatePrecision(formats strfmt.Registry) error {
if err := validate.Required("precision", "body", m.Precision); err != nil {
return err
}
return nil
}
func (m *Balance) validateValue(formats strfmt.Registry) error {
if err := validate.Required("value", "body", m.Value); err != nil {
return err
}
return nil
}
// ContextValidate validates this balance based on context it is used
func (m *Balance) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *Balance) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *Balance) UnmarshalBinary(b []byte) error {
var res Balance
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil
}

View file

@ -30,6 +30,40 @@ func init() {
"host": "localhost:8090",
"basePath": "/v1",
"paths": {
"/accounting/balance/{address}": {
"get": {
"security": [],
"description": "Getting balance of provided wallet address in NeoFS.",
"produces": [
"application/json"
],
"summary": "Get balance in NeoFS",
"operationId": "getBalance",
"parameters": [
{
"type": "string",
"description": "Base58 encoded wallet address.",
"name": "address",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "Balance of address in NeoFS",
"schema": {
"$ref": "#/definitions/Balance"
}
},
"400": {
"description": "Bad request",
"schema": {
"$ref": "#/definitions/ErrorResponse"
}
}
}
}
},
"/auth": {
"post": {
"security": [],
@ -546,6 +580,25 @@ func init() {
"value": "tag value"
}
},
"Balance": {
"type": "object",
"required": [
"address",
"value",
"precision"
],
"properties": {
"address": {
"type": "string"
},
"precision": {
"type": "integer"
},
"value": {
"type": "string"
}
}
},
"Bearer": {
"description": "Bearer token that is expected to be formed.",
"type": "object",
@ -1305,6 +1358,40 @@ func init() {
"host": "localhost:8090",
"basePath": "/v1",
"paths": {
"/accounting/balance/{address}": {
"get": {
"security": [],
"description": "Getting balance of provided wallet address in NeoFS.",
"produces": [
"application/json"
],
"summary": "Get balance in NeoFS",
"operationId": "getBalance",
"parameters": [
{
"type": "string",
"description": "Base58 encoded wallet address.",
"name": "address",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "Balance of address in NeoFS",
"schema": {
"$ref": "#/definitions/Balance"
}
},
"400": {
"description": "Bad request",
"schema": {
"$ref": "#/definitions/ErrorResponse"
}
}
}
}
},
"/auth": {
"post": {
"security": [],
@ -1917,6 +2004,25 @@ func init() {
"value": "tag value"
}
},
"Balance": {
"type": "object",
"required": [
"address",
"value",
"precision"
],
"properties": {
"address": {
"type": "string"
},
"precision": {
"type": "integer"
},
"value": {
"type": "string"
}
}
},
"Bearer": {
"description": "Bearer token that is expected to be formed.",
"type": "object",

View file

@ -0,0 +1,58 @@
// Code generated by go-swagger; DO NOT EDIT.
package operations
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the generate command
import (
"net/http"
"github.com/go-openapi/runtime/middleware"
)
// GetBalanceHandlerFunc turns a function with the right signature into a get balance handler
type GetBalanceHandlerFunc func(GetBalanceParams) middleware.Responder
// Handle executing the request and returning a response
func (fn GetBalanceHandlerFunc) Handle(params GetBalanceParams) middleware.Responder {
return fn(params)
}
// GetBalanceHandler interface for that can handle valid get balance params
type GetBalanceHandler interface {
Handle(GetBalanceParams) middleware.Responder
}
// NewGetBalance creates a new http.Handler for the get balance operation
func NewGetBalance(ctx *middleware.Context, handler GetBalanceHandler) *GetBalance {
return &GetBalance{Context: ctx, Handler: handler}
}
/* GetBalance swagger:route GET /accounting/balance/{address} getBalance
Get balance in NeoFS
Getting balance of provided wallet address in NeoFS.
*/
type GetBalance struct {
Context *middleware.Context
Handler GetBalanceHandler
}
func (o *GetBalance) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
route, rCtx, _ := o.Context.RouteInfo(r)
if rCtx != nil {
*r = *rCtx
}
var Params = NewGetBalanceParams()
if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params
o.Context.Respond(rw, r, route.Produces, route, err)
return
}
res := o.Handler.Handle(Params) // actually handle the request
o.Context.Respond(rw, r, route.Produces, route, res)
}

View file

@ -0,0 +1,71 @@
// Code generated by go-swagger; DO NOT EDIT.
package operations
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"net/http"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime/middleware"
"github.com/go-openapi/strfmt"
)
// NewGetBalanceParams creates a new GetBalanceParams object
//
// There are no default values defined in the spec.
func NewGetBalanceParams() GetBalanceParams {
return GetBalanceParams{}
}
// GetBalanceParams contains all the bound params for the get balance operation
// typically these are obtained from a http.Request
//
// swagger:parameters getBalance
type GetBalanceParams struct {
// HTTP Request Object
HTTPRequest *http.Request `json:"-"`
/*Base58 encoded wallet address.
Required: true
In: path
*/
Address string
}
// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface
// for simple values it will use straight method calls.
//
// To ensure default values, the struct must have been initialized with NewGetBalanceParams() beforehand.
func (o *GetBalanceParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error {
var res []error
o.HTTPRequest = r
rAddress, rhkAddress, _ := route.Params.GetOK("address")
if err := o.bindAddress(rAddress, rhkAddress, route.Formats); err != nil {
res = append(res, err)
}
if len(res) > 0 {
return errors.CompositeValidationError(res...)
}
return nil
}
// bindAddress binds and validates parameter Address from path.
func (o *GetBalanceParams) bindAddress(rawData []string, hasKey bool, formats strfmt.Registry) error {
var raw string
if len(rawData) > 0 {
raw = rawData[len(rawData)-1]
}
// Required: true
// Parameter is provided by construction from the route
o.Address = raw
return nil
}

View file

@ -0,0 +1,102 @@
// Code generated by go-swagger; DO NOT EDIT.
package operations
// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command
import (
"net/http"
"github.com/go-openapi/runtime"
"github.com/nspcc-dev/neofs-rest-gw/gen/models"
)
// GetBalanceOKCode is the HTTP code returned for type GetBalanceOK
const GetBalanceOKCode int = 200
/*GetBalanceOK Balance of address in NeoFS
swagger:response getBalanceOK
*/
type GetBalanceOK struct {
/*
In: Body
*/
Payload *models.Balance `json:"body,omitempty"`
}
// NewGetBalanceOK creates GetBalanceOK with default headers values
func NewGetBalanceOK() *GetBalanceOK {
return &GetBalanceOK{}
}
// WithPayload adds the payload to the get balance o k response
func (o *GetBalanceOK) WithPayload(payload *models.Balance) *GetBalanceOK {
o.Payload = payload
return o
}
// SetPayload sets the payload to the get balance o k response
func (o *GetBalanceOK) SetPayload(payload *models.Balance) {
o.Payload = payload
}
// WriteResponse to the client
func (o *GetBalanceOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(200)
if o.Payload != nil {
payload := o.Payload
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
}
}
}
// GetBalanceBadRequestCode is the HTTP code returned for type GetBalanceBadRequest
const GetBalanceBadRequestCode int = 400
/*GetBalanceBadRequest Bad request
swagger:response getBalanceBadRequest
*/
type GetBalanceBadRequest struct {
/*
In: Body
*/
Payload *models.ErrorResponse `json:"body,omitempty"`
}
// NewGetBalanceBadRequest creates GetBalanceBadRequest with default headers values
func NewGetBalanceBadRequest() *GetBalanceBadRequest {
return &GetBalanceBadRequest{}
}
// WithPayload adds the payload to the get balance bad request response
func (o *GetBalanceBadRequest) WithPayload(payload *models.ErrorResponse) *GetBalanceBadRequest {
o.Payload = payload
return o
}
// SetPayload sets the payload to the get balance bad request response
func (o *GetBalanceBadRequest) SetPayload(payload *models.ErrorResponse) {
o.Payload = payload
}
// WriteResponse to the client
func (o *GetBalanceBadRequest) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
rw.WriteHeader(400)
if o.Payload != nil {
payload := o.Payload
if err := producer.Produce(rw, payload); err != nil {
panic(err) // let the recovery middleware deal with this
}
}
}

View file

@ -53,6 +53,9 @@ func NewNeofsRestGwAPI(spec *loads.Document) *NeofsRestGwAPI {
DeleteObjectHandler: DeleteObjectHandlerFunc(func(params DeleteObjectParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation DeleteObject has not yet been implemented")
}),
GetBalanceHandler: GetBalanceHandlerFunc(func(params GetBalanceParams) middleware.Responder {
return middleware.NotImplemented("operation GetBalance has not yet been implemented")
}),
GetContainerHandler: GetContainerHandlerFunc(func(params GetContainerParams) middleware.Responder {
return middleware.NotImplemented("operation GetContainer has not yet been implemented")
}),
@ -133,6 +136,8 @@ type NeofsRestGwAPI struct {
DeleteContainerHandler DeleteContainerHandler
// DeleteObjectHandler sets the operation handler for the delete object operation
DeleteObjectHandler DeleteObjectHandler
// GetBalanceHandler sets the operation handler for the get balance operation
GetBalanceHandler GetBalanceHandler
// GetContainerHandler sets the operation handler for the get container operation
GetContainerHandler GetContainerHandler
// GetContainerEACLHandler sets the operation handler for the get container e ACL operation
@ -239,6 +244,9 @@ func (o *NeofsRestGwAPI) Validate() error {
if o.DeleteObjectHandler == nil {
unregistered = append(unregistered, "DeleteObjectHandler")
}
if o.GetBalanceHandler == nil {
unregistered = append(unregistered, "GetBalanceHandler")
}
if o.GetContainerHandler == nil {
unregistered = append(unregistered, "GetContainerHandler")
}
@ -377,6 +385,10 @@ func (o *NeofsRestGwAPI) initHandlerCache() {
if o.handlers["GET"] == nil {
o.handlers["GET"] = make(map[string]http.Handler)
}
o.handlers["GET"]["/accounting/balance/{address}"] = NewGetBalance(o.context, o.GetBalanceHandler)
if o.handlers["GET"] == nil {
o.handlers["GET"] = make(map[string]http.Handler)
}
o.handlers["GET"]["/containers/{containerId}"] = NewGetContainer(o.context, o.GetContainerHandler)
if o.handlers["GET"] == nil {
o.handlers["GET"] = make(map[string]http.Handler)

View file

@ -80,6 +80,8 @@ func (a *API) Configure(api *operations.NeofsRestGwAPI) http.Handler {
api.AuthHandler = operations.AuthHandlerFunc(a.PostAuth)
api.GetBalanceHandler = operations.GetBalanceHandlerFunc(a.Balance)
api.PutObjectHandler = operations.PutObjectHandlerFunc(a.PutObjects)
api.GetObjectInfoHandler = operations.GetObjectInfoHandlerFunc(a.GetObjectInfo)
api.DeleteObjectHandler = operations.DeleteObjectHandlerFunc(a.DeleteObject)

37
handlers/balance.go Normal file
View file

@ -0,0 +1,37 @@
package handlers
import (
"strconv"
"github.com/go-openapi/runtime/middleware"
"github.com/nspcc-dev/neofs-rest-gw/gen/models"
"github.com/nspcc-dev/neofs-rest-gw/gen/restapi/operations"
"github.com/nspcc-dev/neofs-rest-gw/internal/util"
"github.com/nspcc-dev/neofs-sdk-go/pool"
"github.com/nspcc-dev/neofs-sdk-go/user"
)
// Balance handler that get balance from NeoFS.
func (a *API) Balance(params operations.GetBalanceParams) middleware.Responder {
var ownerID user.ID
if err := ownerID.DecodeString(params.Address); err != nil {
resp := a.logAndGetErrorResponse("parse address", err)
return operations.NewGetBalanceBadRequest().WithPayload(resp)
}
var prm pool.PrmBalanceGet
prm.SetAccount(ownerID)
neofsBalance, err := a.pool.Balance(params.HTTPRequest.Context(), prm)
if err != nil {
resp := a.logAndGetErrorResponse("get balance", err)
return operations.NewGetBalanceBadRequest().WithPayload(resp)
}
var resp models.Balance
resp.Address = util.NewString(params.Address)
resp.Value = util.NewString(strconv.FormatInt(neofsBalance.Value(), 10))
resp.Precision = util.NewInteger(int64(neofsBalance.Precision()))
return operations.NewGetBalanceOK().WithPayload(&resp)
}

View file

@ -92,6 +92,30 @@ paths:
schema:
$ref: '#/definitions/ErrorResponse'
/accounting/balance/{address}:
get:
operationId: getBalance
summary: Get balance in NeoFS
description: Getting balance of provided wallet address in NeoFS.
security: [ ]
parameters:
- in: path
name: address
type: string
required: true
description: Base58 encoded wallet address.
produces:
- application/json
responses:
200:
description: Balance of address in NeoFS
schema:
$ref: '#/definitions/Balance'
400:
description: Bad request
schema:
$ref: '#/definitions/ErrorResponse'
/objects:
parameters:
- $ref: '#/parameters/signatureParam'
@ -822,6 +846,19 @@ definitions:
value: "tag value"
Principal:
type: string
Balance:
type: object
properties:
address:
type: string
value:
type: string
precision:
type: integer
required:
- address
- value
- precision
ErrorType:
description: Error type. Allow determine source of the error.
type: string