forked from TrueCloudLab/frostfs-node
16f13bc0a5
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>
127 lines
2.9 KiB
Go
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
|
|
}
|