forked from TrueCloudLab/frostfs-s3-gw
79 lines
2 KiB
Go
79 lines
2 KiB
Go
|
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
|
||
|
}
|