From 1be65c63aed28d9dbfd48ec8428aff52ed4c20f6 Mon Sep 17 00:00:00 2001 From: Bruk Ori Date: Wed, 24 Jul 2024 14:41:42 +0300 Subject: [PATCH] [#1] Add additional security Signed-off-by: Ori Bruk --- README.md | 4 +- client/pom.xml | 4 +- .../sdk/{services => }/FrostFSClient.java | 57 ++++++------ .../frostfs/sdk/constants/CryptoConst.java | 3 + .../frostfs/sdk/jdo/ClientEnvironment.java | 11 ++- .../info/frostfs/sdk/jdo/ClientSettings.java | 8 ++ .../main/java/info/frostfs/sdk/jdo/ECDsa.java | 6 ++ .../frostfs/sdk/jdo/PutObjectParameters.java | 4 + ...rService.java => ContainerClientImpl.java} | 84 +++++++++-------- ...tmapService.java => NetmapClientImpl.java} | 16 ++-- ...jectService.java => ObjectClientImpl.java} | 93 ++++++++++--------- ...{ObjectTools.java => ObjectToolsImpl.java} | 30 +++--- ...ionService.java => SessionClientImpl.java} | 17 ++-- .../impl/{ => rwhelper}/ObjectReader.java | 2 +- .../impl/{ => rwhelper}/ObjectWriter.java | 2 +- .../impl/{ => rwhelper}/SearchReader.java | 2 +- .../info/frostfs/sdk/tools/GrpcClient.java | 3 + .../info/frostfs/sdk/tools/MessageHelper.java | 3 + .../frostfs/sdk/tools/RequestConstructor.java | 15 ++- .../info/frostfs/sdk/tools/RequestSigner.java | 5 +- .../java/info/frostfs/sdk/tools/Verifier.java | 23 ++++- cryptography/pom.xml | 5 + .../java/info/frostfs/sdk/ArrayHelper.java | 2 + .../main/java/info/frostfs/sdk/Base58.java | 18 +++- .../main/java/info/frostfs/sdk/Helper.java | 24 ++++- .../java/info/frostfs/sdk/KeyExtension.java | 31 ++++++- models/pom.xml | 15 ++- .../java/info/frostfs/sdk/UUIDExtension.java | 20 +++- .../info/frostfs/sdk/constants/AppConst.java | 5 + .../frostfs/sdk/constants/FieldConst.java | 4 + .../frostfs/sdk/constants/XHeaderConst.java | 3 + .../java/info/frostfs/sdk/dto/MetaHeader.java | 26 +++++- .../java/info/frostfs/sdk/dto/OwnerId.java | 9 +- .../main/java/info/frostfs/sdk/dto/Split.java | 12 ++- .../java/info/frostfs/sdk/dto/SplitId.java | 20 ++-- .../java/info/frostfs/sdk/dto/Status.java | 5 +- .../java/info/frostfs/sdk/dto/Version.java | 25 +++-- .../sdk/dto/container/ContainerId.java | 22 +++-- .../info/frostfs/sdk/dto/netmap/Replica.java | 28 +++--- .../frostfs/sdk/dto/object/LargeObject.java | 5 + .../frostfs/sdk/dto/object/LinkObject.java | 5 + .../sdk/dto/object/ObjectAttribute.java | 18 ++-- .../frostfs/sdk/dto/object/ObjectFrostFS.java | 18 ++-- .../frostfs/sdk/dto/object/ObjectHeader.java | 34 ++++--- .../info/frostfs/sdk/dto/object/ObjectId.java | 18 +++- .../frostfs/sdk/mappers/MetaHeaderMapper.java | 9 ++ .../frostfs/sdk/mappers/OwnerIdMapper.java | 9 ++ .../frostfs/sdk/mappers/SessionMapper.java | 13 +++ .../frostfs/sdk/mappers/SignatureMapper.java | 9 +- .../frostfs/sdk/mappers/StatusMapper.java | 7 +- .../frostfs/sdk/mappers/VersionMapper.java | 13 +++ .../mappers/container/ContainerIdMapper.java | 9 ++ .../mappers/container/ContainerMapper.java | 11 +++ .../mappers/netmap/NetmapSnapshotMapper.java | 9 ++ .../sdk/mappers/netmap/NodeInfoMapper.java | 11 +++ .../mappers/netmap/PlacementPolicyMapper.java | 13 +++ .../sdk/mappers/netmap/ReplicaMapper.java | 13 +++ .../mappers/object/ObjectAttributeMapper.java | 13 +++ .../mappers/object/ObjectFilterMapper.java | 7 ++ .../mappers/object/ObjectFrostFSMapper.java | 17 +++- .../mappers/object/ObjectHeaderMapper.java | 13 ++- .../sdk/mappers/object/ObjectIdMapper.java | 11 ++- 62 files changed, 670 insertions(+), 281 deletions(-) rename client/src/main/java/info/frostfs/sdk/{services => }/FrostFSClient.java (65%) rename client/src/main/java/info/frostfs/sdk/services/impl/{ContainerService.java => ContainerClientImpl.java} (58%) rename client/src/main/java/info/frostfs/sdk/services/impl/{NetmapService.java => NetmapClientImpl.java} (91%) rename client/src/main/java/info/frostfs/sdk/services/impl/{ObjectService.java => ObjectClientImpl.java} (81%) rename client/src/main/java/info/frostfs/sdk/services/impl/{ObjectTools.java => ObjectToolsImpl.java} (79%) rename client/src/main/java/info/frostfs/sdk/services/impl/{SessionService.java => SessionClientImpl.java} (79%) rename client/src/main/java/info/frostfs/sdk/services/impl/{ => rwhelper}/ObjectReader.java (96%) rename client/src/main/java/info/frostfs/sdk/services/impl/{ => rwhelper}/ObjectWriter.java (97%) rename client/src/main/java/info/frostfs/sdk/services/impl/{ => rwhelper}/SearchReader.java (91%) diff --git a/README.md b/README.md index ff4652e..bd5444b 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ import info.frostfs.sdk.dto.netmap.PlacementPolicy; import info.frostfs.sdk.dto.netmap.Replica; import info.frostfs.sdk.enums.BasicAcl; import info.frostfs.sdk.jdo.ClientSettings; -import info.frostfs.sdk.services.FrostFSClient; +import info.frostfs.sdk.FrostFSClient; public class ContainerExample { @@ -59,7 +59,7 @@ import info.frostfs.sdk.dto.object.ObjectAttribute; import info.frostfs.sdk.dto.object.ObjectFilter; import info.frostfs.sdk.dto.object.ObjectHeader; import info.frostfs.sdk.jdo.PutObjectParameters; -import info.frostfs.sdk.services.FrostFSClient; +import info.frostfs.sdk.FrostFSClient; import java.io.FileInputStream; import java.io.IOException; diff --git a/client/pom.xml b/client/pom.xml index 917fc46..bb808ce 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -1,6 +1,6 @@ - 4.0.0 diff --git a/client/src/main/java/info/frostfs/sdk/services/FrostFSClient.java b/client/src/main/java/info/frostfs/sdk/FrostFSClient.java similarity index 65% rename from client/src/main/java/info/frostfs/sdk/services/FrostFSClient.java rename to client/src/main/java/info/frostfs/sdk/FrostFSClient.java index da87a20..48fdcc5 100644 --- a/client/src/main/java/info/frostfs/sdk/services/FrostFSClient.java +++ b/client/src/main/java/info/frostfs/sdk/FrostFSClient.java @@ -1,4 +1,4 @@ -package info.frostfs.sdk.services; +package info.frostfs.sdk; import frostfs.session.Types; import info.frostfs.sdk.dto.SessionToken; @@ -15,6 +15,7 @@ import info.frostfs.sdk.jdo.ClientEnvironment; import info.frostfs.sdk.jdo.ClientSettings; import info.frostfs.sdk.jdo.NetworkSettings; import info.frostfs.sdk.jdo.PutObjectParameters; +import info.frostfs.sdk.services.*; import info.frostfs.sdk.services.impl.*; import io.grpc.Channel; @@ -27,11 +28,11 @@ public class FrostFSClient implements ContainerClient, ObjectClient, NetmapClien private static final String ERROR_CLIENT_OPTIONS_INIT = "Options must be initialized."; private static final String ERROR_VERSION_SUPPORT_TEMPLATE = "FrostFS %s is not supported."; - private final ContainerService containerService; - private final NetmapService netmapService; - private final ObjectService objectService; - private final SessionService sessionService; - private final ObjectTools objectTools; + private final ContainerClientImpl containerClientImpl; + private final NetmapClientImpl netmapClientImpl; + private final ObjectClientImpl objectClientImpl; + private final SessionClientImpl sessionClientImpl; + private final ObjectToolsImpl objectToolsImpl; public FrostFSClient(ClientSettings clientSettings) { if (isNull(clientSettings)) { @@ -43,18 +44,18 @@ public class FrostFSClient implements ContainerClient, ObjectClient, NetmapClien Channel channel = initGrpcChannel(clientSettings.getHost(), clientSettings.getCreds()); ClientEnvironment clientEnvironment = - new ClientEnvironment(clientSettings.getKey(), channel, new Version(2, 13), this); + new ClientEnvironment(clientSettings.getKey(), channel, new Version(), this); - this.containerService = new ContainerService(clientEnvironment); - this.netmapService = new NetmapService(clientEnvironment); - this.sessionService = new SessionService(clientEnvironment); - this.objectService = new ObjectService(clientEnvironment); - this.objectTools = new ObjectTools(clientEnvironment); + this.containerClientImpl = new ContainerClientImpl(clientEnvironment); + this.netmapClientImpl = new NetmapClientImpl(clientEnvironment); + this.sessionClientImpl = new SessionClientImpl(clientEnvironment); + this.objectClientImpl = new ObjectClientImpl(clientEnvironment); + this.objectToolsImpl = new ObjectToolsImpl(clientEnvironment); checkFrostFsVersionSupport(clientEnvironment.getVersion()); } private void checkFrostFsVersionSupport(Version version) { - var localNodeInfo = netmapService.getLocalNodeInfo(); + var localNodeInfo = netmapClientImpl.getLocalNodeInfo(); if (!localNodeInfo.getVersion().isSupported(version)) { throw new IllegalArgumentException( String.format(ERROR_VERSION_SUPPORT_TEMPLATE, localNodeInfo.getVersion()) @@ -64,75 +65,75 @@ public class FrostFSClient implements ContainerClient, ObjectClient, NetmapClien @Override public Container getContainer(ContainerId cid) { - return containerService.getContainer(cid); + return containerClientImpl.getContainer(cid); } @Override public List listContainers() { - return containerService.listContainers(); + return containerClientImpl.listContainers(); } @Override public ContainerId createContainer(Container container) { - return containerService.createContainer(container); + return containerClientImpl.createContainer(container); } @Override public void deleteContainer(ContainerId cid) { - containerService.deleteContainer(cid); + containerClientImpl.deleteContainer(cid); } @Override public ObjectHeader getObjectHead(ContainerId containerId, ObjectId objectId) { - return objectService.getObjectHead(containerId, objectId); + return objectClientImpl.getObjectHead(containerId, objectId); } @Override public ObjectFrostFS getObject(ContainerId containerId, ObjectId objectId) { - return objectService.getObject(containerId, objectId); + return objectClientImpl.getObject(containerId, objectId); } @Override public ObjectId putObject(PutObjectParameters parameters) { - return objectService.putObject(parameters); + return objectClientImpl.putObject(parameters); } @Override public void deleteObject(ContainerId containerId, ObjectId objectId) { - objectService.deleteObject(containerId, objectId); + objectClientImpl.deleteObject(containerId, objectId); } @Override public Iterable searchObjects(ContainerId cid, ObjectFilter... filters) { - return objectService.searchObjects(cid, filters); + return objectClientImpl.searchObjects(cid, filters); } @Override public NetmapSnapshot getNetmapSnapshot() { - return netmapService.getNetmapSnapshot(); + return netmapClientImpl.getNetmapSnapshot(); } @Override public NodeInfo getLocalNodeInfo() { - return netmapService.getLocalNodeInfo(); + return netmapClientImpl.getLocalNodeInfo(); } @Override public NetworkSettings getNetworkSettings() { - return netmapService.getNetworkSettings(); + return netmapClientImpl.getNetworkSettings(); } @Override public SessionToken createSession(long expiration) { - return sessionService.createSession(expiration); + return sessionClientImpl.createSession(expiration); } public Types.SessionToken createSessionInternal(long expiration) { - return sessionService.createSessionInternal(expiration); + return sessionClientImpl.createSessionInternal(expiration); } @Override public ObjectId calculateObjectId(ObjectHeader header) { - return objectTools.calculateObjectId(header); + return objectToolsImpl.calculateObjectId(header); } } diff --git a/client/src/main/java/info/frostfs/sdk/constants/CryptoConst.java b/client/src/main/java/info/frostfs/sdk/constants/CryptoConst.java index 84db5c9..4e28686 100644 --- a/client/src/main/java/info/frostfs/sdk/constants/CryptoConst.java +++ b/client/src/main/java/info/frostfs/sdk/constants/CryptoConst.java @@ -2,4 +2,7 @@ package info.frostfs.sdk.constants; public class CryptoConst { public static final String SIGNATURE_ALGORITHM = "NONEwithECDSAinP1363Format"; + + private CryptoConst() { + } } diff --git a/client/src/main/java/info/frostfs/sdk/jdo/ClientEnvironment.java b/client/src/main/java/info/frostfs/sdk/jdo/ClientEnvironment.java index 2165f06..6b140d3 100644 --- a/client/src/main/java/info/frostfs/sdk/jdo/ClientEnvironment.java +++ b/client/src/main/java/info/frostfs/sdk/jdo/ClientEnvironment.java @@ -2,8 +2,11 @@ package info.frostfs.sdk.jdo; import info.frostfs.sdk.dto.OwnerId; import info.frostfs.sdk.dto.Version; -import info.frostfs.sdk.services.FrostFSClient; +import info.frostfs.sdk.FrostFSClient; import io.grpc.Channel; +import org.apache.commons.lang3.StringUtils; + +import static java.util.Objects.isNull; public class ClientEnvironment { private final OwnerId ownerId; @@ -14,8 +17,12 @@ public class ClientEnvironment { private NetworkSettings networkSettings; public ClientEnvironment(String wif, Channel channel, Version version, FrostFSClient frostFSClient) { + if (StringUtils.isEmpty(wif) || isNull(channel) || isNull(version) || isNull(frostFSClient)) { + throw new IllegalArgumentException("One of the input attributes is missing"); + } + this.key = new ECDsa(wif); - this.ownerId = OwnerId.fromKey(key.getPublicKeyByte()); + this.ownerId = new OwnerId(key.getPublicKeyByte()); this.version = version; this.channel = channel; this.frostFSClient = frostFSClient; diff --git a/client/src/main/java/info/frostfs/sdk/jdo/ClientSettings.java b/client/src/main/java/info/frostfs/sdk/jdo/ClientSettings.java index 03b83ad..5f7bd32 100644 --- a/client/src/main/java/info/frostfs/sdk/jdo/ClientSettings.java +++ b/client/src/main/java/info/frostfs/sdk/jdo/ClientSettings.java @@ -13,6 +13,14 @@ public class ClientSettings { public ClientSettings(String key, String host) { this.key = key; this.host = host; + validate(); + } + + public ClientSettings(String key, String host, ChannelCredentials creds) { + this.key = key; + this.host = host; + this.creds = creds; + validate(); } public ChannelCredentials getCreds() { diff --git a/client/src/main/java/info/frostfs/sdk/jdo/ECDsa.java b/client/src/main/java/info/frostfs/sdk/jdo/ECDsa.java index 060eef9..d328c10 100644 --- a/client/src/main/java/info/frostfs/sdk/jdo/ECDsa.java +++ b/client/src/main/java/info/frostfs/sdk/jdo/ECDsa.java @@ -1,5 +1,7 @@ package info.frostfs.sdk.jdo; +import org.apache.commons.lang3.StringUtils; + import java.security.PrivateKey; import static info.frostfs.sdk.KeyExtension.*; @@ -10,6 +12,10 @@ public class ECDsa { private final PrivateKey privateKey; public ECDsa(String wif) { + if (StringUtils.isEmpty(wif)) { + throw new IllegalArgumentException("Wif is invalid"); + } + this.privateKeyByte = getPrivateKeyFromWIF(wif); this.publicKeyByte = loadPublicKey(privateKeyByte); this.privateKey = loadPrivateKey(privateKeyByte); diff --git a/client/src/main/java/info/frostfs/sdk/jdo/PutObjectParameters.java b/client/src/main/java/info/frostfs/sdk/jdo/PutObjectParameters.java index cd3338d..3c4ecdd 100644 --- a/client/src/main/java/info/frostfs/sdk/jdo/PutObjectParameters.java +++ b/client/src/main/java/info/frostfs/sdk/jdo/PutObjectParameters.java @@ -19,11 +19,15 @@ public class PutObjectParameters { this.payload = payload; this.clientCut = clientCut; this.bufferMaxSize = bufferMaxSize; + + validate(); } public PutObjectParameters(ObjectHeader header, FileInputStream payload) { this.header = header; this.payload = payload; + + validate(); } public ObjectHeader getHeader() { diff --git a/client/src/main/java/info/frostfs/sdk/services/impl/ContainerService.java b/client/src/main/java/info/frostfs/sdk/services/impl/ContainerClientImpl.java similarity index 58% rename from client/src/main/java/info/frostfs/sdk/services/impl/ContainerService.java rename to client/src/main/java/info/frostfs/sdk/services/impl/ContainerClientImpl.java index 1e2f5e7..5c0e7af 100644 --- a/client/src/main/java/info/frostfs/sdk/services/impl/ContainerService.java +++ b/client/src/main/java/info/frostfs/sdk/services/impl/ContainerClientImpl.java @@ -11,33 +11,36 @@ import info.frostfs.sdk.mappers.container.ContainerIdMapper; import info.frostfs.sdk.mappers.container.ContainerMapper; import info.frostfs.sdk.services.ContainerClient; import info.frostfs.sdk.services.ContextAccessor; -import info.frostfs.sdk.tools.Verifier; import info.frostfs.sdk.tools.RequestConstructor; import info.frostfs.sdk.tools.RequestSigner; +import info.frostfs.sdk.tools.Verifier; import java.util.List; import java.util.stream.Collectors; -import static info.frostfs.sdk.tools.RequestConstructor.addMetaHeader; -import static info.frostfs.sdk.tools.RequestSigner.signRFC6979; +import static java.util.Objects.isNull; -public class ContainerService extends ContextAccessor implements ContainerClient { +public class ContainerClientImpl extends ContextAccessor implements ContainerClient { private final ContainerServiceGrpc.ContainerServiceBlockingStub serviceBlockingStub; - public ContainerService(ClientEnvironment clientEnvironment) { + public ContainerClientImpl(ClientEnvironment clientEnvironment) { super(clientEnvironment); this.serviceBlockingStub = ContainerServiceGrpc.newBlockingStub(clientEnvironment.getChannel()); } + @Override public Container getContainer(ContainerId cid) { - var request = Service.GetRequest.newBuilder() - .setBody( - Service.GetRequest.Body.newBuilder() - .setContainerId(ContainerIdMapper.toGrpcMessage(cid)) - .build() - ); + if (isNull(cid)) { + throw new IllegalArgumentException("ContainerId is not present"); + } - RequestConstructor.addMetaHeader(request); + var body = Service.GetRequest.Body.newBuilder() + .setContainerId(ContainerIdMapper.toGrpcMessage(cid)) + .build(); + var request = Service.GetRequest.newBuilder() + .setBody(body); + + RequestConstructor.addDefaultMetaHeader(request); RequestSigner.sign(request, getContext().getKey()); var response = serviceBlockingStub.get(request.build()); @@ -46,15 +49,15 @@ public class ContainerService extends ContextAccessor implements ContainerClient return ContainerMapper.toModel(response.getBody().getContainer()); } + @Override public List listContainers() { + var body = Service.ListRequest.Body.newBuilder() + .setOwnerId(OwnerIdMapper.toGrpcMessage(getContext().getOwnerId())) + .build(); var request = Service.ListRequest.newBuilder() - .setBody( - Service.ListRequest.Body.newBuilder() - .setOwnerId(OwnerIdMapper.toGrpcMessage(getContext().getOwnerId())) - .build() - ); + .setBody(body); - RequestConstructor.addMetaHeader(request); + RequestConstructor.addDefaultMetaHeader(request); RequestSigner.sign(request, getContext().getKey()); var response = serviceBlockingStub.list(request.build()); @@ -62,51 +65,54 @@ public class ContainerService extends ContextAccessor implements ContainerClient Verifier.checkResponse(response); return response.getBody().getContainerIdsList().stream() - .map(cid -> ContainerId.fromHash(cid.getValue().toByteArray())) + .map(cid -> new ContainerId(cid.getValue().toByteArray())) .collect(Collectors.toList()); } + @Override public ContainerId createContainer(Container container) { - var grpcContainer = ContainerMapper.toGrpcMessage(container); + if (isNull(container)) { + throw new IllegalArgumentException("Container is not present"); + } + var grpcContainer = ContainerMapper.toGrpcMessage(container); grpcContainer = grpcContainer.toBuilder() .setOwnerId(OwnerIdMapper.toGrpcMessage(getContext().getOwnerId())) .setVersion(VersionMapper.toGrpcMessage(getContext().getVersion())) .build(); + var body = Service.PutRequest.Body.newBuilder() + .setContainer(grpcContainer) + .setSignature(RequestSigner.signRFC6979(getContext().getKey(), grpcContainer)) + .build(); var request = Service.PutRequest.newBuilder() - .setBody( - Service.PutRequest.Body.newBuilder() - .setContainer(grpcContainer) - .setSignature( - RequestSigner.signRFC6979(getContext().getKey(), grpcContainer) - ) - .build() - ); + .setBody(body); - RequestConstructor.addMetaHeader(request); + RequestConstructor.addDefaultMetaHeader(request); RequestSigner.sign(request, getContext().getKey()); var response = serviceBlockingStub.put(request.build()); Verifier.checkResponse(response); - return ContainerId.fromHash(response.getBody().getContainerId().getValue().toByteArray()); + return new ContainerId(response.getBody().getContainerId().getValue().toByteArray()); } + @Override public void deleteContainer(ContainerId cid) { + if (isNull(cid)) { + throw new IllegalArgumentException("ContainerId is not present"); + } + var grpcContainerId = ContainerIdMapper.toGrpcMessage(cid); + var body = Service.DeleteRequest.Body.newBuilder() + .setContainerId(grpcContainerId) + .setSignature(RequestSigner.signRFC6979(getContext().getKey(), grpcContainerId.getValue())) + .build(); var request = Service.DeleteRequest.newBuilder() - .setBody( - Service.DeleteRequest.Body.newBuilder() - .setContainerId(grpcContainerId) - .setSignature(RequestSigner.signRFC6979( - getContext().getKey(), grpcContainerId.getValue() - )) - .build() - ); + .setBody(body); - RequestConstructor.addMetaHeader(request); + RequestConstructor.addDefaultMetaHeader(request); RequestSigner.sign(request, getContext().getKey()); var response = serviceBlockingStub.delete(request.build()); diff --git a/client/src/main/java/info/frostfs/sdk/services/impl/NetmapService.java b/client/src/main/java/info/frostfs/sdk/services/impl/NetmapClientImpl.java similarity index 91% rename from client/src/main/java/info/frostfs/sdk/services/impl/NetmapService.java rename to client/src/main/java/info/frostfs/sdk/services/impl/NetmapClientImpl.java index 19c5995..b38624c 100644 --- a/client/src/main/java/info/frostfs/sdk/services/impl/NetmapService.java +++ b/client/src/main/java/info/frostfs/sdk/services/impl/NetmapClientImpl.java @@ -11,25 +11,27 @@ import info.frostfs.sdk.mappers.netmap.NetmapSnapshotMapper; import info.frostfs.sdk.mappers.netmap.NodeInfoMapper; import info.frostfs.sdk.services.ContextAccessor; import info.frostfs.sdk.services.NetmapClient; +import info.frostfs.sdk.tools.RequestConstructor; import info.frostfs.sdk.tools.Verifier; import java.nio.charset.StandardCharsets; -import static info.frostfs.sdk.tools.RequestConstructor.addMetaHeader; import static info.frostfs.sdk.tools.RequestSigner.sign; import static java.util.Objects.nonNull; -public class NetmapService extends ContextAccessor implements NetmapClient { +public class NetmapClientImpl extends ContextAccessor implements NetmapClient { private final NetmapServiceGrpc.NetmapServiceBlockingStub netmapServiceClient; - public NetmapService(ClientEnvironment clientEnvironment) { + public NetmapClientImpl(ClientEnvironment clientEnvironment) { super(clientEnvironment); this.netmapServiceClient = NetmapServiceGrpc.newBlockingStub(getContext().getChannel()); } private static boolean getBoolValue(byte[] bytes) { for (var byteValue : bytes) { - if (byteValue != 0) return true; + if (byteValue != 0) { + return true; + } } return false; @@ -115,7 +117,7 @@ public class NetmapService extends ContextAccessor implements NetmapClient { var request = Service.LocalNodeInfoRequest.newBuilder() .setBody(Service.LocalNodeInfoRequest.Body.newBuilder().build()); - addMetaHeader(request); + RequestConstructor.addDefaultMetaHeader(request); sign(request, getContext().getKey()); var response = netmapServiceClient.localNodeInfo(request.build()); @@ -128,7 +130,7 @@ public class NetmapService extends ContextAccessor implements NetmapClient { var request = Service.NetworkInfoRequest.newBuilder() .setBody(Service.NetworkInfoRequest.Body.newBuilder().build()); - addMetaHeader(request); + RequestConstructor.addDefaultMetaHeader(request); sign(request, getContext().getKey()); var response = netmapServiceClient.networkInfo(request.build()); @@ -143,7 +145,7 @@ public class NetmapService extends ContextAccessor implements NetmapClient { var request = Service.NetmapSnapshotRequest.newBuilder() .setBody(Service.NetmapSnapshotRequest.Body.newBuilder().build()); - addMetaHeader(request); + RequestConstructor.addDefaultMetaHeader(request); sign(request, getContext().getKey()); var response = netmapServiceClient.netmapSnapshot(request.build()); diff --git a/client/src/main/java/info/frostfs/sdk/services/impl/ObjectService.java b/client/src/main/java/info/frostfs/sdk/services/impl/ObjectClientImpl.java similarity index 81% rename from client/src/main/java/info/frostfs/sdk/services/impl/ObjectService.java rename to client/src/main/java/info/frostfs/sdk/services/impl/ObjectClientImpl.java index ca2652b..69046d6 100644 --- a/client/src/main/java/info/frostfs/sdk/services/impl/ObjectService.java +++ b/client/src/main/java/info/frostfs/sdk/services/impl/ObjectClientImpl.java @@ -20,6 +20,10 @@ import info.frostfs.sdk.mappers.object.ObjectHeaderMapper; import info.frostfs.sdk.mappers.object.ObjectIdMapper; import info.frostfs.sdk.services.ContextAccessor; import info.frostfs.sdk.services.ObjectClient; +import info.frostfs.sdk.services.impl.rwhelper.ObjectReader; +import info.frostfs.sdk.services.impl.rwhelper.ObjectWriter; +import info.frostfs.sdk.services.impl.rwhelper.SearchReader; +import info.frostfs.sdk.tools.RequestConstructor; import info.frostfs.sdk.tools.Verifier; import org.apache.commons.collections4.CollectionUtils; @@ -30,39 +34,37 @@ import java.util.Arrays; import java.util.List; import static info.frostfs.sdk.Helper.getSha256; -import static info.frostfs.sdk.tools.RequestConstructor.addMetaHeader; import static info.frostfs.sdk.tools.RequestConstructor.addObjectSessionToken; import static info.frostfs.sdk.tools.RequestSigner.sign; import static java.util.Objects.nonNull; -public class ObjectService extends ContextAccessor implements ObjectClient { +public class ObjectClientImpl extends ContextAccessor implements ObjectClient { private static final String ERROR_PAYLOAD = "PayloadLength must be specified"; private final ObjectServiceGrpc.ObjectServiceBlockingStub objectServiceBlockingClient; private final ObjectServiceGrpc.ObjectServiceStub objectServiceClient; - private final ObjectTools objectTools; + private final ObjectToolsImpl objectToolsImpl; - public ObjectService(ClientEnvironment clientEnvironment) { + public ObjectClientImpl(ClientEnvironment clientEnvironment) { super(clientEnvironment); this.objectServiceBlockingClient = ObjectServiceGrpc.newBlockingStub(getContext().getChannel()); this.objectServiceClient = ObjectServiceGrpc.newStub(getContext().getChannel()); - this.objectTools = new ObjectTools(clientEnvironment); + this.objectToolsImpl = new ObjectToolsImpl(clientEnvironment); } @Override public ObjectHeader getObjectHead(ContainerId cid, ObjectId oid) { + var address = Types.Address.newBuilder() + .setContainerId(ContainerIdMapper.toGrpcMessage(cid)) + .setObjectId(ObjectIdMapper.toGrpcMessage(oid)) + .build(); + var body = Service.HeadRequest.Body.newBuilder() + .setAddress(address) + .build(); var request = Service.HeadRequest.newBuilder() - .setBody( - Service.HeadRequest.Body.newBuilder() - .setAddress( - Types.Address.newBuilder() - .setContainerId(ContainerIdMapper.toGrpcMessage(cid)) - .setObjectId(ObjectIdMapper.toGrpcMessage(oid)) - .build() - ).build() - ); + .setBody(body); - addMetaHeader(request); + RequestConstructor.addDefaultMetaHeader(request); sign(request, getContext().getKey()); var response = objectServiceBlockingClient.head(request.build()); @@ -75,19 +77,17 @@ public class ObjectService extends ContextAccessor implements ObjectClient { public ObjectFrostFS getObject(ContainerId cid, ObjectId oid) { var sessionToken = getContext().getFrostFSClient().createSessionInternal(-1); + var address = Types.Address.newBuilder() + .setContainerId(ContainerIdMapper.toGrpcMessage(cid)) + .setObjectId(ObjectIdMapper.toGrpcMessage(oid)) + .build(); + var body = Service.GetRequest.Body.newBuilder() + .setAddress(address) + .build(); var request = Service.GetRequest.newBuilder() - .setBody( - Service.GetRequest.Body.newBuilder() - .setAddress( - Types.Address.newBuilder() - .setContainerId(ContainerIdMapper.toGrpcMessage(cid)) - .setObjectId(ObjectIdMapper.toGrpcMessage(oid)) - .build() - ) - .build() - ); + .setBody(body); - addMetaHeader(request); + RequestConstructor.addDefaultMetaHeader(request); addObjectSessionToken( request, sessionToken, ContainerIdMapper.toGrpcMessage(cid), ObjectIdMapper.toGrpcMessage(oid), frostfs.session.Types.ObjectSessionContext.Verb.GET, getContext().getKey() @@ -101,18 +101,17 @@ public class ObjectService extends ContextAccessor implements ObjectClient { @Override public void deleteObject(ContainerId cid, ObjectId oid) { + var address = Types.Address.newBuilder() + .setContainerId(ContainerIdMapper.toGrpcMessage(cid)) + .setObjectId(ObjectIdMapper.toGrpcMessage(oid)) + .build(); + var body = Service.DeleteRequest.Body.newBuilder() + .setAddress(address) + .build(); var request = Service.DeleteRequest.newBuilder() - .setBody( - Service.DeleteRequest.Body.newBuilder() - .setAddress( - Types.Address.newBuilder() - .setContainerId(ContainerIdMapper.toGrpcMessage(cid)) - .setObjectId(ObjectIdMapper.toGrpcMessage(oid)) - .build() - ) - .build()); + .setBody(body); - addMetaHeader(request); + RequestConstructor.addDefaultMetaHeader(request); sign(request, getContext().getKey()); var response = objectServiceBlockingClient.delete(request.build()); @@ -132,12 +131,12 @@ public class ObjectService extends ContextAccessor implements ObjectClient { var request = Service.SearchRequest.newBuilder() .setBody(body.build()); - addMetaHeader(request); + RequestConstructor.addDefaultMetaHeader(request); sign(request, getContext().getKey()); var objectsIds = searchObjects(request.build()); - return Iterables.transform(objectsIds, input -> ObjectId.fromHash(input.getValue().toByteArray())); + return Iterables.transform(objectsIds, input -> new ObjectId(input.getValue().toByteArray())); } @Override @@ -150,13 +149,13 @@ public class ObjectService extends ContextAccessor implements ObjectClient { public ObjectId putSingleObject(ObjectFrostFS modelObject) { var sessionToken = getContext().getFrostFSClient().createSessionInternal(-1); - var grpcObject = objectTools.createObject(modelObject); + var grpcObject = objectToolsImpl.createObject(modelObject); var request = Service.PutSingleRequest.newBuilder() .setBody(Service.PutSingleRequest.Body.newBuilder().setObject(grpcObject).build()); - addMetaHeader(request); + RequestConstructor.addDefaultMetaHeader(request); addObjectSessionToken( request, sessionToken, grpcObject.getHeader().getContainerId(), grpcObject.getObjectId(), frostfs.session.Types.ObjectSessionContext.Verb.PUT, getContext().getKey() @@ -167,7 +166,7 @@ public class ObjectService extends ContextAccessor implements ObjectClient { Verifier.checkResponse(response); - return ObjectId.fromHash(grpcObject.getObjectId().getValue().toByteArray()); + return new ObjectId(grpcObject.getObjectId().getValue().toByteArray()); } private frostfs.object.Types.Object getObject(Service.GetRequest request) { @@ -215,7 +214,7 @@ public class ObjectService extends ContextAccessor implements ObjectClient { ).build() ); - addMetaHeader(initRequest); + RequestConstructor.addDefaultMetaHeader(initRequest); addObjectSessionToken( initRequest, sessionToken, hdr.getContainerId(), oid, frostfs.session.Types.ObjectSessionContext.Verb.PUT, getContext().getKey() @@ -232,8 +231,9 @@ public class ObjectService extends ContextAccessor implements ObjectClient { var buffer = new byte[bufferSize]; while (true) { var bytesCount = readNBytes(parameters.getPayload(), buffer, bufferSize); - if (bytesCount <= 0) + if (bytesCount <= 0) { break; + } var chunkRequest = Service.PutRequest.newBuilder(initRequest.build()) .setBody( @@ -249,7 +249,7 @@ public class ObjectService extends ContextAccessor implements ObjectClient { var response = writer.complete(); Verifier.checkResponse(response); - return ObjectId.fromHash(response.getBody().getObjectId().getValue().toByteArray()); + return new ObjectId(response.getBody().getObjectId().getValue().toByteArray()); } private ObjectId putClientCutObject(PutObjectParameters parameters) { @@ -285,8 +285,9 @@ public class ObjectService extends ContextAccessor implements ObjectClient { ); currentObject.setSplit(split); - if (largeObject.getPayloadLength() == fullLength) + if (largeObject.getPayloadLength() == fullLength) { break; + } objectId = putSingleObject(currentObject); @@ -314,7 +315,7 @@ public class ObjectService extends ContextAccessor implements ObjectClient { putSingleObject(linkObject); - return objectTools.calculateObjectId(largeObject.getHeader()); + return objectToolsImpl.calculateObjectId(largeObject.getHeader()); } private ObjectWriter putObjectInit(Service.PutRequest initRequest) { diff --git a/client/src/main/java/info/frostfs/sdk/services/impl/ObjectTools.java b/client/src/main/java/info/frostfs/sdk/services/impl/ObjectToolsImpl.java similarity index 79% rename from client/src/main/java/info/frostfs/sdk/services/impl/ObjectTools.java rename to client/src/main/java/info/frostfs/sdk/services/impl/ObjectToolsImpl.java index 5eb0680..b68a26e 100644 --- a/client/src/main/java/info/frostfs/sdk/services/impl/ObjectTools.java +++ b/client/src/main/java/info/frostfs/sdk/services/impl/ObjectToolsImpl.java @@ -18,8 +18,8 @@ import static info.frostfs.sdk.Helper.getSha256; import static info.frostfs.sdk.tools.RequestSigner.signData; import static java.util.Objects.nonNull; -public class ObjectTools extends ContextAccessor implements ToolsClient { - public ObjectTools(ClientEnvironment context) { +public class ObjectToolsImpl extends ContextAccessor implements ToolsClient { + public ObjectToolsImpl(ClientEnvironment context) { super(context); } @@ -59,15 +59,13 @@ public class ObjectTools extends ContextAccessor implements ToolsClient { if (nonNull(split.getParentHeader())) { var grpcParentHeader = createHeader(split.getParentHeader(), new byte[]{}); var parent = frostfs.refs.Types.ObjectID.newBuilder().setValue(getSha256(grpcParentHeader)).build(); + var parentSig = frostfs.refs.Types.Signature.newBuilder() + .setKey(ByteString.copyFrom(getContext().getKey().getPublicKeyByte())) + .setSign(ByteString.copyFrom(signData(getContext().getKey(), parent.toByteArray()))); - splitGrpc - .setParent(parent) + splitGrpc.setParent(parent) .setParentHeader(grpcParentHeader) - .setParentSignature( - frostfs.refs.Types.Signature.newBuilder() - .setKey(ByteString.copyFrom(getContext().getKey().getPublicKeyByte())) - .setSign(ByteString.copyFrom(signData(getContext().getKey(), parent.toByteArray()))) - ); + .setParentSignature(parentSig); split.setParent(ObjectIdMapper.toModel(parent)); } @@ -79,15 +77,14 @@ public class ObjectTools extends ContextAccessor implements ToolsClient { var grpcHeader = grpcHeaderBuilder.build(); var objectId = frostfs.refs.Types.ObjectID.newBuilder().setValue(getSha256(grpcHeader)).build(); + var sig = frostfs.refs.Types.Signature.newBuilder() + .setKey(ByteString.copyFrom(getContext().getKey().getPublicKeyByte())) + .setSign(ByteString.copyFrom(signData(getContext().getKey(), objectId.toByteArray()))); return Types.Object.newBuilder() .setHeader(grpcHeader) .setObjectId(objectId) .setPayload(ByteString.copyFrom(objectFrostFs.getPayload())) - .setSignature( - frostfs.refs.Types.Signature.newBuilder() - .setKey(ByteString.copyFrom(getContext().getKey().getPublicKeyByte())) - .setSign(ByteString.copyFrom(signData(getContext().getKey(), objectId.toByteArray()))) - ) + .setSignature(sig) .build(); } @@ -96,10 +93,11 @@ public class ObjectTools extends ContextAccessor implements ToolsClient { .setOwnerId(OwnerIdMapper.toGrpcMessage(getContext().getOwnerId())) .setVersion(VersionMapper.toGrpcMessage(getContext().getVersion())); - if (header.getPayloadCheckSum() != null) + if (header.getPayloadCheckSum() != null) { grpcHeader.setPayloadHash(sha256Checksum(header.getPayloadCheckSum())); - else if (payload != null) + } else if (payload != null) { grpcHeader.setPayloadHash(sha256Checksum(payload)); + } return grpcHeader.build(); } diff --git a/client/src/main/java/info/frostfs/sdk/services/impl/SessionService.java b/client/src/main/java/info/frostfs/sdk/services/impl/SessionClientImpl.java similarity index 79% rename from client/src/main/java/info/frostfs/sdk/services/impl/SessionService.java rename to client/src/main/java/info/frostfs/sdk/services/impl/SessionClientImpl.java index d6bf950..137c178 100644 --- a/client/src/main/java/info/frostfs/sdk/services/impl/SessionService.java +++ b/client/src/main/java/info/frostfs/sdk/services/impl/SessionClientImpl.java @@ -11,13 +11,12 @@ import info.frostfs.sdk.services.ContextAccessor; import info.frostfs.sdk.services.SessionClient; import info.frostfs.sdk.tools.RequestConstructor; -import static info.frostfs.sdk.tools.RequestConstructor.addMetaHeader; import static info.frostfs.sdk.tools.RequestSigner.sign; -public class SessionService extends ContextAccessor implements SessionClient { +public class SessionClientImpl extends ContextAccessor implements SessionClient { private final SessionServiceGrpc.SessionServiceBlockingStub serviceBlockingStub; - public SessionService(ClientEnvironment clientEnvironment) { + public SessionClientImpl(ClientEnvironment clientEnvironment) { super(clientEnvironment); this.serviceBlockingStub = SessionServiceGrpc.newBlockingStub(getContext().getChannel()); } @@ -30,14 +29,14 @@ public class SessionService extends ContextAccessor implements SessionClient { } public Types.SessionToken createSessionInternal(long expiration) { + var body = Service.CreateRequest.Body.newBuilder() + .setOwnerId(OwnerIdMapper.toGrpcMessage(getContext().getOwnerId())) + .setExpiration(expiration) + .build(); var request = Service.CreateRequest.newBuilder() - .setBody( - Service.CreateRequest.Body.newBuilder() - .setOwnerId(OwnerIdMapper.toGrpcMessage(getContext().getOwnerId())) - .setExpiration(expiration).build() - ); + .setBody(body); - RequestConstructor.addMetaHeader(request); + RequestConstructor.addDefaultMetaHeader(request); sign(request, getContext().getKey()); return createSession(request.build()); diff --git a/client/src/main/java/info/frostfs/sdk/services/impl/ObjectReader.java b/client/src/main/java/info/frostfs/sdk/services/impl/rwhelper/ObjectReader.java similarity index 96% rename from client/src/main/java/info/frostfs/sdk/services/impl/ObjectReader.java rename to client/src/main/java/info/frostfs/sdk/services/impl/rwhelper/ObjectReader.java index 62a9a70..d686921 100644 --- a/client/src/main/java/info/frostfs/sdk/services/impl/ObjectReader.java +++ b/client/src/main/java/info/frostfs/sdk/services/impl/rwhelper/ObjectReader.java @@ -1,4 +1,4 @@ -package info.frostfs.sdk.services.impl; +package info.frostfs.sdk.services.impl.rwhelper; import frostfs.object.Service; import frostfs.object.Types; diff --git a/client/src/main/java/info/frostfs/sdk/services/impl/ObjectWriter.java b/client/src/main/java/info/frostfs/sdk/services/impl/rwhelper/ObjectWriter.java similarity index 97% rename from client/src/main/java/info/frostfs/sdk/services/impl/ObjectWriter.java rename to client/src/main/java/info/frostfs/sdk/services/impl/rwhelper/ObjectWriter.java index 8642dc8..7d6271b 100644 --- a/client/src/main/java/info/frostfs/sdk/services/impl/ObjectWriter.java +++ b/client/src/main/java/info/frostfs/sdk/services/impl/rwhelper/ObjectWriter.java @@ -1,4 +1,4 @@ -package info.frostfs.sdk.services.impl; +package info.frostfs.sdk.services.impl.rwhelper; import frostfs.object.ObjectServiceGrpc; import frostfs.object.Service; diff --git a/client/src/main/java/info/frostfs/sdk/services/impl/SearchReader.java b/client/src/main/java/info/frostfs/sdk/services/impl/rwhelper/SearchReader.java similarity index 91% rename from client/src/main/java/info/frostfs/sdk/services/impl/SearchReader.java rename to client/src/main/java/info/frostfs/sdk/services/impl/rwhelper/SearchReader.java index 873d48b..ec42c05 100644 --- a/client/src/main/java/info/frostfs/sdk/services/impl/SearchReader.java +++ b/client/src/main/java/info/frostfs/sdk/services/impl/rwhelper/SearchReader.java @@ -1,4 +1,4 @@ -package info.frostfs.sdk.services.impl; +package info.frostfs.sdk.services.impl.rwhelper; import frostfs.object.Service; import info.frostfs.sdk.tools.Verifier; diff --git a/client/src/main/java/info/frostfs/sdk/tools/GrpcClient.java b/client/src/main/java/info/frostfs/sdk/tools/GrpcClient.java index 729d3e5..96ef9b2 100644 --- a/client/src/main/java/info/frostfs/sdk/tools/GrpcClient.java +++ b/client/src/main/java/info/frostfs/sdk/tools/GrpcClient.java @@ -12,6 +12,9 @@ import static java.util.Objects.isNull; public class GrpcClient { private static final String ERROR_INVALID_HOST_TEMPLATE = "Host %s has invalid format. Error: %s"; + private GrpcClient() { + } + public static Channel initGrpcChannel(String host, ChannelCredentials creds) { try { URI uri = new URI(host); diff --git a/client/src/main/java/info/frostfs/sdk/tools/MessageHelper.java b/client/src/main/java/info/frostfs/sdk/tools/MessageHelper.java index 00f87c4..cb0005f 100644 --- a/client/src/main/java/info/frostfs/sdk/tools/MessageHelper.java +++ b/client/src/main/java/info/frostfs/sdk/tools/MessageHelper.java @@ -5,6 +5,9 @@ import com.google.protobuf.MessageOrBuilder; public class MessageHelper { + private MessageHelper() { + } + public static Message getField(MessageOrBuilder messageOrBuilder, String fieldName) { return (Message) messageOrBuilder.getField(messageOrBuilder.getDescriptorForType().findFieldByName(fieldName)); } diff --git a/client/src/main/java/info/frostfs/sdk/tools/RequestConstructor.java b/client/src/main/java/info/frostfs/sdk/tools/RequestConstructor.java index 9660de5..047d146 100644 --- a/client/src/main/java/info/frostfs/sdk/tools/RequestConstructor.java +++ b/client/src/main/java/info/frostfs/sdk/tools/RequestConstructor.java @@ -14,13 +14,20 @@ import static java.util.Objects.isNull; public class RequestConstructor { - public static void addMetaHeader(Message.Builder request) { + private RequestConstructor() { + } + + public static void addDefaultMetaHeader(Message.Builder request) { addMetaHeader(request, null); } public static void addMetaHeader(Message.Builder request, Types.RequestMetaHeader metaHeader) { + if (isNull(request)) { + return; + } + if (isNull(metaHeader) || metaHeader.getSerializedSize() == 0) { - metaHeader = MetaHeaderMapper.toGrpcMessage(MetaHeader.getDefault()); + metaHeader = MetaHeaderMapper.toGrpcMessage(new MetaHeader()); setField(request, META_HEADER_FIELD_NAME, metaHeader); } } @@ -31,6 +38,10 @@ public class RequestConstructor { frostfs.refs.Types.ObjectID oid, Types.ObjectSessionContext.Verb verb, ECDsa key) { + if (isNull(request) || isNull(sessionToken)) { + return; + } + var header = (Types.RequestMetaHeader) getField(request, META_HEADER_FIELD_NAME); if (header.getSessionToken().getSerializedSize() > 0) { return; diff --git a/client/src/main/java/info/frostfs/sdk/tools/RequestSigner.java b/client/src/main/java/info/frostfs/sdk/tools/RequestSigner.java index 315af58..ea7d828 100644 --- a/client/src/main/java/info/frostfs/sdk/tools/RequestSigner.java +++ b/client/src/main/java/info/frostfs/sdk/tools/RequestSigner.java @@ -3,8 +3,8 @@ package info.frostfs.sdk.tools; import com.google.protobuf.ByteString; import com.google.protobuf.Message; import frostfs.session.Types; -import info.frostfs.sdk.jdo.ECDsa; import info.frostfs.sdk.constants.CryptoConst; +import info.frostfs.sdk.jdo.ECDsa; import org.apache.commons.codec.digest.DigestUtils; import org.bouncycastle.asn1.sec.SECNamedCurves; import org.bouncycastle.asn1.sec.SECObjectIdentifiers; @@ -24,6 +24,9 @@ public class RequestSigner { public static final String ERROR_UNSUPPORTED_TYPE_TEMPLATE = "Unsupported message type: %s"; public static final int RFC6979_SIGNATURE_SIZE = 64; + private RequestSigner() { + } + public static byte[] signData(ECDsa key, byte[] data) { var hash = new byte[65]; hash[0] = 0x04; diff --git a/client/src/main/java/info/frostfs/sdk/tools/Verifier.java b/client/src/main/java/info/frostfs/sdk/tools/Verifier.java index 8fed127..48a2afc 100644 --- a/client/src/main/java/info/frostfs/sdk/tools/Verifier.java +++ b/client/src/main/java/info/frostfs/sdk/tools/Verifier.java @@ -2,8 +2,8 @@ package info.frostfs.sdk.tools; import com.google.protobuf.Message; import frostfs.session.Types; -import info.frostfs.sdk.mappers.StatusMapper; import info.frostfs.sdk.constants.CryptoConst; +import info.frostfs.sdk.mappers.StatusMapper; import org.apache.commons.codec.digest.DigestUtils; import org.bouncycastle.asn1.sec.SECNamedCurves; import org.bouncycastle.asn1.sec.SECObjectIdentifiers; @@ -28,12 +28,17 @@ public class Verifier { public static final String ERROR_INVALID_RESPONSE = "Invalid response"; public static final int RFC6979_SIG_SIZE = 64; + private Verifier() { + } + public static boolean verifyRFC6979(frostfs.refs.Types.SignatureRFC6979 signature, Message data) { return verifyRFC6979(signature.getKey().toByteArray(), data.toByteArray(), signature.getSign().toByteArray()); } public static boolean verifyRFC6979(byte[] publicKey, byte[] data, byte[] sig) { - if (isNull(publicKey) || isNull(data) || isNull(sig)) return false; + if (isNull(publicKey) || isNull(data) || isNull(sig)) { + return false; + } var rs = decodeSignature(sig); var digest = createSHA256(); @@ -85,9 +90,15 @@ public class Verifier { public static boolean verifyMatryoshkaLevel(Message data, frostfs.session.Types.ResponseMetaHeader meta, frostfs.session.Types.ResponseVerificationHeader verification) { - if (!verifyMessagePart(verification.getMetaSignature(), meta)) return false; + if (!verifyMessagePart(verification.getMetaSignature(), meta)) { + return false; + } + var origin = verification.getOrigin(); - if (!verifyMessagePart(verification.getOriginSignature(), origin)) return false; + if (!verifyMessagePart(verification.getOriginSignature(), origin)) { + return false; + } + if (origin.getSerializedSize() == 0) { return verifyMessagePart(verification.getBodySignature(), data); } @@ -96,7 +107,9 @@ public class Verifier { } public static boolean verifyMessagePart(frostfs.refs.Types.Signature sig, Message data) { - if (sig.getSerializedSize() == 0 || sig.getKey().isEmpty() || sig.getSign().isEmpty()) return false; + if (sig.getSerializedSize() == 0 || sig.getKey().isEmpty() || sig.getSign().isEmpty()) { + return false; + } var publicKey = getPublicKeyFromBytes(sig.getKey().toByteArray()); diff --git a/cryptography/pom.xml b/cryptography/pom.xml index 156b0bd..385a810 100644 --- a/cryptography/pom.xml +++ b/cryptography/pom.xml @@ -29,6 +29,11 @@ bcprov-jdk18on 1.78.1 + + org.apache.commons + commons-lang3 + 3.14.0 + \ No newline at end of file diff --git a/cryptography/src/main/java/info/frostfs/sdk/ArrayHelper.java b/cryptography/src/main/java/info/frostfs/sdk/ArrayHelper.java index ae43afd..915f202 100644 --- a/cryptography/src/main/java/info/frostfs/sdk/ArrayHelper.java +++ b/cryptography/src/main/java/info/frostfs/sdk/ArrayHelper.java @@ -1,6 +1,8 @@ package info.frostfs.sdk; public class ArrayHelper { + private ArrayHelper() { + } public static byte[] concat(byte[] startArray, byte[] endArray) { byte[] result = new byte[startArray.length + endArray.length]; diff --git a/cryptography/src/main/java/info/frostfs/sdk/Base58.java b/cryptography/src/main/java/info/frostfs/sdk/Base58.java index f75d705..6321d58 100644 --- a/cryptography/src/main/java/info/frostfs/sdk/Base58.java +++ b/cryptography/src/main/java/info/frostfs/sdk/Base58.java @@ -1,5 +1,7 @@ package info.frostfs.sdk; +import org.apache.commons.lang3.StringUtils; + import java.util.Arrays; import static info.frostfs.sdk.ArrayHelper.concat; @@ -18,8 +20,11 @@ public class Base58 { } } + private Base58() { + } + public static byte[] base58CheckDecode(String input) { - if (isNull(input) || input.isEmpty()) { + if (StringUtils.isEmpty(input)) { throw new IllegalArgumentException("Input value is missing"); } @@ -30,10 +35,9 @@ public class Base58 { byte[] decode = Arrays.copyOfRange(buffer, 0, buffer.length - 4); byte[] checksum = getSha256(getSha256(decode)); - if (!Arrays.equals( - Arrays.copyOfRange(buffer, buffer.length - 4, buffer.length), - Arrays.copyOfRange(checksum, 0, 4) - )) { + var bufferEnd = Arrays.copyOfRange(buffer, buffer.length - 4, buffer.length); + var checksumStart = Arrays.copyOfRange(checksum, 0, 4); + if (!Arrays.equals(bufferEnd, checksumStart)) { throw new IllegalArgumentException(); } @@ -41,6 +45,10 @@ public class Base58 { } public static String base58CheckEncode(byte[] data) { + if (isNull(data)) { + throw new IllegalArgumentException("Input value is missing"); + } + byte[] checksum = getSha256(getSha256(data)); var buffer = concat(data, Arrays.copyOfRange(checksum, 0, 4)); var ret = encode(buffer); diff --git a/cryptography/src/main/java/info/frostfs/sdk/Helper.java b/cryptography/src/main/java/info/frostfs/sdk/Helper.java index a6068e2..58b8c1e 100644 --- a/cryptography/src/main/java/info/frostfs/sdk/Helper.java +++ b/cryptography/src/main/java/info/frostfs/sdk/Helper.java @@ -8,9 +8,17 @@ import java.math.BigInteger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; +import static java.util.Objects.isNull; + public class Helper { + private Helper() { + } public static byte[] getRIPEMD160(byte[] value) { + if (isNull(value)) { + throw new IllegalArgumentException("Input value is missing"); + } + var hash = new byte[20]; var digest = new RIPEMD160Digest(); digest.update(value, 0, value.length); @@ -27,14 +35,26 @@ public class Helper { } public static byte[] getSha256(byte[] value) { + if (isNull(value)) { + throw new IllegalArgumentException("Input value is missing"); + } + return getSha256Instance().digest(value); } public static ByteString getSha256(Message value) { + if (isNull(value)) { + throw new IllegalArgumentException("Input value is missing"); + } + return ByteString.copyFrom(getSha256(value.toByteArray())); } - public static String getHexString(byte[] array) { - return String.format("%0" + (array.length << 1) + "x", new BigInteger(1, array)); + public static String getHexString(byte[] value) { + if (isNull(value)) { + throw new IllegalArgumentException("Input value is missing"); + } + + return String.format("%0" + (value.length << 1) + "x", new BigInteger(1, value)); } } diff --git a/cryptography/src/main/java/info/frostfs/sdk/KeyExtension.java b/cryptography/src/main/java/info/frostfs/sdk/KeyExtension.java index 4ef8ffe..40affe5 100644 --- a/cryptography/src/main/java/info/frostfs/sdk/KeyExtension.java +++ b/cryptography/src/main/java/info/frostfs/sdk/KeyExtension.java @@ -1,5 +1,6 @@ package info.frostfs.sdk; +import org.apache.commons.lang3.StringUtils; import org.bouncycastle.asn1.sec.SECNamedCurves; import org.bouncycastle.asn1.sec.SECObjectIdentifiers; import org.bouncycastle.asn1.x9.X9ECParameters; @@ -25,19 +26,23 @@ import java.util.Arrays; import static info.frostfs.sdk.Helper.getRIPEMD160; import static info.frostfs.sdk.Helper.getSha256; +import static java.util.Objects.isNull; import static org.bouncycastle.util.BigIntegers.fromUnsignedByteArray; public class KeyExtension { public static final byte NEO_ADDRESS_VERSION = 0x35; + private static final int DECODE_ADDRESS_LENGTH = 21; private static final int COMPRESSED_PUBLIC_KEY_LENGTH = 33; private static final int UNCOMPRESSED_PUBLIC_KEY_LENGTH = 65; - private static final int CHECK_SIG_DESCRIPTOR = ByteBuffer .wrap(getSha256("System.Crypto.CheckSig".getBytes(StandardCharsets.US_ASCII))) .order(ByteOrder.LITTLE_ENDIAN).getInt(); + private KeyExtension() { + } public static byte[] compress(byte[] publicKey) { + checkInputValue(publicKey); if (publicKey.length != UNCOMPRESSED_PUBLIC_KEY_LENGTH) { throw new IllegalArgumentException( String.format("Compress argument isn't uncompressed public key. Expected length=%s, actual=%s", @@ -51,11 +56,17 @@ public class KeyExtension { } public static byte[] getPrivateKeyFromWIF(String wif) { + if (StringUtils.isEmpty(wif)) { + throw new IllegalArgumentException("Input value is missing"); + } + var data = Base58.base58CheckDecode(wif); return Arrays.copyOfRange(data, 1, data.length - 1); } public static byte[] loadPublicKey(byte[] privateKey) { + checkInputValue(privateKey); + X9ECParameters params = SECNamedCurves.getByOID(SECObjectIdentifiers.secp256r1); ECDomainParameters domain = new ECDomainParameters( params.getCurve(), params.getG(), params.getN(), params.getH() @@ -66,6 +77,8 @@ public class KeyExtension { } public static PrivateKey loadPrivateKey(byte[] privateKey) { + checkInputValue(privateKey); + X9ECParameters params = SECNamedCurves.getByOID(SECObjectIdentifiers.secp256r1); ECDomainParameters domain = new ECDomainParameters( params.getCurve(), params.getG(), params.getN(), params.getH() @@ -85,6 +98,8 @@ public class KeyExtension { } public static PublicKey getPublicKeyFromBytes(byte[] publicKey) { + checkInputValue(publicKey); + if (publicKey.length != COMPRESSED_PUBLIC_KEY_LENGTH) { throw new IllegalArgumentException( String.format("Decompress argument isn't compressed public key. Expected length=%s, actual=%s", @@ -116,12 +131,14 @@ public class KeyExtension { } public static byte[] getScriptHash(byte[] publicKey) { - var script = createSignatureRedeemScript(publicKey); + checkInputValue(publicKey); + var script = createSignatureRedeemScript(publicKey); return getRIPEMD160(getSha256(script)); } public static String publicKeyToAddress(byte[] publicKey) { + checkInputValue(publicKey); if (publicKey.length != COMPRESSED_PUBLIC_KEY_LENGTH) { throw new IllegalArgumentException( String.format("PublicKey isn't encoded compressed public key. Expected length=%s, actual=%s", @@ -133,7 +150,8 @@ public class KeyExtension { } private static String toAddress(byte[] scriptHash, byte version) { - byte[] data = new byte[21]; + checkInputValue(scriptHash); + byte[] data = new byte[DECODE_ADDRESS_LENGTH]; data[0] = version; System.arraycopy(scriptHash, 0, data, 1, scriptHash.length); return Base58.base58CheckEncode(data); @@ -150,6 +168,7 @@ public class KeyExtension { } private static byte[] createSignatureRedeemScript(byte[] publicKey) { + checkInputValue(publicKey); if (publicKey.length != COMPRESSED_PUBLIC_KEY_LENGTH) { throw new IllegalArgumentException( String.format("PublicKey isn't encoded compressed public key. Expected length=%s, actual=%s", @@ -164,4 +183,10 @@ public class KeyExtension { script = ArrayHelper.concat(script, getBytes(CHECK_SIG_DESCRIPTOR)); //Neo_Crypto_CheckSig return script; } + + private static void checkInputValue(byte[] data) { + if (isNull(data)) { + throw new IllegalArgumentException("Input value is missing"); + } + } } diff --git a/models/pom.xml b/models/pom.xml index e9dd655..edc1c26 100644 --- a/models/pom.xml +++ b/models/pom.xml @@ -18,11 +18,6 @@ - - org.apache.commons - commons-lang3 - 3.14.0 - info.frostfs.sdk cryptography @@ -33,6 +28,16 @@ protos 0.1.0 + + org.apache.commons + commons-lang3 + 3.14.0 + + + org.apache.commons + commons-collections4 + 4.4 + \ No newline at end of file diff --git a/models/src/main/java/info/frostfs/sdk/UUIDExtension.java b/models/src/main/java/info/frostfs/sdk/UUIDExtension.java index 7edc01c..730a1a5 100644 --- a/models/src/main/java/info/frostfs/sdk/UUIDExtension.java +++ b/models/src/main/java/info/frostfs/sdk/UUIDExtension.java @@ -3,19 +3,33 @@ package info.frostfs.sdk; import java.nio.ByteBuffer; import java.util.UUID; +import static java.util.Objects.isNull; + public class UUIDExtension { + private static final int UUID_BYTE_ARRAY_LENGTH = 16; + + private UUIDExtension() { + } public static UUID asUuid(byte[] bytes) { + if (isNull(bytes) || bytes.length != UUID_BYTE_ARRAY_LENGTH) { + throw new IllegalArgumentException("Uuid byte array length must be " + UUID_BYTE_ARRAY_LENGTH); + } + ByteBuffer bb = ByteBuffer.wrap(bytes); long firstLong = bb.getLong(); long secondLong = bb.getLong(); return new UUID(firstLong, secondLong); } - public static byte[] asBytes(UUID id) { + public static byte[] asBytes(UUID uuid) { + if (isNull(uuid)) { + throw new IllegalArgumentException("Uuid is not present"); + } + ByteBuffer bb = ByteBuffer.allocate(16); - bb.putLong(id.getMostSignificantBits()); - bb.putLong(id.getLeastSignificantBits()); + bb.putLong(uuid.getMostSignificantBits()); + bb.putLong(uuid.getLeastSignificantBits()); return bb.array(); } } diff --git a/models/src/main/java/info/frostfs/sdk/constants/AppConst.java b/models/src/main/java/info/frostfs/sdk/constants/AppConst.java index ea60f0e..a823466 100644 --- a/models/src/main/java/info/frostfs/sdk/constants/AppConst.java +++ b/models/src/main/java/info/frostfs/sdk/constants/AppConst.java @@ -1,6 +1,11 @@ package info.frostfs.sdk.constants; public class AppConst { + public static final int DEFAULT_MAJOR_VERSION = 2; + public static final int DEFAULT_MINOR_VERSION = 13; public static final int OBJECT_CHUNK_SIZE = 3 * (1 << 20); public static final int SHA256_HASH_LENGTH = 32; + + private AppConst() { + } } diff --git a/models/src/main/java/info/frostfs/sdk/constants/FieldConst.java b/models/src/main/java/info/frostfs/sdk/constants/FieldConst.java index fe85aad..636df86 100644 --- a/models/src/main/java/info/frostfs/sdk/constants/FieldConst.java +++ b/models/src/main/java/info/frostfs/sdk/constants/FieldConst.java @@ -8,4 +8,8 @@ public class FieldConst { public static final String ORIGIN_FIELD_NAME = "origin"; public static final String ORIGIN_SIGNATURE_FIELD_NAME = "origin_signature"; public static final String VERIFY_HEADER_FIELD_NAME = "verify_header"; + public static final String EMPTY_STRING = ""; + + private FieldConst() { + } } diff --git a/models/src/main/java/info/frostfs/sdk/constants/XHeaderConst.java b/models/src/main/java/info/frostfs/sdk/constants/XHeaderConst.java index c1cc83c..e8b2c72 100644 --- a/models/src/main/java/info/frostfs/sdk/constants/XHeaderConst.java +++ b/models/src/main/java/info/frostfs/sdk/constants/XHeaderConst.java @@ -4,4 +4,7 @@ public class XHeaderConst { public static final String RESERVED_XHEADER_PREFIX = "__SYSTEM__"; public static final String XHEADER_NETMAP_EPOCH = RESERVED_XHEADER_PREFIX + "NETMAP_EPOCH"; public static final String XHEADER_NETMAP_LOOKUP_DEPTH = RESERVED_XHEADER_PREFIX + "NETMAP_LOOKUP_DEPTH"; + + private XHeaderConst() { + } } diff --git a/models/src/main/java/info/frostfs/sdk/dto/MetaHeader.java b/models/src/main/java/info/frostfs/sdk/dto/MetaHeader.java index 4e22f46..9d6735e 100644 --- a/models/src/main/java/info/frostfs/sdk/dto/MetaHeader.java +++ b/models/src/main/java/info/frostfs/sdk/dto/MetaHeader.java @@ -1,18 +1,28 @@ package info.frostfs.sdk.dto; +import static info.frostfs.sdk.constants.AppConst.DEFAULT_MAJOR_VERSION; +import static info.frostfs.sdk.constants.AppConst.DEFAULT_MINOR_VERSION; +import static java.util.Objects.isNull; + public class MetaHeader { private Version version; private int epoch; private int ttl; public MetaHeader(Version version, int epoch, int ttl) { + if (isNull(version) || epoch < 0 || ttl <= 0) { + throw new IllegalArgumentException("One of the input attributes is invalid or missing"); + } + this.version = version; this.epoch = epoch; this.ttl = ttl; } - public static MetaHeader getDefault() { - return new MetaHeader(new Version(2, 13), 0, 2); + public MetaHeader() { + this.version = new Version(DEFAULT_MAJOR_VERSION, DEFAULT_MINOR_VERSION); + this.epoch = 0; + this.ttl = 2; } public Version getVersion() { @@ -20,6 +30,10 @@ public class MetaHeader { } public void setVersion(Version version) { + if (isNull(version)) { + throw new IllegalArgumentException("Version is missing."); + } + this.version = version; } @@ -28,6 +42,10 @@ public class MetaHeader { } public void setEpoch(int epoch) { + if (epoch < 0) { + throw new IllegalArgumentException("The epoch must be greater than or equal to zero."); + } + this.epoch = epoch; } @@ -36,6 +54,10 @@ public class MetaHeader { } public void setTtl(int ttl) { + if (ttl <= 0) { + throw new IllegalArgumentException("The ttl must be greater than zero."); + } + this.ttl = ttl; } } diff --git a/models/src/main/java/info/frostfs/sdk/dto/OwnerId.java b/models/src/main/java/info/frostfs/sdk/dto/OwnerId.java index d4a173b..1603e21 100644 --- a/models/src/main/java/info/frostfs/sdk/dto/OwnerId.java +++ b/models/src/main/java/info/frostfs/sdk/dto/OwnerId.java @@ -3,6 +3,7 @@ package info.frostfs.sdk.dto; import info.frostfs.sdk.Base58; import static info.frostfs.sdk.KeyExtension.publicKeyToAddress; +import static java.util.Objects.isNull; public class OwnerId { private final String value; @@ -11,8 +12,12 @@ public class OwnerId { this.value = value; } - public static OwnerId fromKey(byte[] publicKey) { - return new OwnerId(publicKeyToAddress(publicKey)); + public OwnerId(byte[] publicKey) { + if (isNull(publicKey) || publicKey.length == 0) { + throw new IllegalArgumentException("PublicKey is invalid"); + } + + this.value = publicKeyToAddress(publicKey); } public String getValue() { diff --git a/models/src/main/java/info/frostfs/sdk/dto/Split.java b/models/src/main/java/info/frostfs/sdk/dto/Split.java index 2b5726a..642ed58 100644 --- a/models/src/main/java/info/frostfs/sdk/dto/Split.java +++ b/models/src/main/java/info/frostfs/sdk/dto/Split.java @@ -6,9 +6,11 @@ import info.frostfs.sdk.dto.object.ObjectId; import java.util.ArrayList; import java.util.List; +import static java.util.Objects.isNull; + public class Split { private final List children; - private SplitId splitId; + private final SplitId splitId; private ObjectId parent; private ObjectId previous; private Signature parentSignature; @@ -19,6 +21,10 @@ public class Split { } public Split(SplitId splitId) { + if (isNull(splitId)) { + throw new IllegalArgumentException("SplitId is not present"); + } + this.splitId = splitId; this.children = new ArrayList<>(); } @@ -27,10 +33,6 @@ public class Split { return splitId; } - private void setSplitId(SplitId splitId) { - this.splitId = splitId; - } - public ObjectId getParent() { return parent; } diff --git a/models/src/main/java/info/frostfs/sdk/dto/SplitId.java b/models/src/main/java/info/frostfs/sdk/dto/SplitId.java index 6ecc031..3ced690 100644 --- a/models/src/main/java/info/frostfs/sdk/dto/SplitId.java +++ b/models/src/main/java/info/frostfs/sdk/dto/SplitId.java @@ -9,30 +9,22 @@ import static java.util.Objects.isNull; public class SplitId { private final UUID id; - public SplitId(UUID uuid) { - this.id = uuid; - } - public SplitId() { this.id = UUID.randomUUID(); } - private SplitId(byte[] binary) { + public SplitId(UUID uuid) { + this.id = uuid; + } + + public SplitId(byte[] binary) { this.id = asUuid(binary); } - private SplitId(String str) { + public SplitId(String str) { this.id = UUID.fromString(str); } - public static SplitId createFromBinary(byte[] binaryData) { - return new SplitId(binaryData); - } - - public static SplitId createFromString(String stringData) { - return new SplitId(stringData); - } - @Override public String toString() { return id.toString(); diff --git a/models/src/main/java/info/frostfs/sdk/dto/Status.java b/models/src/main/java/info/frostfs/sdk/dto/Status.java index dd242a3..e1075b5 100644 --- a/models/src/main/java/info/frostfs/sdk/dto/Status.java +++ b/models/src/main/java/info/frostfs/sdk/dto/Status.java @@ -2,6 +2,7 @@ package info.frostfs.sdk.dto; import info.frostfs.sdk.enums.StatusCode; +import static info.frostfs.sdk.constants.FieldConst.EMPTY_STRING; import static java.util.Objects.isNull; public class Status { @@ -10,12 +11,12 @@ public class Status { public Status(StatusCode code, String message) { this.code = code; - this.message = isNull(message) ? "" : message; + this.message = isNull(message) ? EMPTY_STRING : message; } public Status(StatusCode code) { this.code = code; - this.message = ""; + this.message = EMPTY_STRING; } public StatusCode getCode() { diff --git a/models/src/main/java/info/frostfs/sdk/dto/Version.java b/models/src/main/java/info/frostfs/sdk/dto/Version.java index 563d8b6..0222922 100644 --- a/models/src/main/java/info/frostfs/sdk/dto/Version.java +++ b/models/src/main/java/info/frostfs/sdk/dto/Version.java @@ -1,36 +1,41 @@ package info.frostfs.sdk.dto; +import static info.frostfs.sdk.constants.AppConst.DEFAULT_MAJOR_VERSION; +import static info.frostfs.sdk.constants.AppConst.DEFAULT_MINOR_VERSION; +import static java.util.Objects.isNull; + public class Version { - private int major; - private int minor; + private final int major; + private final int minor; public Version(int major, int minor) { this.major = major; this.minor = minor; } + public Version() { + this.major = DEFAULT_MAJOR_VERSION; + this.minor = DEFAULT_MINOR_VERSION; + } + public int getMajor() { return major; } - public void setMajor(int major) { - this.major = major; - } - public int getMinor() { return minor; } - public void setMinor(int minor) { - this.minor = minor; - } - @Override public String toString() { return "v" + major + "." + minor; } public boolean isSupported(Version version) { + if (isNull(version)) { + return false; + } + return major == version.getMajor(); } } diff --git a/models/src/main/java/info/frostfs/sdk/dto/container/ContainerId.java b/models/src/main/java/info/frostfs/sdk/dto/container/ContainerId.java index b24a069..1cd39b2 100644 --- a/models/src/main/java/info/frostfs/sdk/dto/container/ContainerId.java +++ b/models/src/main/java/info/frostfs/sdk/dto/container/ContainerId.java @@ -2,29 +2,33 @@ package info.frostfs.sdk.dto.container; import info.frostfs.sdk.Base58; import info.frostfs.sdk.constants.AppConst; +import org.apache.commons.lang3.StringUtils; + +import static java.util.Objects.isNull; public class ContainerId { - private String value; + private final String value; public ContainerId(String value) { + if (StringUtils.isEmpty(value)) { + throw new IllegalArgumentException("ContainerId value is missing"); + } + this.value = value; } - public static ContainerId fromHash(byte[] hash) { - if (hash.length != AppConst.SHA256_HASH_LENGTH) { - throw new IllegalArgumentException("ContainerID must be a sha256 hash."); + public ContainerId(byte[] hash) { + if (isNull(hash) || hash.length != AppConst.SHA256_HASH_LENGTH) { + throw new IllegalArgumentException("ContainerId must be a sha256 hash."); } - return new ContainerId(Base58.encode(hash)); + + this.value = Base58.encode(hash); } public String getValue() { return value; } - public void setValue(String value) { - this.value = value; - } - @Override public String toString() { return value; diff --git a/models/src/main/java/info/frostfs/sdk/dto/netmap/Replica.java b/models/src/main/java/info/frostfs/sdk/dto/netmap/Replica.java index 235d288..74e3886 100644 --- a/models/src/main/java/info/frostfs/sdk/dto/netmap/Replica.java +++ b/models/src/main/java/info/frostfs/sdk/dto/netmap/Replica.java @@ -1,34 +1,36 @@ package info.frostfs.sdk.dto.netmap; -import static java.util.Objects.isNull; +import org.apache.commons.lang3.StringUtils; + +import static info.frostfs.sdk.constants.FieldConst.EMPTY_STRING; public class Replica { - private int count; - private String selector; + private final int count; + private final String selector; public Replica(int count, String selector) { + if (count <= 0) { + throw new IllegalArgumentException("Replica count must be positive"); + } + this.count = count; - this.selector = isNull(selector) ? "" : selector; + this.selector = StringUtils.isEmpty(selector) ? EMPTY_STRING : selector; } public Replica(int count) { + if (count <= 0) { + throw new IllegalArgumentException("Replica count must be positive"); + } + this.count = count; - this.selector = ""; + this.selector = EMPTY_STRING; } public int getCount() { return count; } - public void setCount(int count) { - this.count = count; - } - public String getSelector() { return selector; } - - public void setSelector(String selector) { - this.selector = selector; - } } diff --git a/models/src/main/java/info/frostfs/sdk/dto/object/LargeObject.java b/models/src/main/java/info/frostfs/sdk/dto/object/LargeObject.java index 4cab2ed..915b745 100644 --- a/models/src/main/java/info/frostfs/sdk/dto/object/LargeObject.java +++ b/models/src/main/java/info/frostfs/sdk/dto/object/LargeObject.java @@ -5,6 +5,7 @@ import info.frostfs.sdk.dto.container.ContainerId; import java.security.MessageDigest; import static info.frostfs.sdk.Helper.getSha256Instance; +import static java.util.Objects.isNull; public class LargeObject extends ObjectFrostFS { private final MessageDigest payloadHash; @@ -15,6 +16,10 @@ public class LargeObject extends ObjectFrostFS { } public void appendBlock(byte[] bytes, int count) { + if (count == 0 || isNull(bytes) || bytes.length == 0) { + return; + } + this.getHeader().increasePayloadLength(count); this.payloadHash.update(bytes, 0, count); } diff --git a/models/src/main/java/info/frostfs/sdk/dto/object/LinkObject.java b/models/src/main/java/info/frostfs/sdk/dto/object/LinkObject.java index b641888..d7a7091 100644 --- a/models/src/main/java/info/frostfs/sdk/dto/object/LinkObject.java +++ b/models/src/main/java/info/frostfs/sdk/dto/object/LinkObject.java @@ -3,6 +3,7 @@ package info.frostfs.sdk.dto.object; import info.frostfs.sdk.dto.Split; import info.frostfs.sdk.dto.SplitId; import info.frostfs.sdk.dto.container.ContainerId; +import org.apache.commons.collections4.CollectionUtils; import java.util.List; @@ -16,6 +17,10 @@ public class LinkObject extends ObjectFrostFS { } public void addChildren(List objectIds) { + if (CollectionUtils.isEmpty(objectIds)) { + return; + } + this.getHeader().getSplit().getChildren().addAll(objectIds); } } diff --git a/models/src/main/java/info/frostfs/sdk/dto/object/ObjectAttribute.java b/models/src/main/java/info/frostfs/sdk/dto/object/ObjectAttribute.java index 0c2554b..60a3ede 100644 --- a/models/src/main/java/info/frostfs/sdk/dto/object/ObjectAttribute.java +++ b/models/src/main/java/info/frostfs/sdk/dto/object/ObjectAttribute.java @@ -1,10 +1,16 @@ package info.frostfs.sdk.dto.object; +import org.apache.commons.lang3.StringUtils; + public class ObjectAttribute { - private String key; - private String value; + private final String key; + private final String value; public ObjectAttribute(String key, String value) { + if (StringUtils.isEmpty(key) || StringUtils.isEmpty(value)) { + throw new IllegalArgumentException("One of the input attributes is missing"); + } + this.key = key; this.value = value; } @@ -13,15 +19,7 @@ public class ObjectAttribute { return key; } - public void setKey(String key) { - this.key = key; - } - public String getValue() { return value; } - - public void setValue(String value) { - this.value = value; - } } diff --git a/models/src/main/java/info/frostfs/sdk/dto/object/ObjectFrostFS.java b/models/src/main/java/info/frostfs/sdk/dto/object/ObjectFrostFS.java index 5001161..af5f463 100644 --- a/models/src/main/java/info/frostfs/sdk/dto/object/ObjectFrostFS.java +++ b/models/src/main/java/info/frostfs/sdk/dto/object/ObjectFrostFS.java @@ -10,34 +10,34 @@ import java.util.List; import static java.util.Objects.isNull; public class ObjectFrostFS { - private ObjectHeader header; + private final ObjectHeader header; private ObjectId objectId; private byte[] payload; public ObjectFrostFS(ObjectHeader header, ObjectId objectId, byte[] payload) { + if (isNull(header)) { + throw new IllegalArgumentException("Object header is missing"); + } + this.header = header; this.objectId = objectId; this.payload = payload; } - public ObjectFrostFS(ContainerId container, byte[] payload) { + public ObjectFrostFS(ContainerId containerId, byte[] payload) { this.payload = payload; - this.header = new ObjectHeader(container, new ArrayList<>()); + this.header = new ObjectHeader(containerId, new ArrayList<>()); } - public ObjectFrostFS(ContainerId container, byte[] payload, ObjectType objectType) { + public ObjectFrostFS(ContainerId containerId, byte[] payload, ObjectType objectType) { this.payload = payload; - this.header = new ObjectHeader(container, objectType, new ArrayList<>()); + this.header = new ObjectHeader(containerId, objectType, new ArrayList<>()); } public ObjectHeader getHeader() { return header; } - public void setHeader(ObjectHeader header) { - this.header = header; - } - public ObjectId getObjectId() { return objectId; } diff --git a/models/src/main/java/info/frostfs/sdk/dto/object/ObjectHeader.java b/models/src/main/java/info/frostfs/sdk/dto/object/ObjectHeader.java index 147ec4e..208b936 100644 --- a/models/src/main/java/info/frostfs/sdk/dto/object/ObjectHeader.java +++ b/models/src/main/java/info/frostfs/sdk/dto/object/ObjectHeader.java @@ -8,11 +8,13 @@ import info.frostfs.sdk.enums.ObjectType; import java.util.List; +import static java.util.Objects.isNull; + public class ObjectHeader { + private final ContainerId containerId; + private final ObjectType objectType; private List attributes; - private ContainerId containerId; private long size; - private ObjectType objectType; private Version version; private OwnerId ownerId; private long payloadLength; @@ -21,6 +23,10 @@ public class ObjectHeader { public ObjectHeader(ContainerId containerId, ObjectType objectType, List attributes, long size, Version version) { + if (isNull(containerId) || isNull(objectType)) { + throw new IllegalArgumentException("ContainerId or objectType is not present"); + } + this.attributes = attributes; this.containerId = containerId; this.size = size; @@ -28,13 +34,21 @@ public class ObjectHeader { this.version = version; } - public ObjectHeader(ContainerId containerId, ObjectType type, List attributes) { + public ObjectHeader(ContainerId containerId, ObjectType objectType, List attributes) { + if (isNull(containerId) || isNull(objectType)) { + throw new IllegalArgumentException("ContainerId or objectType is not present"); + } + this.attributes = attributes; this.containerId = containerId; - this.objectType = type; + this.objectType = objectType; } public ObjectHeader(ContainerId containerId, List attributes) { + if (isNull(containerId)) { + throw new IllegalArgumentException("ContainerId is not present"); + } + this.attributes = attributes; this.containerId = containerId; this.objectType = ObjectType.REGULAR; @@ -73,6 +87,10 @@ public class ObjectHeader { } public void setSplit(Split split) { + if (isNull(split)) { + throw new IllegalArgumentException("Split is not present"); + } + this.split = split; } @@ -88,10 +106,6 @@ public class ObjectHeader { return containerId; } - public void setContainerId(ContainerId containerId) { - this.containerId = containerId; - } - public long getSize() { return size; } @@ -104,10 +118,6 @@ public class ObjectHeader { return objectType; } - public void setObjectType(ObjectType objectType) { - this.objectType = objectType; - } - public Version getVersion() { return version; } diff --git a/models/src/main/java/info/frostfs/sdk/dto/object/ObjectId.java b/models/src/main/java/info/frostfs/sdk/dto/object/ObjectId.java index 3c9965a..7c6bffb 100644 --- a/models/src/main/java/info/frostfs/sdk/dto/object/ObjectId.java +++ b/models/src/main/java/info/frostfs/sdk/dto/object/ObjectId.java @@ -2,19 +2,27 @@ package info.frostfs.sdk.dto.object; import info.frostfs.sdk.Base58; import info.frostfs.sdk.constants.AppConst; +import org.apache.commons.lang3.StringUtils; + +import static java.util.Objects.isNull; public class ObjectId { private final String value; - public ObjectId(String id) { - this.value = id; + public ObjectId(String value) { + if (StringUtils.isEmpty(value)) { + throw new IllegalArgumentException("ObjectId value is missing"); + } + + this.value = value; } - public static ObjectId fromHash(byte[] hash) { - if (hash.length != AppConst.SHA256_HASH_LENGTH) { + public ObjectId(byte[] hash) { + if (isNull(hash) || hash.length != AppConst.SHA256_HASH_LENGTH) { throw new IllegalArgumentException("ObjectId must be a sha256 hash."); } - return new ObjectId(Base58.encode(hash)); + + this.value = Base58.encode(hash); } public String getValue() { diff --git a/models/src/main/java/info/frostfs/sdk/mappers/MetaHeaderMapper.java b/models/src/main/java/info/frostfs/sdk/mappers/MetaHeaderMapper.java index 736871c..0b90453 100644 --- a/models/src/main/java/info/frostfs/sdk/mappers/MetaHeaderMapper.java +++ b/models/src/main/java/info/frostfs/sdk/mappers/MetaHeaderMapper.java @@ -3,9 +3,18 @@ package info.frostfs.sdk.mappers; import frostfs.session.Types; import info.frostfs.sdk.dto.MetaHeader; +import static java.util.Objects.isNull; + public class MetaHeaderMapper { + private MetaHeaderMapper() { + } + public static Types.RequestMetaHeader toGrpcMessage(MetaHeader metaHeader) { + if (isNull(metaHeader)) { + return null; + } + return Types.RequestMetaHeader.newBuilder() .setVersion(VersionMapper.toGrpcMessage(metaHeader.getVersion())) .setEpoch(metaHeader.getEpoch()) diff --git a/models/src/main/java/info/frostfs/sdk/mappers/OwnerIdMapper.java b/models/src/main/java/info/frostfs/sdk/mappers/OwnerIdMapper.java index 69cb6e8..a0a6b64 100644 --- a/models/src/main/java/info/frostfs/sdk/mappers/OwnerIdMapper.java +++ b/models/src/main/java/info/frostfs/sdk/mappers/OwnerIdMapper.java @@ -4,9 +4,18 @@ import com.google.protobuf.ByteString; import frostfs.refs.Types; import info.frostfs.sdk.dto.OwnerId; +import static java.util.Objects.isNull; + public class OwnerIdMapper { + private OwnerIdMapper() { + } + public static Types.OwnerID toGrpcMessage(OwnerId ownerId) { + if (isNull(ownerId)) { + return null; + } + return Types.OwnerID.newBuilder() .setValue(ByteString.copyFrom(ownerId.toHash())) .build(); diff --git a/models/src/main/java/info/frostfs/sdk/mappers/SessionMapper.java b/models/src/main/java/info/frostfs/sdk/mappers/SessionMapper.java index c13a61e..45331cf 100644 --- a/models/src/main/java/info/frostfs/sdk/mappers/SessionMapper.java +++ b/models/src/main/java/info/frostfs/sdk/mappers/SessionMapper.java @@ -6,9 +6,18 @@ import frostfs.session.Types; import java.io.IOException; +import static java.util.Objects.isNull; + public class SessionMapper { + private SessionMapper() { + } + public static byte[] serialize(Types.SessionToken token) { + if (isNull(token)) { + throw new IllegalArgumentException("Token is not present"); + } + try { byte[] bytes = new byte[token.getSerializedSize()]; CodedOutputStream stream = CodedOutputStream.newInstance(bytes); @@ -20,6 +29,10 @@ public class SessionMapper { } public static Types.SessionToken deserializeSessionToken(byte[] bytes) { + if (isNull(bytes) || bytes.length == 0) { + throw new IllegalArgumentException("Token is not present"); + } + try { return Types.SessionToken.newBuilder().mergeFrom(bytes).build(); } catch (InvalidProtocolBufferException exp) { diff --git a/models/src/main/java/info/frostfs/sdk/mappers/SignatureMapper.java b/models/src/main/java/info/frostfs/sdk/mappers/SignatureMapper.java index 1a62bfd..5f14f4a 100644 --- a/models/src/main/java/info/frostfs/sdk/mappers/SignatureMapper.java +++ b/models/src/main/java/info/frostfs/sdk/mappers/SignatureMapper.java @@ -8,7 +8,14 @@ import static java.util.Objects.isNull; public class SignatureMapper { - public static Types.Signature ToGrpcMessage(Signature signature) { + private SignatureMapper() { + } + + public static Types.Signature toGrpcMessage(Signature signature) { + if (isNull(signature)) { + return null; + } + var scheme = Types.SignatureScheme.forNumber(signature.getScheme().value); if (isNull(scheme)) { throw new IllegalArgumentException( diff --git a/models/src/main/java/info/frostfs/sdk/mappers/StatusMapper.java b/models/src/main/java/info/frostfs/sdk/mappers/StatusMapper.java index 7c6f3b1..2bfa717 100644 --- a/models/src/main/java/info/frostfs/sdk/mappers/StatusMapper.java +++ b/models/src/main/java/info/frostfs/sdk/mappers/StatusMapper.java @@ -8,8 +8,13 @@ import static java.util.Objects.isNull; public class StatusMapper { + private StatusMapper() { + } + public static Status toModel(Types.Status status) { - if (isNull(status)) return new Status(StatusCode.SUCCESS); + if (isNull(status)) { + return new Status(StatusCode.SUCCESS); + } var statusCode = StatusCode.get(status.getCode()); if (isNull(statusCode)) { diff --git a/models/src/main/java/info/frostfs/sdk/mappers/VersionMapper.java b/models/src/main/java/info/frostfs/sdk/mappers/VersionMapper.java index 7888a67..13e7a0d 100644 --- a/models/src/main/java/info/frostfs/sdk/mappers/VersionMapper.java +++ b/models/src/main/java/info/frostfs/sdk/mappers/VersionMapper.java @@ -3,9 +3,18 @@ package info.frostfs.sdk.mappers; import frostfs.refs.Types; import info.frostfs.sdk.dto.Version; +import static java.util.Objects.isNull; + public class VersionMapper { + private VersionMapper() { + } + public static Types.Version toGrpcMessage(Version version) { + if (isNull(version)) { + return null; + } + return Types.Version.newBuilder() .setMajor(version.getMajor()) .setMinor(version.getMinor()) @@ -13,6 +22,10 @@ public class VersionMapper { } public static Version toModel(Types.Version version) { + if (isNull(version)) { + return null; + } + return new Version(version.getMajor(), version.getMinor()); } } diff --git a/models/src/main/java/info/frostfs/sdk/mappers/container/ContainerIdMapper.java b/models/src/main/java/info/frostfs/sdk/mappers/container/ContainerIdMapper.java index cbe7237..26e941c 100644 --- a/models/src/main/java/info/frostfs/sdk/mappers/container/ContainerIdMapper.java +++ b/models/src/main/java/info/frostfs/sdk/mappers/container/ContainerIdMapper.java @@ -4,9 +4,18 @@ import com.google.protobuf.ByteString; import frostfs.refs.Types; import info.frostfs.sdk.dto.container.ContainerId; +import static java.util.Objects.isNull; + public class ContainerIdMapper { + private ContainerIdMapper() { + } + public static Types.ContainerID toGrpcMessage(ContainerId containerId) { + if (isNull(containerId)) { + return null; + } + return Types.ContainerID.newBuilder() .setValue(ByteString.copyFrom(containerId.toHash())) .build(); diff --git a/models/src/main/java/info/frostfs/sdk/mappers/container/ContainerMapper.java b/models/src/main/java/info/frostfs/sdk/mappers/container/ContainerMapper.java index ff36486..9aa1741 100644 --- a/models/src/main/java/info/frostfs/sdk/mappers/container/ContainerMapper.java +++ b/models/src/main/java/info/frostfs/sdk/mappers/container/ContainerMapper.java @@ -13,7 +13,14 @@ import static java.util.Objects.isNull; public class ContainerMapper { + private ContainerMapper() { + } + public static Types.Container toGrpcMessage(Container container) { + if (isNull(container)) { + return null; + } + return Types.Container.newBuilder() .setBasicAcl(container.getBasicAcl().value) .setPlacementPolicy(PlacementPolicyMapper.toGrpcMessage(container.getPlacementPolicy())) @@ -22,6 +29,10 @@ public class ContainerMapper { } public static Container toModel(Types.Container containerGrpc) { + if (isNull(containerGrpc)) { + return null; + } + var basicAcl = BasicAcl.get(containerGrpc.getBasicAcl()); if (isNull(basicAcl)) { throw new IllegalArgumentException( diff --git a/models/src/main/java/info/frostfs/sdk/mappers/netmap/NetmapSnapshotMapper.java b/models/src/main/java/info/frostfs/sdk/mappers/netmap/NetmapSnapshotMapper.java index a396f58..f911e74 100644 --- a/models/src/main/java/info/frostfs/sdk/mappers/netmap/NetmapSnapshotMapper.java +++ b/models/src/main/java/info/frostfs/sdk/mappers/netmap/NetmapSnapshotMapper.java @@ -5,9 +5,18 @@ import info.frostfs.sdk.dto.netmap.NetmapSnapshot; import java.util.stream.Collectors; +import static java.util.Objects.isNull; + public class NetmapSnapshotMapper { + private NetmapSnapshotMapper() { + } + public static NetmapSnapshot toModel(Service.NetmapSnapshotResponse netmap) { + if (isNull(netmap)) { + return null; + } + return new NetmapSnapshot( netmap.getBody().getNetmap().getEpoch(), netmap.getBody().getNetmap().getNodesList().stream() diff --git a/models/src/main/java/info/frostfs/sdk/mappers/netmap/NodeInfoMapper.java b/models/src/main/java/info/frostfs/sdk/mappers/netmap/NodeInfoMapper.java index c2bd9b7..d91dcd1 100644 --- a/models/src/main/java/info/frostfs/sdk/mappers/netmap/NodeInfoMapper.java +++ b/models/src/main/java/info/frostfs/sdk/mappers/netmap/NodeInfoMapper.java @@ -13,11 +13,22 @@ import static java.util.Objects.isNull; public class NodeInfoMapper { + private NodeInfoMapper() { + } + public static NodeInfo toModel(Service.LocalNodeInfoResponse.Body nodeInfo) { + if (isNull(nodeInfo)) { + return null; + } + return toModel(nodeInfo.getNodeInfo(), nodeInfo.getVersion()); } public static NodeInfo toModel(frostfs.netmap.Types.NodeInfo nodeInfo, Types.Version version) { + if (isNull(nodeInfo)) { + return null; + } + NodeState nodeState = NodeState.get(nodeInfo.getState().getNumber()); if (isNull(nodeState)) { throw new IllegalArgumentException( diff --git a/models/src/main/java/info/frostfs/sdk/mappers/netmap/PlacementPolicyMapper.java b/models/src/main/java/info/frostfs/sdk/mappers/netmap/PlacementPolicyMapper.java index 4a6675c..f5bdaef 100644 --- a/models/src/main/java/info/frostfs/sdk/mappers/netmap/PlacementPolicyMapper.java +++ b/models/src/main/java/info/frostfs/sdk/mappers/netmap/PlacementPolicyMapper.java @@ -4,9 +4,18 @@ import frostfs.netmap.Types; import info.frostfs.sdk.dto.netmap.PlacementPolicy; import info.frostfs.sdk.dto.netmap.Replica; +import static java.util.Objects.isNull; + public class PlacementPolicyMapper { + private PlacementPolicyMapper() { + } + public static Types.PlacementPolicy toGrpcMessage(PlacementPolicy placementPolicy) { + if (isNull(placementPolicy)) { + return null; + } + var pp = Types.PlacementPolicy.newBuilder() .setUnique(placementPolicy.isUnique()); @@ -18,6 +27,10 @@ public class PlacementPolicyMapper { } public static PlacementPolicy toModel(Types.PlacementPolicy placementPolicy) { + if (isNull(placementPolicy)) { + return null; + } + return new PlacementPolicy( placementPolicy.getUnique(), placementPolicy.getReplicasList().stream().map(ReplicaMapper::toModel).toArray(Replica[]::new) diff --git a/models/src/main/java/info/frostfs/sdk/mappers/netmap/ReplicaMapper.java b/models/src/main/java/info/frostfs/sdk/mappers/netmap/ReplicaMapper.java index eef3e70..e25ec21 100644 --- a/models/src/main/java/info/frostfs/sdk/mappers/netmap/ReplicaMapper.java +++ b/models/src/main/java/info/frostfs/sdk/mappers/netmap/ReplicaMapper.java @@ -3,9 +3,18 @@ package info.frostfs.sdk.mappers.netmap; import frostfs.netmap.Types; import info.frostfs.sdk.dto.netmap.Replica; +import static java.util.Objects.isNull; + public class ReplicaMapper { + private ReplicaMapper() { + } + public static Types.Replica toGrpcMessage(Replica replica) { + if (isNull(replica)) { + return null; + } + return Types.Replica.newBuilder() .setCount(replica.getCount()) .setSelector(replica.getSelector()) @@ -13,6 +22,10 @@ public class ReplicaMapper { } public static Replica toModel(Types.Replica replica) { + if (isNull(replica)) { + return null; + } + return new Replica(replica.getCount(), replica.getSelector()); } } diff --git a/models/src/main/java/info/frostfs/sdk/mappers/object/ObjectAttributeMapper.java b/models/src/main/java/info/frostfs/sdk/mappers/object/ObjectAttributeMapper.java index 62c67cb..17c3e94 100644 --- a/models/src/main/java/info/frostfs/sdk/mappers/object/ObjectAttributeMapper.java +++ b/models/src/main/java/info/frostfs/sdk/mappers/object/ObjectAttributeMapper.java @@ -3,9 +3,18 @@ package info.frostfs.sdk.mappers.object; import frostfs.object.Types; import info.frostfs.sdk.dto.object.ObjectAttribute; +import static java.util.Objects.isNull; + public class ObjectAttributeMapper { + private ObjectAttributeMapper() { + } + public static Types.Header.Attribute toGrpcMessage(ObjectAttribute attribute) { + if (isNull(attribute)) { + return null; + } + return Types.Header.Attribute.newBuilder() .setKey(attribute.getKey()) .setValue(attribute.getValue()) @@ -13,6 +22,10 @@ public class ObjectAttributeMapper { } public static ObjectAttribute toModel(Types.Header.Attribute attribute) { + if (isNull(attribute)) { + return null; + } + return new ObjectAttribute(attribute.getKey(), attribute.getValue()); } } diff --git a/models/src/main/java/info/frostfs/sdk/mappers/object/ObjectFilterMapper.java b/models/src/main/java/info/frostfs/sdk/mappers/object/ObjectFilterMapper.java index 8bbe23e..b1c121d 100644 --- a/models/src/main/java/info/frostfs/sdk/mappers/object/ObjectFilterMapper.java +++ b/models/src/main/java/info/frostfs/sdk/mappers/object/ObjectFilterMapper.java @@ -8,7 +8,14 @@ import static java.util.Objects.isNull; public class ObjectFilterMapper { + private ObjectFilterMapper() { + } + public static Service.SearchRequest.Body.Filter toGrpcMessage(ObjectFilter filter) { + if (isNull(filter)) { + return null; + } + var objectMatchType = Types.MatchType.forNumber(filter.getMatchType().value); if (isNull(objectMatchType)) { throw new IllegalArgumentException( diff --git a/models/src/main/java/info/frostfs/sdk/mappers/object/ObjectFrostFSMapper.java b/models/src/main/java/info/frostfs/sdk/mappers/object/ObjectFrostFSMapper.java index 28b8332..aa5f698 100644 --- a/models/src/main/java/info/frostfs/sdk/mappers/object/ObjectFrostFSMapper.java +++ b/models/src/main/java/info/frostfs/sdk/mappers/object/ObjectFrostFSMapper.java @@ -4,13 +4,22 @@ import frostfs.object.Types; import info.frostfs.sdk.dto.object.ObjectFrostFS; import info.frostfs.sdk.dto.object.ObjectId; +import static java.util.Objects.isNull; + public class ObjectFrostFSMapper { - public static ObjectFrostFS toModel(Types.Object obj) { + private ObjectFrostFSMapper() { + } + + public static ObjectFrostFS toModel(Types.Object object) { + if (isNull(object)) { + return null; + } + return new ObjectFrostFS( - ObjectHeaderMapper.toModel(obj.getHeader()), - ObjectId.fromHash(obj.getObjectId().getValue().toByteArray()), - obj.getPayload().toByteArray() + ObjectHeaderMapper.toModel(object.getHeader()), + new ObjectId(object.getObjectId().getValue().toByteArray()), + object.getPayload().toByteArray() ); } } diff --git a/models/src/main/java/info/frostfs/sdk/mappers/object/ObjectHeaderMapper.java b/models/src/main/java/info/frostfs/sdk/mappers/object/ObjectHeaderMapper.java index 6b8bc91..fc5b4cc 100644 --- a/models/src/main/java/info/frostfs/sdk/mappers/object/ObjectHeaderMapper.java +++ b/models/src/main/java/info/frostfs/sdk/mappers/object/ObjectHeaderMapper.java @@ -14,7 +14,14 @@ import static java.util.Objects.isNull; public class ObjectHeaderMapper { + private ObjectHeaderMapper() { + } + public static Types.Header toGrpcMessage(ObjectHeader header) { + if (isNull(header)) { + return null; + } + var objectType = Types.ObjectType.forNumber(header.getObjectType().value); if (isNull(objectType)) { throw new IllegalArgumentException( @@ -34,6 +41,10 @@ public class ObjectHeaderMapper { } public static ObjectHeader toModel(Types.Header header) { + if (isNull(header)) { + return null; + } + var objectType = ObjectType.get(header.getObjectTypeValue()); if (isNull(objectType)) { throw new IllegalArgumentException( @@ -42,7 +53,7 @@ public class ObjectHeaderMapper { } return new ObjectHeader( - ContainerId.fromHash(header.getContainerId().getValue().toByteArray()), + new ContainerId(header.getContainerId().getValue().toByteArray()), objectType, header.getAttributesList().stream().map(ObjectAttributeMapper::toModel).collect(Collectors.toList()), header.getPayloadLength(), diff --git a/models/src/main/java/info/frostfs/sdk/mappers/object/ObjectIdMapper.java b/models/src/main/java/info/frostfs/sdk/mappers/object/ObjectIdMapper.java index 62ca7c5..af51095 100644 --- a/models/src/main/java/info/frostfs/sdk/mappers/object/ObjectIdMapper.java +++ b/models/src/main/java/info/frostfs/sdk/mappers/object/ObjectIdMapper.java @@ -4,15 +4,24 @@ import com.google.protobuf.ByteString; import frostfs.refs.Types; import info.frostfs.sdk.dto.object.ObjectId; +import static java.util.Objects.isNull; + public class ObjectIdMapper { + private ObjectIdMapper() { + } + public static Types.ObjectID toGrpcMessage(ObjectId objectId) { + if (isNull(objectId)) { + return null; + } + return Types.ObjectID.newBuilder() .setValue(ByteString.copyFrom(objectId.toHash())) .build(); } public static ObjectId toModel(Types.ObjectID objectId) { - return ObjectId.fromHash(objectId.getValue().toByteArray()); + return new ObjectId(objectId.getValue().toByteArray()); } }