diff --git a/src/FrostFS.SDK.Client/Mappers/Object/ObjectHeaderMapper.cs b/src/FrostFS.SDK.Client/Mappers/Object/ObjectHeaderMapper.cs index 317b31c..2b4bd43 100644 --- a/src/FrostFS.SDK.Client/Mappers/Object/ObjectHeaderMapper.cs +++ b/src/FrostFS.SDK.Client/Mappers/Object/ObjectHeaderMapper.cs @@ -24,25 +24,14 @@ public static class ObjectHeaderMapper _ => throw new ArgumentException($"Unknown ObjectType. Value: '{header.ObjectType}'.") }; - FrostFsSplit? split = null; - - if (header.Split != null) - { - var children = header.Split.Children.Count != 0 ? new ReadOnlyCollection( - header.Split.Children.Select(x => x.ToModel()).ToList()) : null; - - split = new FrostFsSplit(new SplitId(header.Split.SplitId.ToUuid()), - header.Split.Previous?.ToModel(), - header.Split.Parent?.ToModel(), - header.Split.ParentHeader?.ToModel(), - null, - children); - } + FrostFsSplit? split = header!.Split != null + ? header.Split.ToModel() + : null; var model = new FrostFsObjectHeader( new FrostFsContainerId(Base58.Encode(header.ContainerId.Value.Span)), objTypeName, - header.Attributes.Select(attribute => attribute.ToModel()).ToArray(), + [.. header.Attributes.Select(attribute => attribute.ToModel())], split, header.OwnerId.ToModel(), header.Version.ToModel()) @@ -52,4 +41,18 @@ public static class ObjectHeaderMapper return model; } + + public static FrostFsSplit ToModel(this Header.Types.Split split) + { + var children = split!.Children.Count != 0 + ? new ReadOnlyCollection([.. split.Children.Select(x => x.ToModel())]) + : null; + + return new FrostFsSplit(new SplitId(split.SplitId.ToUuid()), + split.Previous?.ToModel(), + split.Parent?.ToModel(), + split.ParentHeader?.ToModel(), + null, + children); + } } diff --git a/src/FrostFS.SDK.Client/Models/Object/FrostFsSplit.cs b/src/FrostFS.SDK.Client/Models/Object/FrostFsSplit.cs index bd850cb..5afd46b 100644 --- a/src/FrostFS.SDK.Client/Models/Object/FrostFsSplit.cs +++ b/src/FrostFS.SDK.Client/Models/Object/FrostFsSplit.cs @@ -1,4 +1,7 @@ using System.Collections.ObjectModel; +using System.Linq; +using FrostFS.Object; +using FrostFS.SDK.Client.Mappers.GRPC; namespace FrostFS.SDK; @@ -9,6 +12,8 @@ public class FrostFsSplit(SplitId splitId, FrostFsSignature? parentSignature = null, ReadOnlyCollection? children = null) { + private Header.Types.Split? _split; + public FrostFsSplit() : this(new SplitId()) { } @@ -24,4 +29,25 @@ public class FrostFsSplit(SplitId splitId, public FrostFsObjectHeader? ParentHeader { get; set; } = parentHeader; public ReadOnlyCollection? Children { get; } = children; + + public Header.Types.Split GetSplit() + { + if (_split == null) + { + _split = new Header.Types.Split + { + SplitId = SplitId?.GetSplitId(), + Parent = Parent?.ToMessage(), + ParentHeader = ParentHeader?.GetHeader(), + ParentSignature = ParentSignature?.ToMessage() + }; + + if (Children != null) + { + _split.Children.AddRange(Children.Select(x => x.ToMessage())); + } + } + + return _split; + } } diff --git a/src/FrostFS.SDK.Client/Parameters/PrmObjectPatch.cs b/src/FrostFS.SDK.Client/Parameters/PrmObjectPatch.cs index 7b26f5b..fc02c7c 100644 --- a/src/FrostFS.SDK.Client/Parameters/PrmObjectPatch.cs +++ b/src/FrostFS.SDK.Client/Parameters/PrmObjectPatch.cs @@ -10,6 +10,7 @@ public readonly struct PrmObjectPatch( FrostFsSessionToken? sessionToken = null, bool replaceAttributes = false, FrostFsAttributePair[]? newAttributes = null, + FrostFsSplit? newSplitHeader = null, string[]? xheaders = null) : ISessionToken, System.IEquatable { public FrostFsAddress Address { get; } = address; @@ -23,6 +24,8 @@ public readonly struct PrmObjectPatch( public FrostFsAttributePair[]? NewAttributes { get; } = newAttributes; + public FrostFsSplit? NewSplitHeader { get; } = newSplitHeader; + public bool ReplaceAttributes { get; } = replaceAttributes; public int MaxChunkLength { get; } = maxChunkLength; diff --git a/src/FrostFS.SDK.Client/Services/ObjectServiceProvider.cs b/src/FrostFS.SDK.Client/Services/ObjectServiceProvider.cs index 3ce543d..62dc2be 100644 --- a/src/FrostFS.SDK.Client/Services/ObjectServiceProvider.cs +++ b/src/FrostFS.SDK.Client/Services/ObjectServiceProvider.cs @@ -356,6 +356,11 @@ internal sealed class ObjectServiceProvider(ObjectService.ObjectServiceClient cl } } + if (args.NewSplitHeader != null) + { + request.Body.NewSplitHeader = args.NewSplitHeader.GetSplit(); + } + isFirstChunk = false; } else diff --git a/src/FrostFS.SDK.Protos/object/service.proto b/src/FrostFS.SDK.Protos/object/service.proto index 2b8042b..d490dca 100644 --- a/src/FrostFS.SDK.Protos/object/service.proto +++ b/src/FrostFS.SDK.Protos/object/service.proto @@ -887,6 +887,10 @@ message PatchRequest { // key, then it just replaces it while merging the lists. bool replace_attributes = 3; + // New split header for the object. This defines how the object will relate + // to other objects in a split operation. + neo.fs.v2.object.Header.Split new_split_header = 5; + // The patch for the object's payload. message Patch { // The range of the source object for which the payload is replaced by the