bf78cddf69
Make all `Client` methods to return structured values and error. Parse v2 status messages in all RPC and provide status getter from all result structures. Returns status failures as status result instead of error. Interface changes: * all methods return `<method>Res` structure; * rename some methods to be more clear; * unify TZ and SHA256 objecy payload hashing in single method. Behavior changes: * client doesn't verify object header structure received via Object.Head. If the caller was tied to verification, now it must do it explicitly. Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
176 lines
4.2 KiB
Go
176 lines
4.2 KiB
Go
package client
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
v2netmap "github.com/nspcc-dev/neofs-api-go/v2/netmap"
|
|
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/netmap"
|
|
"github.com/nspcc-dev/neofs-sdk-go/version"
|
|
)
|
|
|
|
// Netmap contains methods related to netmap.
|
|
type Netmap interface {
|
|
// EndpointInfo returns attributes, address and public key of the node, specified
|
|
// in client constructor via address or open connection. This can be used as a
|
|
// health check to see if node is alive and responses to requests.
|
|
EndpointInfo(context.Context, ...CallOption) (*EndpointInfoRes, error)
|
|
|
|
// NetworkInfo returns information about the NeoFS network of which the remote server is a part.
|
|
NetworkInfo(context.Context, ...CallOption) (*NetworkInfoRes, error)
|
|
}
|
|
|
|
// EACLWithSignature represents eACL table/signature pair.
|
|
type EndpointInfo struct {
|
|
version *version.Version
|
|
|
|
ni *netmap.NodeInfo
|
|
}
|
|
|
|
// LatestVersion returns latest NeoFS API version in use.
|
|
func (e *EndpointInfo) LatestVersion() *version.Version {
|
|
return e.version
|
|
}
|
|
|
|
// NodeInfo returns returns information about the NeoFS node.
|
|
func (e *EndpointInfo) NodeInfo() *netmap.NodeInfo {
|
|
return e.ni
|
|
}
|
|
|
|
type EndpointInfoRes struct {
|
|
statusRes
|
|
|
|
info *EndpointInfo
|
|
}
|
|
|
|
func (x EndpointInfoRes) Info() *EndpointInfo {
|
|
return x.info
|
|
}
|
|
|
|
func (x *EndpointInfoRes) setInfo(info *EndpointInfo) {
|
|
x.info = info
|
|
}
|
|
|
|
// EndpointInfo returns attributes, address and public key of the node, specified
|
|
// in client constructor via address or open connection. This can be used as a
|
|
// health check to see if node is alive and responses to requests.
|
|
func (c *clientImpl) EndpointInfo(ctx context.Context, opts ...CallOption) (*EndpointInfoRes, error) {
|
|
// apply all available options
|
|
callOptions := c.defaultCallOptions()
|
|
|
|
for i := range opts {
|
|
opts[i](callOptions)
|
|
}
|
|
|
|
reqBody := new(v2netmap.LocalNodeInfoRequestBody)
|
|
|
|
req := new(v2netmap.LocalNodeInfoRequest)
|
|
req.SetBody(reqBody)
|
|
req.SetMetaHeader(v2MetaHeaderFromOpts(callOptions))
|
|
|
|
err := v2signature.SignServiceMessage(callOptions.key, req)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
resp, err := rpcapi.LocalNodeInfo(c.Raw(), req)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("transport error: %w", err)
|
|
}
|
|
|
|
var (
|
|
res = new(EndpointInfoRes)
|
|
procPrm processResponseV2Prm
|
|
procRes processResponseV2Res
|
|
)
|
|
|
|
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
|
|
}
|
|
|
|
body := resp.GetBody()
|
|
|
|
res.setInfo(&EndpointInfo{
|
|
version: version.NewFromV2(body.GetVersion()),
|
|
ni: netmap.NewNodeInfoFromV2(body.GetNodeInfo()),
|
|
})
|
|
|
|
return res, nil
|
|
}
|
|
|
|
type NetworkInfoRes struct {
|
|
statusRes
|
|
|
|
info *netmap.NetworkInfo
|
|
}
|
|
|
|
func (x NetworkInfoRes) Info() *netmap.NetworkInfo {
|
|
return x.info
|
|
}
|
|
|
|
func (x *NetworkInfoRes) setInfo(info *netmap.NetworkInfo) {
|
|
x.info = info
|
|
}
|
|
|
|
// NetworkInfo returns information about the NeoFS network of which the remote server is a part.
|
|
func (c *clientImpl) NetworkInfo(ctx context.Context, opts ...CallOption) (*NetworkInfoRes, error) {
|
|
// apply all available options
|
|
callOptions := c.defaultCallOptions()
|
|
|
|
for i := range opts {
|
|
opts[i](callOptions)
|
|
}
|
|
|
|
reqBody := new(v2netmap.NetworkInfoRequestBody)
|
|
|
|
req := new(v2netmap.NetworkInfoRequest)
|
|
req.SetBody(reqBody)
|
|
req.SetMetaHeader(v2MetaHeaderFromOpts(callOptions))
|
|
|
|
err := v2signature.SignServiceMessage(callOptions.key, req)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
resp, err := rpcapi.NetworkInfo(c.Raw(), req, client.WithContext(ctx))
|
|
if err != nil {
|
|
return nil, fmt.Errorf("v2 NetworkInfo RPC failure: %w", err)
|
|
}
|
|
|
|
var (
|
|
res = new(NetworkInfoRes)
|
|
procPrm processResponseV2Prm
|
|
procRes processResponseV2Res
|
|
)
|
|
|
|
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
|
|
}
|
|
|
|
res.setInfo(netmap.NewNetworkInfoFromV2(resp.GetBody().GetNetworkInfo()))
|
|
|
|
return res, nil
|
|
}
|