frostfs-node/pkg/services/object/put/remote.go
Alex Vanin 16f13bc0a5 [#522] Use HostAddrString as RPC endpoint instead of IPAddrString
To enable TLS support we can't operate with IP addresses directly.
Certificates are issued with host names so it is required to
pass them into RPC client. DNS resolving should be done by transport
layer and not be a part of node. Therefore `IPAddrString` usage is
removed from code.

Signed-off-by: Alex Vanin <alexey@nspcc.ru>
2021-05-18 12:07:00 +03:00

127 lines
2.9 KiB
Go

package putsvc
import (
"context"
"github.com/nspcc-dev/neofs-api-go/pkg/client"
"github.com/nspcc-dev/neofs-node/pkg/core/object"
"github.com/nspcc-dev/neofs-node/pkg/network"
"github.com/nspcc-dev/neofs-node/pkg/services/object/util"
"github.com/nspcc-dev/neofs-node/pkg/services/object_manager/transformer"
"github.com/pkg/errors"
)
type remoteTarget struct {
transformer.ObjectTarget
ctx context.Context
keyStorage *util.KeyStorage
commonPrm *util.CommonPrm
addr *network.Address
obj *object.Object
clientConstructor ClientConstructor
}
// RemoteSender represents utility for
// sending an object to a remote host.
type RemoteSender struct {
keyStorage *util.KeyStorage
clientConstructor ClientConstructor
}
// RemotePutPrm groups remote put operation parameters.
type RemotePutPrm struct {
node *network.Address
obj *object.Object
}
func (t *remoteTarget) WriteHeader(obj *object.RawObject) error {
t.obj = obj.Object()
return nil
}
func (t *remoteTarget) Close() (*transformer.AccessIdentifiers, error) {
key, err := t.keyStorage.GetKey(t.commonPrm.SessionToken())
if err != nil {
return nil, errors.Wrapf(err, "(%T) could not receive private key", t)
}
addr, err := t.addr.HostAddrString()
if err != nil {
return nil, err
}
c, err := t.clientConstructor.Get(addr)
if err != nil {
return nil, errors.Wrapf(err, "(%T) could not create SDK client %s", t, addr)
}
id, err := c.PutObject(t.ctx, new(client.PutObjectParams).
WithObject(
t.obj.SDK(),
),
append(
t.commonPrm.RemoteCallOptions(),
client.WithTTL(1), // FIXME: use constant
client.WithKey(key),
)...,
)
if err != nil {
return nil, errors.Wrapf(err, "(%T) could not put object to %s", t, addr)
}
return new(transformer.AccessIdentifiers).
WithSelfID(id), nil
}
// NewRemoteSender creates, initializes and returns new RemoteSender instance.
func NewRemoteSender(keyStorage *util.KeyStorage, cons ClientConstructor) *RemoteSender {
return &RemoteSender{
keyStorage: keyStorage,
clientConstructor: cons,
}
}
// WithNodeAddress sets network address of the remote node.
func (p *RemotePutPrm) WithNodeAddress(v *network.Address) *RemotePutPrm {
if p != nil {
p.node = v
}
return p
}
// WithObject sets transferred object.
func (p *RemotePutPrm) WithObject(v *object.Object) *RemotePutPrm {
if p != nil {
p.obj = v
}
return p
}
// PutObject sends object to remote node.
func (s *RemoteSender) PutObject(ctx context.Context, p *RemotePutPrm) error {
t := &remoteTarget{
ctx: ctx,
keyStorage: s.keyStorage,
addr: p.node,
clientConstructor: s.clientConstructor,
}
if err := t.WriteHeader(object.NewRawFromObject(p.obj)); err != nil {
return errors.Wrapf(err, "(%T) could not send object header", s)
} else if _, err := t.Close(); err != nil {
return errors.Wrapf(err, "(%T) could not send object", s)
}
return nil
}