[#1] Add additional security
All checks were successful
DCO / DCO (pull_request) Successful in 28s
All checks were successful
DCO / DCO (pull_request) Successful in 28s
Signed-off-by: Ori Bruk <o.bruk@yadro.com>
This commit is contained in:
parent
bf2f19f08d
commit
1be65c63ae
62 changed files with 670 additions and 281 deletions
|
@ -26,7 +26,7 @@ import info.frostfs.sdk.dto.netmap.PlacementPolicy;
|
||||||
import info.frostfs.sdk.dto.netmap.Replica;
|
import info.frostfs.sdk.dto.netmap.Replica;
|
||||||
import info.frostfs.sdk.enums.BasicAcl;
|
import info.frostfs.sdk.enums.BasicAcl;
|
||||||
import info.frostfs.sdk.jdo.ClientSettings;
|
import info.frostfs.sdk.jdo.ClientSettings;
|
||||||
import info.frostfs.sdk.services.FrostFSClient;
|
import info.frostfs.sdk.FrostFSClient;
|
||||||
|
|
||||||
public class ContainerExample {
|
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.ObjectFilter;
|
||||||
import info.frostfs.sdk.dto.object.ObjectHeader;
|
import info.frostfs.sdk.dto.object.ObjectHeader;
|
||||||
import info.frostfs.sdk.jdo.PutObjectParameters;
|
import info.frostfs.sdk.jdo.PutObjectParameters;
|
||||||
import info.frostfs.sdk.services.FrostFSClient;
|
import info.frostfs.sdk.FrostFSClient;
|
||||||
|
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<parent>
|
<parent>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package info.frostfs.sdk.services;
|
package info.frostfs.sdk;
|
||||||
|
|
||||||
import frostfs.session.Types;
|
import frostfs.session.Types;
|
||||||
import info.frostfs.sdk.dto.SessionToken;
|
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.ClientSettings;
|
||||||
import info.frostfs.sdk.jdo.NetworkSettings;
|
import info.frostfs.sdk.jdo.NetworkSettings;
|
||||||
import info.frostfs.sdk.jdo.PutObjectParameters;
|
import info.frostfs.sdk.jdo.PutObjectParameters;
|
||||||
|
import info.frostfs.sdk.services.*;
|
||||||
import info.frostfs.sdk.services.impl.*;
|
import info.frostfs.sdk.services.impl.*;
|
||||||
import io.grpc.Channel;
|
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_CLIENT_OPTIONS_INIT = "Options must be initialized.";
|
||||||
private static final String ERROR_VERSION_SUPPORT_TEMPLATE = "FrostFS %s is not supported.";
|
private static final String ERROR_VERSION_SUPPORT_TEMPLATE = "FrostFS %s is not supported.";
|
||||||
|
|
||||||
private final ContainerService containerService;
|
private final ContainerClientImpl containerClientImpl;
|
||||||
private final NetmapService netmapService;
|
private final NetmapClientImpl netmapClientImpl;
|
||||||
private final ObjectService objectService;
|
private final ObjectClientImpl objectClientImpl;
|
||||||
private final SessionService sessionService;
|
private final SessionClientImpl sessionClientImpl;
|
||||||
private final ObjectTools objectTools;
|
private final ObjectToolsImpl objectToolsImpl;
|
||||||
|
|
||||||
public FrostFSClient(ClientSettings clientSettings) {
|
public FrostFSClient(ClientSettings clientSettings) {
|
||||||
if (isNull(clientSettings)) {
|
if (isNull(clientSettings)) {
|
||||||
|
@ -43,18 +44,18 @@ public class FrostFSClient implements ContainerClient, ObjectClient, NetmapClien
|
||||||
Channel channel = initGrpcChannel(clientSettings.getHost(), clientSettings.getCreds());
|
Channel channel = initGrpcChannel(clientSettings.getHost(), clientSettings.getCreds());
|
||||||
|
|
||||||
ClientEnvironment clientEnvironment =
|
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.containerClientImpl = new ContainerClientImpl(clientEnvironment);
|
||||||
this.netmapService = new NetmapService(clientEnvironment);
|
this.netmapClientImpl = new NetmapClientImpl(clientEnvironment);
|
||||||
this.sessionService = new SessionService(clientEnvironment);
|
this.sessionClientImpl = new SessionClientImpl(clientEnvironment);
|
||||||
this.objectService = new ObjectService(clientEnvironment);
|
this.objectClientImpl = new ObjectClientImpl(clientEnvironment);
|
||||||
this.objectTools = new ObjectTools(clientEnvironment);
|
this.objectToolsImpl = new ObjectToolsImpl(clientEnvironment);
|
||||||
checkFrostFsVersionSupport(clientEnvironment.getVersion());
|
checkFrostFsVersionSupport(clientEnvironment.getVersion());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkFrostFsVersionSupport(Version version) {
|
private void checkFrostFsVersionSupport(Version version) {
|
||||||
var localNodeInfo = netmapService.getLocalNodeInfo();
|
var localNodeInfo = netmapClientImpl.getLocalNodeInfo();
|
||||||
if (!localNodeInfo.getVersion().isSupported(version)) {
|
if (!localNodeInfo.getVersion().isSupported(version)) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
String.format(ERROR_VERSION_SUPPORT_TEMPLATE, localNodeInfo.getVersion())
|
String.format(ERROR_VERSION_SUPPORT_TEMPLATE, localNodeInfo.getVersion())
|
||||||
|
@ -64,75 +65,75 @@ public class FrostFSClient implements ContainerClient, ObjectClient, NetmapClien
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Container getContainer(ContainerId cid) {
|
public Container getContainer(ContainerId cid) {
|
||||||
return containerService.getContainer(cid);
|
return containerClientImpl.getContainer(cid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ContainerId> listContainers() {
|
public List<ContainerId> listContainers() {
|
||||||
return containerService.listContainers();
|
return containerClientImpl.listContainers();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ContainerId createContainer(Container container) {
|
public ContainerId createContainer(Container container) {
|
||||||
return containerService.createContainer(container);
|
return containerClientImpl.createContainer(container);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteContainer(ContainerId cid) {
|
public void deleteContainer(ContainerId cid) {
|
||||||
containerService.deleteContainer(cid);
|
containerClientImpl.deleteContainer(cid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ObjectHeader getObjectHead(ContainerId containerId, ObjectId objectId) {
|
public ObjectHeader getObjectHead(ContainerId containerId, ObjectId objectId) {
|
||||||
return objectService.getObjectHead(containerId, objectId);
|
return objectClientImpl.getObjectHead(containerId, objectId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ObjectFrostFS getObject(ContainerId containerId, ObjectId objectId) {
|
public ObjectFrostFS getObject(ContainerId containerId, ObjectId objectId) {
|
||||||
return objectService.getObject(containerId, objectId);
|
return objectClientImpl.getObject(containerId, objectId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ObjectId putObject(PutObjectParameters parameters) {
|
public ObjectId putObject(PutObjectParameters parameters) {
|
||||||
return objectService.putObject(parameters);
|
return objectClientImpl.putObject(parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteObject(ContainerId containerId, ObjectId objectId) {
|
public void deleteObject(ContainerId containerId, ObjectId objectId) {
|
||||||
objectService.deleteObject(containerId, objectId);
|
objectClientImpl.deleteObject(containerId, objectId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<ObjectId> searchObjects(ContainerId cid, ObjectFilter... filters) {
|
public Iterable<ObjectId> searchObjects(ContainerId cid, ObjectFilter... filters) {
|
||||||
return objectService.searchObjects(cid, filters);
|
return objectClientImpl.searchObjects(cid, filters);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NetmapSnapshot getNetmapSnapshot() {
|
public NetmapSnapshot getNetmapSnapshot() {
|
||||||
return netmapService.getNetmapSnapshot();
|
return netmapClientImpl.getNetmapSnapshot();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NodeInfo getLocalNodeInfo() {
|
public NodeInfo getLocalNodeInfo() {
|
||||||
return netmapService.getLocalNodeInfo();
|
return netmapClientImpl.getLocalNodeInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NetworkSettings getNetworkSettings() {
|
public NetworkSettings getNetworkSettings() {
|
||||||
return netmapService.getNetworkSettings();
|
return netmapClientImpl.getNetworkSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SessionToken createSession(long expiration) {
|
public SessionToken createSession(long expiration) {
|
||||||
return sessionService.createSession(expiration);
|
return sessionClientImpl.createSession(expiration);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Types.SessionToken createSessionInternal(long expiration) {
|
public Types.SessionToken createSessionInternal(long expiration) {
|
||||||
return sessionService.createSessionInternal(expiration);
|
return sessionClientImpl.createSessionInternal(expiration);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ObjectId calculateObjectId(ObjectHeader header) {
|
public ObjectId calculateObjectId(ObjectHeader header) {
|
||||||
return objectTools.calculateObjectId(header);
|
return objectToolsImpl.calculateObjectId(header);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,4 +2,7 @@ package info.frostfs.sdk.constants;
|
||||||
|
|
||||||
public class CryptoConst {
|
public class CryptoConst {
|
||||||
public static final String SIGNATURE_ALGORITHM = "NONEwithECDSAinP1363Format";
|
public static final String SIGNATURE_ALGORITHM = "NONEwithECDSAinP1363Format";
|
||||||
|
|
||||||
|
private CryptoConst() {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,11 @@ package info.frostfs.sdk.jdo;
|
||||||
|
|
||||||
import info.frostfs.sdk.dto.OwnerId;
|
import info.frostfs.sdk.dto.OwnerId;
|
||||||
import info.frostfs.sdk.dto.Version;
|
import info.frostfs.sdk.dto.Version;
|
||||||
import info.frostfs.sdk.services.FrostFSClient;
|
import info.frostfs.sdk.FrostFSClient;
|
||||||
import io.grpc.Channel;
|
import io.grpc.Channel;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import static java.util.Objects.isNull;
|
||||||
|
|
||||||
public class ClientEnvironment {
|
public class ClientEnvironment {
|
||||||
private final OwnerId ownerId;
|
private final OwnerId ownerId;
|
||||||
|
@ -14,8 +17,12 @@ public class ClientEnvironment {
|
||||||
private NetworkSettings networkSettings;
|
private NetworkSettings networkSettings;
|
||||||
|
|
||||||
public ClientEnvironment(String wif, Channel channel, Version version, FrostFSClient frostFSClient) {
|
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.key = new ECDsa(wif);
|
||||||
this.ownerId = OwnerId.fromKey(key.getPublicKeyByte());
|
this.ownerId = new OwnerId(key.getPublicKeyByte());
|
||||||
this.version = version;
|
this.version = version;
|
||||||
this.channel = channel;
|
this.channel = channel;
|
||||||
this.frostFSClient = frostFSClient;
|
this.frostFSClient = frostFSClient;
|
||||||
|
|
|
@ -13,6 +13,14 @@ public class ClientSettings {
|
||||||
public ClientSettings(String key, String host) {
|
public ClientSettings(String key, String host) {
|
||||||
this.key = key;
|
this.key = key;
|
||||||
this.host = host;
|
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() {
|
public ChannelCredentials getCreds() {
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package info.frostfs.sdk.jdo;
|
package info.frostfs.sdk.jdo;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import java.security.PrivateKey;
|
import java.security.PrivateKey;
|
||||||
|
|
||||||
import static info.frostfs.sdk.KeyExtension.*;
|
import static info.frostfs.sdk.KeyExtension.*;
|
||||||
|
@ -10,6 +12,10 @@ public class ECDsa {
|
||||||
private final PrivateKey privateKey;
|
private final PrivateKey privateKey;
|
||||||
|
|
||||||
public ECDsa(String wif) {
|
public ECDsa(String wif) {
|
||||||
|
if (StringUtils.isEmpty(wif)) {
|
||||||
|
throw new IllegalArgumentException("Wif is invalid");
|
||||||
|
}
|
||||||
|
|
||||||
this.privateKeyByte = getPrivateKeyFromWIF(wif);
|
this.privateKeyByte = getPrivateKeyFromWIF(wif);
|
||||||
this.publicKeyByte = loadPublicKey(privateKeyByte);
|
this.publicKeyByte = loadPublicKey(privateKeyByte);
|
||||||
this.privateKey = loadPrivateKey(privateKeyByte);
|
this.privateKey = loadPrivateKey(privateKeyByte);
|
||||||
|
|
|
@ -19,11 +19,15 @@ public class PutObjectParameters {
|
||||||
this.payload = payload;
|
this.payload = payload;
|
||||||
this.clientCut = clientCut;
|
this.clientCut = clientCut;
|
||||||
this.bufferMaxSize = bufferMaxSize;
|
this.bufferMaxSize = bufferMaxSize;
|
||||||
|
|
||||||
|
validate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public PutObjectParameters(ObjectHeader header, FileInputStream payload) {
|
public PutObjectParameters(ObjectHeader header, FileInputStream payload) {
|
||||||
this.header = header;
|
this.header = header;
|
||||||
this.payload = payload;
|
this.payload = payload;
|
||||||
|
|
||||||
|
validate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObjectHeader getHeader() {
|
public ObjectHeader getHeader() {
|
||||||
|
|
|
@ -11,33 +11,36 @@ import info.frostfs.sdk.mappers.container.ContainerIdMapper;
|
||||||
import info.frostfs.sdk.mappers.container.ContainerMapper;
|
import info.frostfs.sdk.mappers.container.ContainerMapper;
|
||||||
import info.frostfs.sdk.services.ContainerClient;
|
import info.frostfs.sdk.services.ContainerClient;
|
||||||
import info.frostfs.sdk.services.ContextAccessor;
|
import info.frostfs.sdk.services.ContextAccessor;
|
||||||
import info.frostfs.sdk.tools.Verifier;
|
|
||||||
import info.frostfs.sdk.tools.RequestConstructor;
|
import info.frostfs.sdk.tools.RequestConstructor;
|
||||||
import info.frostfs.sdk.tools.RequestSigner;
|
import info.frostfs.sdk.tools.RequestSigner;
|
||||||
|
import info.frostfs.sdk.tools.Verifier;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static info.frostfs.sdk.tools.RequestConstructor.addMetaHeader;
|
import static java.util.Objects.isNull;
|
||||||
import static info.frostfs.sdk.tools.RequestSigner.signRFC6979;
|
|
||||||
|
|
||||||
public class ContainerService extends ContextAccessor implements ContainerClient {
|
public class ContainerClientImpl extends ContextAccessor implements ContainerClient {
|
||||||
private final ContainerServiceGrpc.ContainerServiceBlockingStub serviceBlockingStub;
|
private final ContainerServiceGrpc.ContainerServiceBlockingStub serviceBlockingStub;
|
||||||
|
|
||||||
public ContainerService(ClientEnvironment clientEnvironment) {
|
public ContainerClientImpl(ClientEnvironment clientEnvironment) {
|
||||||
super(clientEnvironment);
|
super(clientEnvironment);
|
||||||
this.serviceBlockingStub = ContainerServiceGrpc.newBlockingStub(clientEnvironment.getChannel());
|
this.serviceBlockingStub = ContainerServiceGrpc.newBlockingStub(clientEnvironment.getChannel());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Container getContainer(ContainerId cid) {
|
public Container getContainer(ContainerId cid) {
|
||||||
var request = Service.GetRequest.newBuilder()
|
if (isNull(cid)) {
|
||||||
.setBody(
|
throw new IllegalArgumentException("ContainerId is not present");
|
||||||
Service.GetRequest.Body.newBuilder()
|
}
|
||||||
.setContainerId(ContainerIdMapper.toGrpcMessage(cid))
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
|
|
||||||
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());
|
RequestSigner.sign(request, getContext().getKey());
|
||||||
|
|
||||||
var response = serviceBlockingStub.get(request.build());
|
var response = serviceBlockingStub.get(request.build());
|
||||||
|
@ -46,15 +49,15 @@ public class ContainerService extends ContextAccessor implements ContainerClient
|
||||||
return ContainerMapper.toModel(response.getBody().getContainer());
|
return ContainerMapper.toModel(response.getBody().getContainer());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public List<ContainerId> listContainers() {
|
public List<ContainerId> listContainers() {
|
||||||
var request = Service.ListRequest.newBuilder()
|
var body = Service.ListRequest.Body.newBuilder()
|
||||||
.setBody(
|
|
||||||
Service.ListRequest.Body.newBuilder()
|
|
||||||
.setOwnerId(OwnerIdMapper.toGrpcMessage(getContext().getOwnerId()))
|
.setOwnerId(OwnerIdMapper.toGrpcMessage(getContext().getOwnerId()))
|
||||||
.build()
|
.build();
|
||||||
);
|
var request = Service.ListRequest.newBuilder()
|
||||||
|
.setBody(body);
|
||||||
|
|
||||||
RequestConstructor.addMetaHeader(request);
|
RequestConstructor.addDefaultMetaHeader(request);
|
||||||
RequestSigner.sign(request, getContext().getKey());
|
RequestSigner.sign(request, getContext().getKey());
|
||||||
|
|
||||||
var response = serviceBlockingStub.list(request.build());
|
var response = serviceBlockingStub.list(request.build());
|
||||||
|
@ -62,51 +65,54 @@ public class ContainerService extends ContextAccessor implements ContainerClient
|
||||||
Verifier.checkResponse(response);
|
Verifier.checkResponse(response);
|
||||||
|
|
||||||
return response.getBody().getContainerIdsList().stream()
|
return response.getBody().getContainerIdsList().stream()
|
||||||
.map(cid -> ContainerId.fromHash(cid.getValue().toByteArray()))
|
.map(cid -> new ContainerId(cid.getValue().toByteArray()))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public ContainerId createContainer(Container container) {
|
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()
|
grpcContainer = grpcContainer.toBuilder()
|
||||||
.setOwnerId(OwnerIdMapper.toGrpcMessage(getContext().getOwnerId()))
|
.setOwnerId(OwnerIdMapper.toGrpcMessage(getContext().getOwnerId()))
|
||||||
.setVersion(VersionMapper.toGrpcMessage(getContext().getVersion()))
|
.setVersion(VersionMapper.toGrpcMessage(getContext().getVersion()))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
var request = Service.PutRequest.newBuilder()
|
var body = Service.PutRequest.Body.newBuilder()
|
||||||
.setBody(
|
|
||||||
Service.PutRequest.Body.newBuilder()
|
|
||||||
.setContainer(grpcContainer)
|
.setContainer(grpcContainer)
|
||||||
.setSignature(
|
.setSignature(RequestSigner.signRFC6979(getContext().getKey(), grpcContainer))
|
||||||
RequestSigner.signRFC6979(getContext().getKey(), grpcContainer)
|
.build();
|
||||||
)
|
var request = Service.PutRequest.newBuilder()
|
||||||
.build()
|
.setBody(body);
|
||||||
);
|
|
||||||
|
|
||||||
RequestConstructor.addMetaHeader(request);
|
RequestConstructor.addDefaultMetaHeader(request);
|
||||||
RequestSigner.sign(request, getContext().getKey());
|
RequestSigner.sign(request, getContext().getKey());
|
||||||
|
|
||||||
var response = serviceBlockingStub.put(request.build());
|
var response = serviceBlockingStub.put(request.build());
|
||||||
|
|
||||||
Verifier.checkResponse(response);
|
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) {
|
public void deleteContainer(ContainerId cid) {
|
||||||
|
if (isNull(cid)) {
|
||||||
|
throw new IllegalArgumentException("ContainerId is not present");
|
||||||
|
}
|
||||||
|
|
||||||
var grpcContainerId = ContainerIdMapper.toGrpcMessage(cid);
|
var grpcContainerId = ContainerIdMapper.toGrpcMessage(cid);
|
||||||
|
|
||||||
var request = Service.DeleteRequest.newBuilder()
|
var body = Service.DeleteRequest.Body.newBuilder()
|
||||||
.setBody(
|
|
||||||
Service.DeleteRequest.Body.newBuilder()
|
|
||||||
.setContainerId(grpcContainerId)
|
.setContainerId(grpcContainerId)
|
||||||
.setSignature(RequestSigner.signRFC6979(
|
.setSignature(RequestSigner.signRFC6979(getContext().getKey(), grpcContainerId.getValue()))
|
||||||
getContext().getKey(), grpcContainerId.getValue()
|
.build();
|
||||||
))
|
var request = Service.DeleteRequest.newBuilder()
|
||||||
.build()
|
.setBody(body);
|
||||||
);
|
|
||||||
|
|
||||||
RequestConstructor.addMetaHeader(request);
|
RequestConstructor.addDefaultMetaHeader(request);
|
||||||
RequestSigner.sign(request, getContext().getKey());
|
RequestSigner.sign(request, getContext().getKey());
|
||||||
|
|
||||||
var response = serviceBlockingStub.delete(request.build());
|
var response = serviceBlockingStub.delete(request.build());
|
|
@ -11,25 +11,27 @@ import info.frostfs.sdk.mappers.netmap.NetmapSnapshotMapper;
|
||||||
import info.frostfs.sdk.mappers.netmap.NodeInfoMapper;
|
import info.frostfs.sdk.mappers.netmap.NodeInfoMapper;
|
||||||
import info.frostfs.sdk.services.ContextAccessor;
|
import info.frostfs.sdk.services.ContextAccessor;
|
||||||
import info.frostfs.sdk.services.NetmapClient;
|
import info.frostfs.sdk.services.NetmapClient;
|
||||||
|
import info.frostfs.sdk.tools.RequestConstructor;
|
||||||
import info.frostfs.sdk.tools.Verifier;
|
import info.frostfs.sdk.tools.Verifier;
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
import static info.frostfs.sdk.tools.RequestConstructor.addMetaHeader;
|
|
||||||
import static info.frostfs.sdk.tools.RequestSigner.sign;
|
import static info.frostfs.sdk.tools.RequestSigner.sign;
|
||||||
import static java.util.Objects.nonNull;
|
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;
|
private final NetmapServiceGrpc.NetmapServiceBlockingStub netmapServiceClient;
|
||||||
|
|
||||||
public NetmapService(ClientEnvironment clientEnvironment) {
|
public NetmapClientImpl(ClientEnvironment clientEnvironment) {
|
||||||
super(clientEnvironment);
|
super(clientEnvironment);
|
||||||
this.netmapServiceClient = NetmapServiceGrpc.newBlockingStub(getContext().getChannel());
|
this.netmapServiceClient = NetmapServiceGrpc.newBlockingStub(getContext().getChannel());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean getBoolValue(byte[] bytes) {
|
private static boolean getBoolValue(byte[] bytes) {
|
||||||
for (var byteValue : bytes) {
|
for (var byteValue : bytes) {
|
||||||
if (byteValue != 0) return true;
|
if (byteValue != 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -115,7 +117,7 @@ public class NetmapService extends ContextAccessor implements NetmapClient {
|
||||||
var request = Service.LocalNodeInfoRequest.newBuilder()
|
var request = Service.LocalNodeInfoRequest.newBuilder()
|
||||||
.setBody(Service.LocalNodeInfoRequest.Body.newBuilder().build());
|
.setBody(Service.LocalNodeInfoRequest.Body.newBuilder().build());
|
||||||
|
|
||||||
addMetaHeader(request);
|
RequestConstructor.addDefaultMetaHeader(request);
|
||||||
sign(request, getContext().getKey());
|
sign(request, getContext().getKey());
|
||||||
|
|
||||||
var response = netmapServiceClient.localNodeInfo(request.build());
|
var response = netmapServiceClient.localNodeInfo(request.build());
|
||||||
|
@ -128,7 +130,7 @@ public class NetmapService extends ContextAccessor implements NetmapClient {
|
||||||
var request = Service.NetworkInfoRequest.newBuilder()
|
var request = Service.NetworkInfoRequest.newBuilder()
|
||||||
.setBody(Service.NetworkInfoRequest.Body.newBuilder().build());
|
.setBody(Service.NetworkInfoRequest.Body.newBuilder().build());
|
||||||
|
|
||||||
addMetaHeader(request);
|
RequestConstructor.addDefaultMetaHeader(request);
|
||||||
sign(request, getContext().getKey());
|
sign(request, getContext().getKey());
|
||||||
|
|
||||||
var response = netmapServiceClient.networkInfo(request.build());
|
var response = netmapServiceClient.networkInfo(request.build());
|
||||||
|
@ -143,7 +145,7 @@ public class NetmapService extends ContextAccessor implements NetmapClient {
|
||||||
var request = Service.NetmapSnapshotRequest.newBuilder()
|
var request = Service.NetmapSnapshotRequest.newBuilder()
|
||||||
.setBody(Service.NetmapSnapshotRequest.Body.newBuilder().build());
|
.setBody(Service.NetmapSnapshotRequest.Body.newBuilder().build());
|
||||||
|
|
||||||
addMetaHeader(request);
|
RequestConstructor.addDefaultMetaHeader(request);
|
||||||
sign(request, getContext().getKey());
|
sign(request, getContext().getKey());
|
||||||
|
|
||||||
var response = netmapServiceClient.netmapSnapshot(request.build());
|
var response = netmapServiceClient.netmapSnapshot(request.build());
|
|
@ -20,6 +20,10 @@ import info.frostfs.sdk.mappers.object.ObjectHeaderMapper;
|
||||||
import info.frostfs.sdk.mappers.object.ObjectIdMapper;
|
import info.frostfs.sdk.mappers.object.ObjectIdMapper;
|
||||||
import info.frostfs.sdk.services.ContextAccessor;
|
import info.frostfs.sdk.services.ContextAccessor;
|
||||||
import info.frostfs.sdk.services.ObjectClient;
|
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 info.frostfs.sdk.tools.Verifier;
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
|
|
||||||
|
@ -30,39 +34,37 @@ import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static info.frostfs.sdk.Helper.getSha256;
|
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.RequestConstructor.addObjectSessionToken;
|
||||||
import static info.frostfs.sdk.tools.RequestSigner.sign;
|
import static info.frostfs.sdk.tools.RequestSigner.sign;
|
||||||
import static java.util.Objects.nonNull;
|
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 static final String ERROR_PAYLOAD = "PayloadLength must be specified";
|
||||||
|
|
||||||
private final ObjectServiceGrpc.ObjectServiceBlockingStub objectServiceBlockingClient;
|
private final ObjectServiceGrpc.ObjectServiceBlockingStub objectServiceBlockingClient;
|
||||||
private final ObjectServiceGrpc.ObjectServiceStub objectServiceClient;
|
private final ObjectServiceGrpc.ObjectServiceStub objectServiceClient;
|
||||||
private final ObjectTools objectTools;
|
private final ObjectToolsImpl objectToolsImpl;
|
||||||
|
|
||||||
public ObjectService(ClientEnvironment clientEnvironment) {
|
public ObjectClientImpl(ClientEnvironment clientEnvironment) {
|
||||||
super(clientEnvironment);
|
super(clientEnvironment);
|
||||||
this.objectServiceBlockingClient = ObjectServiceGrpc.newBlockingStub(getContext().getChannel());
|
this.objectServiceBlockingClient = ObjectServiceGrpc.newBlockingStub(getContext().getChannel());
|
||||||
this.objectServiceClient = ObjectServiceGrpc.newStub(getContext().getChannel());
|
this.objectServiceClient = ObjectServiceGrpc.newStub(getContext().getChannel());
|
||||||
this.objectTools = new ObjectTools(clientEnvironment);
|
this.objectToolsImpl = new ObjectToolsImpl(clientEnvironment);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ObjectHeader getObjectHead(ContainerId cid, ObjectId oid) {
|
public ObjectHeader getObjectHead(ContainerId cid, ObjectId oid) {
|
||||||
var request = Service.HeadRequest.newBuilder()
|
var address = Types.Address.newBuilder()
|
||||||
.setBody(
|
|
||||||
Service.HeadRequest.Body.newBuilder()
|
|
||||||
.setAddress(
|
|
||||||
Types.Address.newBuilder()
|
|
||||||
.setContainerId(ContainerIdMapper.toGrpcMessage(cid))
|
.setContainerId(ContainerIdMapper.toGrpcMessage(cid))
|
||||||
.setObjectId(ObjectIdMapper.toGrpcMessage(oid))
|
.setObjectId(ObjectIdMapper.toGrpcMessage(oid))
|
||||||
.build()
|
.build();
|
||||||
).build()
|
var body = Service.HeadRequest.Body.newBuilder()
|
||||||
);
|
.setAddress(address)
|
||||||
|
.build();
|
||||||
|
var request = Service.HeadRequest.newBuilder()
|
||||||
|
.setBody(body);
|
||||||
|
|
||||||
addMetaHeader(request);
|
RequestConstructor.addDefaultMetaHeader(request);
|
||||||
sign(request, getContext().getKey());
|
sign(request, getContext().getKey());
|
||||||
|
|
||||||
var response = objectServiceBlockingClient.head(request.build());
|
var response = objectServiceBlockingClient.head(request.build());
|
||||||
|
@ -75,19 +77,17 @@ public class ObjectService extends ContextAccessor implements ObjectClient {
|
||||||
public ObjectFrostFS getObject(ContainerId cid, ObjectId oid) {
|
public ObjectFrostFS getObject(ContainerId cid, ObjectId oid) {
|
||||||
var sessionToken = getContext().getFrostFSClient().createSessionInternal(-1);
|
var sessionToken = getContext().getFrostFSClient().createSessionInternal(-1);
|
||||||
|
|
||||||
var request = Service.GetRequest.newBuilder()
|
var address = Types.Address.newBuilder()
|
||||||
.setBody(
|
|
||||||
Service.GetRequest.Body.newBuilder()
|
|
||||||
.setAddress(
|
|
||||||
Types.Address.newBuilder()
|
|
||||||
.setContainerId(ContainerIdMapper.toGrpcMessage(cid))
|
.setContainerId(ContainerIdMapper.toGrpcMessage(cid))
|
||||||
.setObjectId(ObjectIdMapper.toGrpcMessage(oid))
|
.setObjectId(ObjectIdMapper.toGrpcMessage(oid))
|
||||||
.build()
|
.build();
|
||||||
)
|
var body = Service.GetRequest.Body.newBuilder()
|
||||||
.build()
|
.setAddress(address)
|
||||||
);
|
.build();
|
||||||
|
var request = Service.GetRequest.newBuilder()
|
||||||
|
.setBody(body);
|
||||||
|
|
||||||
addMetaHeader(request);
|
RequestConstructor.addDefaultMetaHeader(request);
|
||||||
addObjectSessionToken(
|
addObjectSessionToken(
|
||||||
request, sessionToken, ContainerIdMapper.toGrpcMessage(cid), ObjectIdMapper.toGrpcMessage(oid),
|
request, sessionToken, ContainerIdMapper.toGrpcMessage(cid), ObjectIdMapper.toGrpcMessage(oid),
|
||||||
frostfs.session.Types.ObjectSessionContext.Verb.GET, getContext().getKey()
|
frostfs.session.Types.ObjectSessionContext.Verb.GET, getContext().getKey()
|
||||||
|
@ -101,18 +101,17 @@ public class ObjectService extends ContextAccessor implements ObjectClient {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteObject(ContainerId cid, ObjectId oid) {
|
public void deleteObject(ContainerId cid, ObjectId oid) {
|
||||||
var request = Service.DeleteRequest.newBuilder()
|
var address = Types.Address.newBuilder()
|
||||||
.setBody(
|
|
||||||
Service.DeleteRequest.Body.newBuilder()
|
|
||||||
.setAddress(
|
|
||||||
Types.Address.newBuilder()
|
|
||||||
.setContainerId(ContainerIdMapper.toGrpcMessage(cid))
|
.setContainerId(ContainerIdMapper.toGrpcMessage(cid))
|
||||||
.setObjectId(ObjectIdMapper.toGrpcMessage(oid))
|
.setObjectId(ObjectIdMapper.toGrpcMessage(oid))
|
||||||
.build()
|
.build();
|
||||||
)
|
var body = Service.DeleteRequest.Body.newBuilder()
|
||||||
.build());
|
.setAddress(address)
|
||||||
|
.build();
|
||||||
|
var request = Service.DeleteRequest.newBuilder()
|
||||||
|
.setBody(body);
|
||||||
|
|
||||||
addMetaHeader(request);
|
RequestConstructor.addDefaultMetaHeader(request);
|
||||||
sign(request, getContext().getKey());
|
sign(request, getContext().getKey());
|
||||||
|
|
||||||
var response = objectServiceBlockingClient.delete(request.build());
|
var response = objectServiceBlockingClient.delete(request.build());
|
||||||
|
@ -132,12 +131,12 @@ public class ObjectService extends ContextAccessor implements ObjectClient {
|
||||||
var request = Service.SearchRequest.newBuilder()
|
var request = Service.SearchRequest.newBuilder()
|
||||||
.setBody(body.build());
|
.setBody(body.build());
|
||||||
|
|
||||||
addMetaHeader(request);
|
RequestConstructor.addDefaultMetaHeader(request);
|
||||||
sign(request, getContext().getKey());
|
sign(request, getContext().getKey());
|
||||||
|
|
||||||
var objectsIds = searchObjects(request.build());
|
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
|
@Override
|
||||||
|
@ -150,13 +149,13 @@ public class ObjectService extends ContextAccessor implements ObjectClient {
|
||||||
public ObjectId putSingleObject(ObjectFrostFS modelObject) {
|
public ObjectId putSingleObject(ObjectFrostFS modelObject) {
|
||||||
var sessionToken = getContext().getFrostFSClient().createSessionInternal(-1);
|
var sessionToken = getContext().getFrostFSClient().createSessionInternal(-1);
|
||||||
|
|
||||||
var grpcObject = objectTools.createObject(modelObject);
|
var grpcObject = objectToolsImpl.createObject(modelObject);
|
||||||
|
|
||||||
var request = Service.PutSingleRequest.newBuilder()
|
var request = Service.PutSingleRequest.newBuilder()
|
||||||
.setBody(Service.PutSingleRequest.Body.newBuilder().setObject(grpcObject).build());
|
.setBody(Service.PutSingleRequest.Body.newBuilder().setObject(grpcObject).build());
|
||||||
|
|
||||||
|
|
||||||
addMetaHeader(request);
|
RequestConstructor.addDefaultMetaHeader(request);
|
||||||
addObjectSessionToken(
|
addObjectSessionToken(
|
||||||
request, sessionToken, grpcObject.getHeader().getContainerId(), grpcObject.getObjectId(),
|
request, sessionToken, grpcObject.getHeader().getContainerId(), grpcObject.getObjectId(),
|
||||||
frostfs.session.Types.ObjectSessionContext.Verb.PUT, getContext().getKey()
|
frostfs.session.Types.ObjectSessionContext.Verb.PUT, getContext().getKey()
|
||||||
|
@ -167,7 +166,7 @@ public class ObjectService extends ContextAccessor implements ObjectClient {
|
||||||
|
|
||||||
Verifier.checkResponse(response);
|
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) {
|
private frostfs.object.Types.Object getObject(Service.GetRequest request) {
|
||||||
|
@ -215,7 +214,7 @@ public class ObjectService extends ContextAccessor implements ObjectClient {
|
||||||
).build()
|
).build()
|
||||||
);
|
);
|
||||||
|
|
||||||
addMetaHeader(initRequest);
|
RequestConstructor.addDefaultMetaHeader(initRequest);
|
||||||
addObjectSessionToken(
|
addObjectSessionToken(
|
||||||
initRequest, sessionToken, hdr.getContainerId(), oid,
|
initRequest, sessionToken, hdr.getContainerId(), oid,
|
||||||
frostfs.session.Types.ObjectSessionContext.Verb.PUT, getContext().getKey()
|
frostfs.session.Types.ObjectSessionContext.Verb.PUT, getContext().getKey()
|
||||||
|
@ -232,8 +231,9 @@ public class ObjectService extends ContextAccessor implements ObjectClient {
|
||||||
var buffer = new byte[bufferSize];
|
var buffer = new byte[bufferSize];
|
||||||
while (true) {
|
while (true) {
|
||||||
var bytesCount = readNBytes(parameters.getPayload(), buffer, bufferSize);
|
var bytesCount = readNBytes(parameters.getPayload(), buffer, bufferSize);
|
||||||
if (bytesCount <= 0)
|
if (bytesCount <= 0) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
var chunkRequest = Service.PutRequest.newBuilder(initRequest.build())
|
var chunkRequest = Service.PutRequest.newBuilder(initRequest.build())
|
||||||
.setBody(
|
.setBody(
|
||||||
|
@ -249,7 +249,7 @@ public class ObjectService extends ContextAccessor implements ObjectClient {
|
||||||
var response = writer.complete();
|
var response = writer.complete();
|
||||||
Verifier.checkResponse(response);
|
Verifier.checkResponse(response);
|
||||||
|
|
||||||
return ObjectId.fromHash(response.getBody().getObjectId().getValue().toByteArray());
|
return new ObjectId(response.getBody().getObjectId().getValue().toByteArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
private ObjectId putClientCutObject(PutObjectParameters parameters) {
|
private ObjectId putClientCutObject(PutObjectParameters parameters) {
|
||||||
|
@ -285,8 +285,9 @@ public class ObjectService extends ContextAccessor implements ObjectClient {
|
||||||
);
|
);
|
||||||
currentObject.setSplit(split);
|
currentObject.setSplit(split);
|
||||||
|
|
||||||
if (largeObject.getPayloadLength() == fullLength)
|
if (largeObject.getPayloadLength() == fullLength) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
objectId = putSingleObject(currentObject);
|
objectId = putSingleObject(currentObject);
|
||||||
|
|
||||||
|
@ -314,7 +315,7 @@ public class ObjectService extends ContextAccessor implements ObjectClient {
|
||||||
|
|
||||||
putSingleObject(linkObject);
|
putSingleObject(linkObject);
|
||||||
|
|
||||||
return objectTools.calculateObjectId(largeObject.getHeader());
|
return objectToolsImpl.calculateObjectId(largeObject.getHeader());
|
||||||
}
|
}
|
||||||
|
|
||||||
private ObjectWriter putObjectInit(Service.PutRequest initRequest) {
|
private ObjectWriter putObjectInit(Service.PutRequest initRequest) {
|
|
@ -18,8 +18,8 @@ import static info.frostfs.sdk.Helper.getSha256;
|
||||||
import static info.frostfs.sdk.tools.RequestSigner.signData;
|
import static info.frostfs.sdk.tools.RequestSigner.signData;
|
||||||
import static java.util.Objects.nonNull;
|
import static java.util.Objects.nonNull;
|
||||||
|
|
||||||
public class ObjectTools extends ContextAccessor implements ToolsClient {
|
public class ObjectToolsImpl extends ContextAccessor implements ToolsClient {
|
||||||
public ObjectTools(ClientEnvironment context) {
|
public ObjectToolsImpl(ClientEnvironment context) {
|
||||||
super(context);
|
super(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,15 +59,13 @@ public class ObjectTools extends ContextAccessor implements ToolsClient {
|
||||||
if (nonNull(split.getParentHeader())) {
|
if (nonNull(split.getParentHeader())) {
|
||||||
var grpcParentHeader = createHeader(split.getParentHeader(), new byte[]{});
|
var grpcParentHeader = createHeader(split.getParentHeader(), new byte[]{});
|
||||||
var parent = frostfs.refs.Types.ObjectID.newBuilder().setValue(getSha256(grpcParentHeader)).build();
|
var parent = frostfs.refs.Types.ObjectID.newBuilder().setValue(getSha256(grpcParentHeader)).build();
|
||||||
|
var parentSig = frostfs.refs.Types.Signature.newBuilder()
|
||||||
splitGrpc
|
|
||||||
.setParent(parent)
|
|
||||||
.setParentHeader(grpcParentHeader)
|
|
||||||
.setParentSignature(
|
|
||||||
frostfs.refs.Types.Signature.newBuilder()
|
|
||||||
.setKey(ByteString.copyFrom(getContext().getKey().getPublicKeyByte()))
|
.setKey(ByteString.copyFrom(getContext().getKey().getPublicKeyByte()))
|
||||||
.setSign(ByteString.copyFrom(signData(getContext().getKey(), parent.toByteArray())))
|
.setSign(ByteString.copyFrom(signData(getContext().getKey(), parent.toByteArray())));
|
||||||
);
|
|
||||||
|
splitGrpc.setParent(parent)
|
||||||
|
.setParentHeader(grpcParentHeader)
|
||||||
|
.setParentSignature(parentSig);
|
||||||
|
|
||||||
split.setParent(ObjectIdMapper.toModel(parent));
|
split.setParent(ObjectIdMapper.toModel(parent));
|
||||||
}
|
}
|
||||||
|
@ -79,15 +77,14 @@ public class ObjectTools extends ContextAccessor implements ToolsClient {
|
||||||
|
|
||||||
var grpcHeader = grpcHeaderBuilder.build();
|
var grpcHeader = grpcHeaderBuilder.build();
|
||||||
var objectId = frostfs.refs.Types.ObjectID.newBuilder().setValue(getSha256(grpcHeader)).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()
|
return Types.Object.newBuilder()
|
||||||
.setHeader(grpcHeader)
|
.setHeader(grpcHeader)
|
||||||
.setObjectId(objectId)
|
.setObjectId(objectId)
|
||||||
.setPayload(ByteString.copyFrom(objectFrostFs.getPayload()))
|
.setPayload(ByteString.copyFrom(objectFrostFs.getPayload()))
|
||||||
.setSignature(
|
.setSignature(sig)
|
||||||
frostfs.refs.Types.Signature.newBuilder()
|
|
||||||
.setKey(ByteString.copyFrom(getContext().getKey().getPublicKeyByte()))
|
|
||||||
.setSign(ByteString.copyFrom(signData(getContext().getKey(), objectId.toByteArray())))
|
|
||||||
)
|
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,10 +93,11 @@ public class ObjectTools extends ContextAccessor implements ToolsClient {
|
||||||
.setOwnerId(OwnerIdMapper.toGrpcMessage(getContext().getOwnerId()))
|
.setOwnerId(OwnerIdMapper.toGrpcMessage(getContext().getOwnerId()))
|
||||||
.setVersion(VersionMapper.toGrpcMessage(getContext().getVersion()));
|
.setVersion(VersionMapper.toGrpcMessage(getContext().getVersion()));
|
||||||
|
|
||||||
if (header.getPayloadCheckSum() != null)
|
if (header.getPayloadCheckSum() != null) {
|
||||||
grpcHeader.setPayloadHash(sha256Checksum(header.getPayloadCheckSum()));
|
grpcHeader.setPayloadHash(sha256Checksum(header.getPayloadCheckSum()));
|
||||||
else if (payload != null)
|
} else if (payload != null) {
|
||||||
grpcHeader.setPayloadHash(sha256Checksum(payload));
|
grpcHeader.setPayloadHash(sha256Checksum(payload));
|
||||||
|
}
|
||||||
|
|
||||||
return grpcHeader.build();
|
return grpcHeader.build();
|
||||||
}
|
}
|
|
@ -11,13 +11,12 @@ import info.frostfs.sdk.services.ContextAccessor;
|
||||||
import info.frostfs.sdk.services.SessionClient;
|
import info.frostfs.sdk.services.SessionClient;
|
||||||
import info.frostfs.sdk.tools.RequestConstructor;
|
import info.frostfs.sdk.tools.RequestConstructor;
|
||||||
|
|
||||||
import static info.frostfs.sdk.tools.RequestConstructor.addMetaHeader;
|
|
||||||
import static info.frostfs.sdk.tools.RequestSigner.sign;
|
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;
|
private final SessionServiceGrpc.SessionServiceBlockingStub serviceBlockingStub;
|
||||||
|
|
||||||
public SessionService(ClientEnvironment clientEnvironment) {
|
public SessionClientImpl(ClientEnvironment clientEnvironment) {
|
||||||
super(clientEnvironment);
|
super(clientEnvironment);
|
||||||
this.serviceBlockingStub = SessionServiceGrpc.newBlockingStub(getContext().getChannel());
|
this.serviceBlockingStub = SessionServiceGrpc.newBlockingStub(getContext().getChannel());
|
||||||
}
|
}
|
||||||
|
@ -30,14 +29,14 @@ public class SessionService extends ContextAccessor implements SessionClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Types.SessionToken createSessionInternal(long expiration) {
|
public Types.SessionToken createSessionInternal(long expiration) {
|
||||||
var request = Service.CreateRequest.newBuilder()
|
var body = Service.CreateRequest.Body.newBuilder()
|
||||||
.setBody(
|
|
||||||
Service.CreateRequest.Body.newBuilder()
|
|
||||||
.setOwnerId(OwnerIdMapper.toGrpcMessage(getContext().getOwnerId()))
|
.setOwnerId(OwnerIdMapper.toGrpcMessage(getContext().getOwnerId()))
|
||||||
.setExpiration(expiration).build()
|
.setExpiration(expiration)
|
||||||
);
|
.build();
|
||||||
|
var request = Service.CreateRequest.newBuilder()
|
||||||
|
.setBody(body);
|
||||||
|
|
||||||
RequestConstructor.addMetaHeader(request);
|
RequestConstructor.addDefaultMetaHeader(request);
|
||||||
sign(request, getContext().getKey());
|
sign(request, getContext().getKey());
|
||||||
|
|
||||||
return createSession(request.build());
|
return createSession(request.build());
|
|
@ -1,4 +1,4 @@
|
||||||
package info.frostfs.sdk.services.impl;
|
package info.frostfs.sdk.services.impl.rwhelper;
|
||||||
|
|
||||||
import frostfs.object.Service;
|
import frostfs.object.Service;
|
||||||
import frostfs.object.Types;
|
import frostfs.object.Types;
|
|
@ -1,4 +1,4 @@
|
||||||
package info.frostfs.sdk.services.impl;
|
package info.frostfs.sdk.services.impl.rwhelper;
|
||||||
|
|
||||||
import frostfs.object.ObjectServiceGrpc;
|
import frostfs.object.ObjectServiceGrpc;
|
||||||
import frostfs.object.Service;
|
import frostfs.object.Service;
|
|
@ -1,4 +1,4 @@
|
||||||
package info.frostfs.sdk.services.impl;
|
package info.frostfs.sdk.services.impl.rwhelper;
|
||||||
|
|
||||||
import frostfs.object.Service;
|
import frostfs.object.Service;
|
||||||
import info.frostfs.sdk.tools.Verifier;
|
import info.frostfs.sdk.tools.Verifier;
|
|
@ -12,6 +12,9 @@ import static java.util.Objects.isNull;
|
||||||
public class GrpcClient {
|
public class GrpcClient {
|
||||||
private static final String ERROR_INVALID_HOST_TEMPLATE = "Host %s has invalid format. Error: %s";
|
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) {
|
public static Channel initGrpcChannel(String host, ChannelCredentials creds) {
|
||||||
try {
|
try {
|
||||||
URI uri = new URI(host);
|
URI uri = new URI(host);
|
||||||
|
|
|
@ -5,6 +5,9 @@ import com.google.protobuf.MessageOrBuilder;
|
||||||
|
|
||||||
public class MessageHelper {
|
public class MessageHelper {
|
||||||
|
|
||||||
|
private MessageHelper() {
|
||||||
|
}
|
||||||
|
|
||||||
public static Message getField(MessageOrBuilder messageOrBuilder, String fieldName) {
|
public static Message getField(MessageOrBuilder messageOrBuilder, String fieldName) {
|
||||||
return (Message) messageOrBuilder.getField(messageOrBuilder.getDescriptorForType().findFieldByName(fieldName));
|
return (Message) messageOrBuilder.getField(messageOrBuilder.getDescriptorForType().findFieldByName(fieldName));
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,13 +14,20 @@ import static java.util.Objects.isNull;
|
||||||
|
|
||||||
public class RequestConstructor {
|
public class RequestConstructor {
|
||||||
|
|
||||||
public static void addMetaHeader(Message.Builder request) {
|
private RequestConstructor() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void addDefaultMetaHeader(Message.Builder request) {
|
||||||
addMetaHeader(request, null);
|
addMetaHeader(request, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void addMetaHeader(Message.Builder request, Types.RequestMetaHeader metaHeader) {
|
public static void addMetaHeader(Message.Builder request, Types.RequestMetaHeader metaHeader) {
|
||||||
|
if (isNull(request)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (isNull(metaHeader) || metaHeader.getSerializedSize() == 0) {
|
if (isNull(metaHeader) || metaHeader.getSerializedSize() == 0) {
|
||||||
metaHeader = MetaHeaderMapper.toGrpcMessage(MetaHeader.getDefault());
|
metaHeader = MetaHeaderMapper.toGrpcMessage(new MetaHeader());
|
||||||
setField(request, META_HEADER_FIELD_NAME, metaHeader);
|
setField(request, META_HEADER_FIELD_NAME, metaHeader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,6 +38,10 @@ public class RequestConstructor {
|
||||||
frostfs.refs.Types.ObjectID oid,
|
frostfs.refs.Types.ObjectID oid,
|
||||||
Types.ObjectSessionContext.Verb verb,
|
Types.ObjectSessionContext.Verb verb,
|
||||||
ECDsa key) {
|
ECDsa key) {
|
||||||
|
if (isNull(request) || isNull(sessionToken)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var header = (Types.RequestMetaHeader) getField(request, META_HEADER_FIELD_NAME);
|
var header = (Types.RequestMetaHeader) getField(request, META_HEADER_FIELD_NAME);
|
||||||
if (header.getSessionToken().getSerializedSize() > 0) {
|
if (header.getSessionToken().getSerializedSize() > 0) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -3,8 +3,8 @@ package info.frostfs.sdk.tools;
|
||||||
import com.google.protobuf.ByteString;
|
import com.google.protobuf.ByteString;
|
||||||
import com.google.protobuf.Message;
|
import com.google.protobuf.Message;
|
||||||
import frostfs.session.Types;
|
import frostfs.session.Types;
|
||||||
import info.frostfs.sdk.jdo.ECDsa;
|
|
||||||
import info.frostfs.sdk.constants.CryptoConst;
|
import info.frostfs.sdk.constants.CryptoConst;
|
||||||
|
import info.frostfs.sdk.jdo.ECDsa;
|
||||||
import org.apache.commons.codec.digest.DigestUtils;
|
import org.apache.commons.codec.digest.DigestUtils;
|
||||||
import org.bouncycastle.asn1.sec.SECNamedCurves;
|
import org.bouncycastle.asn1.sec.SECNamedCurves;
|
||||||
import org.bouncycastle.asn1.sec.SECObjectIdentifiers;
|
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 String ERROR_UNSUPPORTED_TYPE_TEMPLATE = "Unsupported message type: %s";
|
||||||
public static final int RFC6979_SIGNATURE_SIZE = 64;
|
public static final int RFC6979_SIGNATURE_SIZE = 64;
|
||||||
|
|
||||||
|
private RequestSigner() {
|
||||||
|
}
|
||||||
|
|
||||||
public static byte[] signData(ECDsa key, byte[] data) {
|
public static byte[] signData(ECDsa key, byte[] data) {
|
||||||
var hash = new byte[65];
|
var hash = new byte[65];
|
||||||
hash[0] = 0x04;
|
hash[0] = 0x04;
|
||||||
|
|
|
@ -2,8 +2,8 @@ package info.frostfs.sdk.tools;
|
||||||
|
|
||||||
import com.google.protobuf.Message;
|
import com.google.protobuf.Message;
|
||||||
import frostfs.session.Types;
|
import frostfs.session.Types;
|
||||||
import info.frostfs.sdk.mappers.StatusMapper;
|
|
||||||
import info.frostfs.sdk.constants.CryptoConst;
|
import info.frostfs.sdk.constants.CryptoConst;
|
||||||
|
import info.frostfs.sdk.mappers.StatusMapper;
|
||||||
import org.apache.commons.codec.digest.DigestUtils;
|
import org.apache.commons.codec.digest.DigestUtils;
|
||||||
import org.bouncycastle.asn1.sec.SECNamedCurves;
|
import org.bouncycastle.asn1.sec.SECNamedCurves;
|
||||||
import org.bouncycastle.asn1.sec.SECObjectIdentifiers;
|
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 String ERROR_INVALID_RESPONSE = "Invalid response";
|
||||||
public static final int RFC6979_SIG_SIZE = 64;
|
public static final int RFC6979_SIG_SIZE = 64;
|
||||||
|
|
||||||
|
private Verifier() {
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean verifyRFC6979(frostfs.refs.Types.SignatureRFC6979 signature, Message data) {
|
public static boolean verifyRFC6979(frostfs.refs.Types.SignatureRFC6979 signature, Message data) {
|
||||||
return verifyRFC6979(signature.getKey().toByteArray(), data.toByteArray(), signature.getSign().toByteArray());
|
return verifyRFC6979(signature.getKey().toByteArray(), data.toByteArray(), signature.getSign().toByteArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean verifyRFC6979(byte[] publicKey, byte[] data, byte[] sig) {
|
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 rs = decodeSignature(sig);
|
||||||
var digest = createSHA256();
|
var digest = createSHA256();
|
||||||
|
@ -85,9 +90,15 @@ public class Verifier {
|
||||||
public static boolean verifyMatryoshkaLevel(Message data,
|
public static boolean verifyMatryoshkaLevel(Message data,
|
||||||
frostfs.session.Types.ResponseMetaHeader meta,
|
frostfs.session.Types.ResponseMetaHeader meta,
|
||||||
frostfs.session.Types.ResponseVerificationHeader verification) {
|
frostfs.session.Types.ResponseVerificationHeader verification) {
|
||||||
if (!verifyMessagePart(verification.getMetaSignature(), meta)) return false;
|
if (!verifyMessagePart(verification.getMetaSignature(), meta)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
var origin = verification.getOrigin();
|
var origin = verification.getOrigin();
|
||||||
if (!verifyMessagePart(verification.getOriginSignature(), origin)) return false;
|
if (!verifyMessagePart(verification.getOriginSignature(), origin)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (origin.getSerializedSize() == 0) {
|
if (origin.getSerializedSize() == 0) {
|
||||||
return verifyMessagePart(verification.getBodySignature(), data);
|
return verifyMessagePart(verification.getBodySignature(), data);
|
||||||
}
|
}
|
||||||
|
@ -96,7 +107,9 @@ public class Verifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean verifyMessagePart(frostfs.refs.Types.Signature sig, Message data) {
|
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());
|
var publicKey = getPublicKeyFromBytes(sig.getKey().toByteArray());
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,11 @@
|
||||||
<artifactId>bcprov-jdk18on</artifactId>
|
<artifactId>bcprov-jdk18on</artifactId>
|
||||||
<version>1.78.1</version>
|
<version>1.78.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
<version>3.14.0</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -1,6 +1,8 @@
|
||||||
package info.frostfs.sdk;
|
package info.frostfs.sdk;
|
||||||
|
|
||||||
public class ArrayHelper {
|
public class ArrayHelper {
|
||||||
|
private ArrayHelper() {
|
||||||
|
}
|
||||||
|
|
||||||
public static byte[] concat(byte[] startArray, byte[] endArray) {
|
public static byte[] concat(byte[] startArray, byte[] endArray) {
|
||||||
byte[] result = new byte[startArray.length + endArray.length];
|
byte[] result = new byte[startArray.length + endArray.length];
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package info.frostfs.sdk;
|
package info.frostfs.sdk;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
import static info.frostfs.sdk.ArrayHelper.concat;
|
import static info.frostfs.sdk.ArrayHelper.concat;
|
||||||
|
@ -18,8 +20,11 @@ public class Base58 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Base58() {
|
||||||
|
}
|
||||||
|
|
||||||
public static byte[] base58CheckDecode(String input) {
|
public static byte[] base58CheckDecode(String input) {
|
||||||
if (isNull(input) || input.isEmpty()) {
|
if (StringUtils.isEmpty(input)) {
|
||||||
throw new IllegalArgumentException("Input value is missing");
|
throw new IllegalArgumentException("Input value is missing");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,10 +35,9 @@ public class Base58 {
|
||||||
|
|
||||||
byte[] decode = Arrays.copyOfRange(buffer, 0, buffer.length - 4);
|
byte[] decode = Arrays.copyOfRange(buffer, 0, buffer.length - 4);
|
||||||
byte[] checksum = getSha256(getSha256(decode));
|
byte[] checksum = getSha256(getSha256(decode));
|
||||||
if (!Arrays.equals(
|
var bufferEnd = Arrays.copyOfRange(buffer, buffer.length - 4, buffer.length);
|
||||||
Arrays.copyOfRange(buffer, buffer.length - 4, buffer.length),
|
var checksumStart = Arrays.copyOfRange(checksum, 0, 4);
|
||||||
Arrays.copyOfRange(checksum, 0, 4)
|
if (!Arrays.equals(bufferEnd, checksumStart)) {
|
||||||
)) {
|
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,6 +45,10 @@ public class Base58 {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String base58CheckEncode(byte[] data) {
|
public static String base58CheckEncode(byte[] data) {
|
||||||
|
if (isNull(data)) {
|
||||||
|
throw new IllegalArgumentException("Input value is missing");
|
||||||
|
}
|
||||||
|
|
||||||
byte[] checksum = getSha256(getSha256(data));
|
byte[] checksum = getSha256(getSha256(data));
|
||||||
var buffer = concat(data, Arrays.copyOfRange(checksum, 0, 4));
|
var buffer = concat(data, Arrays.copyOfRange(checksum, 0, 4));
|
||||||
var ret = encode(buffer);
|
var ret = encode(buffer);
|
||||||
|
|
|
@ -8,9 +8,17 @@ import java.math.BigInteger;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
|
||||||
|
import static java.util.Objects.isNull;
|
||||||
|
|
||||||
public class Helper {
|
public class Helper {
|
||||||
|
private Helper() {
|
||||||
|
}
|
||||||
|
|
||||||
public static byte[] getRIPEMD160(byte[] value) {
|
public static byte[] getRIPEMD160(byte[] value) {
|
||||||
|
if (isNull(value)) {
|
||||||
|
throw new IllegalArgumentException("Input value is missing");
|
||||||
|
}
|
||||||
|
|
||||||
var hash = new byte[20];
|
var hash = new byte[20];
|
||||||
var digest = new RIPEMD160Digest();
|
var digest = new RIPEMD160Digest();
|
||||||
digest.update(value, 0, value.length);
|
digest.update(value, 0, value.length);
|
||||||
|
@ -27,14 +35,26 @@ public class Helper {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] getSha256(byte[] value) {
|
public static byte[] getSha256(byte[] value) {
|
||||||
|
if (isNull(value)) {
|
||||||
|
throw new IllegalArgumentException("Input value is missing");
|
||||||
|
}
|
||||||
|
|
||||||
return getSha256Instance().digest(value);
|
return getSha256Instance().digest(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ByteString getSha256(Message value) {
|
public static ByteString getSha256(Message value) {
|
||||||
|
if (isNull(value)) {
|
||||||
|
throw new IllegalArgumentException("Input value is missing");
|
||||||
|
}
|
||||||
|
|
||||||
return ByteString.copyFrom(getSha256(value.toByteArray()));
|
return ByteString.copyFrom(getSha256(value.toByteArray()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getHexString(byte[] array) {
|
public static String getHexString(byte[] value) {
|
||||||
return String.format("%0" + (array.length << 1) + "x", new BigInteger(1, array));
|
if (isNull(value)) {
|
||||||
|
throw new IllegalArgumentException("Input value is missing");
|
||||||
|
}
|
||||||
|
|
||||||
|
return String.format("%0" + (value.length << 1) + "x", new BigInteger(1, value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package info.frostfs.sdk;
|
package info.frostfs.sdk;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.bouncycastle.asn1.sec.SECNamedCurves;
|
import org.bouncycastle.asn1.sec.SECNamedCurves;
|
||||||
import org.bouncycastle.asn1.sec.SECObjectIdentifiers;
|
import org.bouncycastle.asn1.sec.SECObjectIdentifiers;
|
||||||
import org.bouncycastle.asn1.x9.X9ECParameters;
|
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.getRIPEMD160;
|
||||||
import static info.frostfs.sdk.Helper.getSha256;
|
import static info.frostfs.sdk.Helper.getSha256;
|
||||||
|
import static java.util.Objects.isNull;
|
||||||
import static org.bouncycastle.util.BigIntegers.fromUnsignedByteArray;
|
import static org.bouncycastle.util.BigIntegers.fromUnsignedByteArray;
|
||||||
|
|
||||||
public class KeyExtension {
|
public class KeyExtension {
|
||||||
public static final byte NEO_ADDRESS_VERSION = 0x35;
|
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 COMPRESSED_PUBLIC_KEY_LENGTH = 33;
|
||||||
private static final int UNCOMPRESSED_PUBLIC_KEY_LENGTH = 65;
|
private static final int UNCOMPRESSED_PUBLIC_KEY_LENGTH = 65;
|
||||||
|
|
||||||
private static final int CHECK_SIG_DESCRIPTOR = ByteBuffer
|
private static final int CHECK_SIG_DESCRIPTOR = ByteBuffer
|
||||||
.wrap(getSha256("System.Crypto.CheckSig".getBytes(StandardCharsets.US_ASCII)))
|
.wrap(getSha256("System.Crypto.CheckSig".getBytes(StandardCharsets.US_ASCII)))
|
||||||
.order(ByteOrder.LITTLE_ENDIAN).getInt();
|
.order(ByteOrder.LITTLE_ENDIAN).getInt();
|
||||||
|
|
||||||
|
private KeyExtension() {
|
||||||
|
}
|
||||||
|
|
||||||
public static byte[] compress(byte[] publicKey) {
|
public static byte[] compress(byte[] publicKey) {
|
||||||
|
checkInputValue(publicKey);
|
||||||
if (publicKey.length != UNCOMPRESSED_PUBLIC_KEY_LENGTH) {
|
if (publicKey.length != UNCOMPRESSED_PUBLIC_KEY_LENGTH) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
String.format("Compress argument isn't uncompressed public key. Expected length=%s, actual=%s",
|
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) {
|
public static byte[] getPrivateKeyFromWIF(String wif) {
|
||||||
|
if (StringUtils.isEmpty(wif)) {
|
||||||
|
throw new IllegalArgumentException("Input value is missing");
|
||||||
|
}
|
||||||
|
|
||||||
var data = Base58.base58CheckDecode(wif);
|
var data = Base58.base58CheckDecode(wif);
|
||||||
return Arrays.copyOfRange(data, 1, data.length - 1);
|
return Arrays.copyOfRange(data, 1, data.length - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] loadPublicKey(byte[] privateKey) {
|
public static byte[] loadPublicKey(byte[] privateKey) {
|
||||||
|
checkInputValue(privateKey);
|
||||||
|
|
||||||
X9ECParameters params = SECNamedCurves.getByOID(SECObjectIdentifiers.secp256r1);
|
X9ECParameters params = SECNamedCurves.getByOID(SECObjectIdentifiers.secp256r1);
|
||||||
ECDomainParameters domain = new ECDomainParameters(
|
ECDomainParameters domain = new ECDomainParameters(
|
||||||
params.getCurve(), params.getG(), params.getN(), params.getH()
|
params.getCurve(), params.getG(), params.getN(), params.getH()
|
||||||
|
@ -66,6 +77,8 @@ public class KeyExtension {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PrivateKey loadPrivateKey(byte[] privateKey) {
|
public static PrivateKey loadPrivateKey(byte[] privateKey) {
|
||||||
|
checkInputValue(privateKey);
|
||||||
|
|
||||||
X9ECParameters params = SECNamedCurves.getByOID(SECObjectIdentifiers.secp256r1);
|
X9ECParameters params = SECNamedCurves.getByOID(SECObjectIdentifiers.secp256r1);
|
||||||
ECDomainParameters domain = new ECDomainParameters(
|
ECDomainParameters domain = new ECDomainParameters(
|
||||||
params.getCurve(), params.getG(), params.getN(), params.getH()
|
params.getCurve(), params.getG(), params.getN(), params.getH()
|
||||||
|
@ -85,6 +98,8 @@ public class KeyExtension {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PublicKey getPublicKeyFromBytes(byte[] publicKey) {
|
public static PublicKey getPublicKeyFromBytes(byte[] publicKey) {
|
||||||
|
checkInputValue(publicKey);
|
||||||
|
|
||||||
if (publicKey.length != COMPRESSED_PUBLIC_KEY_LENGTH) {
|
if (publicKey.length != COMPRESSED_PUBLIC_KEY_LENGTH) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
String.format("Decompress argument isn't compressed public key. Expected length=%s, actual=%s",
|
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) {
|
public static byte[] getScriptHash(byte[] publicKey) {
|
||||||
var script = createSignatureRedeemScript(publicKey);
|
checkInputValue(publicKey);
|
||||||
|
|
||||||
|
var script = createSignatureRedeemScript(publicKey);
|
||||||
return getRIPEMD160(getSha256(script));
|
return getRIPEMD160(getSha256(script));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String publicKeyToAddress(byte[] publicKey) {
|
public static String publicKeyToAddress(byte[] publicKey) {
|
||||||
|
checkInputValue(publicKey);
|
||||||
if (publicKey.length != COMPRESSED_PUBLIC_KEY_LENGTH) {
|
if (publicKey.length != COMPRESSED_PUBLIC_KEY_LENGTH) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
String.format("PublicKey isn't encoded compressed public key. Expected length=%s, actual=%s",
|
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) {
|
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;
|
data[0] = version;
|
||||||
System.arraycopy(scriptHash, 0, data, 1, scriptHash.length);
|
System.arraycopy(scriptHash, 0, data, 1, scriptHash.length);
|
||||||
return Base58.base58CheckEncode(data);
|
return Base58.base58CheckEncode(data);
|
||||||
|
@ -150,6 +168,7 @@ public class KeyExtension {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] createSignatureRedeemScript(byte[] publicKey) {
|
private static byte[] createSignatureRedeemScript(byte[] publicKey) {
|
||||||
|
checkInputValue(publicKey);
|
||||||
if (publicKey.length != COMPRESSED_PUBLIC_KEY_LENGTH) {
|
if (publicKey.length != COMPRESSED_PUBLIC_KEY_LENGTH) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
String.format("PublicKey isn't encoded compressed public key. Expected length=%s, actual=%s",
|
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
|
script = ArrayHelper.concat(script, getBytes(CHECK_SIG_DESCRIPTOR)); //Neo_Crypto_CheckSig
|
||||||
return script;
|
return script;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void checkInputValue(byte[] data) {
|
||||||
|
if (isNull(data)) {
|
||||||
|
throw new IllegalArgumentException("Input value is missing");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,11 +18,6 @@
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.commons</groupId>
|
|
||||||
<artifactId>commons-lang3</artifactId>
|
|
||||||
<version>3.14.0</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>info.frostfs.sdk</groupId>
|
<groupId>info.frostfs.sdk</groupId>
|
||||||
<artifactId>cryptography</artifactId>
|
<artifactId>cryptography</artifactId>
|
||||||
|
@ -33,6 +28,16 @@
|
||||||
<artifactId>protos</artifactId>
|
<artifactId>protos</artifactId>
|
||||||
<version>0.1.0</version>
|
<version>0.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
<version>3.14.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-collections4</artifactId>
|
||||||
|
<version>4.4</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -3,19 +3,33 @@ package info.frostfs.sdk;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static java.util.Objects.isNull;
|
||||||
|
|
||||||
public class UUIDExtension {
|
public class UUIDExtension {
|
||||||
|
private static final int UUID_BYTE_ARRAY_LENGTH = 16;
|
||||||
|
|
||||||
|
private UUIDExtension() {
|
||||||
|
}
|
||||||
|
|
||||||
public static UUID asUuid(byte[] bytes) {
|
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);
|
ByteBuffer bb = ByteBuffer.wrap(bytes);
|
||||||
long firstLong = bb.getLong();
|
long firstLong = bb.getLong();
|
||||||
long secondLong = bb.getLong();
|
long secondLong = bb.getLong();
|
||||||
return new UUID(firstLong, secondLong);
|
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);
|
ByteBuffer bb = ByteBuffer.allocate(16);
|
||||||
bb.putLong(id.getMostSignificantBits());
|
bb.putLong(uuid.getMostSignificantBits());
|
||||||
bb.putLong(id.getLeastSignificantBits());
|
bb.putLong(uuid.getLeastSignificantBits());
|
||||||
return bb.array();
|
return bb.array();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
package info.frostfs.sdk.constants;
|
package info.frostfs.sdk.constants;
|
||||||
|
|
||||||
public class AppConst {
|
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 OBJECT_CHUNK_SIZE = 3 * (1 << 20);
|
||||||
public static final int SHA256_HASH_LENGTH = 32;
|
public static final int SHA256_HASH_LENGTH = 32;
|
||||||
|
|
||||||
|
private AppConst() {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,4 +8,8 @@ public class FieldConst {
|
||||||
public static final String ORIGIN_FIELD_NAME = "origin";
|
public static final String ORIGIN_FIELD_NAME = "origin";
|
||||||
public static final String ORIGIN_SIGNATURE_FIELD_NAME = "origin_signature";
|
public static final String ORIGIN_SIGNATURE_FIELD_NAME = "origin_signature";
|
||||||
public static final String VERIFY_HEADER_FIELD_NAME = "verify_header";
|
public static final String VERIFY_HEADER_FIELD_NAME = "verify_header";
|
||||||
|
public static final String EMPTY_STRING = "";
|
||||||
|
|
||||||
|
private FieldConst() {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,4 +4,7 @@ public class XHeaderConst {
|
||||||
public static final String RESERVED_XHEADER_PREFIX = "__SYSTEM__";
|
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_EPOCH = RESERVED_XHEADER_PREFIX + "NETMAP_EPOCH";
|
||||||
public static final String XHEADER_NETMAP_LOOKUP_DEPTH = RESERVED_XHEADER_PREFIX + "NETMAP_LOOKUP_DEPTH";
|
public static final String XHEADER_NETMAP_LOOKUP_DEPTH = RESERVED_XHEADER_PREFIX + "NETMAP_LOOKUP_DEPTH";
|
||||||
|
|
||||||
|
private XHeaderConst() {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,28 @@
|
||||||
package info.frostfs.sdk.dto;
|
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 {
|
public class MetaHeader {
|
||||||
private Version version;
|
private Version version;
|
||||||
private int epoch;
|
private int epoch;
|
||||||
private int ttl;
|
private int ttl;
|
||||||
|
|
||||||
public MetaHeader(Version version, int epoch, 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.version = version;
|
||||||
this.epoch = epoch;
|
this.epoch = epoch;
|
||||||
this.ttl = ttl;
|
this.ttl = ttl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MetaHeader getDefault() {
|
public MetaHeader() {
|
||||||
return new MetaHeader(new Version(2, 13), 0, 2);
|
this.version = new Version(DEFAULT_MAJOR_VERSION, DEFAULT_MINOR_VERSION);
|
||||||
|
this.epoch = 0;
|
||||||
|
this.ttl = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Version getVersion() {
|
public Version getVersion() {
|
||||||
|
@ -20,6 +30,10 @@ public class MetaHeader {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setVersion(Version version) {
|
public void setVersion(Version version) {
|
||||||
|
if (isNull(version)) {
|
||||||
|
throw new IllegalArgumentException("Version is missing.");
|
||||||
|
}
|
||||||
|
|
||||||
this.version = version;
|
this.version = version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +42,10 @@ public class MetaHeader {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setEpoch(int epoch) {
|
public void setEpoch(int epoch) {
|
||||||
|
if (epoch < 0) {
|
||||||
|
throw new IllegalArgumentException("The epoch must be greater than or equal to zero.");
|
||||||
|
}
|
||||||
|
|
||||||
this.epoch = epoch;
|
this.epoch = epoch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,6 +54,10 @@ public class MetaHeader {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTtl(int ttl) {
|
public void setTtl(int ttl) {
|
||||||
|
if (ttl <= 0) {
|
||||||
|
throw new IllegalArgumentException("The ttl must be greater than zero.");
|
||||||
|
}
|
||||||
|
|
||||||
this.ttl = ttl;
|
this.ttl = ttl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package info.frostfs.sdk.dto;
|
||||||
import info.frostfs.sdk.Base58;
|
import info.frostfs.sdk.Base58;
|
||||||
|
|
||||||
import static info.frostfs.sdk.KeyExtension.publicKeyToAddress;
|
import static info.frostfs.sdk.KeyExtension.publicKeyToAddress;
|
||||||
|
import static java.util.Objects.isNull;
|
||||||
|
|
||||||
public class OwnerId {
|
public class OwnerId {
|
||||||
private final String value;
|
private final String value;
|
||||||
|
@ -11,8 +12,12 @@ public class OwnerId {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static OwnerId fromKey(byte[] publicKey) {
|
public OwnerId(byte[] publicKey) {
|
||||||
return new OwnerId(publicKeyToAddress(publicKey));
|
if (isNull(publicKey) || publicKey.length == 0) {
|
||||||
|
throw new IllegalArgumentException("PublicKey is invalid");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.value = publicKeyToAddress(publicKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getValue() {
|
public String getValue() {
|
||||||
|
|
|
@ -6,9 +6,11 @@ import info.frostfs.sdk.dto.object.ObjectId;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static java.util.Objects.isNull;
|
||||||
|
|
||||||
public class Split {
|
public class Split {
|
||||||
private final List<ObjectId> children;
|
private final List<ObjectId> children;
|
||||||
private SplitId splitId;
|
private final SplitId splitId;
|
||||||
private ObjectId parent;
|
private ObjectId parent;
|
||||||
private ObjectId previous;
|
private ObjectId previous;
|
||||||
private Signature parentSignature;
|
private Signature parentSignature;
|
||||||
|
@ -19,6 +21,10 @@ public class Split {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Split(SplitId splitId) {
|
public Split(SplitId splitId) {
|
||||||
|
if (isNull(splitId)) {
|
||||||
|
throw new IllegalArgumentException("SplitId is not present");
|
||||||
|
}
|
||||||
|
|
||||||
this.splitId = splitId;
|
this.splitId = splitId;
|
||||||
this.children = new ArrayList<>();
|
this.children = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
@ -27,10 +33,6 @@ public class Split {
|
||||||
return splitId;
|
return splitId;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setSplitId(SplitId splitId) {
|
|
||||||
this.splitId = splitId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ObjectId getParent() {
|
public ObjectId getParent() {
|
||||||
return parent;
|
return parent;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,30 +9,22 @@ import static java.util.Objects.isNull;
|
||||||
public class SplitId {
|
public class SplitId {
|
||||||
private final UUID id;
|
private final UUID id;
|
||||||
|
|
||||||
public SplitId(UUID uuid) {
|
|
||||||
this.id = uuid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SplitId() {
|
public SplitId() {
|
||||||
this.id = UUID.randomUUID();
|
this.id = UUID.randomUUID();
|
||||||
}
|
}
|
||||||
|
|
||||||
private SplitId(byte[] binary) {
|
public SplitId(UUID uuid) {
|
||||||
|
this.id = uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SplitId(byte[] binary) {
|
||||||
this.id = asUuid(binary);
|
this.id = asUuid(binary);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SplitId(String str) {
|
public SplitId(String str) {
|
||||||
this.id = UUID.fromString(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
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return id.toString();
|
return id.toString();
|
||||||
|
|
|
@ -2,6 +2,7 @@ package info.frostfs.sdk.dto;
|
||||||
|
|
||||||
import info.frostfs.sdk.enums.StatusCode;
|
import info.frostfs.sdk.enums.StatusCode;
|
||||||
|
|
||||||
|
import static info.frostfs.sdk.constants.FieldConst.EMPTY_STRING;
|
||||||
import static java.util.Objects.isNull;
|
import static java.util.Objects.isNull;
|
||||||
|
|
||||||
public class Status {
|
public class Status {
|
||||||
|
@ -10,12 +11,12 @@ public class Status {
|
||||||
|
|
||||||
public Status(StatusCode code, String message) {
|
public Status(StatusCode code, String message) {
|
||||||
this.code = code;
|
this.code = code;
|
||||||
this.message = isNull(message) ? "" : message;
|
this.message = isNull(message) ? EMPTY_STRING : message;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Status(StatusCode code) {
|
public Status(StatusCode code) {
|
||||||
this.code = code;
|
this.code = code;
|
||||||
this.message = "";
|
this.message = EMPTY_STRING;
|
||||||
}
|
}
|
||||||
|
|
||||||
public StatusCode getCode() {
|
public StatusCode getCode() {
|
||||||
|
|
|
@ -1,36 +1,41 @@
|
||||||
package info.frostfs.sdk.dto;
|
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 {
|
public class Version {
|
||||||
private int major;
|
private final int major;
|
||||||
private int minor;
|
private final int minor;
|
||||||
|
|
||||||
public Version(int major, int minor) {
|
public Version(int major, int minor) {
|
||||||
this.major = major;
|
this.major = major;
|
||||||
this.minor = minor;
|
this.minor = minor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Version() {
|
||||||
|
this.major = DEFAULT_MAJOR_VERSION;
|
||||||
|
this.minor = DEFAULT_MINOR_VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
public int getMajor() {
|
public int getMajor() {
|
||||||
return major;
|
return major;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMajor(int major) {
|
|
||||||
this.major = major;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMinor() {
|
public int getMinor() {
|
||||||
return minor;
|
return minor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMinor(int minor) {
|
|
||||||
this.minor = minor;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "v" + major + "." + minor;
|
return "v" + major + "." + minor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSupported(Version version) {
|
public boolean isSupported(Version version) {
|
||||||
|
if (isNull(version)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return major == version.getMajor();
|
return major == version.getMajor();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,29 +2,33 @@ package info.frostfs.sdk.dto.container;
|
||||||
|
|
||||||
import info.frostfs.sdk.Base58;
|
import info.frostfs.sdk.Base58;
|
||||||
import info.frostfs.sdk.constants.AppConst;
|
import info.frostfs.sdk.constants.AppConst;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import static java.util.Objects.isNull;
|
||||||
|
|
||||||
public class ContainerId {
|
public class ContainerId {
|
||||||
private String value;
|
private final String value;
|
||||||
|
|
||||||
public ContainerId(String value) {
|
public ContainerId(String value) {
|
||||||
|
if (StringUtils.isEmpty(value)) {
|
||||||
|
throw new IllegalArgumentException("ContainerId value is missing");
|
||||||
|
}
|
||||||
|
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ContainerId fromHash(byte[] hash) {
|
public ContainerId(byte[] hash) {
|
||||||
if (hash.length != AppConst.SHA256_HASH_LENGTH) {
|
if (isNull(hash) || hash.length != AppConst.SHA256_HASH_LENGTH) {
|
||||||
throw new IllegalArgumentException("ContainerID must be a sha256 hash.");
|
throw new IllegalArgumentException("ContainerId must be a sha256 hash.");
|
||||||
}
|
}
|
||||||
return new ContainerId(Base58.encode(hash));
|
|
||||||
|
this.value = Base58.encode(hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getValue() {
|
public String getValue() {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setValue(String value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return value;
|
return value;
|
||||||
|
|
|
@ -1,34 +1,36 @@
|
||||||
package info.frostfs.sdk.dto.netmap;
|
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 {
|
public class Replica {
|
||||||
private int count;
|
private final int count;
|
||||||
private String selector;
|
private final String selector;
|
||||||
|
|
||||||
public Replica(int count, String selector) {
|
public Replica(int count, String selector) {
|
||||||
|
if (count <= 0) {
|
||||||
|
throw new IllegalArgumentException("Replica count must be positive");
|
||||||
|
}
|
||||||
|
|
||||||
this.count = count;
|
this.count = count;
|
||||||
this.selector = isNull(selector) ? "" : selector;
|
this.selector = StringUtils.isEmpty(selector) ? EMPTY_STRING : selector;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Replica(int count) {
|
public Replica(int count) {
|
||||||
|
if (count <= 0) {
|
||||||
|
throw new IllegalArgumentException("Replica count must be positive");
|
||||||
|
}
|
||||||
|
|
||||||
this.count = count;
|
this.count = count;
|
||||||
this.selector = "";
|
this.selector = EMPTY_STRING;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCount() {
|
public int getCount() {
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCount(int count) {
|
|
||||||
this.count = count;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSelector() {
|
public String getSelector() {
|
||||||
return selector;
|
return selector;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSelector(String selector) {
|
|
||||||
this.selector = selector;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import info.frostfs.sdk.dto.container.ContainerId;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
|
|
||||||
import static info.frostfs.sdk.Helper.getSha256Instance;
|
import static info.frostfs.sdk.Helper.getSha256Instance;
|
||||||
|
import static java.util.Objects.isNull;
|
||||||
|
|
||||||
public class LargeObject extends ObjectFrostFS {
|
public class LargeObject extends ObjectFrostFS {
|
||||||
private final MessageDigest payloadHash;
|
private final MessageDigest payloadHash;
|
||||||
|
@ -15,6 +16,10 @@ public class LargeObject extends ObjectFrostFS {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void appendBlock(byte[] bytes, int count) {
|
public void appendBlock(byte[] bytes, int count) {
|
||||||
|
if (count == 0 || isNull(bytes) || bytes.length == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.getHeader().increasePayloadLength(count);
|
this.getHeader().increasePayloadLength(count);
|
||||||
this.payloadHash.update(bytes, 0, count);
|
this.payloadHash.update(bytes, 0, count);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package info.frostfs.sdk.dto.object;
|
||||||
import info.frostfs.sdk.dto.Split;
|
import info.frostfs.sdk.dto.Split;
|
||||||
import info.frostfs.sdk.dto.SplitId;
|
import info.frostfs.sdk.dto.SplitId;
|
||||||
import info.frostfs.sdk.dto.container.ContainerId;
|
import info.frostfs.sdk.dto.container.ContainerId;
|
||||||
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -16,6 +17,10 @@ public class LinkObject extends ObjectFrostFS {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addChildren(List<ObjectId> objectIds) {
|
public void addChildren(List<ObjectId> objectIds) {
|
||||||
|
if (CollectionUtils.isEmpty(objectIds)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.getHeader().getSplit().getChildren().addAll(objectIds);
|
this.getHeader().getSplit().getChildren().addAll(objectIds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,16 @@
|
||||||
package info.frostfs.sdk.dto.object;
|
package info.frostfs.sdk.dto.object;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
public class ObjectAttribute {
|
public class ObjectAttribute {
|
||||||
private String key;
|
private final String key;
|
||||||
private String value;
|
private final String value;
|
||||||
|
|
||||||
public ObjectAttribute(String key, 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.key = key;
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
@ -13,15 +19,7 @@ public class ObjectAttribute {
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setKey(String key) {
|
|
||||||
this.key = key;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getValue() {
|
public String getValue() {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setValue(String value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,34 +10,34 @@ import java.util.List;
|
||||||
import static java.util.Objects.isNull;
|
import static java.util.Objects.isNull;
|
||||||
|
|
||||||
public class ObjectFrostFS {
|
public class ObjectFrostFS {
|
||||||
private ObjectHeader header;
|
private final ObjectHeader header;
|
||||||
private ObjectId objectId;
|
private ObjectId objectId;
|
||||||
private byte[] payload;
|
private byte[] payload;
|
||||||
|
|
||||||
public ObjectFrostFS(ObjectHeader header, ObjectId objectId, byte[] payload) {
|
public ObjectFrostFS(ObjectHeader header, ObjectId objectId, byte[] payload) {
|
||||||
|
if (isNull(header)) {
|
||||||
|
throw new IllegalArgumentException("Object header is missing");
|
||||||
|
}
|
||||||
|
|
||||||
this.header = header;
|
this.header = header;
|
||||||
this.objectId = objectId;
|
this.objectId = objectId;
|
||||||
this.payload = payload;
|
this.payload = payload;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObjectFrostFS(ContainerId container, byte[] payload) {
|
public ObjectFrostFS(ContainerId containerId, byte[] payload) {
|
||||||
this.payload = 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.payload = payload;
|
||||||
this.header = new ObjectHeader(container, objectType, new ArrayList<>());
|
this.header = new ObjectHeader(containerId, objectType, new ArrayList<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObjectHeader getHeader() {
|
public ObjectHeader getHeader() {
|
||||||
return header;
|
return header;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setHeader(ObjectHeader header) {
|
|
||||||
this.header = header;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ObjectId getObjectId() {
|
public ObjectId getObjectId() {
|
||||||
return objectId;
|
return objectId;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,11 +8,13 @@ import info.frostfs.sdk.enums.ObjectType;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static java.util.Objects.isNull;
|
||||||
|
|
||||||
public class ObjectHeader {
|
public class ObjectHeader {
|
||||||
|
private final ContainerId containerId;
|
||||||
|
private final ObjectType objectType;
|
||||||
private List<ObjectAttribute> attributes;
|
private List<ObjectAttribute> attributes;
|
||||||
private ContainerId containerId;
|
|
||||||
private long size;
|
private long size;
|
||||||
private ObjectType objectType;
|
|
||||||
private Version version;
|
private Version version;
|
||||||
private OwnerId ownerId;
|
private OwnerId ownerId;
|
||||||
private long payloadLength;
|
private long payloadLength;
|
||||||
|
@ -21,6 +23,10 @@ public class ObjectHeader {
|
||||||
|
|
||||||
public ObjectHeader(ContainerId containerId, ObjectType objectType,
|
public ObjectHeader(ContainerId containerId, ObjectType objectType,
|
||||||
List<ObjectAttribute> attributes, long size, Version version) {
|
List<ObjectAttribute> attributes, long size, Version version) {
|
||||||
|
if (isNull(containerId) || isNull(objectType)) {
|
||||||
|
throw new IllegalArgumentException("ContainerId or objectType is not present");
|
||||||
|
}
|
||||||
|
|
||||||
this.attributes = attributes;
|
this.attributes = attributes;
|
||||||
this.containerId = containerId;
|
this.containerId = containerId;
|
||||||
this.size = size;
|
this.size = size;
|
||||||
|
@ -28,13 +34,21 @@ public class ObjectHeader {
|
||||||
this.version = version;
|
this.version = version;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObjectHeader(ContainerId containerId, ObjectType type, List<ObjectAttribute> attributes) {
|
public ObjectHeader(ContainerId containerId, ObjectType objectType, List<ObjectAttribute> attributes) {
|
||||||
|
if (isNull(containerId) || isNull(objectType)) {
|
||||||
|
throw new IllegalArgumentException("ContainerId or objectType is not present");
|
||||||
|
}
|
||||||
|
|
||||||
this.attributes = attributes;
|
this.attributes = attributes;
|
||||||
this.containerId = containerId;
|
this.containerId = containerId;
|
||||||
this.objectType = type;
|
this.objectType = objectType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObjectHeader(ContainerId containerId, List<ObjectAttribute> attributes) {
|
public ObjectHeader(ContainerId containerId, List<ObjectAttribute> attributes) {
|
||||||
|
if (isNull(containerId)) {
|
||||||
|
throw new IllegalArgumentException("ContainerId is not present");
|
||||||
|
}
|
||||||
|
|
||||||
this.attributes = attributes;
|
this.attributes = attributes;
|
||||||
this.containerId = containerId;
|
this.containerId = containerId;
|
||||||
this.objectType = ObjectType.REGULAR;
|
this.objectType = ObjectType.REGULAR;
|
||||||
|
@ -73,6 +87,10 @@ public class ObjectHeader {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSplit(Split split) {
|
public void setSplit(Split split) {
|
||||||
|
if (isNull(split)) {
|
||||||
|
throw new IllegalArgumentException("Split is not present");
|
||||||
|
}
|
||||||
|
|
||||||
this.split = split;
|
this.split = split;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,10 +106,6 @@ public class ObjectHeader {
|
||||||
return containerId;
|
return containerId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setContainerId(ContainerId containerId) {
|
|
||||||
this.containerId = containerId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getSize() {
|
public long getSize() {
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
@ -104,10 +118,6 @@ public class ObjectHeader {
|
||||||
return objectType;
|
return objectType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setObjectType(ObjectType objectType) {
|
|
||||||
this.objectType = objectType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Version getVersion() {
|
public Version getVersion() {
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,19 +2,27 @@ package info.frostfs.sdk.dto.object;
|
||||||
|
|
||||||
import info.frostfs.sdk.Base58;
|
import info.frostfs.sdk.Base58;
|
||||||
import info.frostfs.sdk.constants.AppConst;
|
import info.frostfs.sdk.constants.AppConst;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import static java.util.Objects.isNull;
|
||||||
|
|
||||||
public class ObjectId {
|
public class ObjectId {
|
||||||
private final String value;
|
private final String value;
|
||||||
|
|
||||||
public ObjectId(String id) {
|
public ObjectId(String value) {
|
||||||
this.value = id;
|
if (StringUtils.isEmpty(value)) {
|
||||||
|
throw new IllegalArgumentException("ObjectId value is missing");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ObjectId fromHash(byte[] hash) {
|
this.value = value;
|
||||||
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.");
|
throw new IllegalArgumentException("ObjectId must be a sha256 hash.");
|
||||||
}
|
}
|
||||||
return new ObjectId(Base58.encode(hash));
|
|
||||||
|
this.value = Base58.encode(hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getValue() {
|
public String getValue() {
|
||||||
|
|
|
@ -3,9 +3,18 @@ package info.frostfs.sdk.mappers;
|
||||||
import frostfs.session.Types;
|
import frostfs.session.Types;
|
||||||
import info.frostfs.sdk.dto.MetaHeader;
|
import info.frostfs.sdk.dto.MetaHeader;
|
||||||
|
|
||||||
|
import static java.util.Objects.isNull;
|
||||||
|
|
||||||
public class MetaHeaderMapper {
|
public class MetaHeaderMapper {
|
||||||
|
|
||||||
|
private MetaHeaderMapper() {
|
||||||
|
}
|
||||||
|
|
||||||
public static Types.RequestMetaHeader toGrpcMessage(MetaHeader metaHeader) {
|
public static Types.RequestMetaHeader toGrpcMessage(MetaHeader metaHeader) {
|
||||||
|
if (isNull(metaHeader)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return Types.RequestMetaHeader.newBuilder()
|
return Types.RequestMetaHeader.newBuilder()
|
||||||
.setVersion(VersionMapper.toGrpcMessage(metaHeader.getVersion()))
|
.setVersion(VersionMapper.toGrpcMessage(metaHeader.getVersion()))
|
||||||
.setEpoch(metaHeader.getEpoch())
|
.setEpoch(metaHeader.getEpoch())
|
||||||
|
|
|
@ -4,9 +4,18 @@ import com.google.protobuf.ByteString;
|
||||||
import frostfs.refs.Types;
|
import frostfs.refs.Types;
|
||||||
import info.frostfs.sdk.dto.OwnerId;
|
import info.frostfs.sdk.dto.OwnerId;
|
||||||
|
|
||||||
|
import static java.util.Objects.isNull;
|
||||||
|
|
||||||
public class OwnerIdMapper {
|
public class OwnerIdMapper {
|
||||||
|
|
||||||
|
private OwnerIdMapper() {
|
||||||
|
}
|
||||||
|
|
||||||
public static Types.OwnerID toGrpcMessage(OwnerId ownerId) {
|
public static Types.OwnerID toGrpcMessage(OwnerId ownerId) {
|
||||||
|
if (isNull(ownerId)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return Types.OwnerID.newBuilder()
|
return Types.OwnerID.newBuilder()
|
||||||
.setValue(ByteString.copyFrom(ownerId.toHash()))
|
.setValue(ByteString.copyFrom(ownerId.toHash()))
|
||||||
.build();
|
.build();
|
||||||
|
|
|
@ -6,9 +6,18 @@ import frostfs.session.Types;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import static java.util.Objects.isNull;
|
||||||
|
|
||||||
public class SessionMapper {
|
public class SessionMapper {
|
||||||
|
|
||||||
|
private SessionMapper() {
|
||||||
|
}
|
||||||
|
|
||||||
public static byte[] serialize(Types.SessionToken token) {
|
public static byte[] serialize(Types.SessionToken token) {
|
||||||
|
if (isNull(token)) {
|
||||||
|
throw new IllegalArgumentException("Token is not present");
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
byte[] bytes = new byte[token.getSerializedSize()];
|
byte[] bytes = new byte[token.getSerializedSize()];
|
||||||
CodedOutputStream stream = CodedOutputStream.newInstance(bytes);
|
CodedOutputStream stream = CodedOutputStream.newInstance(bytes);
|
||||||
|
@ -20,6 +29,10 @@ public class SessionMapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Types.SessionToken deserializeSessionToken(byte[] bytes) {
|
public static Types.SessionToken deserializeSessionToken(byte[] bytes) {
|
||||||
|
if (isNull(bytes) || bytes.length == 0) {
|
||||||
|
throw new IllegalArgumentException("Token is not present");
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return Types.SessionToken.newBuilder().mergeFrom(bytes).build();
|
return Types.SessionToken.newBuilder().mergeFrom(bytes).build();
|
||||||
} catch (InvalidProtocolBufferException exp) {
|
} catch (InvalidProtocolBufferException exp) {
|
||||||
|
|
|
@ -8,7 +8,14 @@ import static java.util.Objects.isNull;
|
||||||
|
|
||||||
public class SignatureMapper {
|
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);
|
var scheme = Types.SignatureScheme.forNumber(signature.getScheme().value);
|
||||||
if (isNull(scheme)) {
|
if (isNull(scheme)) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
|
|
|
@ -8,8 +8,13 @@ import static java.util.Objects.isNull;
|
||||||
|
|
||||||
public class StatusMapper {
|
public class StatusMapper {
|
||||||
|
|
||||||
|
private StatusMapper() {
|
||||||
|
}
|
||||||
|
|
||||||
public static Status toModel(Types.Status status) {
|
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());
|
var statusCode = StatusCode.get(status.getCode());
|
||||||
if (isNull(statusCode)) {
|
if (isNull(statusCode)) {
|
||||||
|
|
|
@ -3,9 +3,18 @@ package info.frostfs.sdk.mappers;
|
||||||
import frostfs.refs.Types;
|
import frostfs.refs.Types;
|
||||||
import info.frostfs.sdk.dto.Version;
|
import info.frostfs.sdk.dto.Version;
|
||||||
|
|
||||||
|
import static java.util.Objects.isNull;
|
||||||
|
|
||||||
public class VersionMapper {
|
public class VersionMapper {
|
||||||
|
|
||||||
|
private VersionMapper() {
|
||||||
|
}
|
||||||
|
|
||||||
public static Types.Version toGrpcMessage(Version version) {
|
public static Types.Version toGrpcMessage(Version version) {
|
||||||
|
if (isNull(version)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return Types.Version.newBuilder()
|
return Types.Version.newBuilder()
|
||||||
.setMajor(version.getMajor())
|
.setMajor(version.getMajor())
|
||||||
.setMinor(version.getMinor())
|
.setMinor(version.getMinor())
|
||||||
|
@ -13,6 +22,10 @@ public class VersionMapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Version toModel(Types.Version version) {
|
public static Version toModel(Types.Version version) {
|
||||||
|
if (isNull(version)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return new Version(version.getMajor(), version.getMinor());
|
return new Version(version.getMajor(), version.getMinor());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,18 @@ import com.google.protobuf.ByteString;
|
||||||
import frostfs.refs.Types;
|
import frostfs.refs.Types;
|
||||||
import info.frostfs.sdk.dto.container.ContainerId;
|
import info.frostfs.sdk.dto.container.ContainerId;
|
||||||
|
|
||||||
|
import static java.util.Objects.isNull;
|
||||||
|
|
||||||
public class ContainerIdMapper {
|
public class ContainerIdMapper {
|
||||||
|
|
||||||
|
private ContainerIdMapper() {
|
||||||
|
}
|
||||||
|
|
||||||
public static Types.ContainerID toGrpcMessage(ContainerId containerId) {
|
public static Types.ContainerID toGrpcMessage(ContainerId containerId) {
|
||||||
|
if (isNull(containerId)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return Types.ContainerID.newBuilder()
|
return Types.ContainerID.newBuilder()
|
||||||
.setValue(ByteString.copyFrom(containerId.toHash()))
|
.setValue(ByteString.copyFrom(containerId.toHash()))
|
||||||
.build();
|
.build();
|
||||||
|
|
|
@ -13,7 +13,14 @@ import static java.util.Objects.isNull;
|
||||||
|
|
||||||
public class ContainerMapper {
|
public class ContainerMapper {
|
||||||
|
|
||||||
|
private ContainerMapper() {
|
||||||
|
}
|
||||||
|
|
||||||
public static Types.Container toGrpcMessage(Container container) {
|
public static Types.Container toGrpcMessage(Container container) {
|
||||||
|
if (isNull(container)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return Types.Container.newBuilder()
|
return Types.Container.newBuilder()
|
||||||
.setBasicAcl(container.getBasicAcl().value)
|
.setBasicAcl(container.getBasicAcl().value)
|
||||||
.setPlacementPolicy(PlacementPolicyMapper.toGrpcMessage(container.getPlacementPolicy()))
|
.setPlacementPolicy(PlacementPolicyMapper.toGrpcMessage(container.getPlacementPolicy()))
|
||||||
|
@ -22,6 +29,10 @@ public class ContainerMapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Container toModel(Types.Container containerGrpc) {
|
public static Container toModel(Types.Container containerGrpc) {
|
||||||
|
if (isNull(containerGrpc)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
var basicAcl = BasicAcl.get(containerGrpc.getBasicAcl());
|
var basicAcl = BasicAcl.get(containerGrpc.getBasicAcl());
|
||||||
if (isNull(basicAcl)) {
|
if (isNull(basicAcl)) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
|
|
|
@ -5,9 +5,18 @@ import info.frostfs.sdk.dto.netmap.NetmapSnapshot;
|
||||||
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static java.util.Objects.isNull;
|
||||||
|
|
||||||
public class NetmapSnapshotMapper {
|
public class NetmapSnapshotMapper {
|
||||||
|
|
||||||
|
private NetmapSnapshotMapper() {
|
||||||
|
}
|
||||||
|
|
||||||
public static NetmapSnapshot toModel(Service.NetmapSnapshotResponse netmap) {
|
public static NetmapSnapshot toModel(Service.NetmapSnapshotResponse netmap) {
|
||||||
|
if (isNull(netmap)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return new NetmapSnapshot(
|
return new NetmapSnapshot(
|
||||||
netmap.getBody().getNetmap().getEpoch(),
|
netmap.getBody().getNetmap().getEpoch(),
|
||||||
netmap.getBody().getNetmap().getNodesList().stream()
|
netmap.getBody().getNetmap().getNodesList().stream()
|
||||||
|
|
|
@ -13,11 +13,22 @@ import static java.util.Objects.isNull;
|
||||||
|
|
||||||
public class NodeInfoMapper {
|
public class NodeInfoMapper {
|
||||||
|
|
||||||
|
private NodeInfoMapper() {
|
||||||
|
}
|
||||||
|
|
||||||
public static NodeInfo toModel(Service.LocalNodeInfoResponse.Body nodeInfo) {
|
public static NodeInfo toModel(Service.LocalNodeInfoResponse.Body nodeInfo) {
|
||||||
|
if (isNull(nodeInfo)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return toModel(nodeInfo.getNodeInfo(), nodeInfo.getVersion());
|
return toModel(nodeInfo.getNodeInfo(), nodeInfo.getVersion());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static NodeInfo toModel(frostfs.netmap.Types.NodeInfo nodeInfo, Types.Version version) {
|
public static NodeInfo toModel(frostfs.netmap.Types.NodeInfo nodeInfo, Types.Version version) {
|
||||||
|
if (isNull(nodeInfo)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
NodeState nodeState = NodeState.get(nodeInfo.getState().getNumber());
|
NodeState nodeState = NodeState.get(nodeInfo.getState().getNumber());
|
||||||
if (isNull(nodeState)) {
|
if (isNull(nodeState)) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
|
|
|
@ -4,9 +4,18 @@ import frostfs.netmap.Types;
|
||||||
import info.frostfs.sdk.dto.netmap.PlacementPolicy;
|
import info.frostfs.sdk.dto.netmap.PlacementPolicy;
|
||||||
import info.frostfs.sdk.dto.netmap.Replica;
|
import info.frostfs.sdk.dto.netmap.Replica;
|
||||||
|
|
||||||
|
import static java.util.Objects.isNull;
|
||||||
|
|
||||||
public class PlacementPolicyMapper {
|
public class PlacementPolicyMapper {
|
||||||
|
|
||||||
|
private PlacementPolicyMapper() {
|
||||||
|
}
|
||||||
|
|
||||||
public static Types.PlacementPolicy toGrpcMessage(PlacementPolicy placementPolicy) {
|
public static Types.PlacementPolicy toGrpcMessage(PlacementPolicy placementPolicy) {
|
||||||
|
if (isNull(placementPolicy)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
var pp = Types.PlacementPolicy.newBuilder()
|
var pp = Types.PlacementPolicy.newBuilder()
|
||||||
.setUnique(placementPolicy.isUnique());
|
.setUnique(placementPolicy.isUnique());
|
||||||
|
|
||||||
|
@ -18,6 +27,10 @@ public class PlacementPolicyMapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PlacementPolicy toModel(Types.PlacementPolicy placementPolicy) {
|
public static PlacementPolicy toModel(Types.PlacementPolicy placementPolicy) {
|
||||||
|
if (isNull(placementPolicy)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return new PlacementPolicy(
|
return new PlacementPolicy(
|
||||||
placementPolicy.getUnique(),
|
placementPolicy.getUnique(),
|
||||||
placementPolicy.getReplicasList().stream().map(ReplicaMapper::toModel).toArray(Replica[]::new)
|
placementPolicy.getReplicasList().stream().map(ReplicaMapper::toModel).toArray(Replica[]::new)
|
||||||
|
|
|
@ -3,9 +3,18 @@ package info.frostfs.sdk.mappers.netmap;
|
||||||
import frostfs.netmap.Types;
|
import frostfs.netmap.Types;
|
||||||
import info.frostfs.sdk.dto.netmap.Replica;
|
import info.frostfs.sdk.dto.netmap.Replica;
|
||||||
|
|
||||||
|
import static java.util.Objects.isNull;
|
||||||
|
|
||||||
public class ReplicaMapper {
|
public class ReplicaMapper {
|
||||||
|
|
||||||
|
private ReplicaMapper() {
|
||||||
|
}
|
||||||
|
|
||||||
public static Types.Replica toGrpcMessage(Replica replica) {
|
public static Types.Replica toGrpcMessage(Replica replica) {
|
||||||
|
if (isNull(replica)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return Types.Replica.newBuilder()
|
return Types.Replica.newBuilder()
|
||||||
.setCount(replica.getCount())
|
.setCount(replica.getCount())
|
||||||
.setSelector(replica.getSelector())
|
.setSelector(replica.getSelector())
|
||||||
|
@ -13,6 +22,10 @@ public class ReplicaMapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Replica toModel(Types.Replica replica) {
|
public static Replica toModel(Types.Replica replica) {
|
||||||
|
if (isNull(replica)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return new Replica(replica.getCount(), replica.getSelector());
|
return new Replica(replica.getCount(), replica.getSelector());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,18 @@ package info.frostfs.sdk.mappers.object;
|
||||||
import frostfs.object.Types;
|
import frostfs.object.Types;
|
||||||
import info.frostfs.sdk.dto.object.ObjectAttribute;
|
import info.frostfs.sdk.dto.object.ObjectAttribute;
|
||||||
|
|
||||||
|
import static java.util.Objects.isNull;
|
||||||
|
|
||||||
public class ObjectAttributeMapper {
|
public class ObjectAttributeMapper {
|
||||||
|
|
||||||
|
private ObjectAttributeMapper() {
|
||||||
|
}
|
||||||
|
|
||||||
public static Types.Header.Attribute toGrpcMessage(ObjectAttribute attribute) {
|
public static Types.Header.Attribute toGrpcMessage(ObjectAttribute attribute) {
|
||||||
|
if (isNull(attribute)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return Types.Header.Attribute.newBuilder()
|
return Types.Header.Attribute.newBuilder()
|
||||||
.setKey(attribute.getKey())
|
.setKey(attribute.getKey())
|
||||||
.setValue(attribute.getValue())
|
.setValue(attribute.getValue())
|
||||||
|
@ -13,6 +22,10 @@ public class ObjectAttributeMapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ObjectAttribute toModel(Types.Header.Attribute attribute) {
|
public static ObjectAttribute toModel(Types.Header.Attribute attribute) {
|
||||||
|
if (isNull(attribute)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return new ObjectAttribute(attribute.getKey(), attribute.getValue());
|
return new ObjectAttribute(attribute.getKey(), attribute.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,14 @@ import static java.util.Objects.isNull;
|
||||||
|
|
||||||
public class ObjectFilterMapper {
|
public class ObjectFilterMapper {
|
||||||
|
|
||||||
|
private ObjectFilterMapper() {
|
||||||
|
}
|
||||||
|
|
||||||
public static Service.SearchRequest.Body.Filter toGrpcMessage(ObjectFilter filter) {
|
public static Service.SearchRequest.Body.Filter toGrpcMessage(ObjectFilter filter) {
|
||||||
|
if (isNull(filter)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
var objectMatchType = Types.MatchType.forNumber(filter.getMatchType().value);
|
var objectMatchType = Types.MatchType.forNumber(filter.getMatchType().value);
|
||||||
if (isNull(objectMatchType)) {
|
if (isNull(objectMatchType)) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
|
|
|
@ -4,13 +4,22 @@ import frostfs.object.Types;
|
||||||
import info.frostfs.sdk.dto.object.ObjectFrostFS;
|
import info.frostfs.sdk.dto.object.ObjectFrostFS;
|
||||||
import info.frostfs.sdk.dto.object.ObjectId;
|
import info.frostfs.sdk.dto.object.ObjectId;
|
||||||
|
|
||||||
|
import static java.util.Objects.isNull;
|
||||||
|
|
||||||
public class ObjectFrostFSMapper {
|
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(
|
return new ObjectFrostFS(
|
||||||
ObjectHeaderMapper.toModel(obj.getHeader()),
|
ObjectHeaderMapper.toModel(object.getHeader()),
|
||||||
ObjectId.fromHash(obj.getObjectId().getValue().toByteArray()),
|
new ObjectId(object.getObjectId().getValue().toByteArray()),
|
||||||
obj.getPayload().toByteArray()
|
object.getPayload().toByteArray()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,14 @@ import static java.util.Objects.isNull;
|
||||||
|
|
||||||
public class ObjectHeaderMapper {
|
public class ObjectHeaderMapper {
|
||||||
|
|
||||||
|
private ObjectHeaderMapper() {
|
||||||
|
}
|
||||||
|
|
||||||
public static Types.Header toGrpcMessage(ObjectHeader header) {
|
public static Types.Header toGrpcMessage(ObjectHeader header) {
|
||||||
|
if (isNull(header)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
var objectType = Types.ObjectType.forNumber(header.getObjectType().value);
|
var objectType = Types.ObjectType.forNumber(header.getObjectType().value);
|
||||||
if (isNull(objectType)) {
|
if (isNull(objectType)) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
|
@ -34,6 +41,10 @@ public class ObjectHeaderMapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ObjectHeader toModel(Types.Header header) {
|
public static ObjectHeader toModel(Types.Header header) {
|
||||||
|
if (isNull(header)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
var objectType = ObjectType.get(header.getObjectTypeValue());
|
var objectType = ObjectType.get(header.getObjectTypeValue());
|
||||||
if (isNull(objectType)) {
|
if (isNull(objectType)) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
|
@ -42,7 +53,7 @@ public class ObjectHeaderMapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ObjectHeader(
|
return new ObjectHeader(
|
||||||
ContainerId.fromHash(header.getContainerId().getValue().toByteArray()),
|
new ContainerId(header.getContainerId().getValue().toByteArray()),
|
||||||
objectType,
|
objectType,
|
||||||
header.getAttributesList().stream().map(ObjectAttributeMapper::toModel).collect(Collectors.toList()),
|
header.getAttributesList().stream().map(ObjectAttributeMapper::toModel).collect(Collectors.toList()),
|
||||||
header.getPayloadLength(),
|
header.getPayloadLength(),
|
||||||
|
|
|
@ -4,15 +4,24 @@ import com.google.protobuf.ByteString;
|
||||||
import frostfs.refs.Types;
|
import frostfs.refs.Types;
|
||||||
import info.frostfs.sdk.dto.object.ObjectId;
|
import info.frostfs.sdk.dto.object.ObjectId;
|
||||||
|
|
||||||
|
import static java.util.Objects.isNull;
|
||||||
|
|
||||||
public class ObjectIdMapper {
|
public class ObjectIdMapper {
|
||||||
|
|
||||||
|
private ObjectIdMapper() {
|
||||||
|
}
|
||||||
|
|
||||||
public static Types.ObjectID toGrpcMessage(ObjectId objectId) {
|
public static Types.ObjectID toGrpcMessage(ObjectId objectId) {
|
||||||
|
if (isNull(objectId)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return Types.ObjectID.newBuilder()
|
return Types.ObjectID.newBuilder()
|
||||||
.setValue(ByteString.copyFrom(objectId.toHash()))
|
.setValue(ByteString.copyFrom(objectId.toHash()))
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ObjectId toModel(Types.ObjectID objectId) {
|
public static ObjectId toModel(Types.ObjectID objectId) {
|
||||||
return ObjectId.fromHash(objectId.getValue().toByteArray());
|
return new ObjectId(objectId.getValue().toByteArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue