Assume API supports status codes #547
13 changed files with 59 additions and 91 deletions
4
go.mod
4
go.mod
|
@ -3,10 +3,10 @@ module git.frostfs.info/TrueCloudLab/frostfs-node
|
||||||
go 1.19
|
go 1.19
|
||||||
|
|
||||||
require (
|
require (
|
||||||
git.frostfs.info/TrueCloudLab/frostfs-api-go/v2 v2.15.1-0.20230719100335-582d94c81c74
|
git.frostfs.info/TrueCloudLab/frostfs-api-go/v2 v2.15.1-0.20230726155259-7a5ee927c8a2
|
||||||
git.frostfs.info/TrueCloudLab/frostfs-contract v0.0.0-20230627134746-36f3d39c406a
|
git.frostfs.info/TrueCloudLab/frostfs-contract v0.0.0-20230627134746-36f3d39c406a
|
||||||
git.frostfs.info/TrueCloudLab/frostfs-observability v0.0.0-20230531082742-c97d21411eb6
|
git.frostfs.info/TrueCloudLab/frostfs-observability v0.0.0-20230531082742-c97d21411eb6
|
||||||
git.frostfs.info/TrueCloudLab/frostfs-sdk-go v0.0.0-20230719130356-5defed4ab435
|
git.frostfs.info/TrueCloudLab/frostfs-sdk-go v0.0.0-20230731113339-0fe0d716784b
|
||||||
git.frostfs.info/TrueCloudLab/hrw v1.2.1
|
git.frostfs.info/TrueCloudLab/hrw v1.2.1
|
||||||
git.frostfs.info/TrueCloudLab/tzhash v1.8.0
|
git.frostfs.info/TrueCloudLab/tzhash v1.8.0
|
||||||
github.com/cheggaaa/pb v1.0.29
|
github.com/cheggaaa/pb v1.0.29
|
||||||
|
|
BIN
go.sum
BIN
go.sum
Binary file not shown.
|
@ -111,6 +111,7 @@ func (db *DB) put(tx *bbolt.Tx,
|
||||||
|
|
||||||
exists, err := db.exists(tx, objectCore.AddressOf(obj), currEpoch)
|
exists, err := db.exists(tx, objectCore.AddressOf(obj), currEpoch)
|
||||||
|
|
||||||
|
var splitInfoError *objectSDK.SplitInfoError
|
||||||
if errors.As(err, &splitInfoError) {
|
if errors.As(err, &splitInfoError) {
|
||||||
exists = true // object exists, however it is virtual
|
exists = true // object exists, however it is virtual
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
|
|
|
@ -427,6 +427,7 @@ func (db *DB) selectObjectID(
|
||||||
addr.SetContainer(cnr)
|
addr.SetContainer(cnr)
|
||||||
addr.SetObject(id)
|
addr.SetObject(id)
|
||||||
|
|
||||||
|
var splitInfoError *objectSDK.SplitInfoError
|
||||||
ok, err := db.exists(tx, addr, currEpoch)
|
ok, err := db.exists(tx, addr, currEpoch)
|
||||||
if (err == nil && ok) || errors.As(err, &splitInfoError) {
|
if (err == nil && ok) || errors.As(err, &splitInfoError) {
|
||||||
raw := make([]byte, objectKeySize)
|
raw := make([]byte, objectKeySize)
|
||||||
|
|
|
@ -120,8 +120,6 @@ const (
|
||||||
addressKeySize = cidSize + objectKeySize
|
addressKeySize = cidSize + objectKeySize
|
||||||
)
|
)
|
||||||
|
|
||||||
var splitInfoError *objectSDK.SplitInfoError // for errors.As comparisons
|
|
||||||
|
|
||||||
func bucketName(cnr cid.ID, prefix byte, key []byte) []byte {
|
func bucketName(cnr cid.ID, prefix byte, key []byte) []byte {
|
||||||
key[0] = prefix
|
key[0] = prefix
|
||||||
cnr.Encode(key[1:])
|
cnr.Encode(key[1:])
|
||||||
|
|
|
@ -23,5 +23,5 @@ func NewSignService(key *ecdsa.PrivateKey, svc Server) Server {
|
||||||
|
|
||||||
func (s *signService) Balance(ctx context.Context, req *accounting.BalanceRequest) (*accounting.BalanceResponse, error) {
|
func (s *signService) Balance(ctx context.Context, req *accounting.BalanceRequest) (*accounting.BalanceResponse, error) {
|
||||||
resp, err := util.EnsureNonNilResponse(s.svc.Balance(ctx, req))
|
resp, err := util.EnsureNonNilResponse(s.svc.Balance(ctx, req))
|
||||||
return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err)
|
return resp, s.sigSvc.SignResponse(resp, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,62 +24,62 @@ func NewSignService(key *ecdsa.PrivateKey, svc Server) Server {
|
||||||
func (s *signService) Put(ctx context.Context, req *container.PutRequest) (*container.PutResponse, error) {
|
func (s *signService) Put(ctx context.Context, req *container.PutRequest) (*container.PutResponse, error) {
|
||||||
if err := s.sigSvc.VerifyRequest(req); err != nil {
|
if err := s.sigSvc.VerifyRequest(req); err != nil {
|
||||||
resp := new(container.PutResponse)
|
resp := new(container.PutResponse)
|
||||||
return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err)
|
return resp, s.sigSvc.SignResponse(resp, err)
|
||||||
}
|
}
|
||||||
resp, err := util.EnsureNonNilResponse(s.svc.Put(ctx, req))
|
resp, err := util.EnsureNonNilResponse(s.svc.Put(ctx, req))
|
||||||
return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err)
|
return resp, s.sigSvc.SignResponse(resp, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *signService) Delete(ctx context.Context, req *container.DeleteRequest) (*container.DeleteResponse, error) {
|
func (s *signService) Delete(ctx context.Context, req *container.DeleteRequest) (*container.DeleteResponse, error) {
|
||||||
if err := s.sigSvc.VerifyRequest(req); err != nil {
|
if err := s.sigSvc.VerifyRequest(req); err != nil {
|
||||||
resp := new(container.DeleteResponse)
|
resp := new(container.DeleteResponse)
|
||||||
return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err)
|
return resp, s.sigSvc.SignResponse(resp, err)
|
||||||
}
|
}
|
||||||
resp, err := util.EnsureNonNilResponse(s.svc.Delete(ctx, req))
|
resp, err := util.EnsureNonNilResponse(s.svc.Delete(ctx, req))
|
||||||
return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err)
|
return resp, s.sigSvc.SignResponse(resp, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *signService) Get(ctx context.Context, req *container.GetRequest) (*container.GetResponse, error) {
|
func (s *signService) Get(ctx context.Context, req *container.GetRequest) (*container.GetResponse, error) {
|
||||||
if err := s.sigSvc.VerifyRequest(req); err != nil {
|
if err := s.sigSvc.VerifyRequest(req); err != nil {
|
||||||
resp := new(container.GetResponse)
|
resp := new(container.GetResponse)
|
||||||
return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err)
|
return resp, s.sigSvc.SignResponse(resp, err)
|
||||||
}
|
}
|
||||||
resp, err := util.EnsureNonNilResponse(s.svc.Get(ctx, req))
|
resp, err := util.EnsureNonNilResponse(s.svc.Get(ctx, req))
|
||||||
return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err)
|
return resp, s.sigSvc.SignResponse(resp, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *signService) List(ctx context.Context, req *container.ListRequest) (*container.ListResponse, error) {
|
func (s *signService) List(ctx context.Context, req *container.ListRequest) (*container.ListResponse, error) {
|
||||||
if err := s.sigSvc.VerifyRequest(req); err != nil {
|
if err := s.sigSvc.VerifyRequest(req); err != nil {
|
||||||
resp := new(container.ListResponse)
|
resp := new(container.ListResponse)
|
||||||
return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err)
|
return resp, s.sigSvc.SignResponse(resp, err)
|
||||||
}
|
}
|
||||||
resp, err := util.EnsureNonNilResponse(s.svc.List(ctx, req))
|
resp, err := util.EnsureNonNilResponse(s.svc.List(ctx, req))
|
||||||
return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err)
|
return resp, s.sigSvc.SignResponse(resp, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *signService) SetExtendedACL(ctx context.Context, req *container.SetExtendedACLRequest) (*container.SetExtendedACLResponse, error) {
|
func (s *signService) SetExtendedACL(ctx context.Context, req *container.SetExtendedACLRequest) (*container.SetExtendedACLResponse, error) {
|
||||||
if err := s.sigSvc.VerifyRequest(req); err != nil {
|
if err := s.sigSvc.VerifyRequest(req); err != nil {
|
||||||
resp := new(container.SetExtendedACLResponse)
|
resp := new(container.SetExtendedACLResponse)
|
||||||
return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err)
|
return resp, s.sigSvc.SignResponse(resp, err)
|
||||||
}
|
}
|
||||||
resp, err := util.EnsureNonNilResponse(s.svc.SetExtendedACL(ctx, req))
|
resp, err := util.EnsureNonNilResponse(s.svc.SetExtendedACL(ctx, req))
|
||||||
return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err)
|
return resp, s.sigSvc.SignResponse(resp, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *signService) GetExtendedACL(ctx context.Context, req *container.GetExtendedACLRequest) (*container.GetExtendedACLResponse, error) {
|
func (s *signService) GetExtendedACL(ctx context.Context, req *container.GetExtendedACLRequest) (*container.GetExtendedACLResponse, error) {
|
||||||
if err := s.sigSvc.VerifyRequest(req); err != nil {
|
if err := s.sigSvc.VerifyRequest(req); err != nil {
|
||||||
resp := new(container.GetExtendedACLResponse)
|
resp := new(container.GetExtendedACLResponse)
|
||||||
return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err)
|
return resp, s.sigSvc.SignResponse(resp, err)
|
||||||
}
|
}
|
||||||
resp, err := util.EnsureNonNilResponse(s.svc.GetExtendedACL(ctx, req))
|
resp, err := util.EnsureNonNilResponse(s.svc.GetExtendedACL(ctx, req))
|
||||||
return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err)
|
return resp, s.sigSvc.SignResponse(resp, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *signService) AnnounceUsedSpace(ctx context.Context, req *container.AnnounceUsedSpaceRequest) (*container.AnnounceUsedSpaceResponse, error) {
|
func (s *signService) AnnounceUsedSpace(ctx context.Context, req *container.AnnounceUsedSpaceRequest) (*container.AnnounceUsedSpaceResponse, error) {
|
||||||
if err := s.sigSvc.VerifyRequest(req); err != nil {
|
if err := s.sigSvc.VerifyRequest(req); err != nil {
|
||||||
resp := new(container.AnnounceUsedSpaceResponse)
|
resp := new(container.AnnounceUsedSpaceResponse)
|
||||||
return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err)
|
return resp, s.sigSvc.SignResponse(resp, err)
|
||||||
}
|
}
|
||||||
resp, err := util.EnsureNonNilResponse(s.svc.AnnounceUsedSpace(ctx, req))
|
resp, err := util.EnsureNonNilResponse(s.svc.AnnounceUsedSpace(ctx, req))
|
||||||
return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err)
|
return resp, s.sigSvc.SignResponse(resp, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,26 +26,26 @@ func (s *signService) LocalNodeInfo(
|
||||||
req *netmap.LocalNodeInfoRequest) (*netmap.LocalNodeInfoResponse, error) {
|
req *netmap.LocalNodeInfoRequest) (*netmap.LocalNodeInfoResponse, error) {
|
||||||
if err := s.sigSvc.VerifyRequest(req); err != nil {
|
if err := s.sigSvc.VerifyRequest(req); err != nil {
|
||||||
resp := new(netmap.LocalNodeInfoResponse)
|
resp := new(netmap.LocalNodeInfoResponse)
|
||||||
return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err)
|
return resp, s.sigSvc.SignResponse(resp, err)
|
||||||
}
|
}
|
||||||
resp, err := util.EnsureNonNilResponse(s.svc.LocalNodeInfo(ctx, req))
|
resp, err := util.EnsureNonNilResponse(s.svc.LocalNodeInfo(ctx, req))
|
||||||
return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err)
|
return resp, s.sigSvc.SignResponse(resp, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *signService) NetworkInfo(ctx context.Context, req *netmap.NetworkInfoRequest) (*netmap.NetworkInfoResponse, error) {
|
func (s *signService) NetworkInfo(ctx context.Context, req *netmap.NetworkInfoRequest) (*netmap.NetworkInfoResponse, error) {
|
||||||
if err := s.sigSvc.VerifyRequest(req); err != nil {
|
if err := s.sigSvc.VerifyRequest(req); err != nil {
|
||||||
resp := new(netmap.NetworkInfoResponse)
|
resp := new(netmap.NetworkInfoResponse)
|
||||||
return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err)
|
return resp, s.sigSvc.SignResponse(resp, err)
|
||||||
}
|
}
|
||||||
resp, err := util.EnsureNonNilResponse(s.svc.NetworkInfo(ctx, req))
|
resp, err := util.EnsureNonNilResponse(s.svc.NetworkInfo(ctx, req))
|
||||||
return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err)
|
return resp, s.sigSvc.SignResponse(resp, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *signService) Snapshot(ctx context.Context, req *netmap.SnapshotRequest) (*netmap.SnapshotResponse, error) {
|
func (s *signService) Snapshot(ctx context.Context, req *netmap.SnapshotRequest) (*netmap.SnapshotResponse, error) {
|
||||||
if err := s.sigSvc.VerifyRequest(req); err != nil {
|
if err := s.sigSvc.VerifyRequest(req); err != nil {
|
||||||
resp := new(netmap.SnapshotResponse)
|
resp := new(netmap.SnapshotResponse)
|
||||||
return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err)
|
return resp, s.sigSvc.SignResponse(resp, err)
|
||||||
}
|
}
|
||||||
resp, err := util.EnsureNonNilResponse(s.svc.Snapshot(ctx, req))
|
resp, err := util.EnsureNonNilResponse(s.svc.Snapshot(ctx, req))
|
||||||
return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err)
|
return resp, s.sigSvc.SignResponse(resp, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,9 +47,6 @@ type traversal struct {
|
||||||
// need of additional broadcast after the object is saved
|
// need of additional broadcast after the object is saved
|
||||||
extraBroadcastEnabled bool
|
extraBroadcastEnabled bool
|
||||||
|
|
||||||
// mtx protects mExclude map.
|
|
||||||
mtx sync.RWMutex
|
|
||||||
|
|
||||||
// container nodes which was processed during the primary object placement
|
// container nodes which was processed during the primary object placement
|
||||||
mExclude map[string]struct{}
|
mExclude map[string]struct{}
|
||||||
}
|
}
|
||||||
|
@ -75,21 +72,17 @@ func (x *traversal) submitProcessed(n placement.Node) {
|
||||||
if x.extraBroadcastEnabled {
|
if x.extraBroadcastEnabled {
|
||||||
key := string(n.PublicKey())
|
key := string(n.PublicKey())
|
||||||
|
|
||||||
x.mtx.Lock()
|
|
||||||
if x.mExclude == nil {
|
if x.mExclude == nil {
|
||||||
x.mExclude = make(map[string]struct{}, 1)
|
x.mExclude = make(map[string]struct{}, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
x.mExclude[key] = struct{}{}
|
x.mExclude[key] = struct{}{}
|
||||||
x.mtx.Unlock()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// checks if specified node was processed during the primary object placement.
|
// checks if specified node was processed during the primary object placement.
|
||||||
func (x *traversal) processed(n placement.Node) bool {
|
func (x *traversal) processed(n placement.Node) bool {
|
||||||
x.mtx.RLock()
|
|
||||||
_, ok := x.mExclude[string(n.PublicKey())]
|
_, ok := x.mExclude[string(n.PublicKey())]
|
||||||
x.mtx.RUnlock()
|
|
||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,13 +228,6 @@ func (t *distributedTarget) iterateAddresses(ctx context.Context, traverser *pla
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
|
|
||||||
err := t.sendObject(ctx, nodeDesc{local: isLocal, info: addr})
|
err := t.sendObject(ctx, nodeDesc{local: isLocal, info: addr})
|
||||||
|
|
||||||
// mark the container node as processed in order to exclude it
|
|
||||||
// in subsequent container broadcast. Note that we don't
|
|
||||||
// process this node during broadcast if primary placement
|
|
||||||
// on it failed.
|
|
||||||
t.traversal.submitProcessed(addr)
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resErr.Store(err)
|
resErr.Store(err)
|
||||||
svcutil.LogServiceError(t.log, "PUT", addr.Addresses(), err)
|
svcutil.LogServiceError(t.log, "PUT", addr.Addresses(), err)
|
||||||
|
@ -254,6 +240,12 @@ func (t *distributedTarget) iterateAddresses(ctx context.Context, traverser *pla
|
||||||
svcutil.LogWorkerPoolError(t.log, "PUT", err)
|
svcutil.LogWorkerPoolError(t.log, "PUT", err)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mark the container node as processed in order to exclude it
|
||||||
|
// in subsequent container broadcast. Note that we don't
|
||||||
|
// process this node during broadcast if primary placement
|
||||||
|
// on it failed.
|
||||||
|
t.traversal.submitProcessed(addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
|
|
|
@ -152,7 +152,6 @@ func (s *Service) saveToNodes(ctx context.Context, obj *objectSDK.Object, req *o
|
||||||
opts: placementOptions,
|
opts: placementOptions,
|
||||||
extraBroadcastEnabled: len(obj.Children()) > 0 ||
|
extraBroadcastEnabled: len(obj.Children()) > 0 ||
|
||||||
(!localOnly && (obj.Type() == objectSDK.TypeTombstone || obj.Type() == objectSDK.TypeLock)),
|
(!localOnly && (obj.Type() == objectSDK.TypeTombstone || obj.Type() == objectSDK.TypeLock)),
|
||||||
mtx: sync.RWMutex{},
|
|
||||||
mExclude: make(map[string]struct{}),
|
mExclude: make(map[string]struct{}),
|
||||||
}
|
}
|
||||||
signer := &putSingleRequestSigner{
|
signer := &putSingleRequestSigner{
|
||||||
|
@ -261,8 +260,6 @@ func (s *Service) saveToPlacementNodes(ctx context.Context,
|
||||||
|
|
||||||
err := s.saveToPlacementNode(ctx, &nodeDesc{local: local, info: nodeAddress}, obj, signer)
|
err := s.saveToPlacementNode(ctx, &nodeDesc{local: local, info: nodeAddress}, obj, signer)
|
||||||
|
|
||||||
traversal.submitProcessed(nodeAddress)
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resultError.Store(err)
|
resultError.Store(err)
|
||||||
svcutil.LogServiceError(s.log, "PUT", nodeAddress.Addresses(), err)
|
svcutil.LogServiceError(s.log, "PUT", nodeAddress.Addresses(), err)
|
||||||
|
@ -275,6 +272,8 @@ func (s *Service) saveToPlacementNodes(ctx context.Context,
|
||||||
svcutil.LogWorkerPoolError(s.log, "PUT", err)
|
svcutil.LogWorkerPoolError(s.log, "PUT", err)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
traversal.submitProcessed(nodeAddress)
|
||||||
}
|
}
|
||||||
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
|
|
|
@ -19,29 +19,25 @@ type SignService struct {
|
||||||
|
|
||||||
type searchStreamSigner struct {
|
type searchStreamSigner struct {
|
||||||
SearchStream
|
SearchStream
|
||||||
statusSupported bool
|
sigSvc *util.SignService
|
||||||
sigSvc *util.SignService
|
|
||||||
|
|
||||||
nonEmptyResp bool // set on first Send call
|
nonEmptyResp bool // set on first Send call
|
||||||
}
|
}
|
||||||
|
|
||||||
type getStreamSigner struct {
|
type getStreamSigner struct {
|
||||||
GetObjectStream
|
GetObjectStream
|
||||||
statusSupported bool
|
sigSvc *util.SignService
|
||||||
sigSvc *util.SignService
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type putStreamSigner struct {
|
type putStreamSigner struct {
|
||||||
sigSvc *util.SignService
|
sigSvc *util.SignService
|
||||||
stream PutObjectStream
|
stream PutObjectStream
|
||||||
statusSupported bool
|
err error
|
||||||
err error
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type getRangeStreamSigner struct {
|
type getRangeStreamSigner struct {
|
||||||
GetObjectRangeStream
|
GetObjectRangeStream
|
||||||
statusSupported bool
|
sigSvc *util.SignService
|
||||||
sigSvc *util.SignService
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSignService(key *ecdsa.PrivateKey, svc ServiceServer) *SignService {
|
func NewSignService(key *ecdsa.PrivateKey, svc ServiceServer) *SignService {
|
||||||
|
@ -53,7 +49,7 @@ func NewSignService(key *ecdsa.PrivateKey, svc ServiceServer) *SignService {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *getStreamSigner) Send(resp *object.GetResponse) error {
|
func (s *getStreamSigner) Send(resp *object.GetResponse) error {
|
||||||
if err := s.sigSvc.SignResponse(s.statusSupported, resp, nil); err != nil {
|
if err := s.sigSvc.SignResponse(resp, nil); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return s.GetObjectStream.Send(resp)
|
return s.GetObjectStream.Send(resp)
|
||||||
|
@ -62,20 +58,17 @@ func (s *getStreamSigner) Send(resp *object.GetResponse) error {
|
||||||
func (s *SignService) Get(req *object.GetRequest, stream GetObjectStream) error {
|
func (s *SignService) Get(req *object.GetRequest, stream GetObjectStream) error {
|
||||||
if err := s.sigSvc.VerifyRequest(req); err != nil {
|
if err := s.sigSvc.VerifyRequest(req); err != nil {
|
||||||
resp := new(object.GetResponse)
|
resp := new(object.GetResponse)
|
||||||
_ = s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err)
|
_ = s.sigSvc.SignResponse(resp, err)
|
||||||
return stream.Send(resp)
|
return stream.Send(resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.svc.Get(req, &getStreamSigner{
|
return s.svc.Get(req, &getStreamSigner{
|
||||||
GetObjectStream: stream,
|
GetObjectStream: stream,
|
||||||
sigSvc: s.sigSvc,
|
sigSvc: s.sigSvc,
|
||||||
statusSupported: util.IsStatusSupported(req),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *putStreamSigner) Send(ctx context.Context, req *object.PutRequest) error {
|
func (s *putStreamSigner) Send(ctx context.Context, req *object.PutRequest) error {
|
||||||
s.statusSupported = util.IsStatusSupported(req)
|
|
||||||
|
|
||||||
if s.err = s.sigSvc.VerifyRequest(req); s.err != nil {
|
if s.err = s.sigSvc.VerifyRequest(req); s.err != nil {
|
||||||
return util.ErrAbortStream
|
return util.ErrAbortStream
|
||||||
}
|
}
|
||||||
|
@ -96,7 +89,7 @@ func (s *putStreamSigner) CloseAndRecv(ctx context.Context) (resp *object.PutRes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return resp, s.sigSvc.SignResponse(s.statusSupported, resp, err)
|
return resp, s.sigSvc.SignResponse(resp, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SignService) Put() (PutObjectStream, error) {
|
func (s *SignService) Put() (PutObjectStream, error) {
|
||||||
|
@ -114,24 +107,24 @@ func (s *SignService) Put() (PutObjectStream, error) {
|
||||||
func (s *SignService) Head(ctx context.Context, req *object.HeadRequest) (*object.HeadResponse, error) {
|
func (s *SignService) Head(ctx context.Context, req *object.HeadRequest) (*object.HeadResponse, error) {
|
||||||
if err := s.sigSvc.VerifyRequest(req); err != nil {
|
if err := s.sigSvc.VerifyRequest(req); err != nil {
|
||||||
resp := new(object.HeadResponse)
|
resp := new(object.HeadResponse)
|
||||||
return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err)
|
return resp, s.sigSvc.SignResponse(resp, err)
|
||||||
}
|
}
|
||||||
resp, err := util.EnsureNonNilResponse(s.svc.Head(ctx, req))
|
resp, err := util.EnsureNonNilResponse(s.svc.Head(ctx, req))
|
||||||
return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err)
|
return resp, s.sigSvc.SignResponse(resp, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SignService) PutSingle(ctx context.Context, req *object.PutSingleRequest) (*object.PutSingleResponse, error) {
|
func (s *SignService) PutSingle(ctx context.Context, req *object.PutSingleRequest) (*object.PutSingleResponse, error) {
|
||||||
if err := s.sigSvc.VerifyRequest(req); err != nil {
|
if err := s.sigSvc.VerifyRequest(req); err != nil {
|
||||||
resp := new(object.PutSingleResponse)
|
resp := new(object.PutSingleResponse)
|
||||||
return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err)
|
return resp, s.sigSvc.SignResponse(resp, err)
|
||||||
}
|
}
|
||||||
resp, err := util.EnsureNonNilResponse(s.svc.PutSingle(ctx, req))
|
resp, err := util.EnsureNonNilResponse(s.svc.PutSingle(ctx, req))
|
||||||
return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err)
|
return resp, s.sigSvc.SignResponse(resp, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *searchStreamSigner) Send(resp *object.SearchResponse) error {
|
func (s *searchStreamSigner) Send(resp *object.SearchResponse) error {
|
||||||
s.nonEmptyResp = true
|
s.nonEmptyResp = true
|
||||||
if err := s.sigSvc.SignResponse(s.statusSupported, resp, nil); err != nil {
|
if err := s.sigSvc.SignResponse(resp, nil); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return s.SearchStream.Send(resp)
|
return s.SearchStream.Send(resp)
|
||||||
|
@ -140,14 +133,13 @@ func (s *searchStreamSigner) Send(resp *object.SearchResponse) error {
|
||||||
func (s *SignService) Search(req *object.SearchRequest, stream SearchStream) error {
|
func (s *SignService) Search(req *object.SearchRequest, stream SearchStream) error {
|
||||||
if err := s.sigSvc.VerifyRequest(req); err != nil {
|
if err := s.sigSvc.VerifyRequest(req); err != nil {
|
||||||
resp := new(object.SearchResponse)
|
resp := new(object.SearchResponse)
|
||||||
_ = s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err)
|
_ = s.sigSvc.SignResponse(resp, err)
|
||||||
return stream.Send(resp)
|
return stream.Send(resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
ss := &searchStreamSigner{
|
ss := &searchStreamSigner{
|
||||||
SearchStream: stream,
|
SearchStream: stream,
|
||||||
sigSvc: s.sigSvc,
|
sigSvc: s.sigSvc,
|
||||||
statusSupported: util.IsStatusSupported(req),
|
|
||||||
}
|
}
|
||||||
err := s.svc.Search(req, ss)
|
err := s.svc.Search(req, ss)
|
||||||
if err == nil && !ss.nonEmptyResp {
|
if err == nil && !ss.nonEmptyResp {
|
||||||
|
@ -164,14 +156,14 @@ func (s *SignService) Search(req *object.SearchRequest, stream SearchStream) err
|
||||||
func (s *SignService) Delete(ctx context.Context, req *object.DeleteRequest) (*object.DeleteResponse, error) {
|
func (s *SignService) Delete(ctx context.Context, req *object.DeleteRequest) (*object.DeleteResponse, error) {
|
||||||
if err := s.sigSvc.VerifyRequest(req); err != nil {
|
if err := s.sigSvc.VerifyRequest(req); err != nil {
|
||||||
resp := new(object.DeleteResponse)
|
resp := new(object.DeleteResponse)
|
||||||
return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err)
|
return resp, s.sigSvc.SignResponse(resp, err)
|
||||||
}
|
}
|
||||||
resp, err := util.EnsureNonNilResponse(s.svc.Delete(ctx, req))
|
resp, err := util.EnsureNonNilResponse(s.svc.Delete(ctx, req))
|
||||||
return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err)
|
return resp, s.sigSvc.SignResponse(resp, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *getRangeStreamSigner) Send(resp *object.GetRangeResponse) error {
|
func (s *getRangeStreamSigner) Send(resp *object.GetRangeResponse) error {
|
||||||
if err := s.sigSvc.SignResponse(s.statusSupported, resp, nil); err != nil {
|
if err := s.sigSvc.SignResponse(resp, nil); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return s.GetObjectRangeStream.Send(resp)
|
return s.GetObjectRangeStream.Send(resp)
|
||||||
|
@ -180,22 +172,21 @@ func (s *getRangeStreamSigner) Send(resp *object.GetRangeResponse) error {
|
||||||
func (s *SignService) GetRange(req *object.GetRangeRequest, stream GetObjectRangeStream) error {
|
func (s *SignService) GetRange(req *object.GetRangeRequest, stream GetObjectRangeStream) error {
|
||||||
if err := s.sigSvc.VerifyRequest(req); err != nil {
|
if err := s.sigSvc.VerifyRequest(req); err != nil {
|
||||||
resp := new(object.GetRangeResponse)
|
resp := new(object.GetRangeResponse)
|
||||||
_ = s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err)
|
_ = s.sigSvc.SignResponse(resp, err)
|
||||||
return stream.Send(resp)
|
return stream.Send(resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.svc.GetRange(req, &getRangeStreamSigner{
|
return s.svc.GetRange(req, &getRangeStreamSigner{
|
||||||
GetObjectRangeStream: stream,
|
GetObjectRangeStream: stream,
|
||||||
sigSvc: s.sigSvc,
|
sigSvc: s.sigSvc,
|
||||||
statusSupported: util.IsStatusSupported(req),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SignService) GetRangeHash(ctx context.Context, req *object.GetRangeHashRequest) (*object.GetRangeHashResponse, error) {
|
func (s *SignService) GetRangeHash(ctx context.Context, req *object.GetRangeHashRequest) (*object.GetRangeHashResponse, error) {
|
||||||
if err := s.sigSvc.VerifyRequest(req); err != nil {
|
if err := s.sigSvc.VerifyRequest(req); err != nil {
|
||||||
resp := new(object.GetRangeHashResponse)
|
resp := new(object.GetRangeHashResponse)
|
||||||
return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err)
|
return resp, s.sigSvc.SignResponse(resp, err)
|
||||||
}
|
}
|
||||||
resp, err := util.EnsureNonNilResponse(s.svc.GetRangeHash(ctx, req))
|
resp, err := util.EnsureNonNilResponse(s.svc.GetRangeHash(ctx, req))
|
||||||
return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err)
|
return resp, s.sigSvc.SignResponse(resp, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,8 +24,8 @@ func NewSignService(key *ecdsa.PrivateKey, svc Server) Server {
|
||||||
func (s *signService) Create(ctx context.Context, req *session.CreateRequest) (*session.CreateResponse, error) {
|
func (s *signService) Create(ctx context.Context, req *session.CreateRequest) (*session.CreateResponse, error) {
|
||||||
if err := s.sigSvc.VerifyRequest(req); err != nil {
|
if err := s.sigSvc.VerifyRequest(req); err != nil {
|
||||||
resp := new(session.CreateResponse)
|
resp := new(session.CreateResponse)
|
||||||
return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err)
|
return resp, s.sigSvc.SignResponse(resp, err)
|
||||||
}
|
}
|
||||||
resp, err := util.EnsureNonNilResponse(s.svc.Create(ctx, req))
|
resp, err := util.EnsureNonNilResponse(s.svc.Create(ctx, req))
|
||||||
return resp, s.sigSvc.SignResponse(util.IsStatusSupported(req), resp, err)
|
return resp, s.sigSvc.SignResponse(resp, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,12 +36,8 @@ func NewUnarySignService(key *ecdsa.PrivateKey) *SignService {
|
||||||
// The signature error affects the result depending on the protocol version:
|
// The signature error affects the result depending on the protocol version:
|
||||||
// - if status return is supported, panics since we cannot return the failed status, because it will not be signed.
|
// - if status return is supported, panics since we cannot return the failed status, because it will not be signed.
|
||||||
// - otherwise, returns error in order to transport it directly.
|
// - otherwise, returns error in order to transport it directly.
|
||||||
func (s *SignService) SignResponse(statusSupported bool, resp ResponseMessage, err error) error {
|
func (s *SignService) SignResponse(resp ResponseMessage, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !statusSupported {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
setStatusV2(resp, err)
|
setStatusV2(resp, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,16 +66,6 @@ func EnsureNonNilResponse[T any](resp *T, err error) (*T, error) {
|
||||||
return new(T), err
|
return new(T), err
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsStatusSupported returns true iff request version implies expecting status return.
|
|
||||||
// This allows us to handle protocol versions <=2.10 (API statuses was introduced in 2.11 only).
|
|
||||||
func IsStatusSupported(req RequestMessage) bool {
|
|
||||||
version := req.GetMetaHeader().GetVersion()
|
|
||||||
|
|
||||||
mjr := version.GetMajor()
|
|
||||||
|
|
||||||
return mjr > 2 || mjr == 2 && version.GetMinor() >= 11
|
|
||||||
}
|
|
||||||
|
|
||||||
func setStatusV2(resp ResponseMessage, err error) {
|
func setStatusV2(resp ResponseMessage, err error) {
|
||||||
// unwrap error
|
// unwrap error
|
||||||
for e := errors.Unwrap(err); e != nil; e = errors.Unwrap(err) {
|
for e := errors.Unwrap(err); e != nil; e = errors.Unwrap(err) {
|
||||||
|
|
Loading…
Reference in a new issue