frostfs-s3-gw/api/layer/patch.go

79 lines
2 KiB
Go
Raw Normal View History

package layer
import (
"context"
"encoding/hex"
"fmt"
"io"
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
)
type PatchObjectParams struct {
Object *data.ObjectInfo
BktInfo *data.BucketInfo
NewBytes io.Reader
Range *RangeParams
VersioningEnabled bool
}
func (n *Layer) PatchObject(ctx context.Context, p *PatchObjectParams) (*data.ExtendedObjectInfo, error) {
if p.Object.Headers[AttributeDecryptedSize] != "" {
return nil, fmt.Errorf("patch encrypted object")
}
if p.Object.Headers[MultipartObjectSize] != "" {
// TODO: support multipart object patch
return nil, fmt.Errorf("patch multipart object")
}
prmPatch := PrmObjectPatch{
Container: p.BktInfo.CID,
Object: p.Object.ID,
Payload: p.NewBytes,
Range: p.Range,
ObjectSize: p.Object.Size,
}
n.prepareAuthParameters(ctx, &prmPatch.PrmAuth, p.BktInfo.Owner)
objID, err := n.frostFS.PatchObject(ctx, prmPatch)
if err != nil {
return nil, fmt.Errorf("patch object: %w", err)
}
obj, err := n.objectHead(ctx, p.BktInfo, objID)
if err != nil {
return nil, fmt.Errorf("head object: %w", err)
}
payloadChecksum, _ := obj.PayloadChecksum()
hashSum := hex.EncodeToString(payloadChecksum.Value())
newVersion := &data.NodeVersion{
BaseNodeVersion: data.BaseNodeVersion{
OID: objID,
ETag: hashSum,
FilePath: p.Object.Name,
Size: obj.PayloadSize(),
Created: &p.Object.Created,
Owner: &n.gateOwner,
// TODO: Add creation epoch
},
IsUnversioned: !p.VersioningEnabled,
IsCombined: p.Object.Headers[MultipartObjectSize] != "",
}
if newVersion.ID, err = n.treeService.AddVersion(ctx, p.BktInfo, newVersion); err != nil {
return nil, fmt.Errorf("couldn't add new verion to tree service: %w", err)
}
p.Object.ID = objID
p.Object.Size = obj.PayloadSize()
p.Object.MD5Sum = ""
p.Object.HashSum = hashSum
return &data.ExtendedObjectInfo{
ObjectInfo: p.Object,
NodeVersion: newVersion,
}, nil
}