forked from TrueCloudLab/frostfs-sdk-go
[#92] client: Accept structured parameters in non-object operations
Define `XPrm` type for each `X` client operation which structures parameters. Export setters of each parameterized value. Emphasize that some parameters are required. Make the client panic when the parameters are incorrectly set. Get rid of vadiadic call options and `CallOption` type. Improve documentation of client behavior. Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
parent
596774ce5b
commit
213d20e3fb
13 changed files with 1100 additions and 885 deletions
|
@ -2,18 +2,24 @@ package client
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
rpcapi "github.com/nspcc-dev/neofs-api-go/v2/rpc"
|
||||
"github.com/nspcc-dev/neofs-api-go/v2/rpc/client"
|
||||
v2session "github.com/nspcc-dev/neofs-api-go/v2/session"
|
||||
v2signature "github.com/nspcc-dev/neofs-api-go/v2/signature"
|
||||
"github.com/nspcc-dev/neofs-sdk-go/owner"
|
||||
)
|
||||
|
||||
var errMalformedResponseBody = errors.New("malformed response body")
|
||||
// CreateSessionPrm groups parameters of CreateSession operation.
|
||||
type CreateSessionPrm struct {
|
||||
exp uint64
|
||||
}
|
||||
|
||||
// SetExp sets number of the last NepFS epoch in the lifetime of the session after which it will be expired.
|
||||
func (x *CreateSessionPrm) SetExp(exp uint64) {
|
||||
x.exp = exp
|
||||
}
|
||||
|
||||
// CreateSessionRes groups resulting values of CreateSession operation.
|
||||
type CreateSessionRes struct {
|
||||
statusRes
|
||||
|
||||
|
@ -26,6 +32,9 @@ func (x *CreateSessionRes) setID(id []byte) {
|
|||
x.id = id
|
||||
}
|
||||
|
||||
// ID returns identifier of the opened session in a binary NeoFS API protocol format.
|
||||
//
|
||||
// Client doesn't retain value so modification is safe.
|
||||
func (x CreateSessionRes) ID() []byte {
|
||||
return x.id
|
||||
}
|
||||
|
@ -34,66 +43,69 @@ func (x *CreateSessionRes) setSessionKey(key []byte) {
|
|||
x.sessionKey = key
|
||||
}
|
||||
|
||||
func (x CreateSessionRes) SessionKey() []byte {
|
||||
// PublicKey returns public key of the opened session in a binary NeoFS API protocol format.
|
||||
func (x CreateSessionRes) PublicKey() []byte {
|
||||
return x.sessionKey
|
||||
}
|
||||
|
||||
// CreateSession creates session through NeoFS API call.
|
||||
// CreateSession opens a session with the node server on the remote endpoint.
|
||||
// The session lifetime coincides with the server lifetime. Results can be written
|
||||
// to session token which can be later attached to the requests.
|
||||
//
|
||||
// Any client's internal or transport errors are returned as error,
|
||||
// NeoFS status codes are included in the returned results.
|
||||
func (c *Client) CreateSession(ctx context.Context, expiration uint64, opts ...CallOption) (*CreateSessionRes, error) {
|
||||
// apply all available options
|
||||
callOptions := c.defaultCallOptions()
|
||||
|
||||
for i := range opts {
|
||||
opts[i](callOptions)
|
||||
// Any client's internal or transport errors are returned as `error`.
|
||||
// If WithNeoFSErrorParsing option has been provided, unsuccessful
|
||||
// NeoFS status codes are returned as `error`, otherwise, are included
|
||||
// in the returned result structure.
|
||||
//
|
||||
// Immediately panics if parameters are set incorrectly (see CreateSessionPrm docs).
|
||||
// Context is required and must not be nil. It is used for network communication.
|
||||
//
|
||||
// Exactly one return value is non-nil. Server status return is returned in CreateSessionRes.
|
||||
// Reflects all internal errors in second return value (transport problems, response processing, etc.).
|
||||
func (c *Client) CreateSession(ctx context.Context, prm CreateSessionPrm) (*CreateSessionRes, error) {
|
||||
// check context
|
||||
if ctx == nil {
|
||||
panic(panicMsgMissingContext)
|
||||
}
|
||||
|
||||
ownerID := owner.NewIDFromPublicKey(&callOptions.key.PublicKey)
|
||||
ownerID := owner.NewIDFromPublicKey(&c.opts.key.PublicKey)
|
||||
|
||||
// form request body
|
||||
reqBody := new(v2session.CreateRequestBody)
|
||||
reqBody.SetOwnerID(ownerID.ToV2())
|
||||
reqBody.SetExpiration(expiration)
|
||||
reqBody.SetExpiration(prm.exp)
|
||||
|
||||
// for request
|
||||
var req v2session.CreateRequest
|
||||
|
||||
req := new(v2session.CreateRequest)
|
||||
req.SetBody(reqBody)
|
||||
req.SetMetaHeader(v2MetaHeaderFromOpts(callOptions))
|
||||
|
||||
err := v2signature.SignServiceMessage(callOptions.key, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp, err := rpcapi.CreateSession(c.Raw(), req, client.WithContext(ctx))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("transport error: %w", err)
|
||||
}
|
||||
// init call context
|
||||
|
||||
var (
|
||||
res = new(CreateSessionRes)
|
||||
procPrm processResponseV2Prm
|
||||
procRes processResponseV2Res
|
||||
cc contextCall
|
||||
res CreateSessionRes
|
||||
)
|
||||
|
||||
procPrm.callOpts = callOptions
|
||||
procPrm.resp = resp
|
||||
c.initCallContext(&cc)
|
||||
cc.req = &req
|
||||
cc.statusRes = &res
|
||||
cc.call = func() (responseV2, error) {
|
||||
return rpcapi.CreateSession(c.Raw(), &req, client.WithContext(ctx))
|
||||
}
|
||||
cc.result = func(r responseV2) {
|
||||
resp := r.(*v2session.CreateResponse)
|
||||
|
||||
procRes.statusRes = res
|
||||
body := resp.GetBody()
|
||||
|
||||
// process response in general
|
||||
if c.processResponseV2(&procRes, procPrm) {
|
||||
if procRes.cliErr != nil {
|
||||
return nil, procRes.cliErr
|
||||
}
|
||||
|
||||
return res, nil
|
||||
res.setID(body.GetID())
|
||||
res.setSessionKey(body.GetSessionKey())
|
||||
}
|
||||
|
||||
body := resp.GetBody()
|
||||
// process call
|
||||
if !cc.processCall() {
|
||||
return nil, cc.err
|
||||
}
|
||||
|
||||
res.setID(body.GetID())
|
||||
res.setSessionKey(body.GetSessionKey())
|
||||
|
||||
return res, nil
|
||||
return &res, nil
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue