[#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:
Leonard Lyubich 2021-12-02 15:21:54 +03:00 committed by Alex Vanin
parent 596774ce5b
commit 213d20e3fb
13 changed files with 1100 additions and 885 deletions

View file

@ -6,7 +6,6 @@ import (
v2reputation "github.com/nspcc-dev/neofs-api-go/v2/reputation"
rpcapi "github.com/nspcc-dev/neofs-api-go/v2/rpc"
"github.com/nspcc-dev/neofs-api-go/v2/rpc/client"
v2signature "github.com/nspcc-dev/neofs-api-go/v2/signature"
"github.com/nspcc-dev/neofs-sdk-go/reputation"
)
@ -14,26 +13,20 @@ import (
type AnnounceLocalTrustPrm struct {
epoch uint64
trusts []*reputation.Trust
trusts []reputation.Trust
}
// Epoch returns epoch in which the trust was assessed.
func (x AnnounceLocalTrustPrm) Epoch() uint64 {
return x.epoch
}
// SetEpoch sets epoch in which the trust was assessed.
// SetEpoch sets number of NeoFS epoch in which the trust was assessed.
// Required parameter, must not be zero.
func (x *AnnounceLocalTrustPrm) SetEpoch(epoch uint64) {
x.epoch = epoch
}
// Trusts returns list of local trust values.
func (x AnnounceLocalTrustPrm) Trusts() []*reputation.Trust {
return x.trusts
}
// SetTrusts sets list of local trust values.
func (x *AnnounceLocalTrustPrm) SetTrusts(trusts []*reputation.Trust) {
// SetValues sets values describing trust of the client to the NeoFS network participants.
// Required parameter. Must not be empty.
//
// Must not be mutated before the end of the operation.
func (x *AnnounceLocalTrustPrm) SetValues(trusts []reputation.Trust) {
x.trusts = trusts
}
@ -42,59 +35,66 @@ type AnnounceLocalTrustRes struct {
statusRes
}
// AnnounceLocalTrust announces node's local trusts through NeoFS API call.
// AnnounceLocalTrust sends client's trust values to the NeoFS network participants.
//
// 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.
func (c *Client) AnnounceLocalTrust(ctx context.Context, prm AnnounceLocalTrustPrm, opts ...CallOption) (*AnnounceLocalTrustRes, error) {
// apply all available options
callOptions := c.defaultCallOptions()
for i := range opts {
opts[i](callOptions)
//
// Immediately panics if parameters are set incorrectly (see AnnounceLocalTrustPrm 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 AnnounceLocalTrustRes.
// Reflects all internal errors in second return value (transport problems, response processing, etc.).
func (c *Client) AnnounceLocalTrust(ctx context.Context, prm AnnounceLocalTrustPrm) (*AnnounceLocalTrustRes, error) {
// check parameters
switch {
case ctx == nil:
panic(panicMsgMissingContext)
case prm.epoch == 0:
panic("zero epoch")
case len(prm.trusts) == 0:
panic("missing trusts")
}
// form request body
reqBody := new(v2reputation.AnnounceLocalTrustRequestBody)
reqBody.SetEpoch(prm.Epoch())
reqBody.SetTrusts(reputation.TrustsToV2(prm.Trusts()))
reqBody.SetEpoch(prm.epoch)
trusts := make([]*reputation.Trust, 0, len(prm.trusts))
for i := range prm.trusts {
trusts = append(trusts, &prm.trusts[i])
}
reqBody.SetTrusts(reputation.TrustsToV2(trusts))
// form request
var req v2reputation.AnnounceLocalTrustRequest
req := new(v2reputation.AnnounceLocalTrustRequest)
req.SetBody(reqBody)
req.SetMetaHeader(v2MetaHeaderFromOpts(callOptions))
err := v2signature.SignServiceMessage(callOptions.key, req)
if err != nil {
return nil, err
}
resp, err := rpcapi.AnnounceLocalTrust(c.Raw(), req, client.WithContext(ctx))
if err != nil {
return nil, err
}
// init call context
var (
res = new(AnnounceLocalTrustRes)
procPrm processResponseV2Prm
procRes processResponseV2Res
cc contextCall
res AnnounceLocalTrustRes
)
procPrm.callOpts = callOptions
procPrm.resp = resp
procRes.statusRes = res
// process response in general
if c.processResponseV2(&procRes, procPrm) {
if procRes.cliErr != nil {
return nil, procRes.cliErr
}
return res, nil
c.initCallContext(&cc)
cc.req = &req
cc.statusRes = &res
cc.call = func() (responseV2, error) {
return rpcapi.AnnounceLocalTrust(c.Raw(), &req, client.WithContext(ctx))
}
return res, nil
// process call
if !cc.processCall() {
return nil, cc.err
}
return &res, nil
}
// AnnounceIntermediateTrustPrm groups parameters of AnnounceIntermediateTrust operation.
@ -103,35 +103,27 @@ type AnnounceIntermediateTrustPrm struct {
iter uint32
trust *reputation.PeerToPeerTrust
}
func (x *AnnounceIntermediateTrustPrm) Epoch() uint64 {
return x.epoch
trustSet bool
trust reputation.PeerToPeerTrust
}
// SetEpoch sets number of NeoFS epoch with which client's calculation algorithm is initialized.
// Required parameter, must not be zero.
func (x *AnnounceIntermediateTrustPrm) SetEpoch(epoch uint64) {
x.epoch = epoch
}
// Iteration returns sequence number of the iteration.
func (x AnnounceIntermediateTrustPrm) Iteration() uint32 {
return x.iter
}
// SetIteration sets sequence number of the iteration.
// SetIteration sets current sequence number of the client's calculation algorithm.
// By default, corresponds to initial (zero) iteration.
func (x *AnnounceIntermediateTrustPrm) SetIteration(iter uint32) {
x.iter = iter
}
// Trust returns current global trust value computed at the specified iteration.
func (x AnnounceIntermediateTrustPrm) Trust() *reputation.PeerToPeerTrust {
return x.trust
}
// SetTrust sets current global trust value computed at the specified iteration.
func (x *AnnounceIntermediateTrustPrm) SetTrust(trust *reputation.PeerToPeerTrust) {
// SetCurrentValue sets current global trust value computed at the specified iteration
//of the client's calculation algorithm. Required parameter.
func (x *AnnounceIntermediateTrustPrm) SetCurrentValue(trust reputation.PeerToPeerTrust) {
x.trust = trust
x.trustSet = true
}
// AnnounceIntermediateTrustRes groups results of AnnounceIntermediateTrust operation.
@ -139,58 +131,59 @@ type AnnounceIntermediateTrustRes struct {
statusRes
}
// AnnounceIntermediateTrust announces node's intermediate trusts through NeoFS API call.
// AnnounceIntermediateTrust sends global trust values calculated for the specified NeoFS network participants
// at some stage of client's calculation algorithm.
//
// 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.
func (c *Client) AnnounceIntermediateTrust(ctx context.Context, prm AnnounceIntermediateTrustPrm, opts ...CallOption) (*AnnounceIntermediateTrustRes, error) {
// apply all available options
callOptions := c.defaultCallOptions()
for i := range opts {
opts[i](callOptions)
//
// Immediately panics if parameters are set incorrectly (see AnnounceIntermediateTrustPrm 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 AnnounceIntermediateTrustRes.
// Reflects all internal errors in second return value (transport problems, response processing, etc.).
func (c *Client) AnnounceIntermediateTrust(ctx context.Context, prm AnnounceIntermediateTrustPrm) (*AnnounceIntermediateTrustRes, error) {
// check parameters
switch {
case ctx == nil:
panic(panicMsgMissingContext)
case prm.epoch == 0:
panic("zero epoch")
case !prm.trustSet:
panic("current trust value not set")
}
// form request body
reqBody := new(v2reputation.AnnounceIntermediateResultRequestBody)
reqBody.SetEpoch(prm.Epoch())
reqBody.SetIteration(prm.Iteration())
reqBody.SetTrust(prm.Trust().ToV2())
reqBody.SetEpoch(prm.epoch)
reqBody.SetIteration(prm.iter)
reqBody.SetTrust(prm.trust.ToV2())
// form request
var req v2reputation.AnnounceIntermediateResultRequest
req := new(v2reputation.AnnounceIntermediateResultRequest)
req.SetBody(reqBody)
req.SetMetaHeader(v2MetaHeaderFromOpts(callOptions))
err := v2signature.SignServiceMessage(callOptions.key, req)
if err != nil {
return nil, err
}
resp, err := rpcapi.AnnounceIntermediateResult(c.Raw(), req, client.WithContext(ctx))
if err != nil {
return nil, err
}
// init call context
var (
res = new(AnnounceIntermediateTrustRes)
procPrm processResponseV2Prm
procRes processResponseV2Res
cc contextCall
res AnnounceIntermediateTrustRes
)
procPrm.callOpts = callOptions
procPrm.resp = resp
procRes.statusRes = res
// process response in general
if c.processResponseV2(&procRes, procPrm) {
if procRes.cliErr != nil {
return nil, procRes.cliErr
}
return res, nil
c.initCallContext(&cc)
cc.req = &req
cc.statusRes = &res
cc.call = func() (responseV2, error) {
return rpcapi.AnnounceIntermediateResult(c.Raw(), &req, client.WithContext(ctx))
}
return res, nil
// process call
if !cc.processCall() {
return nil, cc.err
}
return &res, nil
}