[#54] Fix patch logic #55

Merged
orikik merged 1 commit from orikik/frostfs-sdk-java:patch into master 2025-04-25 17:50:37 +00:00
4 changed files with 76 additions and 31 deletions

View file

@ -1,5 +1,30 @@
# Changelog
## [0.12.0] - 2025-04-24
### Fixed
- Patch logic
- Patch payload requirements
## [0.11.0] - 2025-04-23
### Added
- Placement policy vectors
## [0.10.0] - 2025-03-10
### Added
- Auto deploy to forgejo
## [0.9.0] - 2025-03-05
### Added
- APE rule deserializer
## [0.9.0] - 2025-03-05
### Added

View file

@ -6,9 +6,7 @@ import info.frostfs.sdk.dto.object.patch.Address;
import info.frostfs.sdk.dto.object.patch.Range;
import info.frostfs.sdk.dto.session.SessionToken;
import info.frostfs.sdk.jdo.parameters.session.SessionContext;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.*;
import java.io.InputStream;
import java.util.List;
@ -21,12 +19,8 @@ public class PrmObjectPatch implements SessionContext {
@NotNull
private Address address;
@NotNull
private Range range;
@NotNull
private InputStream payload;
private List<ObjectAttribute> newAttributes;
private boolean replaceAttributes;
private int maxChunkLength;
@ -39,4 +33,10 @@ public class PrmObjectPatch implements SessionContext {
this.payload = payload;
this.maxChunkLength = maxChunkLength;
}
public PrmObjectPatch(Address address, List<ObjectAttribute> newAttributes, boolean replaceAttributes) {
this.address = address;
this.newAttributes = newAttributes;
this.replaceAttributes = replaceAttributes;
}
}

View file

@ -231,21 +231,29 @@ public class ObjectClientImpl extends ContextAccessor implements ObjectClient {
public ObjectId patchObject(PrmObjectPatch args, CallContext ctx) {
validate(args);
var request = createInitPatchRequest(args);
var protoToken = RequestConstructor.createObjectTokenContext(
getOrCreateSession(args, ctx),
request.getBody().getAddress(),
frostfs.session.Types.ObjectSessionContext.Verb.PATCH,
getContext().getKey()
);
var currentPos = args.getRange().getOffset();
var chunkSize = args.getMaxChunkLength();
byte[] chunkBuffer = new byte[chunkSize];
var service = deadLineAfter(objectServiceClient, ctx.getTimeout(), ctx.getTimeUnit());
PatchStreamer writer = new PatchStreamer(service);
var request = createInitPatchRequest(args, ctx);
writer.write(request.build());
if (nonNull(args.getPayload())) {
patchObjectPayload(request, args, writer);
}
var response = writer.complete();
Verifier.checkResponse(response);
return ObjectIdMapper.toModel(response.getBody().getObjectId());
}
private void patchObjectPayload(Service.PatchRequest.Builder request, PrmObjectPatch args, PatchStreamer writer) {
var currentPos = args.getRange().getOffset();
var chunkSize = args.getMaxChunkLength() > 0 ? args.getMaxChunkLength() : AppConst.OBJECT_CHUNK_SIZE;
byte[] chunkBuffer = new byte[chunkSize];
var bytesCount = readNBytes(args.getPayload(), chunkBuffer, chunkSize);
while (bytesCount > 0) {
var range = Service.Range.newBuilder()
@ -253,25 +261,25 @@ public class ObjectClientImpl extends ContextAccessor implements ObjectClient {
.setLength(bytesCount)
.build();
Service.PatchRequest.Body.Patch.newBuilder()
var patch = Service.PatchRequest.Body.Patch.newBuilder()
.setChunk(ByteString.copyFrom(chunkBuffer, 0, bytesCount))
.setSourceRange(range)
.build();
currentPos += bytesCount;
var body = Service.PatchRequest.Body.newBuilder()
.setAddress(request.getBody().getAddress())
.setPatch(patch)
.build();
request.setBody(body);
RequestConstructor.addMetaHeader(request, args.getXHeaders(), protoToken);
RequestConstructor.addMetaHeader(request, args.getXHeaders(), request.getMetaHeader().getSessionToken());
sign(request, getContext().getKey());
writer.write(request.build());
currentPos += bytesCount;
bytesCount = readNBytes(args.getPayload(), chunkBuffer, chunkSize);
}
var response = writer.complete();
Verifier.checkResponse(response);
return ObjectIdMapper.toModel(response.getBody().getObjectId());
}
private ObjectFrostFS getObject(Service.GetRequest request, CallContext ctx) {
@ -635,14 +643,26 @@ public class ObjectClientImpl extends ContextAccessor implements ObjectClient {
return request.build();
}
private Service.PatchRequest.Builder createInitPatchRequest(PrmObjectPatch args) {
private Service.PatchRequest.Builder createInitPatchRequest(PrmObjectPatch args, CallContext ctx) {
var address = AddressMapper.toGrpcMessage(args.getAddress());
var body = Service.PatchRequest.Body.newBuilder()
.setAddress(address)
.setReplaceAttributes(args.isReplaceAttributes())
.addAllNewAttributes(ObjectAttributeMapper.toGrpcMessages(args.getNewAttributes()))
.build();
return Service.PatchRequest.newBuilder()
var request = Service.PatchRequest.newBuilder()
.setBody(body);
var protoToken = RequestConstructor.createObjectTokenContext(
getOrCreateSession(args, ctx),
request.getBody().getAddress(),
frostfs.session.Types.ObjectSessionContext.Verb.PATCH,
getContext().getKey()
);
RequestConstructor.addMetaHeader(request, args.getXHeaders(), protoToken);
sign(request, getContext().getKey());
return request;
}
}

View file

@ -17,7 +17,7 @@
</modules>
<properties>
<revision>0.11.0</revision>
<revision>0.12.0</revision>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>