frostfs-node/pkg/morph/client/container/put.go
2024-12-12 15:30:12 +03:00

123 lines
2.6 KiB
Go

package container
import (
"context"
"fmt"
containercore "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/container"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/refs"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container"
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
)
// Put marshals container, and passes it to Wrapper's Put method
// along with sig.Key() and sig.Sign().
//
// Returns error if container is nil.
func Put(ctx context.Context, c *Client, cnr containercore.Container) (*cid.ID, error) {
data := cnr.Value.Marshal()
d := container.ReadDomain(cnr.Value)
var prm PutPrm
prm.SetContainer(data)
prm.SetName(d.Name())
prm.SetZone(d.Zone())
if cnr.Session != nil {
prm.SetToken(cnr.Session.Marshal())
}
// TODO(@cthulhu-rider): #468 implement and use another approach to avoid conversion
var sigV2 refs.Signature
cnr.Signature.WriteToV2(&sigV2)
prm.SetKey(sigV2.GetKey())
prm.SetSignature(sigV2.GetSign())
err := c.Put(ctx, prm)
if err != nil {
return nil, err
}
var id cid.ID
container.CalculateIDFromBinary(&id, data)
return &id, nil
}
// PutPrm groups parameters of Put operation.
type PutPrm struct {
cnr []byte
key []byte
sig []byte
token []byte
name string
zone string
client.InvokePrmOptional
}
// SetContainer sets container data.
func (p *PutPrm) SetContainer(cnr []byte) {
p.cnr = cnr
}
// SetKey sets public key.
func (p *PutPrm) SetKey(key []byte) {
p.key = key
}
// SetSignature sets signature.
func (p *PutPrm) SetSignature(sig []byte) {
p.sig = sig
}
// SetToken sets session token.
func (p *PutPrm) SetToken(token []byte) {
p.token = token
}
// SetName sets native name.
func (p *PutPrm) SetName(name string) {
p.name = name
}
// SetZone sets zone.
func (p *PutPrm) SetZone(zone string) {
p.zone = zone
}
// Put saves binary container with its session token, key and signature
// in FrostFS system through Container contract call.
//
// Returns calculated container identifier and any error
// encountered that caused the saving to interrupt.
func (c *Client) Put(ctx context.Context, p PutPrm) error {
if len(p.sig) == 0 || len(p.key) == 0 {
return errNilArgument
}
var (
method string
prm client.InvokePrm
)
if p.name != "" {
method = putNamedMethod
prm.SetArgs(p.cnr, p.sig, p.key, p.token, p.name, p.zone)
} else {
method = putMethod
prm.SetArgs(p.cnr, p.sig, p.key, p.token)
}
prm.SetMethod(method)
prm.InvokePrmOptional = p.InvokePrmOptional
_, err := c.client.Invoke(ctx, prm)
if err != nil {
return fmt.Errorf("invoke method (%s): %w", method, err)
}
return nil
}