git.frostfs.info/TrueCloudLab/frostfs-sdk-go@v0.0.0-20241022124111-5361f0ecebd3/client/accounting.go (about)

     1  package client
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  
     7  	v2accounting "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/accounting"
     8  	"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
     9  	rpcapi "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc"
    10  	"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
    11  	v2session "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session"
    12  	"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/signature"
    13  	"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/accounting"
    14  	apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
    15  	"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
    16  )
    17  
    18  // PrmBalanceGet groups parameters of BalanceGet operation.
    19  type PrmBalanceGet struct {
    20  	XHeaders []string
    21  
    22  	Account user.ID
    23  }
    24  
    25  // SetAccount sets identifier of the FrostFS account for which the balance is requested.
    26  // Required parameter.
    27  //
    28  // Deprecated: Use PrmBalanceGet.Account instead.
    29  func (x *PrmBalanceGet) SetAccount(id user.ID) {
    30  	x.Account = id
    31  }
    32  
    33  func (x *PrmBalanceGet) buildRequest(c *Client) (*v2accounting.BalanceRequest, error) {
    34  	if x.Account.IsEmpty() {
    35  		return nil, errorAccountNotSet
    36  	}
    37  
    38  	var accountV2 refs.OwnerID
    39  	x.Account.WriteToV2(&accountV2)
    40  
    41  	var body v2accounting.BalanceRequestBody
    42  	body.SetOwnerID(&accountV2)
    43  
    44  	var req v2accounting.BalanceRequest
    45  	req.SetBody(&body)
    46  
    47  	c.prepareRequest(&req, new(v2session.RequestMetaHeader))
    48  	return &req, nil
    49  }
    50  
    51  // ResBalanceGet groups resulting values of BalanceGet operation.
    52  type ResBalanceGet struct {
    53  	statusRes
    54  
    55  	amount accounting.Decimal
    56  }
    57  
    58  // Amount returns current amount of funds on the FrostFS account as decimal number.
    59  func (x ResBalanceGet) Amount() accounting.Decimal {
    60  	return x.amount
    61  }
    62  
    63  // BalanceGet requests current balance of the FrostFS account.
    64  //
    65  // Exactly one return value is non-nil. By default, server status is returned in res structure.
    66  // Any client's internal or transport errors are returned as `error`,
    67  // If PrmInit.DisableFrostFSFailuresResolution has been called, unsuccessful
    68  // FrostFS status codes are included in the returned result structure,
    69  // otherwise, are also returned as `error`.
    70  //
    71  // Returns an error if parameters are set incorrectly (see PrmBalanceGet docs).
    72  // Context is required and must not be nil. It is used for network communication.
    73  //
    74  // Return statuses:
    75  //   - global (see Client docs).
    76  func (c *Client) BalanceGet(ctx context.Context, prm PrmBalanceGet) (*ResBalanceGet, error) {
    77  	req, err := prm.buildRequest(c)
    78  	if err != nil {
    79  		return nil, err
    80  	}
    81  
    82  	if err := signature.SignServiceMessage(&c.prm.Key, req); err != nil {
    83  		return nil, fmt.Errorf("sign request: %w", err)
    84  	}
    85  
    86  	resp, err := rpcapi.Balance(&c.c, req, client.WithContext(ctx))
    87  	if err != nil {
    88  		return nil, err
    89  	}
    90  
    91  	var res ResBalanceGet
    92  	res.st, err = c.processResponse(resp)
    93  	if err != nil || !apistatus.IsSuccessful(res.st) {
    94  		return &res, err
    95  	}
    96  
    97  	const fieldBalance = "balance"
    98  
    99  	bal := resp.GetBody().GetBalance()
   100  	if bal == nil {
   101  		return &res, newErrMissingResponseField(fieldBalance)
   102  	}
   103  
   104  	if err := res.amount.ReadFromV2(*bal); err != nil {
   105  		return &res, newErrInvalidResponseField(fieldBalance, err)
   106  	}
   107  	return &res, nil
   108  }