[#34] Provide input parameters for all grpc methods #35
61 changed files with 1411 additions and 625 deletions
112
README.md
112
README.md
|
@ -21,31 +21,40 @@ neo-go wallet export -w <path_to_your_wallet> -d <address_from_p1>
|
||||||
### Container operations
|
### Container operations
|
||||||
|
|
||||||
```java
|
```java
|
||||||
|
import info.frostfs.sdk.FrostFSClient;
|
||||||
import info.frostfs.sdk.dto.container.Container;
|
import info.frostfs.sdk.dto.container.Container;
|
||||||
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 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.FrostFSClient;
|
import info.frostfs.sdk.jdo.parameters.CallContext;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.container.PrmContainerCreate;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.container.PrmContainerDelete;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.container.PrmContainerGet;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.container.PrmContainerGetAll;
|
||||||
|
|
||||||
public class ContainerExample {
|
public class ContainerExample {
|
||||||
|
|
||||||
public void example() {
|
public void example() {
|
||||||
|
var callContext = new CallContext();
|
||||||
ClientSettings clientSettings = new ClientSettings(<your_key>, <your_host>);
|
ClientSettings clientSettings = new ClientSettings(<your_key>, <your_host>);
|
||||||
FrostFSClient frostFSClient = new FrostFSClient(clientSettings);
|
FrostFSClient frostFSClient = new FrostFSClient(clientSettings);
|
||||||
|
|
||||||
// Create container
|
// Create container
|
||||||
var placementPolicy = new PlacementPolicy(new Replica[]{new Replica(1)}, Boolean.TRUE);
|
var placementPolicy = new PlacementPolicy(new Replica[]{new Replica(1)}, true);
|
||||||
var containerId = frostFSClient.createContainer(new Container(BasicAcl.PUBLIC_RW, placementPolicy));
|
var prmContainerCreate = new PrmContainerCreate(new Container(BasicAcl.PUBLIC_RW, placementPolicy));
|
||||||
|
var containerId = frostFSClient.createContainer(prmContainerCreate, callContext);
|
||||||
|
|
||||||
// Get container
|
// Get container
|
||||||
var container = frostFSClient.getContainer(containerId);
|
var prmContainerGet = new PrmContainerGet(containerId);
|
||||||
|
var container = frostFSClient.getContainer(prmContainerGet, callContext);
|
||||||
|
|
||||||
// List containers
|
// List containers
|
||||||
var containerIds = frostFSClient.listContainers();
|
var containerIds = frostFSClient.listContainers(new PrmContainerGetAll(), callContext);
|
||||||
|
|
||||||
// Delete container
|
// Delete container
|
||||||
frostFSClient.deleteContainer(containerId);
|
var prmContainerDelete = new PrmContainerDelete(containerId);
|
||||||
|
frostFSClient.deleteContainer(prmContainerDelete, callContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -53,45 +62,104 @@ public class ContainerExample {
|
||||||
### Object operations
|
### Object operations
|
||||||
|
|
||||||
```java
|
```java
|
||||||
|
import info.frostfs.sdk.dto.object.*;
|
||||||
import info.frostfs.sdk.enums.ObjectType;
|
import info.frostfs.sdk.enums.ObjectType;
|
||||||
import info.frostfs.sdk.dto.container.ContainerId;
|
import info.frostfs.sdk.jdo.ClientSettings;
|
||||||
import info.frostfs.sdk.dto.object.ObjectAttribute;
|
import info.frostfs.sdk.jdo.parameters.CallContext;
|
||||||
import info.frostfs.sdk.dto.object.ObjectFilter;
|
import info.frostfs.sdk.jdo.parameters.object.*;
|
||||||
import info.frostfs.sdk.dto.object.ObjectHeader;
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
import info.frostfs.sdk.dto.object.ObjectId;
|
|
||||||
import info.frostfs.sdk.jdo.PutObjectParameters;
|
|
||||||
import info.frostfs.sdk.FrostFSClient;
|
|
||||||
|
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import static java.util.Objects.isNull;
|
||||||
|
|
||||||
public class ObjectExample {
|
public class ObjectExample {
|
||||||
|
|
||||||
public void example() {
|
public void example() {
|
||||||
|
CallContext callContext = new CallContext();
|
||||||
ClientSettings clientSettings = new ClientSettings(<your_key>, <your_host>);
|
ClientSettings clientSettings = new ClientSettings(<your_key>, <your_host>);
|
||||||
FrostFSClient frostFSClient = new FrostFSClient(clientSettings);
|
FrostFSClient frostFSClient = new FrostFSClient(clientSettings);
|
||||||
|
|
||||||
// Put object
|
// Put object
|
||||||
ObjectId objectId;
|
ObjectId objectId;
|
||||||
try (FileInputStream fis = new FileInputStream("cat.jpg")) {
|
try (FileInputStream file = new FileInputStream("/path/to/file/cat.jpg")) {
|
||||||
var cat = new ObjectHeader(
|
var attribute = new ObjectAttribute("Filename", "cat.jpg");
|
||||||
containerId, ObjectType.REGULAR, new ObjectAttribute[]{new ObjectAttribute("Filename", "cat.jpg")}
|
var cat = new ObjectHeader(containerId, ObjectType.REGULAR, attribute);
|
||||||
);
|
var prmObjectPut = PrmObjectPut.builder().objectHeader(cat).build();
|
||||||
|
var writer = frostFSClient.putObject(prmObjectPut, callContext);
|
||||||
|
|
||||||
var params = new PutObjectParameters(cat, fis);
|
writer.write(file.readAllBytes());
|
||||||
objectId = frostFSClient.putObject(params);
|
objectId = writer.complete();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get object
|
// Get object
|
||||||
var obj = frostFSClient.getObject(containerId, objectId);
|
var prmObjectGet = new PrmObjectGet(containerId, oid);
|
||||||
|
ObjectFrostFS object = frostFSClient.getObject(prmObjectGet, callContext);
|
||||||
|
|
||||||
|
var reader = object.getObjectReader();
|
||||||
|
var chunk = reader.readChunk();
|
||||||
|
var length = chunk.length;
|
||||||
|
byte[] buffer = null;
|
||||||
|
while (length > 0) {
|
||||||
|
buffer = isNull(buffer) ? chunk : ArrayHelper.concat(buffer, chunk);
|
||||||
|
|
||||||
|
chunk = object.getObjectReader().readChunk();
|
||||||
|
length = ArrayUtils.isEmpty(chunk) ? 0 : chunk.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
try (FileOutputStream fos = new FileOutputStream("/path/to/file/newCat.jpg")) {
|
||||||
|
fos.write(buffer);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
|
||||||
// Get object header
|
// Get object header
|
||||||
var objectHeader = frostFSClient.getObjectHead(containerId, objectId);
|
var prmObjectHeadGet = new PrmObjectHeadGet(containerId, objectId);
|
||||||
|
var objectHeader = frostFSClient.getObjectHead(prmObjectHeadGet, callContext);
|
||||||
|
|
||||||
// Search regular objects
|
// Search regular objects
|
||||||
var objectIds = frostFSClient.searchObjects(containerId, new ObjectFilter.FilterByRootObject());
|
var prmObjectSearch = new PrmObjectSearch(containerId, new ObjectFilter.FilterByRootObject());
|
||||||
|
var objectIds = frostFSClient.searchObjects(prmObjectSearch, callContext);
|
||||||
|
|
||||||
|
// Delete object
|
||||||
|
var prmObjectDelete = new PrmObjectDelete(containerId, objectId);
|
||||||
|
frostFSClient.deleteObject(prmObjectDelete, callContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Pool init
|
||||||
|
|
||||||
|
```java
|
||||||
|
import info.frostfs.sdk.jdo.ECDsa;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.CallContext;
|
||||||
|
import info.frostfs.sdk.jdo.pool.NodeParameters;
|
||||||
|
import info.frostfs.sdk.jdo.pool.PoolInitParameters;
|
||||||
|
import info.frostfs.sdk.pool.Pool;
|
||||||
|
|
||||||
|
public class PoolExample {
|
||||||
|
|
||||||
|
public static void example() {
|
||||||
|
CallContext callContext = new CallContext();
|
||||||
|
|
||||||
|
//Init
|
||||||
|
var nodeParam1 = new NodeParameters(1, <your_host1>, 1);
|
||||||
|
var nodeParam2 = new NodeParameters(1, <your_host2>, 1);
|
||||||
|
var nodeParam3 = new NodeParameters(1, <your_host3>, 1);
|
||||||
|
var nodeParam4 = new NodeParameters(1, <your_host4>, 1);
|
||||||
|
|
||||||
|
PoolInitParameters initParameters = new PoolInitParameters();
|
||||||
|
initParameters.setKey(new ECDsa(<your_key>));
|
||||||
|
initParameters.setNodeParams(new NodeParameters[]{nodeParam1, nodeParam2, nodeParam3, nodeParam4});
|
||||||
|
|
||||||
|
|
||||||
|
Pool pool = new Pool(initParameters);
|
||||||
|
|
||||||
|
//Dial (Required!)
|
||||||
|
pool.dial(callContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>info.frostfs.sdk</groupId>
|
<groupId>info.frostfs.sdk</groupId>
|
||||||
<artifactId>frostfs-sdk-java</artifactId>
|
<artifactId>frostfs-sdk-java</artifactId>
|
||||||
<version>0.2.0</version>
|
<version>0.3.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>client</artifactId>
|
<artifactId>client</artifactId>
|
||||||
|
@ -21,17 +21,17 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>info.frostfs.sdk</groupId>
|
<groupId>info.frostfs.sdk</groupId>
|
||||||
<artifactId>cryptography</artifactId>
|
<artifactId>cryptography</artifactId>
|
||||||
<version>0.2.0</version>
|
<version>0.3.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>info.frostfs.sdk</groupId>
|
<groupId>info.frostfs.sdk</groupId>
|
||||||
<artifactId>models</artifactId>
|
<artifactId>models</artifactId>
|
||||||
<version>0.2.0</version>
|
<version>0.3.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>info.frostfs.sdk</groupId>
|
<groupId>info.frostfs.sdk</groupId>
|
||||||
<artifactId>exceptions</artifactId>
|
<artifactId>exceptions</artifactId>
|
||||||
<version>0.2.0</version>
|
<version>0.3.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>commons-codec</groupId>
|
<groupId>commons-codec</groupId>
|
||||||
|
|
|
@ -2,13 +2,11 @@ package info.frostfs.sdk;
|
||||||
|
|
||||||
import frostfs.accounting.Types;
|
import frostfs.accounting.Types;
|
||||||
import info.frostfs.sdk.dto.chain.Chain;
|
import info.frostfs.sdk.dto.chain.Chain;
|
||||||
import info.frostfs.sdk.dto.chain.ChainTarget;
|
|
||||||
import info.frostfs.sdk.dto.container.Container;
|
import info.frostfs.sdk.dto.container.Container;
|
||||||
import info.frostfs.sdk.dto.container.ContainerId;
|
import info.frostfs.sdk.dto.container.ContainerId;
|
||||||
import info.frostfs.sdk.dto.netmap.NetmapSnapshot;
|
import info.frostfs.sdk.dto.netmap.NetmapSnapshot;
|
||||||
import info.frostfs.sdk.dto.netmap.NodeInfo;
|
import info.frostfs.sdk.dto.netmap.NodeInfo;
|
||||||
import info.frostfs.sdk.dto.netmap.Version;
|
import info.frostfs.sdk.dto.netmap.Version;
|
||||||
import info.frostfs.sdk.dto.object.ObjectFilter;
|
|
||||||
import info.frostfs.sdk.dto.object.ObjectFrostFS;
|
import info.frostfs.sdk.dto.object.ObjectFrostFS;
|
||||||
import info.frostfs.sdk.dto.object.ObjectHeader;
|
import info.frostfs.sdk.dto.object.ObjectHeader;
|
||||||
import info.frostfs.sdk.dto.object.ObjectId;
|
import info.frostfs.sdk.dto.object.ObjectId;
|
||||||
|
@ -17,13 +15,24 @@ import info.frostfs.sdk.exceptions.ProcessFrostFSException;
|
||||||
import info.frostfs.sdk.jdo.ClientEnvironment;
|
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.parameters.CallContext;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.ape.PrmApeChainAdd;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.ape.PrmApeChainList;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.ape.PrmApeChainRemove;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.container.PrmContainerCreate;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.container.PrmContainerDelete;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.container.PrmContainerGet;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.container.PrmContainerGetAll;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.object.*;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.session.PrmSessionCreate;
|
||||||
|
import info.frostfs.sdk.jdo.result.ObjectHeaderResult;
|
||||||
import info.frostfs.sdk.pool.SessionCache;
|
import info.frostfs.sdk.pool.SessionCache;
|
||||||
import info.frostfs.sdk.pool.WrapperPrm;
|
import info.frostfs.sdk.pool.WrapperPrm;
|
||||||
import info.frostfs.sdk.services.CommonClient;
|
import info.frostfs.sdk.services.CommonClient;
|
||||||
import info.frostfs.sdk.services.impl.*;
|
import info.frostfs.sdk.services.impl.*;
|
||||||
import info.frostfs.sdk.services.impl.interceptor.Configuration;
|
import info.frostfs.sdk.services.impl.interceptor.Configuration;
|
||||||
import info.frostfs.sdk.services.impl.interceptor.MonitoringClientInterceptor;
|
import info.frostfs.sdk.services.impl.interceptor.MonitoringClientInterceptor;
|
||||||
|
import info.frostfs.sdk.services.impl.rwhelper.ObjectWriter;
|
||||||
import info.frostfs.sdk.utils.Validator;
|
import info.frostfs.sdk.utils.Validator;
|
||||||
import io.grpc.Channel;
|
import io.grpc.Channel;
|
||||||
import io.grpc.ClientInterceptors;
|
import io.grpc.ClientInterceptors;
|
||||||
|
@ -55,8 +64,10 @@ public class FrostFSClient implements CommonClient {
|
||||||
: initGrpcChannel(clientSettings);
|
: initGrpcChannel(clientSettings);
|
||||||
|
|
||||||
Channel interceptChannel = ClientInterceptors.intercept(channel, MONITORING_CLIENT_INTERCEPTOR);
|
Channel interceptChannel = ClientInterceptors.intercept(channel, MONITORING_CLIENT_INTERCEPTOR);
|
||||||
ClientEnvironment clientEnvironment =
|
ClientEnvironment clientEnvironment = new ClientEnvironment(
|
||||||
new ClientEnvironment(clientSettings.getKey(), interceptChannel, new Version(), this);
|
clientSettings.getKey(), interceptChannel, new Version(), this,
|
||||||
|
new SessionCache(0)
|
||||||
|
);
|
||||||
|
|
||||||
Validator.validate(clientEnvironment);
|
Validator.validate(clientEnvironment);
|
||||||
|
|
||||||
|
@ -75,7 +86,7 @@ public class FrostFSClient implements CommonClient {
|
||||||
|
|
||||||
Channel interceptChannel = ClientInterceptors.intercept(channel, MONITORING_CLIENT_INTERCEPTOR);
|
Channel interceptChannel = ClientInterceptors.intercept(channel, MONITORING_CLIENT_INTERCEPTOR);
|
||||||
ClientEnvironment clientEnvironment =
|
ClientEnvironment clientEnvironment =
|
||||||
new ClientEnvironment(prm.getKey(), interceptChannel, new Version(), this);
|
new ClientEnvironment(prm.getKey(), interceptChannel, new Version(), this, cache);
|
||||||
|
|
||||||
Validator.validate(clientEnvironment);
|
Validator.validate(clientEnvironment);
|
||||||
|
|
||||||
|
@ -90,7 +101,7 @@ public class FrostFSClient implements CommonClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkFrostFSVersionSupport(Version version) {
|
private void checkFrostFSVersionSupport(Version version) {
|
||||||
var localNodeInfo = netmapClientImpl.getLocalNodeInfo();
|
var localNodeInfo = netmapClientImpl.getLocalNodeInfo(new CallContext());
|
||||||
if (!localNodeInfo.getVersion().isSupported(version)) {
|
if (!localNodeInfo.getVersion().isSupported(version)) {
|
||||||
throw new ProcessFrostFSException(
|
throw new ProcessFrostFSException(
|
||||||
String.format(VERSION_UNSUPPORTED_TEMPLATE, localNodeInfo.getVersion())
|
String.format(VERSION_UNSUPPORTED_TEMPLATE, localNodeInfo.getVersion())
|
||||||
|
@ -99,92 +110,97 @@ public class FrostFSClient implements CommonClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Container getContainer(ContainerId cid) {
|
public Container getContainer(PrmContainerGet args, CallContext ctx) {
|
||||||
return containerClientImpl.getContainer(cid);
|
return containerClientImpl.getContainer(args, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ContainerId> listContainers() {
|
public List<ContainerId> listContainers(PrmContainerGetAll args, CallContext ctx) {
|
||||||
return containerClientImpl.listContainers();
|
return containerClientImpl.listContainers(args, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ContainerId createContainer(Container container) {
|
public ContainerId createContainer(PrmContainerCreate args, CallContext ctx) {
|
||||||
return containerClientImpl.createContainer(container);
|
return containerClientImpl.createContainer(args, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteContainer(ContainerId cid) {
|
public void deleteContainer(PrmContainerDelete args, CallContext ctx) {
|
||||||
containerClientImpl.deleteContainer(cid);
|
containerClientImpl.deleteContainer(args, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ObjectHeader getObjectHead(ContainerId containerId, ObjectId objectId) {
|
public ObjectHeaderResult getObjectHead(PrmObjectHeadGet args, CallContext ctx) {
|
||||||
return objectClientImpl.getObjectHead(containerId, objectId);
|
return objectClientImpl.getObjectHead(args, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ObjectFrostFS getObject(ContainerId containerId, ObjectId objectId) {
|
public ObjectFrostFS getObject(PrmObjectGet args, CallContext ctx) {
|
||||||
return objectClientImpl.getObject(containerId, objectId);
|
return objectClientImpl.getObject(args, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ObjectId putObject(PutObjectParameters parameters) {
|
public ObjectWriter putObject(PrmObjectPut args, CallContext ctx) {
|
||||||
return objectClientImpl.putObject(parameters);
|
return objectClientImpl.putObject(args, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ObjectId putSingleObject(ObjectFrostFS objectFrostFS) {
|
public ObjectId putClientCutObject(PrmObjectClientCutPut args, CallContext ctx) {
|
||||||
return objectClientImpl.putSingleObject(objectFrostFS);
|
return objectClientImpl.putClientCutObject(args, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteObject(ContainerId containerId, ObjectId objectId) {
|
public ObjectId putSingleObject(PrmObjectSinglePut args, CallContext ctx) {
|
||||||
objectClientImpl.deleteObject(containerId, objectId);
|
return objectClientImpl.putSingleObject(args, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<ObjectId> searchObjects(ContainerId cid, ObjectFilter<?>... filters) {
|
public void deleteObject(PrmObjectDelete args, CallContext ctx) {
|
||||||
return objectClientImpl.searchObjects(cid, filters);
|
objectClientImpl.deleteObject(args, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] addChain(Chain chain, ChainTarget chainTarget) {
|
public Iterable<ObjectId> searchObjects(PrmObjectSearch args, CallContext ctx) {
|
||||||
return apeManagerClient.addChain(chain, chainTarget);
|
return objectClientImpl.searchObjects(args, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeChain(Chain chain, ChainTarget chainTarget) {
|
public byte[] addChain(PrmApeChainAdd args, CallContext ctx) {
|
||||||
apeManagerClient.removeChain(chain, chainTarget);
|
return apeManagerClient.addChain(args, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Chain> listChains(ChainTarget chainTarget) {
|
public void removeChain(PrmApeChainRemove args, CallContext ctx) {
|
||||||
return apeManagerClient.listChains(chainTarget);
|
apeManagerClient.removeChain(args, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NetmapSnapshot getNetmapSnapshot() {
|
public List<Chain> listChains(PrmApeChainList args, CallContext ctx) {
|
||||||
return netmapClientImpl.getNetmapSnapshot();
|
return apeManagerClient.listChains(args, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NodeInfo getLocalNodeInfo() {
|
public NetmapSnapshot getNetmapSnapshot(CallContext ctx) {
|
||||||
return netmapClientImpl.getLocalNodeInfo();
|
return netmapClientImpl.getNetmapSnapshot(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NetworkSettings getNetworkSettings() {
|
public NodeInfo getLocalNodeInfo(CallContext ctx) {
|
||||||
return netmapClientImpl.getNetworkSettings();
|
return netmapClientImpl.getLocalNodeInfo(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SessionToken createSession(long expiration) {
|
public NetworkSettings getNetworkSettings(CallContext ctx) {
|
||||||
return sessionClientImpl.createSession(expiration);
|
return netmapClientImpl.getNetworkSettings(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
public frostfs.session.Types.SessionToken createSessionInternal(long expiration) {
|
@Override
|
||||||
return sessionClientImpl.createSessionInternal(expiration);
|
public SessionToken createSession(PrmSessionCreate args, CallContext ctx) {
|
||||||
|
return sessionClientImpl.createSession(args, ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
public frostfs.session.Types.SessionToken createSessionInternal(PrmSessionCreate args, CallContext ctx) {
|
||||||
|
return sessionClientImpl.createSessionInternal(args, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -193,12 +209,12 @@ public class FrostFSClient implements CommonClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Types.Decimal getBalance() {
|
public Types.Decimal getBalance(CallContext ctx) {
|
||||||
return accountingClient.getBalance();
|
return accountingClient.getBalance(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String dial() {
|
public String dial(CallContext ctx) {
|
||||||
accountingClient.getBalance();
|
accountingClient.getBalance(ctx);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,14 @@ import info.frostfs.sdk.annotations.NotNull;
|
||||||
import info.frostfs.sdk.annotations.Validate;
|
import info.frostfs.sdk.annotations.Validate;
|
||||||
import info.frostfs.sdk.dto.netmap.Version;
|
import info.frostfs.sdk.dto.netmap.Version;
|
||||||
import info.frostfs.sdk.dto.object.OwnerId;
|
import info.frostfs.sdk.dto.object.OwnerId;
|
||||||
|
import info.frostfs.sdk.pool.SessionCache;
|
||||||
import io.grpc.Channel;
|
import io.grpc.Channel;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import static info.frostfs.sdk.Helper.getHexString;
|
||||||
|
import static info.frostfs.sdk.pool.Pool.formCacheKey;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
|
@ -15,35 +20,48 @@ public class ClientEnvironment {
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final OwnerId ownerId;
|
private final OwnerId ownerId;
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final Version version;
|
private final Version version;
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Validate
|
@Validate
|
||||||
private final ECDsa key;
|
private final ECDsa key;
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final Channel channel;
|
private final Channel channel;
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final FrostFSClient frostFSClient;
|
private final FrostFSClient frostFSClient;
|
||||||
|
|
||||||
|
private String sessionKey;
|
||||||
|
private String address;
|
||||||
private NetworkSettings networkSettings;
|
private NetworkSettings networkSettings;
|
||||||
|
|
||||||
public ClientEnvironment(String wif, Channel channel, Version version, FrostFSClient frostFSClient) {
|
private SessionCache sessionCache;
|
||||||
|
|
||||||
|
public ClientEnvironment(String wif, Channel channel, Version version, FrostFSClient frostFSClient,
|
||||||
|
SessionCache sessionCache) {
|
||||||
this.key = new ECDsa(wif);
|
this.key = new ECDsa(wif);
|
||||||
this.ownerId = new OwnerId(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;
|
||||||
|
this.sessionCache = sessionCache;
|
||||||
|
this.address = channel.authority();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClientEnvironment(ECDsa key, Channel channel, Version version, FrostFSClient frostFSClient) {
|
public ClientEnvironment(ECDsa key, Channel channel, Version version, FrostFSClient frostFSClient,
|
||||||
|
SessionCache sessionCache) {
|
||||||
this.key = key;
|
this.key = key;
|
||||||
this.ownerId = new OwnerId(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;
|
||||||
|
this.sessionCache = sessionCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSessionKey() {
|
||||||
|
if (StringUtils.isBlank(sessionKey)) {
|
||||||
|
this.sessionKey = formCacheKey(address, getHexString(key.getPublicKeyByte()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return sessionKey;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,40 +0,0 @@
|
||||||
package info.frostfs.sdk.jdo;
|
|
||||||
|
|
||||||
import info.frostfs.sdk.annotations.NotNull;
|
|
||||||
import info.frostfs.sdk.dto.object.ObjectHeader;
|
|
||||||
import info.frostfs.sdk.dto.session.SessionToken;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
public class PutObjectParameters {
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private ObjectHeader header;
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private InputStream payload;
|
|
||||||
|
|
||||||
private boolean clientCut;
|
|
||||||
private int bufferMaxSize;
|
|
||||||
private byte[] customerBuffer;
|
|
||||||
private SessionToken sessionToken;
|
|
||||||
private int maxObjectSizeCache;
|
|
||||||
private long currentStreamPosition;
|
|
||||||
private long fullLength;
|
|
||||||
|
|
||||||
public PutObjectParameters(ObjectHeader header, InputStream payload, boolean clientCut, int bufferMaxSize) {
|
|
||||||
this.header = header;
|
|
||||||
this.payload = payload;
|
|
||||||
this.clientCut = clientCut;
|
|
||||||
this.bufferMaxSize = bufferMaxSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PutObjectParameters(ObjectHeader header, InputStream payload) {
|
|
||||||
this.header = header;
|
|
||||||
this.payload = payload;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
package info.frostfs.sdk.jdo.parameters;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import static info.frostfs.sdk.constants.AppConst.DEFAULT_GRPC_TIMEOUT;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class CallContext {
|
||||||
|
private final long timeout;
|
||||||
|
|||||||
|
private final TimeUnit timeUnit;
|
||||||
|
|
||||||
|
public CallContext() {
|
||||||
|
this.timeout = DEFAULT_GRPC_TIMEOUT;
|
||||||
|
this.timeUnit = TimeUnit.SECONDS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package info.frostfs.sdk.jdo;
|
package info.frostfs.sdk.jdo.parameters;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
@ -8,14 +8,14 @@ import java.time.LocalDateTime;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class WaitParameters {
|
public class PrmWait {
|
||||||
private static final Duration DEFAULT_TIMEOUT = Duration.ofSeconds(120);
|
private static final Duration DEFAULT_TIMEOUT = Duration.ofSeconds(120);
|
||||||
private static final Duration DEFAULT_POLL_INTERVAL = Duration.ofSeconds(5);
|
private static final Duration DEFAULT_POLL_INTERVAL = Duration.ofSeconds(5);
|
||||||
|
|
||||||
private final Duration timeout;
|
private final Duration timeout;
|
||||||
private final Duration pollInterval;
|
private final Duration pollInterval;
|
||||||
|
|
||||||
public WaitParameters() {
|
public PrmWait() {
|
||||||
this.timeout = DEFAULT_TIMEOUT;
|
this.timeout = DEFAULT_TIMEOUT;
|
||||||
this.pollInterval = DEFAULT_POLL_INTERVAL;
|
this.pollInterval = DEFAULT_POLL_INTERVAL;
|
||||||
}
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package info.frostfs.sdk.jdo.parameters.ape;
|
||||||
|
|
||||||
|
import info.frostfs.sdk.annotations.NotNull;
|
||||||
|
import info.frostfs.sdk.dto.chain.Chain;
|
||||||
|
import info.frostfs.sdk.dto.chain.ChainTarget;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class PrmApeChainAdd {
|
||||||
|
@NotNull
|
||||||
|
private Chain chain;
|
||||||
|
@NotNull
|
||||||
|
private ChainTarget chainTarget;
|
||||||
|
|
||||||
|
private Map<String, String> xHeaders;
|
||||||
|
|
||||||
|
public PrmApeChainAdd(Chain chain, ChainTarget chainTarget) {
|
||||||
|
this.chain = chain;
|
||||||
|
this.chainTarget = chainTarget;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package info.frostfs.sdk.jdo.parameters.ape;
|
||||||
|
|
||||||
|
import info.frostfs.sdk.annotations.NotNull;
|
||||||
|
import info.frostfs.sdk.dto.chain.ChainTarget;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class PrmApeChainList {
|
||||||
|
@NotNull
|
||||||
|
private ChainTarget chainTarget;
|
||||||
|
|
||||||
|
private Map<String, String> xHeaders;
|
||||||
|
|
||||||
|
public PrmApeChainList(ChainTarget chainTarget) {
|
||||||
|
this.chainTarget = chainTarget;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package info.frostfs.sdk.jdo.parameters.ape;
|
||||||
|
|
||||||
|
import info.frostfs.sdk.annotations.NotNull;
|
||||||
|
import info.frostfs.sdk.dto.chain.Chain;
|
||||||
|
import info.frostfs.sdk.dto.chain.ChainTarget;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class PrmApeChainRemove {
|
||||||
|
@NotNull
|
||||||
|
private Chain chain;
|
||||||
|
@NotNull
|
||||||
|
private ChainTarget chainTarget;
|
||||||
|
|
||||||
|
private Map<String, String> xHeaders;
|
||||||
|
|
||||||
|
public PrmApeChainRemove(Chain chain, ChainTarget chainTarget) {
|
||||||
|
this.chain = chain;
|
||||||
|
this.chainTarget = chainTarget;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package info.frostfs.sdk.jdo.parameters.container;
|
||||||
|
|
||||||
|
import info.frostfs.sdk.annotations.NotNull;
|
||||||
|
import info.frostfs.sdk.dto.container.Container;
|
||||||
|
import info.frostfs.sdk.dto.session.SessionToken;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.PrmWait;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.session.SessionContext;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class PrmContainerCreate implements SessionContext {
|
||||||
|
@NotNull
|
||||||
|
private Container container;
|
||||||
|
|
||||||
|
private PrmWait waitParams;
|
||||||
|
private SessionToken sessionToken;
|
||||||
|
private Map<String, String> xHeaders;
|
||||||
|
|
||||||
|
public PrmContainerCreate(Container container, PrmWait waitParams) {
|
||||||
|
this.container = container;
|
||||||
|
this.waitParams = waitParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PrmContainerCreate(Container container) {
|
||||||
|
this.container = container;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package info.frostfs.sdk.jdo.parameters.container;
|
||||||
|
|
||||||
|
import info.frostfs.sdk.annotations.NotNull;
|
||||||
|
import info.frostfs.sdk.dto.container.ContainerId;
|
||||||
|
import info.frostfs.sdk.dto.session.SessionToken;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.PrmWait;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.session.SessionContext;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class PrmContainerDelete implements SessionContext {
|
||||||
|
@NotNull
|
||||||
|
private ContainerId containerId;
|
||||||
|
|
||||||
|
private PrmWait waitParams;
|
||||||
|
private SessionToken sessionToken;
|
||||||
|
private Map<String, String> xHeaders;
|
||||||
|
|
||||||
|
public PrmContainerDelete(ContainerId containerId, PrmWait waitParams) {
|
||||||
|
this.containerId = containerId;
|
||||||
|
this.waitParams = waitParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PrmContainerDelete(ContainerId containerId) {
|
||||||
|
this.containerId = containerId;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package info.frostfs.sdk.jdo.parameters.container;
|
||||||
|
|
||||||
|
import info.frostfs.sdk.annotations.NotNull;
|
||||||
|
import info.frostfs.sdk.dto.container.ContainerId;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class PrmContainerGet {
|
||||||
|
@NotNull
|
||||||
|
private ContainerId containerId;
|
||||||
|
|
||||||
|
private Map<String, String> xHeaders;
|
||||||
|
|
||||||
|
public PrmContainerGet(ContainerId containerId) {
|
||||||
|
this.containerId = containerId;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package info.frostfs.sdk.jdo.parameters.container;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class PrmContainerGetAll {
|
||||||
|
private Map<String, String> xHeaders;
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package info.frostfs.sdk.jdo.parameters.object;
|
||||||
|
|
||||||
|
import info.frostfs.sdk.annotations.NotNull;
|
||||||
|
import info.frostfs.sdk.dto.object.ObjectHeader;
|
||||||
|
import info.frostfs.sdk.dto.session.SessionToken;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.session.SessionContext;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class PrmObjectClientCutPut implements PrmObjectPutBase, SessionContext {
|
||||||
|
@NotNull
|
||||||
|
private final PutObjectContext putObjectContext = new PutObjectContext();
|
||||||
|
@NotNull
|
||||||
|
private ObjectHeader objectHeader;
|
||||||
|
@NotNull
|
||||||
|
private InputStream payload;
|
||||||
|
private int bufferMaxSize;
|
||||||
|
private byte[] customerBuffer;
|
||||||
|
private SessionToken sessionToken;
|
||||||
|
private Map<String, String> xHeaders;
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package info.frostfs.sdk.jdo.parameters.object;
|
||||||
|
|
||||||
|
import info.frostfs.sdk.annotations.NotNull;
|
||||||
|
import info.frostfs.sdk.dto.container.ContainerId;
|
||||||
|
import info.frostfs.sdk.dto.object.ObjectId;
|
||||||
|
import info.frostfs.sdk.dto.session.SessionToken;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.session.SessionContext;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class PrmObjectDelete implements SessionContext {
|
||||||
|
@NotNull
|
||||||
|
private ContainerId containerId;
|
||||||
|
@NotNull
|
||||||
|
private ObjectId objectId;
|
||||||
|
|
||||||
|
private SessionToken sessionToken;
|
||||||
|
private Map<String, String> xHeaders;
|
||||||
|
|
||||||
|
public PrmObjectDelete(ContainerId containerId, ObjectId objectId) {
|
||||||
|
this.containerId = containerId;
|
||||||
|
this.objectId = objectId;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package info.frostfs.sdk.jdo.parameters.object;
|
||||||
|
|
||||||
|
import info.frostfs.sdk.annotations.NotNull;
|
||||||
|
import info.frostfs.sdk.dto.container.ContainerId;
|
||||||
|
import info.frostfs.sdk.dto.object.ObjectId;
|
||||||
|
import info.frostfs.sdk.dto.session.SessionToken;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.session.SessionContext;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class PrmObjectGet implements SessionContext {
|
||||||
|
@NotNull
|
||||||
|
private ContainerId containerId;
|
||||||
|
@NotNull
|
||||||
|
private ObjectId objectId;
|
||||||
|
|
||||||
|
private SessionToken sessionToken;
|
||||||
|
private Map<String, String> xHeaders;
|
||||||
|
|
||||||
|
public PrmObjectGet(ContainerId containerId, ObjectId objectId) {
|
||||||
|
this.containerId = containerId;
|
||||||
|
this.objectId = objectId;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package info.frostfs.sdk.jdo.parameters.object;
|
||||||
|
|
||||||
|
import info.frostfs.sdk.annotations.NotNull;
|
||||||
|
import info.frostfs.sdk.dto.container.ContainerId;
|
||||||
|
import info.frostfs.sdk.dto.object.ObjectId;
|
||||||
|
import info.frostfs.sdk.dto.session.SessionToken;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.session.SessionContext;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class PrmObjectHeadGet implements SessionContext {
|
||||||
|
@NotNull
|
||||||
|
private ContainerId containerId;
|
||||||
|
@NotNull
|
||||||
|
private ObjectId objectId;
|
||||||
|
|
||||||
|
private boolean raw;
|
||||||
|
private SessionToken sessionToken;
|
||||||
|
private Map<String, String> xHeaders;
|
||||||
|
|
||||||
|
public PrmObjectHeadGet(ContainerId containerId, ObjectId objectId) {
|
||||||
|
this.containerId = containerId;
|
||||||
|
this.objectId = objectId;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package info.frostfs.sdk.jdo.parameters.object;
|
||||||
|
|
||||||
|
import info.frostfs.sdk.annotations.NotNull;
|
||||||
|
import info.frostfs.sdk.dto.object.ObjectHeader;
|
||||||
|
import info.frostfs.sdk.dto.session.SessionToken;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.session.SessionContext;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class PrmObjectPut implements PrmObjectPutBase, SessionContext {
|
||||||
|
@NotNull
|
||||||
|
private final PutObjectContext putObjectContext = new PutObjectContext();
|
||||||
|
@NotNull
|
||||||
|
private ObjectHeader objectHeader;
|
||||||
|
|
||||||
|
private SessionToken sessionToken;
|
||||||
|
private Map<String, String> xHeaders;
|
||||||
|
|
||||||
|
public PrmObjectPut(ObjectHeader objectHeader) {
|
||||||
|
this.objectHeader = objectHeader;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package info.frostfs.sdk.jdo.parameters.object;
|
||||||
|
|
||||||
|
import info.frostfs.sdk.dto.object.ObjectHeader;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.session.SessionContext;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public interface PrmObjectPutBase extends SessionContext {
|
||||||
|
ObjectHeader getObjectHeader();
|
||||||
|
|
||||||
|
Map<String, String> getXHeaders();
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package info.frostfs.sdk.jdo.parameters.object;
|
||||||
|
|
||||||
|
import info.frostfs.sdk.annotations.NotNull;
|
||||||
|
import info.frostfs.sdk.dto.container.ContainerId;
|
||||||
|
import info.frostfs.sdk.dto.object.ObjectFilter;
|
||||||
|
import info.frostfs.sdk.dto.session.SessionToken;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.session.SessionContext;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class PrmObjectSearch implements SessionContext {
|
||||||
|
@NotNull
|
||||||
|
private ContainerId containerId;
|
||||||
|
@NotNull
|
||||||
|
private ObjectFilter<?>[] filters;
|
||||||
|
|
||||||
|
private SessionToken sessionToken;
|
||||||
|
private Map<String, String> xHeaders;
|
||||||
|
|
||||||
|
public PrmObjectSearch(ContainerId containerId, ObjectFilter<?>... filters) {
|
||||||
|
this.containerId = containerId;
|
||||||
|
this.filters = filters;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package info.frostfs.sdk.jdo.parameters.object;
|
||||||
|
|
||||||
|
import info.frostfs.sdk.annotations.NotNull;
|
||||||
|
import info.frostfs.sdk.dto.object.ObjectFrostFS;
|
||||||
|
import info.frostfs.sdk.dto.session.SessionToken;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.session.SessionContext;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class PrmObjectSinglePut implements SessionContext {
|
||||||
|
@NotNull
|
||||||
|
private ObjectFrostFS objectFrostFS;
|
||||||
|
|
||||||
|
private SessionToken sessionToken;
|
||||||
|
private Map<String, String> xHeaders;
|
||||||
|
|
||||||
|
public PrmObjectSinglePut(ObjectFrostFS objectFrostFS) {
|
||||||
|
this.objectFrostFS = objectFrostFS;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package info.frostfs.sdk.jdo.parameters.object;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class PutObjectContext {
|
||||||
|
private int maxObjectSizeCache;
|
||||||
|
private long currentStreamPosition;
|
||||||
|
private long fullLength;
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package info.frostfs.sdk.jdo.parameters.session;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Builder
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class PrmSessionCreate {
|
||||||
|
private long expiration; //-1 is max
|
||||||
|
private Map<String, String> xHeaders;
|
||||||
|
|
||||||
|
public PrmSessionCreate(long expiration) {
|
||||||
|
this.expiration = expiration;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package info.frostfs.sdk.jdo.parameters.session;
|
||||||
|
|
||||||
|
import info.frostfs.sdk.dto.session.SessionToken;
|
||||||
|
|
||||||
|
public interface SessionContext {
|
||||||
|
SessionToken getSessionToken();
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package info.frostfs.sdk.jdo.result;
|
||||||
|
|
||||||
|
import info.frostfs.sdk.dto.object.ObjectHeader;
|
||||||
|
import info.frostfs.sdk.dto.object.SplitInfo;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Builder
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class ObjectHeaderResult {
|
||||||
|
private ObjectHeader headerInfo;
|
||||||
|
private SplitInfo splitInfo;
|
||||||
|
}
|
|
@ -4,6 +4,7 @@ import info.frostfs.sdk.FrostFSClient;
|
||||||
import info.frostfs.sdk.enums.MethodIndex;
|
import info.frostfs.sdk.enums.MethodIndex;
|
||||||
import info.frostfs.sdk.exceptions.ResponseFrostFSException;
|
import info.frostfs.sdk.exceptions.ResponseFrostFSException;
|
||||||
import info.frostfs.sdk.exceptions.ValidationFrostFSException;
|
import info.frostfs.sdk.exceptions.ValidationFrostFSException;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.CallContext;
|
||||||
import info.frostfs.sdk.utils.WaitUtil;
|
import info.frostfs.sdk.utils.WaitUtil;
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
@ -45,12 +46,12 @@ public class ClientWrapper extends ClientStatusMonitor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void dial() {
|
public void dial(CallContext ctx) {
|
||||||
FrostFSClient client = getClient();
|
FrostFSClient client = getClient();
|
||||||
if (client == null) {
|
if (client == null) {
|
||||||
throw new ValidationFrostFSException(POOL_CLIENT_UNHEALTHY);
|
throw new ValidationFrostFSException(POOL_CLIENT_UNHEALTHY);
|
||||||
}
|
}
|
||||||
client.dial();
|
client.dial(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleError(Exception exp) {
|
public void handleError(Exception exp) {
|
||||||
|
@ -77,9 +78,9 @@ public class ClientWrapper extends ClientStatusMonitor {
|
||||||
client.close();
|
client.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompletableFuture<Boolean> restartIfUnhealthy() {
|
public CompletableFuture<Boolean> restartIfUnhealthy(CallContext ctx) {
|
||||||
try {
|
try {
|
||||||
client.getLocalNodeInfo();
|
client.getLocalNodeInfo(ctx);
|
||||||
return CompletableFuture.completedFuture(false);
|
return CompletableFuture.completedFuture(false);
|
||||||
} catch (Exception ignored) {
|
} catch (Exception ignored) {
|
||||||
}
|
}
|
||||||
|
@ -88,15 +89,15 @@ public class ClientWrapper extends ClientStatusMonitor {
|
||||||
scheduleGracefulClose();
|
scheduleGracefulClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
return CompletableFuture.completedFuture(restartClient());
|
return CompletableFuture.completedFuture(restartClient(ctx));
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean restartClient() {
|
private boolean restartClient(CallContext ctx) {
|
||||||
FrostFSClient newClient = null;
|
FrostFSClient newClient = null;
|
||||||
try {
|
try {
|
||||||
newClient = new FrostFSClient(wrapperPrm, sessionCache);
|
newClient = new FrostFSClient(wrapperPrm, sessionCache);
|
||||||
|
|
||||||
var error = newClient.dial();
|
var error = newClient.dial(ctx);
|
||||||
if (StringUtils.isNotBlank(error)) {
|
if (StringUtils.isNotBlank(error)) {
|
||||||
setUnhealthyOnDial();
|
setUnhealthyOnDial();
|
||||||
newClient.close();
|
newClient.close();
|
||||||
|
@ -113,7 +114,7 @@ public class ClientWrapper extends ClientStatusMonitor {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
client.getLocalNodeInfo();
|
client.getLocalNodeInfo(ctx);
|
||||||
} catch (Exception exp) {
|
} catch (Exception exp) {
|
||||||
setUnhealthy();
|
setUnhealthy();
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -2,12 +2,14 @@ package info.frostfs.sdk.pool;
|
||||||
|
|
||||||
import frostfs.refs.Types;
|
import frostfs.refs.Types;
|
||||||
import info.frostfs.sdk.dto.chain.Chain;
|
import info.frostfs.sdk.dto.chain.Chain;
|
||||||
import info.frostfs.sdk.dto.chain.ChainTarget;
|
|
||||||
import info.frostfs.sdk.dto.container.Container;
|
import info.frostfs.sdk.dto.container.Container;
|
||||||
import info.frostfs.sdk.dto.container.ContainerId;
|
import info.frostfs.sdk.dto.container.ContainerId;
|
||||||
import info.frostfs.sdk.dto.netmap.NetmapSnapshot;
|
import info.frostfs.sdk.dto.netmap.NetmapSnapshot;
|
||||||
import info.frostfs.sdk.dto.netmap.NodeInfo;
|
import info.frostfs.sdk.dto.netmap.NodeInfo;
|
||||||
import info.frostfs.sdk.dto.object.*;
|
import info.frostfs.sdk.dto.object.ObjectFrostFS;
|
||||||
|
import info.frostfs.sdk.dto.object.ObjectHeader;
|
||||||
|
import info.frostfs.sdk.dto.object.ObjectId;
|
||||||
|
import info.frostfs.sdk.dto.object.OwnerId;
|
||||||
import info.frostfs.sdk.dto.session.SessionToken;
|
import info.frostfs.sdk.dto.session.SessionToken;
|
||||||
import info.frostfs.sdk.exceptions.FrostFSException;
|
import info.frostfs.sdk.exceptions.FrostFSException;
|
||||||
import info.frostfs.sdk.exceptions.SessionExpiredFrostFSException;
|
import info.frostfs.sdk.exceptions.SessionExpiredFrostFSException;
|
||||||
|
@ -15,10 +17,21 @@ import info.frostfs.sdk.exceptions.SessionNotFoundFrostFSException;
|
||||||
import info.frostfs.sdk.exceptions.ValidationFrostFSException;
|
import info.frostfs.sdk.exceptions.ValidationFrostFSException;
|
||||||
import info.frostfs.sdk.jdo.ECDsa;
|
import info.frostfs.sdk.jdo.ECDsa;
|
||||||
import info.frostfs.sdk.jdo.NetworkSettings;
|
import info.frostfs.sdk.jdo.NetworkSettings;
|
||||||
import info.frostfs.sdk.jdo.PutObjectParameters;
|
import info.frostfs.sdk.jdo.parameters.CallContext;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.ape.PrmApeChainAdd;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.ape.PrmApeChainList;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.ape.PrmApeChainRemove;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.container.PrmContainerCreate;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.container.PrmContainerDelete;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.container.PrmContainerGet;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.container.PrmContainerGetAll;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.object.*;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.session.PrmSessionCreate;
|
||||||
import info.frostfs.sdk.jdo.pool.NodeParameters;
|
import info.frostfs.sdk.jdo.pool.NodeParameters;
|
||||||
import info.frostfs.sdk.jdo.pool.PoolInitParameters;
|
import info.frostfs.sdk.jdo.pool.PoolInitParameters;
|
||||||
|
import info.frostfs.sdk.jdo.result.ObjectHeaderResult;
|
||||||
import info.frostfs.sdk.services.CommonClient;
|
import info.frostfs.sdk.services.CommonClient;
|
||||||
|
import info.frostfs.sdk.services.impl.rwhelper.ObjectWriter;
|
||||||
import info.frostfs.sdk.utils.FrostFSMessages;
|
import info.frostfs.sdk.utils.FrostFSMessages;
|
||||||
import info.frostfs.sdk.utils.WaitUtil;
|
import info.frostfs.sdk.utils.WaitUtil;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
@ -171,21 +184,21 @@ public class Pool implements CommonClient {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static SessionToken initSessionForDuration(ClientWrapper cw, long duration) {
|
private static SessionToken initSessionForDuration(CallContext ctx, ClientWrapper cw, long duration) {
|
||||||
var client = cw.getClient();
|
var client = cw.getClient();
|
||||||
NetworkSettings networkInfo = client.getNetworkSettings();
|
NetworkSettings networkInfo = client.getNetworkSettings(ctx);
|
||||||
|
|
||||||
long epoch = networkInfo.getEpochDuration();
|
long epoch = networkInfo.getEpochDuration();
|
||||||
long exp = (Long.MAX_VALUE - epoch < duration) ? Long.MAX_VALUE : (epoch + duration);
|
long exp = (Long.MAX_VALUE - epoch < duration) ? Long.MAX_VALUE : (epoch + duration);
|
||||||
|
|
||||||
return client.createSession(exp);
|
return client.createSession(new PrmSessionCreate(exp), ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String formCacheKey(String address, String key) {
|
public static String formCacheKey(String address, String key) {
|
||||||
return address + key;
|
return address + key;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String dial() {
|
public String dial(CallContext ctx) {
|
||||||
InnerPool[] inner = new InnerPool[rebalanceParams.getNodesParams().length];
|
InnerPool[] inner = new InnerPool[rebalanceParams.getNodesParams().length];
|
||||||
boolean atLeastOneHealthy = false;
|
boolean atLeastOneHealthy = false;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@ -198,10 +211,12 @@ public class Pool implements CommonClient {
|
||||||
boolean dialed = false;
|
boolean dialed = false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
client.dial();
|
client.dial(ctx);
|
||||||
dialed = true;
|
dialed = true;
|
||||||
|
|
||||||
SessionToken token = initSessionForDuration(client, rebalanceParams.getSessionExpirationDuration());
|
SessionToken token = initSessionForDuration(
|
||||||
|
ctx, client, rebalanceParams.getSessionExpirationDuration()
|
||||||
|
);
|
||||||
String cacheKey = formCacheKey(
|
String cacheKey = formCacheKey(
|
||||||
nodeParams.getAddress().get(j),
|
nodeParams.getAddress().get(j),
|
||||||
getHexString(key.getPublicKeyByte())
|
getHexString(key.getPublicKeyByte())
|
||||||
|
@ -236,10 +251,10 @@ public class Pool implements CommonClient {
|
||||||
|
|
||||||
this.innerPools = inner;
|
this.innerPools = inner;
|
||||||
|
|
||||||
NetworkSettings networkSettings = getNetworkSettings();
|
NetworkSettings networkSettings = getNetworkSettings(ctx);
|
||||||
|
|
||||||
this.maxObjectSize = networkSettings.getMaxObjectSize();
|
this.maxObjectSize = networkSettings.getMaxObjectSize();
|
||||||
startRebalance();
|
startRebalance(ctx);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -267,7 +282,7 @@ public class Pool implements CommonClient {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void startRebalance() {
|
public void startRebalance(CallContext ctx) {
|
||||||
double[][] buffers = new double[rebalanceParams.getNodesParams().length][];
|
double[][] buffers = new double[rebalanceParams.getNodesParams().length][];
|
||||||
|
|
||||||
for (int i = 0; i < rebalanceParams.getNodesParams().length; i++) {
|
for (int i = 0; i < rebalanceParams.getNodesParams().length; i++) {
|
||||||
|
@ -276,24 +291,24 @@ public class Pool implements CommonClient {
|
||||||
|
|
||||||
CompletableFuture.runAsync(() -> {
|
CompletableFuture.runAsync(() -> {
|
||||||
WaitUtil.sleep(rebalanceParams.getClientRebalanceInterval());
|
WaitUtil.sleep(rebalanceParams.getClientRebalanceInterval());
|
||||||
updateNodesHealth(buffers);
|
updateNodesHealth(ctx, buffers);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateNodesHealth(double[][] buffers) {
|
private void updateNodesHealth(CallContext ctx, double[][] buffers) {
|
||||||
CompletableFuture<?>[] tasks = new CompletableFuture<?>[innerPools.length];
|
CompletableFuture<?>[] tasks = new CompletableFuture<?>[innerPools.length];
|
||||||
|
|
||||||
for (int i = 0; i < innerPools.length; i++) {
|
for (int i = 0; i < innerPools.length; i++) {
|
||||||
double[] bufferWeights = buffers[i];
|
double[] bufferWeights = buffers[i];
|
||||||
int finalI = i;
|
int finalI = i;
|
||||||
tasks[i] = CompletableFuture.runAsync(() -> updateInnerNodesHealth(finalI, bufferWeights));
|
tasks[i] = CompletableFuture.runAsync(() -> updateInnerNodesHealth(ctx, finalI, bufferWeights));
|
||||||
}
|
}
|
||||||
|
|
||||||
CompletableFuture.allOf(tasks).join();
|
CompletableFuture.allOf(tasks).join();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateInnerNodesHealth(int poolIndex, double[] bufferWeights) {
|
private void updateInnerNodesHealth(CallContext ctx, int poolIndex, double[] bufferWeights) {
|
||||||
if (poolIndex > innerPools.length - 1) {
|
if (poolIndex > innerPools.length - 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -311,7 +326,7 @@ public class Pool implements CommonClient {
|
||||||
AtomicBoolean changed = new AtomicBoolean(false);
|
AtomicBoolean changed = new AtomicBoolean(false);
|
||||||
|
|
||||||
int finalJ = j;
|
int finalJ = j;
|
||||||
tasks[j] = client.restartIfUnhealthy().handle((unused, throwable) -> {
|
tasks[j] = client.restartIfUnhealthy(ctx).handle((unused, throwable) -> {
|
||||||
if (throwable != null) {
|
if (throwable != null) {
|
||||||
error.set(throwable.getMessage());
|
error.set(throwable.getMessage());
|
||||||
bufferWeights[finalJ] = 0;
|
bufferWeights[finalJ] = 0;
|
||||||
|
@ -398,112 +413,112 @@ public class Pool implements CommonClient {
|
||||||
return statistics;
|
return statistics;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Container getContainer(ContainerId cid) {
|
public Container getContainer(PrmContainerGet args, CallContext ctx) {
|
||||||
ClientWrapper client = connection();
|
ClientWrapper client = connection();
|
||||||
return client.getClient().getContainer(cid);
|
return client.getClient().getContainer(args, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ContainerId> listContainers() {
|
public List<ContainerId> listContainers(PrmContainerGetAll args, CallContext ctx) {
|
||||||
ClientWrapper client = connection();
|
ClientWrapper client = connection();
|
||||||
return client.getClient().listContainers();
|
return client.getClient().listContainers(args, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ContainerId createContainer(Container container) {
|
public ContainerId createContainer(PrmContainerCreate args, CallContext ctx) {
|
||||||
ClientWrapper client = connection();
|
ClientWrapper client = connection();
|
||||||
return client.getClient().createContainer(container);
|
return client.getClient().createContainer(args, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteContainer(ContainerId cid) {
|
public void deleteContainer(PrmContainerDelete args, CallContext ctx) {
|
||||||
ClientWrapper client = connection();
|
ClientWrapper client = connection();
|
||||||
client.getClient().deleteContainer(cid);
|
client.getClient().deleteContainer(args, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ObjectHeader getObjectHead(ContainerId containerId, ObjectId objectId) {
|
public ObjectHeaderResult getObjectHead(PrmObjectHeadGet args, CallContext ctx) {
|
||||||
ClientWrapper client = connection();
|
ClientWrapper client = connection();
|
||||||
return client.getClient().getObjectHead(containerId, objectId);
|
return client.getClient().getObjectHead(args, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ObjectFrostFS getObject(ContainerId containerId, ObjectId objectId) {
|
public ObjectFrostFS getObject(PrmObjectGet args, CallContext ctx) {
|
||||||
ClientWrapper client = connection();
|
ClientWrapper client = connection();
|
||||||
return client.getClient().getObject(containerId, objectId);
|
return client.getClient().getObject(args, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ObjectId putObject(PutObjectParameters parameters) {
|
public ObjectWriter putObject(PrmObjectPut args, CallContext ctx) {
|
||||||
ClientWrapper client = connection();
|
ClientWrapper client = connection();
|
||||||
return client.getClient().putObject(parameters);
|
return client.getClient().putObject(args, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ObjectId putSingleObject(ObjectFrostFS objectFrostFS) {
|
public ObjectId putClientCutObject(PrmObjectClientCutPut args, CallContext ctx) {
|
||||||
ClientWrapper client = connection();
|
ClientWrapper client = connection();
|
||||||
return client.getClient().putSingleObject(objectFrostFS);
|
return client.getClient().putClientCutObject(args, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteObject(ContainerId containerId, ObjectId objectId) {
|
public ObjectId putSingleObject(PrmObjectSinglePut args, CallContext ctx) {
|
||||||
ClientWrapper client = connection();
|
ClientWrapper client = connection();
|
||||||
client.getClient().deleteObject(containerId, objectId);
|
return client.getClient().putSingleObject(args, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<ObjectId> searchObjects(ContainerId cid, ObjectFilter<?>... filters) {
|
public void deleteObject(PrmObjectDelete args, CallContext ctx) {
|
||||||
ClientWrapper client = connection();
|
ClientWrapper client = connection();
|
||||||
return client.getClient().searchObjects(cid, filters);
|
client.getClient().deleteObject(args, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] addChain(Chain chain, ChainTarget chainTarget) {
|
public Iterable<ObjectId> searchObjects(PrmObjectSearch args, CallContext ctx) {
|
||||||
ClientWrapper client = connection();
|
ClientWrapper client = connection();
|
||||||
return client.getClient().addChain(chain, chainTarget);
|
return client.getClient().searchObjects(args, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeChain(Chain chain, ChainTarget chainTarget) {
|
public byte[] addChain(PrmApeChainAdd args, CallContext ctx) {
|
||||||
ClientWrapper client = connection();
|
ClientWrapper client = connection();
|
||||||
client.getClient().removeChain(chain, chainTarget);
|
return client.getClient().addChain(args, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Chain> listChains(ChainTarget chainTarget) {
|
public void removeChain(PrmApeChainRemove args, CallContext ctx) {
|
||||||
ClientWrapper client = connection();
|
ClientWrapper client = connection();
|
||||||
return client.getClient().listChains(chainTarget);
|
client.getClient().removeChain(args, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NetmapSnapshot getNetmapSnapshot() {
|
public List<Chain> listChains(PrmApeChainList args, CallContext ctx) {
|
||||||
ClientWrapper client = connection();
|
ClientWrapper client = connection();
|
||||||
return client.getClient().getNetmapSnapshot();
|
return client.getClient().listChains(args, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NodeInfo getLocalNodeInfo() {
|
public NetmapSnapshot getNetmapSnapshot(CallContext ctx) {
|
||||||
ClientWrapper client = connection();
|
ClientWrapper client = connection();
|
||||||
return client.getClient().getLocalNodeInfo();
|
return client.getClient().getNetmapSnapshot(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NetworkSettings getNetworkSettings() {
|
public NodeInfo getLocalNodeInfo(CallContext ctx) {
|
||||||
ClientWrapper client = connection();
|
ClientWrapper client = connection();
|
||||||
return client.getClient().getNetworkSettings();
|
return client.getClient().getLocalNodeInfo(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SessionToken createSession(long expiration) {
|
public NetworkSettings getNetworkSettings(CallContext ctx) {
|
||||||
ClientWrapper client = connection();
|
ClientWrapper client = connection();
|
||||||
return client.getClient().createSession(expiration);
|
return client.getClient().getNetworkSettings(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
public frostfs.session.Types.SessionToken createSessionInternal(long expiration) {
|
@Override
|
||||||
|
public SessionToken createSession(PrmSessionCreate args, CallContext ctx) {
|
||||||
ClientWrapper client = connection();
|
ClientWrapper client = connection();
|
||||||
return client.getClient().createSessionInternal(expiration);
|
return client.getClient().createSession(args, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -513,8 +528,8 @@ public class Pool implements CommonClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public frostfs.accounting.Types.Decimal getBalance() {
|
public frostfs.accounting.Types.Decimal getBalance(CallContext ctx) {
|
||||||
ClientWrapper client = connection();
|
ClientWrapper client = connection();
|
||||||
return client.getClient().getBalance();
|
return client.getClient().getBalance(ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package info.frostfs.sdk.pool;
|
package info.frostfs.sdk.pool;
|
||||||
|
|
||||||
import info.frostfs.sdk.dto.session.SessionToken;
|
import info.frostfs.sdk.dto.session.SessionToken;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
@ -18,18 +19,8 @@ public class SessionCache {
|
||||||
return cache.containsKey(key);
|
return cache.containsKey(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean tryGetValue(String key, SessionToken[] value) {
|
public SessionToken tryGetValue(String key) {
|
||||||
if (key == null) {
|
return StringUtils.isBlank(key) ? null : cache.get(key);
|
||||||
value[0] = null;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
SessionToken token = cache.get(key);
|
|
||||||
if (token != null) {
|
|
||||||
value[0] = token;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setValue(String key, SessionToken value) {
|
public void setValue(String key, SessionToken value) {
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
package info.frostfs.sdk.services;
|
package info.frostfs.sdk.services;
|
||||||
|
|
||||||
import frostfs.accounting.Types;
|
import frostfs.accounting.Types;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.CallContext;
|
||||||
|
|
||||||
public interface AccountingClient {
|
public interface AccountingClient {
|
||||||
Types.Decimal getBalance();
|
Types.Decimal getBalance(CallContext ctx);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
package info.frostfs.sdk.services;
|
package info.frostfs.sdk.services;
|
||||||
|
|
||||||
import info.frostfs.sdk.dto.chain.Chain;
|
import info.frostfs.sdk.dto.chain.Chain;
|
||||||
import info.frostfs.sdk.dto.chain.ChainTarget;
|
import info.frostfs.sdk.jdo.parameters.CallContext;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.ape.PrmApeChainAdd;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.ape.PrmApeChainList;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.ape.PrmApeChainRemove;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public interface ApeManagerClient {
|
public interface ApeManagerClient {
|
||||||
byte[] addChain(Chain chain, ChainTarget chainTarget);
|
byte[] addChain(PrmApeChainAdd args, CallContext ctx);
|
||||||
|
|
||||||
void removeChain(Chain chain, ChainTarget chainTarget);
|
void removeChain(PrmApeChainRemove args, CallContext ctx);
|
||||||
|
|
||||||
List<Chain> listChains(ChainTarget chainTarget);
|
List<Chain> listChains(PrmApeChainList args, CallContext ctx);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,15 +2,20 @@ package info.frostfs.sdk.services;
|
||||||
|
|
||||||
import info.frostfs.sdk.dto.container.Container;
|
import info.frostfs.sdk.dto.container.Container;
|
||||||
import info.frostfs.sdk.dto.container.ContainerId;
|
import info.frostfs.sdk.dto.container.ContainerId;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.CallContext;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.container.PrmContainerCreate;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.container.PrmContainerDelete;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.container.PrmContainerGet;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.container.PrmContainerGetAll;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public interface ContainerClient {
|
public interface ContainerClient {
|
||||||
Container getContainer(ContainerId cid);
|
Container getContainer(PrmContainerGet args, CallContext ctx);
|
||||||
|
|
||||||
List<ContainerId> listContainers();
|
List<ContainerId> listContainers(PrmContainerGetAll args, CallContext ctx);
|
||||||
|
|
||||||
ContainerId createContainer(Container container);
|
ContainerId createContainer(PrmContainerCreate args, CallContext ctx);
|
||||||
|
|
||||||
void deleteContainer(ContainerId cid);
|
void deleteContainer(PrmContainerDelete args, CallContext ctx);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,11 +3,12 @@ package info.frostfs.sdk.services;
|
||||||
import info.frostfs.sdk.dto.netmap.NetmapSnapshot;
|
import info.frostfs.sdk.dto.netmap.NetmapSnapshot;
|
||||||
import info.frostfs.sdk.dto.netmap.NodeInfo;
|
import info.frostfs.sdk.dto.netmap.NodeInfo;
|
||||||
import info.frostfs.sdk.jdo.NetworkSettings;
|
import info.frostfs.sdk.jdo.NetworkSettings;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.CallContext;
|
||||||
|
|
||||||
public interface NetmapClient {
|
public interface NetmapClient {
|
||||||
NetmapSnapshot getNetmapSnapshot();
|
NetmapSnapshot getNetmapSnapshot(CallContext ctx);
|
||||||
|
|
||||||
NodeInfo getLocalNodeInfo();
|
NodeInfo getLocalNodeInfo(CallContext ctx);
|
||||||
|
|
||||||
NetworkSettings getNetworkSettings();
|
NetworkSettings getNetworkSettings(CallContext ctx);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +1,24 @@
|
||||||
package info.frostfs.sdk.services;
|
package info.frostfs.sdk.services;
|
||||||
|
|
||||||
import info.frostfs.sdk.dto.container.ContainerId;
|
|
||||||
import info.frostfs.sdk.dto.object.ObjectFilter;
|
|
||||||
import info.frostfs.sdk.dto.object.ObjectFrostFS;
|
import info.frostfs.sdk.dto.object.ObjectFrostFS;
|
||||||
import info.frostfs.sdk.dto.object.ObjectHeader;
|
|
||||||
import info.frostfs.sdk.dto.object.ObjectId;
|
import info.frostfs.sdk.dto.object.ObjectId;
|
||||||
import info.frostfs.sdk.jdo.PutObjectParameters;
|
import info.frostfs.sdk.jdo.parameters.CallContext;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.object.*;
|
||||||
|
import info.frostfs.sdk.jdo.result.ObjectHeaderResult;
|
||||||
|
import info.frostfs.sdk.services.impl.rwhelper.ObjectWriter;
|
||||||
|
|
||||||
public interface ObjectClient {
|
public interface ObjectClient {
|
||||||
ObjectHeader getObjectHead(ContainerId containerId, ObjectId objectId);
|
ObjectHeaderResult getObjectHead(PrmObjectHeadGet args, CallContext ctx);
|
||||||
|
|
||||||
ObjectFrostFS getObject(ContainerId containerId, ObjectId objectId);
|
ObjectFrostFS getObject(PrmObjectGet args, CallContext ctx);
|
||||||
|
|
||||||
ObjectId putObject(PutObjectParameters parameters);
|
ObjectWriter putObject(PrmObjectPut args, CallContext ctx);
|
||||||
|
|
||||||
ObjectId putSingleObject(ObjectFrostFS objectFrostFS);
|
ObjectId putClientCutObject(PrmObjectClientCutPut args, CallContext ctx);
|
||||||
|
|
||||||
void deleteObject(ContainerId containerId, ObjectId objectId);
|
ObjectId putSingleObject(PrmObjectSinglePut args, CallContext ctx);
|
||||||
|
|
||||||
Iterable<ObjectId> searchObjects(ContainerId cid, ObjectFilter<?>... filters);
|
void deleteObject(PrmObjectDelete args, CallContext ctx);
|
||||||
|
|
||||||
|
Iterable<ObjectId> searchObjects(PrmObjectSearch args, CallContext ctx);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
package info.frostfs.sdk.services;
|
package info.frostfs.sdk.services;
|
||||||
|
|
||||||
import info.frostfs.sdk.dto.session.SessionToken;
|
import info.frostfs.sdk.dto.session.SessionToken;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.CallContext;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.session.PrmSessionCreate;
|
||||||
|
|
||||||
public interface SessionClient {
|
public interface SessionClient {
|
||||||
SessionToken createSession(long expiration);
|
SessionToken createSession(PrmSessionCreate args, CallContext ctx);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package info.frostfs.sdk.services;
|
package info.frostfs.sdk.services;
|
||||||
|
|
||||||
import frostfs.session.Types;
|
|
||||||
import info.frostfs.sdk.dto.session.SessionToken;
|
import info.frostfs.sdk.dto.session.SessionToken;
|
||||||
import info.frostfs.sdk.jdo.ClientEnvironment;
|
import info.frostfs.sdk.jdo.ClientEnvironment;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.CallContext;
|
||||||
|
|
||||||
public interface SessionTools {
|
public interface SessionTools {
|
||||||
Types.SessionToken getOrCreateSession(SessionToken token, ClientEnvironment env);
|
SessionToken getOrCreateSession(ClientEnvironment env, CallContext ctx);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import frostfs.accounting.AccountingServiceGrpc;
|
||||||
import frostfs.accounting.Service;
|
import frostfs.accounting.Service;
|
||||||
import frostfs.accounting.Types;
|
import frostfs.accounting.Types;
|
||||||
import info.frostfs.sdk.jdo.ClientEnvironment;
|
import info.frostfs.sdk.jdo.ClientEnvironment;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.CallContext;
|
||||||
import info.frostfs.sdk.mappers.object.OwnerIdMapper;
|
import info.frostfs.sdk.mappers.object.OwnerIdMapper;
|
||||||
import info.frostfs.sdk.services.AccountingClient;
|
import info.frostfs.sdk.services.AccountingClient;
|
||||||
import info.frostfs.sdk.services.ContextAccessor;
|
import info.frostfs.sdk.services.ContextAccessor;
|
||||||
|
@ -11,7 +12,7 @@ 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 info.frostfs.sdk.tools.Verifier;
|
||||||
|
|
||||||
import java.util.Map;
|
import static info.frostfs.sdk.utils.DeadLineUtil.deadLineAfter;
|
||||||
|
|
||||||
public class AccountingClientImpl extends ContextAccessor implements AccountingClient {
|
public class AccountingClientImpl extends ContextAccessor implements AccountingClient {
|
||||||
private final AccountingServiceGrpc.AccountingServiceBlockingStub serviceBlockingStub;
|
private final AccountingServiceGrpc.AccountingServiceBlockingStub serviceBlockingStub;
|
||||||
|
@ -22,23 +23,24 @@ public class AccountingClientImpl extends ContextAccessor implements AccountingC
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Types.Decimal getBalance() {
|
public Types.Decimal getBalance(CallContext ctx) {
|
||||||
var request = createGetRequest(null);
|
var request = createGetRequest();
|
||||||
|
|
||||||
var response = serviceBlockingStub.balance(request);
|
var service = deadLineAfter(serviceBlockingStub, ctx.getTimeout(), ctx.getTimeUnit());
|
||||||
|
var response = service.balance(request);
|
||||||
|
|
||||||
Verifier.checkResponse(response);
|
Verifier.checkResponse(response);
|
||||||
return response.getBody().getBalance();
|
return response.getBody().getBalance();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Service.BalanceRequest createGetRequest(Map<String, String> xHeaders) {
|
private Service.BalanceRequest createGetRequest() {
|
||||||
var body = Service.BalanceRequest.Body.newBuilder()
|
var body = Service.BalanceRequest.Body.newBuilder()
|
||||||
.setOwnerId(OwnerIdMapper.toGrpcMessage(getContext().getOwnerId()))
|
.setOwnerId(OwnerIdMapper.toGrpcMessage(getContext().getOwnerId()))
|
||||||
.build();
|
.build();
|
||||||
var request = Service.BalanceRequest.newBuilder()
|
var request = Service.BalanceRequest.newBuilder()
|
||||||
.setBody(body);
|
.setBody(body);
|
||||||
|
|
||||||
RequestConstructor.addMetaHeader(request, xHeaders);
|
RequestConstructor.addMetaHeader(request);
|
||||||
RequestSigner.sign(request, getContext().getKey());
|
RequestSigner.sign(request, getContext().getKey());
|
||||||
|
|
||||||
return request.build();
|
return request.build();
|
||||||
|
|
|
@ -5,9 +5,11 @@ import frostfs.ape.Types;
|
||||||
import frostfs.apemanager.APEManagerServiceGrpc;
|
import frostfs.apemanager.APEManagerServiceGrpc;
|
||||||
import frostfs.apemanager.Service;
|
import frostfs.apemanager.Service;
|
||||||
import info.frostfs.sdk.dto.chain.Chain;
|
import info.frostfs.sdk.dto.chain.Chain;
|
||||||
import info.frostfs.sdk.dto.chain.ChainTarget;
|
|
||||||
import info.frostfs.sdk.exceptions.ValidationFrostFSException;
|
|
||||||
import info.frostfs.sdk.jdo.ClientEnvironment;
|
import info.frostfs.sdk.jdo.ClientEnvironment;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.CallContext;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.ape.PrmApeChainAdd;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.ape.PrmApeChainList;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.ape.PrmApeChainRemove;
|
||||||
import info.frostfs.sdk.mappers.chain.ChainMapper;
|
import info.frostfs.sdk.mappers.chain.ChainMapper;
|
||||||
import info.frostfs.sdk.mappers.chain.ChainTargetMapper;
|
import info.frostfs.sdk.mappers.chain.ChainTargetMapper;
|
||||||
import info.frostfs.sdk.services.ApeManagerClient;
|
import info.frostfs.sdk.services.ApeManagerClient;
|
||||||
|
@ -17,10 +19,9 @@ import info.frostfs.sdk.tools.RequestSigner;
|
||||||
import info.frostfs.sdk.tools.Verifier;
|
import info.frostfs.sdk.tools.Verifier;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import static info.frostfs.sdk.constants.ErrorConst.*;
|
import static info.frostfs.sdk.utils.DeadLineUtil.deadLineAfter;
|
||||||
import static java.util.Objects.isNull;
|
import static info.frostfs.sdk.utils.Validator.validate;
|
||||||
|
|
||||||
public class ApeManagerClientImpl extends ContextAccessor implements ApeManagerClient {
|
public class ApeManagerClientImpl extends ContextAccessor implements ApeManagerClient {
|
||||||
private final APEManagerServiceGrpc.APEManagerServiceBlockingStub apeManagerServiceClient;
|
private final APEManagerServiceGrpc.APEManagerServiceBlockingStub apeManagerServiceClient;
|
||||||
|
@ -31,19 +32,13 @@ public class ApeManagerClientImpl extends ContextAccessor implements ApeManagerC
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] addChain(Chain chain, ChainTarget chainTarget) {
|
public byte[] addChain(PrmApeChainAdd args, CallContext ctx) {
|
||||||
if (isNull(chain) || isNull(chainTarget)) {
|
validate(args);
|
||||||
throw new ValidationFrostFSException(
|
|
||||||
String.format(
|
|
||||||
PARAMS_ARE_MISSING_TEMPLATE,
|
|
||||||
String.join(FIELDS_DELIMITER_COMMA, Chain.class.getName(), ChainTarget.class.getName())
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
var request = createAddChainRequest(chain, chainTarget, null);
|
var request = createAddChainRequest(args);
|
||||||
|
|
||||||
var response = apeManagerServiceClient.addChain(request);
|
var service = deadLineAfter(apeManagerServiceClient, ctx.getTimeout(), ctx.getTimeUnit());
|
||||||
|
var response = service.addChain(request);
|
||||||
|
|
||||||
Verifier.checkResponse(response);
|
Verifier.checkResponse(response);
|
||||||
|
|
||||||
|
@ -51,82 +46,70 @@ public class ApeManagerClientImpl extends ContextAccessor implements ApeManagerC
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeChain(Chain chain, ChainTarget chainTarget) {
|
public void removeChain(PrmApeChainRemove args, CallContext ctx) {
|
||||||
if (isNull(chain) || isNull(chainTarget)) {
|
validate(args);
|
||||||
throw new ValidationFrostFSException(
|
|
||||||
String.format(
|
|
||||||
PARAMS_ARE_MISSING_TEMPLATE,
|
|
||||||
String.join(FIELDS_DELIMITER_COMMA, Chain.class.getName(), ChainTarget.class.getName())
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
var request = createRemoveChainRequest(chain, chainTarget, null);
|
var request = createRemoveChainRequest(args);
|
||||||
|
|
||||||
var response = apeManagerServiceClient.removeChain(request);
|
var service = deadLineAfter(apeManagerServiceClient, ctx.getTimeout(), ctx.getTimeUnit());
|
||||||
|
var response = service.removeChain(request);
|
||||||
|
|
||||||
Verifier.checkResponse(response);
|
Verifier.checkResponse(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Chain> listChains(ChainTarget chainTarget) {
|
public List<Chain> listChains(PrmApeChainList args, CallContext ctx) {
|
||||||
if (isNull(chainTarget)) {
|
validate(args);
|
||||||
throw new ValidationFrostFSException(String.format(PARAM_IS_MISSING_TEMPLATE, ChainTarget.class.getName()));
|
|
||||||
}
|
|
||||||
|
|
||||||
var request = createListChainsRequest(chainTarget, null);
|
var request = createListChainsRequest(args);
|
||||||
|
|
||||||
var response = apeManagerServiceClient.listChains(request);
|
var service = deadLineAfter(apeManagerServiceClient, ctx.getTimeout(), ctx.getTimeUnit());
|
||||||
|
var response = service.listChains(request);
|
||||||
|
|
||||||
Verifier.checkResponse(response);
|
Verifier.checkResponse(response);
|
||||||
|
|
||||||
return ChainMapper.toModels(response.getBody().getChainsList());
|
return ChainMapper.toModels(response.getBody().getChainsList());
|
||||||
}
|
}
|
||||||
|
|
||||||
private Service.AddChainRequest createAddChainRequest(Chain chain,
|
private Service.AddChainRequest createAddChainRequest(PrmApeChainAdd args) {
|
||||||
ChainTarget chainTarget,
|
|
||||||
Map<String, String> xHeaders) {
|
|
||||||
var chainGrpc = Types.Chain.newBuilder()
|
var chainGrpc = Types.Chain.newBuilder()
|
||||||
.setRaw(ByteString.copyFrom(chain.getRaw()))
|
.setRaw(ByteString.copyFrom(args.getChain().getRaw()))
|
||||||
.build();
|
.build();
|
||||||
var body = Service.AddChainRequest.Body.newBuilder()
|
var body = Service.AddChainRequest.Body.newBuilder()
|
||||||
.setChain(chainGrpc)
|
.setChain(chainGrpc)
|
||||||
.setTarget(ChainTargetMapper.toGrpcMessage(chainTarget))
|
.setTarget(ChainTargetMapper.toGrpcMessage(args.getChainTarget()))
|
||||||
.build();
|
.build();
|
||||||
var request = Service.AddChainRequest.newBuilder()
|
var request = Service.AddChainRequest.newBuilder()
|
||||||
.setBody(body);
|
.setBody(body);
|
||||||
|
|
||||||
RequestConstructor.addMetaHeader(request, xHeaders);
|
RequestConstructor.addMetaHeader(request, args.getXHeaders());
|
||||||
RequestSigner.sign(request, getContext().getKey());
|
RequestSigner.sign(request, getContext().getKey());
|
||||||
|
|
||||||
return request.build();
|
return request.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Service.RemoveChainRequest createRemoveChainRequest(Chain chain,
|
private Service.RemoveChainRequest createRemoveChainRequest(PrmApeChainRemove args) {
|
||||||
ChainTarget chainTarget,
|
|
||||||
Map<String, String> xHeaders) {
|
|
||||||
var body = Service.RemoveChainRequest.Body.newBuilder()
|
var body = Service.RemoveChainRequest.Body.newBuilder()
|
||||||
.setChainId(ByteString.copyFrom(chain.getRaw()))
|
.setChainId(ByteString.copyFrom(args.getChain().getRaw()))
|
||||||
.setTarget(ChainTargetMapper.toGrpcMessage(chainTarget))
|
.setTarget(ChainTargetMapper.toGrpcMessage(args.getChainTarget()))
|
||||||
.build();
|
.build();
|
||||||
var request = Service.RemoveChainRequest.newBuilder()
|
var request = Service.RemoveChainRequest.newBuilder()
|
||||||
.setBody(body);
|
.setBody(body);
|
||||||
|
|
||||||
RequestConstructor.addMetaHeader(request, xHeaders);
|
RequestConstructor.addMetaHeader(request, args.getXHeaders());
|
||||||
RequestSigner.sign(request, getContext().getKey());
|
RequestSigner.sign(request, getContext().getKey());
|
||||||
|
|
||||||
return request.build();
|
return request.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Service.ListChainsRequest createListChainsRequest(ChainTarget chainTarget,
|
private Service.ListChainsRequest createListChainsRequest(PrmApeChainList args) {
|
||||||
Map<String, String> xHeaders) {
|
|
||||||
var body = Service.ListChainsRequest.Body.newBuilder()
|
var body = Service.ListChainsRequest.Body.newBuilder()
|
||||||
.setTarget(ChainTargetMapper.toGrpcMessage(chainTarget))
|
.setTarget(ChainTargetMapper.toGrpcMessage(args.getChainTarget()))
|
||||||
.build();
|
.build();
|
||||||
var request = Service.ListChainsRequest.newBuilder()
|
var request = Service.ListChainsRequest.newBuilder()
|
||||||
.setBody(body);
|
.setBody(body);
|
||||||
|
|
||||||
RequestConstructor.addMetaHeader(request, xHeaders);
|
RequestConstructor.addMetaHeader(request, args.getXHeaders());
|
||||||
RequestSigner.sign(request, getContext().getKey());
|
RequestSigner.sign(request, getContext().getKey());
|
||||||
|
|
||||||
return request.build();
|
return request.build();
|
||||||
|
|
|
@ -10,9 +10,14 @@ import info.frostfs.sdk.enums.StatusCode;
|
||||||
import info.frostfs.sdk.enums.WaitExpects;
|
import info.frostfs.sdk.enums.WaitExpects;
|
||||||
import info.frostfs.sdk.exceptions.ResponseFrostFSException;
|
import info.frostfs.sdk.exceptions.ResponseFrostFSException;
|
||||||
import info.frostfs.sdk.exceptions.TimeoutFrostFSException;
|
import info.frostfs.sdk.exceptions.TimeoutFrostFSException;
|
||||||
import info.frostfs.sdk.exceptions.ValidationFrostFSException;
|
|
||||||
import info.frostfs.sdk.jdo.ClientEnvironment;
|
import info.frostfs.sdk.jdo.ClientEnvironment;
|
||||||
import info.frostfs.sdk.jdo.WaitParameters;
|
import info.frostfs.sdk.jdo.parameters.CallContext;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.PrmWait;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.container.PrmContainerCreate;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.container.PrmContainerDelete;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.container.PrmContainerGet;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.container.PrmContainerGetAll;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.session.SessionContext;
|
||||||
import info.frostfs.sdk.mappers.container.ContainerIdMapper;
|
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.mappers.netmap.VersionMapper;
|
import info.frostfs.sdk.mappers.netmap.VersionMapper;
|
||||||
|
@ -29,8 +34,11 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static info.frostfs.sdk.constants.ErrorConst.PARAM_IS_MISSING_TEMPLATE;
|
import static info.frostfs.sdk.constants.AttributeConst.DISABLE_HOMOMORPHIC_HASHING_ATTRIBUTE;
|
||||||
|
import static info.frostfs.sdk.utils.DeadLineUtil.deadLineAfter;
|
||||||
|
import static info.frostfs.sdk.utils.Validator.validate;
|
||||||
import static java.util.Objects.isNull;
|
import static java.util.Objects.isNull;
|
||||||
|
import static java.util.Objects.nonNull;
|
||||||
|
|
||||||
public class ContainerClientImpl extends ContextAccessor implements ContainerClient {
|
public class ContainerClientImpl extends ContextAccessor implements ContainerClient {
|
||||||
private final ContainerServiceGrpc.ContainerServiceBlockingStub serviceBlockingStub;
|
private final ContainerServiceGrpc.ContainerServiceBlockingStub serviceBlockingStub;
|
||||||
|
@ -42,29 +50,33 @@ public class ContainerClientImpl extends ContextAccessor implements ContainerCli
|
||||||
this.sessionTools = new SessionToolsImpl(clientEnvironment);
|
this.sessionTools = new SessionToolsImpl(clientEnvironment);
|
||||||
}
|
}
|
||||||
|
|
||||||
public frostfs.session.Types.SessionToken getOrCreateSession(SessionToken sessionToken) {
|
public SessionToken getOrCreateSession(SessionContext sessionContext, CallContext ctx) {
|
||||||
return sessionTools.getOrCreateSession(sessionToken, getContext());
|
return isNull(sessionContext.getSessionToken())
|
||||||
|
? sessionTools.getOrCreateSession(getContext(), ctx)
|
||||||
|
: sessionContext.getSessionToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Container getContainer(ContainerId cid) {
|
public Container getContainer(PrmContainerGet args, CallContext ctx) {
|
||||||
if (isNull(cid)) {
|
validate(args);
|
||||||
throw new ValidationFrostFSException(String.format(PARAM_IS_MISSING_TEMPLATE, ContainerId.class.getName()));
|
|
||||||
}
|
|
||||||
|
|
||||||
var request = createGetRequest(ContainerIdMapper.toGrpcMessage(cid), null);
|
var request = createGetRequest(args);
|
||||||
|
|
||||||
var response = serviceBlockingStub.get(request);
|
var service = deadLineAfter(serviceBlockingStub, ctx.getTimeout(), ctx.getTimeUnit());
|
||||||
|
var response = service.get(request);
|
||||||
|
|
||||||
Verifier.checkResponse(response);
|
Verifier.checkResponse(response);
|
||||||
return ContainerMapper.toModel(response.getBody().getContainer());
|
return ContainerMapper.toModel(response.getBody().getContainer());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ContainerId> listContainers() {
|
public List<ContainerId> listContainers(PrmContainerGetAll args, CallContext ctx) {
|
||||||
var request = createListRequest(null);
|
validate(args);
|
||||||
|
|
||||||
var response = serviceBlockingStub.list(request);
|
var request = createListRequest(args);
|
||||||
|
|
||||||
|
var service = deadLineAfter(serviceBlockingStub, ctx.getTimeout(), ctx.getTimeUnit());
|
||||||
|
var response = service.list(request);
|
||||||
|
|
||||||
Verifier.checkResponse(response);
|
Verifier.checkResponse(response);
|
||||||
|
|
||||||
|
@ -74,43 +86,39 @@ public class ContainerClientImpl extends ContextAccessor implements ContainerCli
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ContainerId createContainer(Container container) {
|
public ContainerId createContainer(PrmContainerCreate args, CallContext ctx) {
|
||||||
if (isNull(container)) {
|
validate(args);
|
||||||
throw new ValidationFrostFSException(String.format(PARAM_IS_MISSING_TEMPLATE, Container.class.getName()));
|
|
||||||
}
|
|
||||||
|
|
||||||
var grpcContainer = ContainerMapper.toGrpcMessage(container);
|
var request = createPutRequest(args, ctx);
|
||||||
var request = createPutRequest(grpcContainer, null);
|
|
||||||
|
|
||||||
var response = serviceBlockingStub.put(request);
|
var service = deadLineAfter(serviceBlockingStub, ctx.getTimeout(), ctx.getTimeUnit());
|
||||||
|
var response = service.put(request);
|
||||||
|
|
||||||
Verifier.checkResponse(response);
|
Verifier.checkResponse(response);
|
||||||
|
|
||||||
waitForContainer(WaitExpects.EXISTS, response.getBody().getContainerId(), null);
|
waitForContainer(WaitExpects.EXISTS, response.getBody().getContainerId(), args.getWaitParams());
|
||||||
|
|
||||||
return new ContainerId(response.getBody().getContainerId().getValue().toByteArray());
|
return new ContainerId(response.getBody().getContainerId().getValue().toByteArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteContainer(ContainerId cid) {
|
public void deleteContainer(PrmContainerDelete args, CallContext ctx) {
|
||||||
if (isNull(cid)) {
|
validate(args);
|
||||||
throw new ValidationFrostFSException(String.format(PARAM_IS_MISSING_TEMPLATE, ContainerId.class.getName()));
|
|
||||||
}
|
|
||||||
|
|
||||||
var grpcContainerId = ContainerIdMapper.toGrpcMessage(cid);
|
var request = createDeleteRequest(args, ctx);
|
||||||
var request = createDeleteRequest(grpcContainerId, null);
|
|
||||||
|
|
||||||
var response = serviceBlockingStub.delete(request);
|
var service = deadLineAfter(serviceBlockingStub, ctx.getTimeout(), ctx.getTimeUnit());
|
||||||
|
var response = service.delete(request);
|
||||||
|
|
||||||
Verifier.checkResponse(response);
|
Verifier.checkResponse(response);
|
||||||
|
|
||||||
waitForContainer(WaitExpects.REMOVED, request.getBody().getContainerId(), null);
|
waitForContainer(WaitExpects.REMOVED, request.getBody().getContainerId(), args.getWaitParams());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void waitForContainer(WaitExpects expect, Types.ContainerID id, WaitParameters waitParams) {
|
private void waitForContainer(WaitExpects expect, Types.ContainerID cid, PrmWait waitParams) {
|
||||||
var request = createGetRequest(id, null);
|
var request = createGetRequest(cid, null);
|
||||||
|
|
||||||
waitParams = isNull(waitParams) ? new WaitParameters() : waitParams;
|
waitParams = isNull(waitParams) ? new PrmWait() : waitParams;
|
||||||
var deadLine = waitParams.getDeadline();
|
var deadLine = waitParams.getDeadline();
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
@ -145,9 +153,12 @@ public class ContainerClientImpl extends ContextAccessor implements ContainerCli
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Service.GetRequest createGetRequest(PrmContainerGet args) {
|
||||||
|
var cid = ContainerIdMapper.toGrpcMessage(args.getContainerId());
|
||||||
|
return createGetRequest(cid, args.getXHeaders());
|
||||||
|
}
|
||||||
|
|
||||||
private Service.GetRequest createGetRequest(Types.ContainerID cid,
|
private Service.GetRequest createGetRequest(Types.ContainerID cid, Map<String, String> xHeaders) {
|
||||||
Map<String, String> xHeaders) {
|
|
||||||
var body = Service.GetRequest.Body.newBuilder()
|
var body = Service.GetRequest.Body.newBuilder()
|
||||||
.setContainerId(cid)
|
.setContainerId(cid)
|
||||||
.build();
|
.build();
|
||||||
|
@ -160,22 +171,22 @@ public class ContainerClientImpl extends ContextAccessor implements ContainerCli
|
||||||
return request.build();
|
return request.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Service.ListRequest createListRequest(Map<String, String> xHeaders) {
|
private Service.ListRequest createListRequest(PrmContainerGetAll args) {
|
||||||
var body = Service.ListRequest.Body.newBuilder()
|
var body = Service.ListRequest.Body.newBuilder()
|
||||||
.setOwnerId(OwnerIdMapper.toGrpcMessage(getContext().getOwnerId()))
|
.setOwnerId(OwnerIdMapper.toGrpcMessage(getContext().getOwnerId()))
|
||||||
.build();
|
.build();
|
||||||
var request = Service.ListRequest.newBuilder()
|
var request = Service.ListRequest.newBuilder()
|
||||||
.setBody(body);
|
.setBody(body);
|
||||||
|
|
||||||
RequestConstructor.addMetaHeader(request, xHeaders);
|
RequestConstructor.addMetaHeader(request, args.getXHeaders());
|
||||||
RequestSigner.sign(request, getContext().getKey());
|
RequestSigner.sign(request, getContext().getKey());
|
||||||
|
|
||||||
return request.build();
|
return request.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Service.PutRequest createPutRequest(frostfs.container.Types.Container container,
|
private Service.PutRequest createPutRequest(PrmContainerCreate args, CallContext ctx) {
|
||||||
Map<String, String> xHeaders) {
|
syncContainerWithNetwork(args.getContainer(), ctx);
|
||||||
container = container.toBuilder()
|
var container = ContainerMapper.toGrpcMessage(args.getContainer()).toBuilder()
|
||||||
.setOwnerId(OwnerIdMapper.toGrpcMessage(getContext().getOwnerId()))
|
.setOwnerId(OwnerIdMapper.toGrpcMessage(getContext().getOwnerId()))
|
||||||
.setVersion(VersionMapper.toGrpcMessage(getContext().getVersion()))
|
.setVersion(VersionMapper.toGrpcMessage(getContext().getVersion()))
|
||||||
.build();
|
.build();
|
||||||
|
@ -187,9 +198,8 @@ public class ContainerClientImpl extends ContextAccessor implements ContainerCli
|
||||||
var request = Service.PutRequest.newBuilder()
|
var request = Service.PutRequest.newBuilder()
|
||||||
.setBody(body);
|
.setBody(body);
|
||||||
|
|
||||||
var sessionToken = getOrCreateSession(null);
|
var sessionToken = getOrCreateSession(args, ctx);
|
||||||
|
var protoToken = RequestConstructor.createContainerTokenContext(
|
||||||
sessionToken = RequestConstructor.createContainerTokenContext(
|
|
||||||
sessionToken,
|
sessionToken,
|
||||||
null,
|
null,
|
||||||
frostfs.session.Types.ContainerSessionContext.Verb.PUT,
|
frostfs.session.Types.ContainerSessionContext.Verb.PUT,
|
||||||
|
@ -197,14 +207,15 @@ public class ContainerClientImpl extends ContextAccessor implements ContainerCli
|
||||||
getContext().getKey()
|
getContext().getKey()
|
||||||
);
|
);
|
||||||
|
|
||||||
RequestConstructor.addMetaHeader(request, xHeaders, sessionToken);
|
RequestConstructor.addMetaHeader(request, args.getXHeaders(), protoToken);
|
||||||
RequestSigner.sign(request, getContext().getKey());
|
RequestSigner.sign(request, getContext().getKey());
|
||||||
|
|
||||||
return request.build();
|
return request.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Service.DeleteRequest createDeleteRequest(Types.ContainerID cid,
|
private Service.DeleteRequest createDeleteRequest(PrmContainerDelete args, CallContext ctx) {
|
||||||
Map<String, String> xHeaders) {
|
var cid = ContainerIdMapper.toGrpcMessage(args.getContainerId());
|
||||||
|
|
||||||
var body = Service.DeleteRequest.Body.newBuilder()
|
var body = Service.DeleteRequest.Body.newBuilder()
|
||||||
.setContainerId(cid)
|
.setContainerId(cid)
|
||||||
.setSignature(RequestSigner.signRFC6979(getContext().getKey(), cid.getValue()))
|
.setSignature(RequestSigner.signRFC6979(getContext().getKey(), cid.getValue()))
|
||||||
|
@ -212,9 +223,8 @@ public class ContainerClientImpl extends ContextAccessor implements ContainerCli
|
||||||
var request = Service.DeleteRequest.newBuilder()
|
var request = Service.DeleteRequest.newBuilder()
|
||||||
.setBody(body);
|
.setBody(body);
|
||||||
|
|
||||||
var sessionToken = getOrCreateSession(null);
|
var sessionToken = getOrCreateSession(args, ctx);
|
||||||
|
var protoToken = RequestConstructor.createContainerTokenContext(
|
||||||
sessionToken = RequestConstructor.createContainerTokenContext(
|
|
||||||
sessionToken,
|
sessionToken,
|
||||||
null,
|
null,
|
||||||
frostfs.session.Types.ContainerSessionContext.Verb.DELETE,
|
frostfs.session.Types.ContainerSessionContext.Verb.DELETE,
|
||||||
|
@ -222,9 +232,18 @@ public class ContainerClientImpl extends ContextAccessor implements ContainerCli
|
||||||
getContext().getKey()
|
getContext().getKey()
|
||||||
);
|
);
|
||||||
|
|
||||||
RequestConstructor.addMetaHeader(request, xHeaders, sessionToken);
|
RequestConstructor.addMetaHeader(request, args.getXHeaders(), protoToken);
|
||||||
RequestSigner.sign(request, getContext().getKey());
|
RequestSigner.sign(request, getContext().getKey());
|
||||||
|
|
||||||
return request.build();
|
return request.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void syncContainerWithNetwork(Container container, CallContext callContext) {
|
||||||
|
var settings = getContext().getFrostFSClient().getNetworkSettings(callContext);
|
||||||
|
if (nonNull(settings.getHomomorphicHashingDisabled()) && settings.getHomomorphicHashingDisabled()) {
|
||||||
|
container.getAttributes().put(DISABLE_HOMOMORPHIC_HASHING_ATTRIBUTE, Boolean.TRUE.toString());
|
||||||
|
} else {
|
||||||
|
container.getAttributes().remove(DISABLE_HOMOMORPHIC_HASHING_ATTRIBUTE, Boolean.TRUE.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import info.frostfs.sdk.dto.netmap.NetmapSnapshot;
|
||||||
import info.frostfs.sdk.dto.netmap.NodeInfo;
|
import info.frostfs.sdk.dto.netmap.NodeInfo;
|
||||||
import info.frostfs.sdk.jdo.ClientEnvironment;
|
import info.frostfs.sdk.jdo.ClientEnvironment;
|
||||||
import info.frostfs.sdk.jdo.NetworkSettings;
|
import info.frostfs.sdk.jdo.NetworkSettings;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.CallContext;
|
||||||
import info.frostfs.sdk.mappers.netmap.NetmapSnapshotMapper;
|
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;
|
||||||
|
@ -17,6 +18,7 @@ import info.frostfs.sdk.tools.Verifier;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
import static info.frostfs.sdk.tools.RequestSigner.sign;
|
import static info.frostfs.sdk.tools.RequestSigner.sign;
|
||||||
|
import static info.frostfs.sdk.utils.DeadLineUtil.deadLineAfter;
|
||||||
import static java.util.Objects.nonNull;
|
import static java.util.Objects.nonNull;
|
||||||
|
|
||||||
public class NetmapClientImpl extends ContextAccessor implements NetmapClient {
|
public class NetmapClientImpl extends ContextAccessor implements NetmapClient {
|
||||||
|
@ -94,12 +96,12 @@ public class NetmapClientImpl extends ContextAccessor implements NetmapClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NetworkSettings getNetworkSettings() {
|
public NetworkSettings getNetworkSettings(CallContext ctx) {
|
||||||
if (nonNull(getContext().getNetworkSettings())) {
|
if (nonNull(getContext().getNetworkSettings())) {
|
||||||
return getContext().getNetworkSettings();
|
return getContext().getNetworkSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
var info = getNetworkInfo();
|
var info = getNetworkInfo(ctx);
|
||||||
|
|
||||||
var settings = new NetworkSettings();
|
var settings = new NetworkSettings();
|
||||||
|
|
||||||
|
@ -113,25 +115,28 @@ public class NetmapClientImpl extends ContextAccessor implements NetmapClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NodeInfo getLocalNodeInfo() {
|
public NodeInfo getLocalNodeInfo(CallContext ctx) {
|
||||||
var request = Service.LocalNodeInfoRequest.newBuilder();
|
var request = Service.LocalNodeInfoRequest.newBuilder();
|
||||||
|
|
||||||
RequestConstructor.addMetaHeader(request);
|
RequestConstructor.addMetaHeader(request);
|
||||||
sign(request, getContext().getKey());
|
sign(request, getContext().getKey());
|
||||||
|
|
||||||
var response = netmapServiceClient.localNodeInfo(request.build());
|
var service = deadLineAfter(netmapServiceClient, ctx.getTimeout(), ctx.getTimeUnit());
|
||||||
|
var response = service.localNodeInfo(request.build());
|
||||||
|
|
||||||
Verifier.checkResponse(response);
|
Verifier.checkResponse(response);
|
||||||
|
|
||||||
return NodeInfoMapper.toModel(response.getBody());
|
return NodeInfoMapper.toModel(response.getBody());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Service.NetworkInfoResponse getNetworkInfo() {
|
public Service.NetworkInfoResponse getNetworkInfo(CallContext ctx) {
|
||||||
var request = Service.NetworkInfoRequest.newBuilder();
|
var request = Service.NetworkInfoRequest.newBuilder();
|
||||||
|
|
||||||
RequestConstructor.addMetaHeader(request);
|
RequestConstructor.addMetaHeader(request);
|
||||||
sign(request, getContext().getKey());
|
sign(request, getContext().getKey());
|
||||||
|
|
||||||
var response = netmapServiceClient.networkInfo(request.build());
|
var service = deadLineAfter(netmapServiceClient, ctx.getTimeout(), ctx.getTimeUnit());
|
||||||
|
var response = service.networkInfo(request.build());
|
||||||
|
|
||||||
Verifier.checkResponse(response);
|
Verifier.checkResponse(response);
|
||||||
|
|
||||||
|
@ -139,13 +144,14 @@ public class NetmapClientImpl extends ContextAccessor implements NetmapClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NetmapSnapshot getNetmapSnapshot() {
|
public NetmapSnapshot getNetmapSnapshot(CallContext ctx) {
|
||||||
var request = Service.NetmapSnapshotRequest.newBuilder();
|
var request = Service.NetmapSnapshotRequest.newBuilder();
|
||||||
|
|
||||||
RequestConstructor.addMetaHeader(request);
|
RequestConstructor.addMetaHeader(request);
|
||||||
sign(request, getContext().getKey());
|
sign(request, getContext().getKey());
|
||||||
|
|
||||||
var response = netmapServiceClient.netmapSnapshot(request.build());
|
var service = deadLineAfter(netmapServiceClient, ctx.getTimeout(), ctx.getTimeUnit());
|
||||||
|
var response = service.netmapSnapshot(request.build());
|
||||||
|
|
||||||
Verifier.checkResponse(response);
|
Verifier.checkResponse(response);
|
||||||
|
|
||||||
|
|
|
@ -6,29 +6,26 @@ import frostfs.object.ObjectServiceGrpc;
|
||||||
import frostfs.object.Service;
|
import frostfs.object.Service;
|
||||||
import frostfs.refs.Types;
|
import frostfs.refs.Types;
|
||||||
import info.frostfs.sdk.constants.AppConst;
|
import info.frostfs.sdk.constants.AppConst;
|
||||||
import info.frostfs.sdk.dto.container.ContainerId;
|
|
||||||
import info.frostfs.sdk.dto.object.*;
|
import info.frostfs.sdk.dto.object.*;
|
||||||
import info.frostfs.sdk.dto.session.SessionToken;
|
import info.frostfs.sdk.dto.session.SessionToken;
|
||||||
import info.frostfs.sdk.enums.ObjectType;
|
import info.frostfs.sdk.enums.ObjectType;
|
||||||
import info.frostfs.sdk.exceptions.ProcessFrostFSException;
|
import info.frostfs.sdk.exceptions.ProcessFrostFSException;
|
||||||
import info.frostfs.sdk.exceptions.ValidationFrostFSException;
|
|
||||||
import info.frostfs.sdk.jdo.ClientEnvironment;
|
import info.frostfs.sdk.jdo.ClientEnvironment;
|
||||||
import info.frostfs.sdk.jdo.PutObjectParameters;
|
|
||||||
import info.frostfs.sdk.jdo.PutObjectResult;
|
import info.frostfs.sdk.jdo.PutObjectResult;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.CallContext;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.object.*;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.session.SessionContext;
|
||||||
|
import info.frostfs.sdk.jdo.result.ObjectHeaderResult;
|
||||||
import info.frostfs.sdk.mappers.container.ContainerIdMapper;
|
import info.frostfs.sdk.mappers.container.ContainerIdMapper;
|
||||||
import info.frostfs.sdk.mappers.object.ObjectFilterMapper;
|
import info.frostfs.sdk.mappers.object.*;
|
||||||
import info.frostfs.sdk.mappers.object.ObjectFrostFSMapper;
|
|
||||||
import info.frostfs.sdk.mappers.object.ObjectHeaderMapper;
|
|
||||||
import info.frostfs.sdk.mappers.object.ObjectIdMapper;
|
|
||||||
import info.frostfs.sdk.mappers.session.SessionMapper;
|
|
||||||
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.ObjectReaderImpl;
|
import info.frostfs.sdk.services.impl.rwhelper.ObjectReaderImpl;
|
||||||
|
import info.frostfs.sdk.services.impl.rwhelper.ObjectStreamer;
|
||||||
import info.frostfs.sdk.services.impl.rwhelper.ObjectWriter;
|
import info.frostfs.sdk.services.impl.rwhelper.ObjectWriter;
|
||||||
import info.frostfs.sdk.services.impl.rwhelper.SearchReader;
|
import info.frostfs.sdk.services.impl.rwhelper.SearchReader;
|
||||||
import info.frostfs.sdk.tools.RequestConstructor;
|
import info.frostfs.sdk.tools.RequestConstructor;
|
||||||
import info.frostfs.sdk.tools.Verifier;
|
import info.frostfs.sdk.tools.Verifier;
|
||||||
import info.frostfs.sdk.utils.Validator;
|
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -37,9 +34,12 @@ import java.util.ArrayList;
|
||||||
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.constants.ErrorConst.*;
|
import static info.frostfs.sdk.constants.ErrorConst.PROTO_MESSAGE_IS_EMPTY_TEMPLATE;
|
||||||
import static info.frostfs.sdk.tools.RequestSigner.sign;
|
import static info.frostfs.sdk.tools.RequestSigner.sign;
|
||||||
|
import static info.frostfs.sdk.utils.DeadLineUtil.deadLineAfter;
|
||||||
|
import static info.frostfs.sdk.utils.Validator.validate;
|
||||||
import static java.util.Objects.isNull;
|
import static java.util.Objects.isNull;
|
||||||
|
import static java.util.Objects.nonNull;
|
||||||
|
|
||||||
public class ObjectClientImpl extends ContextAccessor implements ObjectClient {
|
public class ObjectClientImpl extends ContextAccessor implements ObjectClient {
|
||||||
private final ObjectServiceGrpc.ObjectServiceBlockingStub objectServiceBlockingClient;
|
private final ObjectServiceGrpc.ObjectServiceBlockingStub objectServiceBlockingClient;
|
||||||
|
@ -55,87 +55,153 @@ public class ObjectClientImpl extends ContextAccessor implements ObjectClient {
|
||||||
this.sessionTools = new SessionToolsImpl(clientEnvironment);
|
this.sessionTools = new SessionToolsImpl(clientEnvironment);
|
||||||
}
|
}
|
||||||
|
|
||||||
public frostfs.session.Types.SessionToken getOrCreateSession(SessionToken sessionToken) {
|
public SessionToken getOrCreateSession(SessionContext sessionContext, CallContext ctx) {
|
||||||
return sessionTools.getOrCreateSession(sessionToken, getContext());
|
return isNull(sessionContext.getSessionToken())
|
||||||
|
? sessionTools.getOrCreateSession(getContext(), ctx)
|
||||||
|
: sessionContext.getSessionToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ObjectHeader getObjectHead(ContainerId cid, ObjectId oid) {
|
public ObjectHeaderResult getObjectHead(PrmObjectHeadGet args, CallContext ctx) {
|
||||||
if (isNull(cid) || isNull(oid)) {
|
validate(args);
|
||||||
throw new ValidationFrostFSException(
|
|
||||||
String.format(
|
|
||||||
PARAMS_ARE_MISSING_TEMPLATE,
|
|
||||||
String.join(FIELDS_DELIMITER_COMMA, ContainerId.class.getName(), ObjectId.class.getName())
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
var request = createHeadRequest(ContainerIdMapper.toGrpcMessage(cid), ObjectIdMapper.toGrpcMessage(oid));
|
var request = createHeadRequest(args, ctx);
|
||||||
|
|
||||||
var response = objectServiceBlockingClient.head(request);
|
var service = deadLineAfter(objectServiceBlockingClient, ctx.getTimeout(), ctx.getTimeUnit());
|
||||||
|
var response = service.head(request);
|
||||||
|
|
||||||
Verifier.checkResponse(response);
|
Verifier.checkResponse(response);
|
||||||
|
|
||||||
return ObjectHeaderMapper.toModel(response.getBody().getHeader().getHeader());
|
return ObjectHeaderResult.builder()
|
||||||
|
.headerInfo(ObjectHeaderMapper.toModel(response.getBody().getHeader().getHeader()))
|
||||||
|
.splitInfo(SplitInfoMapper.toModel(response.getBody().getSplitInfo()))
|
||||||
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ObjectFrostFS getObject(ContainerId cid, ObjectId oid) {
|
public ObjectFrostFS getObject(PrmObjectGet args, CallContext ctx) {
|
||||||
var request = createGetRequest(ContainerIdMapper.toGrpcMessage(cid), ObjectIdMapper.toGrpcMessage(oid));
|
validate(args);
|
||||||
|
|
||||||
return getObject(request);
|
var request = createGetRequest(args, ctx);
|
||||||
|
|
||||||
|
return getObject(request, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteObject(ContainerId cid, ObjectId oid) {
|
public void deleteObject(PrmObjectDelete args, CallContext ctx) {
|
||||||
var request = createDeleteRequest(ContainerIdMapper.toGrpcMessage(cid), ObjectIdMapper.toGrpcMessage(oid));
|
validate(args);
|
||||||
|
|
||||||
var response = objectServiceBlockingClient.delete(request);
|
var request = createDeleteRequest(args, ctx);
|
||||||
|
|
||||||
|
var service = deadLineAfter(objectServiceBlockingClient, ctx.getTimeout(), ctx.getTimeUnit());
|
||||||
|
var response = service.delete(request);
|
||||||
|
|
||||||
Verifier.checkResponse(response);
|
Verifier.checkResponse(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<ObjectId> searchObjects(ContainerId cid, ObjectFilter<?>... filters) {
|
public Iterable<ObjectId> searchObjects(PrmObjectSearch args, CallContext ctx) {
|
||||||
var request = createSearchRequest(ContainerIdMapper.toGrpcMessage(cid), filters);
|
validate(args);
|
||||||
|
|
||||||
var objectsIds = searchObjects(request);
|
var request = createSearchRequest(args, ctx);
|
||||||
|
|
||||||
|
var objectsIds = searchObjects(request, ctx);
|
||||||
|
|
||||||
return Iterables.transform(objectsIds, input -> new ObjectId(input.getValue().toByteArray()));
|
return Iterables.transform(objectsIds, input -> new ObjectId(input.getValue().toByteArray()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ObjectId putObject(PutObjectParameters parameters) {
|
public ObjectWriter putObject(PrmObjectPut args, CallContext ctx) {
|
||||||
Validator.validate(parameters);
|
validate(args);
|
||||||
|
|
||||||
if (parameters.isClientCut()) {
|
return new ObjectWriter(getContext(), args, getUploadStream(args, ctx));
|
||||||
return putClientCutObject(parameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parameters.getHeader().getPayloadLength() > 0) {
|
|
||||||
parameters.setFullLength(parameters.getHeader().getPayloadLength());
|
|
||||||
} else {
|
|
||||||
parameters.setFullLength(getStreamSize(parameters.getPayload()));
|
|
||||||
}
|
|
||||||
|
|
||||||
return putStreamObject(parameters).getObjectId();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ObjectId putSingleObject(ObjectFrostFS modelObject) {
|
public ObjectId putClientCutObject(PrmObjectClientCutPut args, CallContext ctx) {
|
||||||
var grpcObject = objectToolsImpl.createObject(modelObject);
|
validate(args);
|
||||||
|
|
||||||
var request = createPutSingleRequest(grpcObject);
|
var header = args.getObjectHeader();
|
||||||
|
var fullLength = header.getPayloadLength() == 0 ? getStreamSize(args.getPayload()) : header.getPayloadLength();
|
||||||
|
args.getPutObjectContext().setFullLength(fullLength);
|
||||||
|
|
||||||
var response = objectServiceBlockingClient.putSingle(request);
|
if (args.getPutObjectContext().getMaxObjectSizeCache() == 0) {
|
||||||
|
var networkSettings = getContext().getFrostFSClient().getNetworkSettings(ctx);
|
||||||
|
args.getPutObjectContext().setMaxObjectSizeCache(networkSettings.getMaxObjectSize().intValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
var restBytes = fullLength - args.getPutObjectContext().getCurrentStreamPosition();
|
||||||
|
var objectSize = restBytes > 0
|
||||||
|
? Math.min(args.getPutObjectContext().getMaxObjectSizeCache(), restBytes)
|
||||||
|
: args.getPutObjectContext().getMaxObjectSizeCache();
|
||||||
|
|
||||||
|
//define collection capacity
|
||||||
|
var restPart = (restBytes % objectSize) > 0 ? 1 : 0;
|
||||||
|
var objectsCount = fullLength > 0 ? (int) (restBytes / objectSize) + restPart : 0;
|
||||||
|
|
||||||
|
List<ObjectId> sentObjectIds = new ArrayList<>(objectsCount);
|
||||||
|
|
||||||
|
// keep attributes for the large object
|
||||||
|
var attributes = args.getObjectHeader().getAttributes();
|
||||||
|
|
||||||
|
Split split = new Split();
|
||||||
|
args.getObjectHeader().setAttributes(new ArrayList<>());
|
||||||
|
|
||||||
|
// send all parts except the last one as separate Objects
|
||||||
|
while (restBytes > (long) args.getPutObjectContext().getMaxObjectSizeCache()) {
|
||||||
|
var previous = CollectionUtils.isNotEmpty(sentObjectIds)
|
||||||
|
? sentObjectIds.get(sentObjectIds.size() - 1)
|
||||||
|
: null;
|
||||||
|
split.setPrevious(previous);
|
||||||
|
args.getObjectHeader().setSplit(split);
|
||||||
|
|
||||||
|
var result = putMultipartStreamObject(args, ctx);
|
||||||
|
|
||||||
|
sentObjectIds.add(result.getObjectId());
|
||||||
|
|
||||||
|
restBytes -= result.getObjectSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
// send the last part and create linkObject
|
||||||
|
if (CollectionUtils.isNotEmpty(sentObjectIds)) {
|
||||||
|
var largeObjectHeader =
|
||||||
|
new ObjectHeader(header.getContainerId(), ObjectType.REGULAR, attributes, fullLength, null);
|
||||||
|
|
||||||
|
split.setParentHeader(largeObjectHeader);
|
||||||
|
|
||||||
|
var result = putMultipartStreamObject(args, ctx);
|
||||||
|
|
||||||
|
sentObjectIds.add(result.getObjectId());
|
||||||
|
|
||||||
|
var linkObject = new LinkObject(header.getContainerId(), split.getSplitId(), largeObjectHeader);
|
||||||
|
linkObject.addChildren(sentObjectIds);
|
||||||
|
|
||||||
|
putSingleObject(new PrmObjectSinglePut(linkObject), ctx);
|
||||||
|
|
||||||
|
return split.getParent();
|
||||||
|
}
|
||||||
|
|
||||||
|
// We are here if the payload is placed to one Object. It means no cut action, just simple PUT.
|
||||||
|
var singlePartResult = putMultipartStreamObject(args, ctx);
|
||||||
|
|
||||||
|
return singlePartResult.getObjectId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ObjectId putSingleObject(PrmObjectSinglePut args, CallContext ctx) {
|
||||||
|
var grpcObject = objectToolsImpl.createObject(args.getObjectFrostFS());
|
||||||
|
var request = createPutSingleRequest(grpcObject, args, ctx);
|
||||||
|
|
||||||
|
var service = deadLineAfter(objectServiceBlockingClient, ctx.getTimeout(), ctx.getTimeUnit());
|
||||||
|
var response = service.putSingle(request);
|
||||||
|
|
||||||
Verifier.checkResponse(response);
|
Verifier.checkResponse(response);
|
||||||
|
|
||||||
return new ObjectId(grpcObject.getObjectId().getValue().toByteArray());
|
return new ObjectId(grpcObject.getObjectId().getValue().toByteArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
private ObjectFrostFS getObject(Service.GetRequest request) {
|
private ObjectFrostFS getObject(Service.GetRequest request, CallContext ctx) {
|
||||||
var reader = getObjectInit(request);
|
var reader = getObjectInit(request, ctx);
|
||||||
|
|
||||||
var grpcObject = reader.readHeader();
|
var grpcObject = reader.readHeader();
|
||||||
var modelObject = ObjectFrostFSMapper.toModel(grpcObject);
|
var modelObject = ObjectFrostFSMapper.toModel(grpcObject);
|
||||||
|
@ -145,39 +211,41 @@ public class ObjectClientImpl extends ContextAccessor implements ObjectClient {
|
||||||
return modelObject;
|
return modelObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ObjectReaderImpl getObjectInit(Service.GetRequest initRequest) {
|
private ObjectReaderImpl getObjectInit(Service.GetRequest initRequest, CallContext ctx) {
|
||||||
if (initRequest.getSerializedSize() == 0) {
|
if (initRequest.getSerializedSize() == 0) {
|
||||||
throw new ProcessFrostFSException(
|
throw new ProcessFrostFSException(
|
||||||
String.format(PROTO_MESSAGE_IS_EMPTY_TEMPLATE, initRequest.getClass().getName())
|
String.format(PROTO_MESSAGE_IS_EMPTY_TEMPLATE, initRequest.getClass().getName())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ObjectReaderImpl(objectServiceBlockingClient.get(initRequest));
|
var service = deadLineAfter(objectServiceBlockingClient, ctx.getTimeout(), ctx.getTimeUnit());
|
||||||
|
return new ObjectReaderImpl(service.get(initRequest));
|
||||||
}
|
}
|
||||||
|
|
||||||
private PutObjectResult putStreamObject(PutObjectParameters parameters) {
|
private PutObjectResult putMultipartStreamObject(PrmObjectClientCutPut args, CallContext ctx) {
|
||||||
var chunkSize = parameters.getBufferMaxSize() > 0 ? parameters.getBufferMaxSize() : AppConst.OBJECT_CHUNK_SIZE;
|
var chunkSize = args.getBufferMaxSize() > 0 ? args.getBufferMaxSize() : AppConst.OBJECT_CHUNK_SIZE;
|
||||||
|
|
||||||
var restBytes = parameters.getFullLength() - parameters.getCurrentStreamPosition();
|
var restBytes =
|
||||||
|
args.getPutObjectContext().getFullLength() - args.getPutObjectContext().getCurrentStreamPosition();
|
||||||
|
|
||||||
chunkSize = (int) Math.min(restBytes, chunkSize);
|
chunkSize = (int) Math.min(restBytes, chunkSize);
|
||||||
|
|
||||||
byte[] chunkBuffer = parameters.getCustomerBuffer() != null
|
byte[] chunkBuffer = args.getCustomerBuffer() != null
|
||||||
? parameters.getCustomerBuffer()
|
? args.getCustomerBuffer()
|
||||||
: new byte[chunkSize];//todo change to pool
|
: new byte[chunkSize];//todo change to pool
|
||||||
|
|
||||||
var sentBytes = 0;
|
var sentBytes = 0;
|
||||||
|
|
||||||
// 0 means no limit from client, so server side cut is performed
|
// 0 means no limit from client, so server side cut is performed
|
||||||
var objectLimitSize = parameters.isClientCut() ? parameters.getMaxObjectSizeCache() : 0;
|
var objectLimitSize = args.getPutObjectContext().getMaxObjectSizeCache();
|
||||||
|
|
||||||
var stream = getUploadStream(parameters);
|
var stream = getUploadStream(args, ctx);
|
||||||
|
|
||||||
while (objectLimitSize == 0 || sentBytes < objectLimitSize) {
|
while (objectLimitSize == 0 || sentBytes < objectLimitSize) {
|
||||||
// send chunks limited to default or user's settings
|
// send chunks limited to default or user's settings
|
||||||
var bufferSize = objectLimitSize > 0 ? Math.min(objectLimitSize - sentBytes, chunkSize) : chunkSize;
|
var bufferSize = objectLimitSize > 0 ? Math.min(objectLimitSize - sentBytes, chunkSize) : chunkSize;
|
||||||
|
|
||||||
var bytesCount = readNBytes(parameters.getPayload(), chunkBuffer, bufferSize);
|
var bytesCount = readNBytes(args.getPayload(), chunkBuffer, bufferSize);
|
||||||
|
|
||||||
if (bytesCount == 0) {
|
if (bytesCount == 0) {
|
||||||
break;
|
break;
|
||||||
|
@ -204,110 +272,40 @@ public class ObjectClientImpl extends ContextAccessor implements ObjectClient {
|
||||||
return new PutObjectResult(objectId, sentBytes);
|
return new PutObjectResult(objectId, sentBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ObjectId putClientCutObject(PutObjectParameters parameters) {
|
private ObjectStreamer getUploadStream(PrmObjectPutBase args, CallContext ctx) {
|
||||||
var header = parameters.getHeader();
|
var header = args.getObjectHeader();
|
||||||
var tokenRaw = getOrCreateSession(parameters.getSessionToken());
|
|
||||||
var token = new SessionToken(SessionMapper.serialize(tokenRaw));
|
|
||||||
parameters.setSessionToken(token);
|
|
||||||
|
|
||||||
var fullLength = header.getPayloadLength() == 0
|
|
||||||
? getStreamSize(parameters.getPayload())
|
|
||||||
: header.getPayloadLength();
|
|
||||||
|
|
||||||
parameters.setFullLength(fullLength);
|
|
||||||
|
|
||||||
if (parameters.getMaxObjectSizeCache() == 0) {
|
|
||||||
var networkSettings = getContext().getFrostFSClient().getNetworkSettings();
|
|
||||||
parameters.setMaxObjectSizeCache(networkSettings.getMaxObjectSize().intValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
var restBytes = fullLength - parameters.getCurrentStreamPosition();
|
|
||||||
var objectSize = restBytes > 0
|
|
||||||
? Math.min(parameters.getMaxObjectSizeCache(), restBytes)
|
|
||||||
: parameters.getMaxObjectSizeCache();
|
|
||||||
|
|
||||||
//define collection capacity
|
|
||||||
var restPart = (restBytes % objectSize) > 0 ? 1 : 0;
|
|
||||||
var objectsCount = fullLength > 0 ? (int) (restBytes / objectSize) + restPart : 0;
|
|
||||||
|
|
||||||
List<ObjectId> sentObjectIds = new ArrayList<>(objectsCount);
|
|
||||||
|
|
||||||
// keep attributes for the large object
|
|
||||||
var attributes = parameters.getHeader().getAttributes();
|
|
||||||
|
|
||||||
Split split = new Split();
|
|
||||||
parameters.getHeader().setSplit(split);
|
|
||||||
parameters.getHeader().setAttributes(new ArrayList<>());
|
|
||||||
|
|
||||||
// send all parts except the last one as separate Objects
|
|
||||||
while (restBytes > (long) parameters.getMaxObjectSizeCache()) {
|
|
||||||
var previous = CollectionUtils.isNotEmpty(sentObjectIds)
|
|
||||||
? sentObjectIds.get(sentObjectIds.size() - 1)
|
|
||||||
: null;
|
|
||||||
split.setPrevious(previous);
|
|
||||||
|
|
||||||
var result = putStreamObject(parameters);
|
|
||||||
|
|
||||||
sentObjectIds.add(result.getObjectId());
|
|
||||||
|
|
||||||
restBytes -= result.getObjectSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
// send the last part and create linkObject
|
|
||||||
if (CollectionUtils.isNotEmpty(sentObjectIds)) {
|
|
||||||
var largeObjectHeader =
|
|
||||||
new ObjectHeader(header.getContainerId(), ObjectType.REGULAR, attributes, fullLength, null);
|
|
||||||
|
|
||||||
split.setParentHeader(largeObjectHeader);
|
|
||||||
|
|
||||||
var result = putStreamObject(parameters);
|
|
||||||
|
|
||||||
sentObjectIds.add(result.getObjectId());
|
|
||||||
|
|
||||||
var linkObject = new LinkObject(header.getContainerId(), split.getSplitId(), largeObjectHeader);
|
|
||||||
linkObject.addChildren(sentObjectIds);
|
|
||||||
|
|
||||||
putSingleObject(linkObject);
|
|
||||||
|
|
||||||
return split.getParent();
|
|
||||||
}
|
|
||||||
|
|
||||||
// We are here if the payload is placed to one Object. It means no cut action, just simple PUT.
|
|
||||||
var singlePartResult = putStreamObject(parameters);
|
|
||||||
|
|
||||||
return singlePartResult.getObjectId();
|
|
||||||
}
|
|
||||||
|
|
||||||
private ObjectWriter getUploadStream(PutObjectParameters parameters) {
|
|
||||||
var header = parameters.getHeader();
|
|
||||||
|
|
||||||
header.setOwnerId(getContext().getOwnerId());
|
header.setOwnerId(getContext().getOwnerId());
|
||||||
header.setVersion(getContext().getVersion());
|
header.setVersion(getContext().getVersion());
|
||||||
|
|
||||||
var grpcHeader = ObjectHeaderMapper.toGrpcMessage(header);
|
var grpcHeader = ObjectHeaderMapper.toGrpcMessage(header);
|
||||||
grpcHeader = objectToolsImpl.updateSplitValues(grpcHeader, header.getSplit());
|
|
||||||
|
if (nonNull(header.getSplit())) {
|
||||||
|
grpcHeader = objectToolsImpl.updateSplitValues(grpcHeader, header.getSplit());
|
||||||
|
}
|
||||||
|
|
||||||
var oid = Types.ObjectID.newBuilder().setValue(getSha256(grpcHeader)).build();
|
var oid = Types.ObjectID.newBuilder().setValue(getSha256(grpcHeader)).build();
|
||||||
|
|
||||||
var initRequest = createInitPutRequest(oid, grpcHeader);
|
var initRequest = createInitPutRequest(oid, grpcHeader, args, ctx);
|
||||||
|
|
||||||
return putObjectInit(initRequest);
|
return putObjectInit(initRequest, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ObjectWriter putObjectInit(Service.PutRequest initRequest) {
|
private ObjectStreamer putObjectInit(Service.PutRequest initRequest, CallContext ctx) {
|
||||||
if (initRequest.getSerializedSize() == 0) {
|
if (initRequest.getSerializedSize() == 0) {
|
||||||
throw new ProcessFrostFSException(
|
throw new ProcessFrostFSException(
|
||||||
String.format(PROTO_MESSAGE_IS_EMPTY_TEMPLATE, initRequest.getClass().getName())
|
String.format(PROTO_MESSAGE_IS_EMPTY_TEMPLATE, initRequest.getClass().getName())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectWriter writer = new ObjectWriter(objectServiceClient);
|
var service = deadLineAfter(objectServiceClient, ctx.getTimeout(), ctx.getTimeUnit());
|
||||||
|
ObjectStreamer writer = new ObjectStreamer(service);
|
||||||
writer.write(initRequest);
|
writer.write(initRequest);
|
||||||
return writer;
|
return writer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Iterable<Types.ObjectID> searchObjects(Service.SearchRequest request) {
|
private Iterable<Types.ObjectID> searchObjects(Service.SearchRequest request, CallContext ctx) {
|
||||||
var reader = getSearchReader(request);
|
var reader = getSearchReader(request, ctx);
|
||||||
var ids = reader.read();
|
var ids = reader.read();
|
||||||
List<Types.ObjectID> result = new ArrayList<>();
|
List<Types.ObjectID> result = new ArrayList<>();
|
||||||
|
|
||||||
|
@ -319,14 +317,15 @@ public class ObjectClientImpl extends ContextAccessor implements ObjectClient {
|
||||||
return result;//todo return yield
|
return result;//todo return yield
|
||||||
}
|
}
|
||||||
|
|
||||||
private SearchReader getSearchReader(Service.SearchRequest initRequest) {
|
private SearchReader getSearchReader(Service.SearchRequest initRequest, CallContext ctx) {
|
||||||
if (initRequest.getSerializedSize() == 0) {
|
if (initRequest.getSerializedSize() == 0) {
|
||||||
throw new ProcessFrostFSException(
|
throw new ProcessFrostFSException(
|
||||||
String.format(PROTO_MESSAGE_IS_EMPTY_TEMPLATE, initRequest.getClass().getName())
|
String.format(PROTO_MESSAGE_IS_EMPTY_TEMPLATE, initRequest.getClass().getName())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new SearchReader(objectServiceBlockingClient.search(initRequest));
|
var service = deadLineAfter(objectServiceBlockingClient, ctx.getTimeout(), ctx.getTimeUnit());
|
||||||
|
return new SearchReader(service.search(initRequest));
|
||||||
}
|
}
|
||||||
|
|
||||||
private int readNBytes(InputStream inputStream, byte[] buffer, int size) {
|
private int readNBytes(InputStream inputStream, byte[] buffer, int size) {
|
||||||
|
@ -345,36 +344,37 @@ public class ObjectClientImpl extends ContextAccessor implements ObjectClient {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Service.HeadRequest createHeadRequest(Types.ContainerID cid, Types.ObjectID oid) {
|
private Service.HeadRequest createHeadRequest(PrmObjectHeadGet args, CallContext ctx) {
|
||||||
var address = Types.Address.newBuilder()
|
var address = Types.Address.newBuilder()
|
||||||
.setContainerId(cid)
|
.setContainerId(ContainerIdMapper.toGrpcMessage(args.getContainerId()))
|
||||||
.setObjectId(oid)
|
.setObjectId(ObjectIdMapper.toGrpcMessage(args.getObjectId()))
|
||||||
.build();
|
.build();
|
||||||
var body = Service.HeadRequest.Body.newBuilder()
|
var body = Service.HeadRequest.Body.newBuilder()
|
||||||
.setAddress(address)
|
.setAddress(address)
|
||||||
|
.setRaw(args.isRaw())
|
||||||
.build();
|
.build();
|
||||||
var request = Service.HeadRequest.newBuilder()
|
var request = Service.HeadRequest.newBuilder()
|
||||||
.setBody(body);
|
.setBody(body);
|
||||||
|
|
||||||
var sessionToken = getOrCreateSession(null);
|
var sessionToken = getOrCreateSession(args, ctx);
|
||||||
|
var protoToken = RequestConstructor.createObjectTokenContext(
|
||||||
sessionToken = RequestConstructor.createObjectTokenContext(
|
|
||||||
sessionToken,
|
sessionToken,
|
||||||
address,
|
address,
|
||||||
frostfs.session.Types.ObjectSessionContext.Verb.HEAD,
|
frostfs.session.Types.ObjectSessionContext.Verb.HEAD,
|
||||||
getContext().getKey()
|
getContext().getKey()
|
||||||
);
|
);
|
||||||
|
|
||||||
RequestConstructor.addMetaHeader(request, null, sessionToken);
|
RequestConstructor.addMetaHeader(request, args.getXHeaders(), protoToken);
|
||||||
sign(request, getContext().getKey());
|
sign(request, getContext().getKey());
|
||||||
|
|
||||||
return request.build();
|
return request.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Service.GetRequest createGetRequest(Types.ContainerID cid, Types.ObjectID oid) {
|
private Service.GetRequest createGetRequest(PrmObjectGet args, CallContext ctx) {
|
||||||
|
|
||||||
var address = Types.Address.newBuilder()
|
var address = Types.Address.newBuilder()
|
||||||
.setContainerId(cid)
|
.setContainerId(ContainerIdMapper.toGrpcMessage(args.getContainerId()))
|
||||||
.setObjectId(oid)
|
.setObjectId(ObjectIdMapper.toGrpcMessage(args.getObjectId()))
|
||||||
.build();
|
.build();
|
||||||
var body = Service.GetRequest.Body.newBuilder()
|
var body = Service.GetRequest.Body.newBuilder()
|
||||||
.setAddress(address)
|
.setAddress(address)
|
||||||
|
@ -382,25 +382,24 @@ public class ObjectClientImpl extends ContextAccessor implements ObjectClient {
|
||||||
var request = Service.GetRequest.newBuilder()
|
var request = Service.GetRequest.newBuilder()
|
||||||
.setBody(body);
|
.setBody(body);
|
||||||
|
|
||||||
var sessionToken = getOrCreateSession(null);
|
var sessionToken = getOrCreateSession(args, ctx);
|
||||||
|
var protoToken = RequestConstructor.createObjectTokenContext(
|
||||||
sessionToken = RequestConstructor.createObjectTokenContext(
|
|
||||||
sessionToken,
|
sessionToken,
|
||||||
address,
|
address,
|
||||||
frostfs.session.Types.ObjectSessionContext.Verb.GET,
|
frostfs.session.Types.ObjectSessionContext.Verb.GET,
|
||||||
getContext().getKey()
|
getContext().getKey()
|
||||||
);
|
);
|
||||||
|
|
||||||
RequestConstructor.addMetaHeader(request, null, sessionToken);
|
RequestConstructor.addMetaHeader(request, args.getXHeaders(), protoToken);
|
||||||
sign(request, getContext().getKey());
|
sign(request, getContext().getKey());
|
||||||
|
|
||||||
return request.build();
|
return request.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Service.DeleteRequest createDeleteRequest(Types.ContainerID cid, Types.ObjectID oid) {
|
private Service.DeleteRequest createDeleteRequest(PrmObjectDelete args, CallContext ctx) {
|
||||||
var address = Types.Address.newBuilder()
|
var address = Types.Address.newBuilder()
|
||||||
.setContainerId(cid)
|
.setContainerId(ContainerIdMapper.toGrpcMessage(args.getContainerId()))
|
||||||
.setObjectId(oid)
|
.setObjectId(ObjectIdMapper.toGrpcMessage(args.getObjectId()))
|
||||||
.build();
|
.build();
|
||||||
var body = Service.DeleteRequest.Body.newBuilder()
|
var body = Service.DeleteRequest.Body.newBuilder()
|
||||||
.setAddress(address)
|
.setAddress(address)
|
||||||
|
@ -408,22 +407,23 @@ public class ObjectClientImpl extends ContextAccessor implements ObjectClient {
|
||||||
var request = Service.DeleteRequest.newBuilder()
|
var request = Service.DeleteRequest.newBuilder()
|
||||||
.setBody(body);
|
.setBody(body);
|
||||||
|
|
||||||
var sessionToken = getOrCreateSession(null);
|
var sessionToken = getOrCreateSession(args, ctx);
|
||||||
|
var protoToken = RequestConstructor.createObjectTokenContext(
|
||||||
sessionToken = RequestConstructor.createObjectTokenContext(
|
|
||||||
sessionToken,
|
sessionToken,
|
||||||
address,
|
address,
|
||||||
frostfs.session.Types.ObjectSessionContext.Verb.DELETE,
|
frostfs.session.Types.ObjectSessionContext.Verb.DELETE,
|
||||||
getContext().getKey()
|
getContext().getKey()
|
||||||
);
|
);
|
||||||
|
|
||||||
RequestConstructor.addMetaHeader(request, null, sessionToken);
|
RequestConstructor.addMetaHeader(request, args.getXHeaders(), protoToken);
|
||||||
sign(request, getContext().getKey());
|
sign(request, getContext().getKey());
|
||||||
|
|
||||||
return request.build();
|
return request.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Service.SearchRequest createSearchRequest(Types.ContainerID cid, ObjectFilter<?>... filters) {
|
private Service.SearchRequest createSearchRequest(PrmObjectSearch args, CallContext ctx) {
|
||||||
|
var cid = ContainerIdMapper.toGrpcMessage(args.getContainerId());
|
||||||
|
|
||||||
var address = Types.Address.newBuilder()
|
var address = Types.Address.newBuilder()
|
||||||
.setContainerId(cid)
|
.setContainerId(cid)
|
||||||
.build();
|
.build();
|
||||||
|
@ -432,29 +432,31 @@ public class ObjectClientImpl extends ContextAccessor implements ObjectClient {
|
||||||
.setContainerId(cid)
|
.setContainerId(cid)
|
||||||
.setVersion(1);// TODO: clarify this param
|
.setVersion(1);// TODO: clarify this param
|
||||||
|
|
||||||
for (ObjectFilter<?> filter : filters) {
|
for (ObjectFilter<?> filter : args.getFilters()) {
|
||||||
body.addFilters(ObjectFilterMapper.toGrpcMessage(filter));
|
body.addFilters(ObjectFilterMapper.toGrpcMessage(filter));
|
||||||
}
|
}
|
||||||
|
|
||||||
var request = Service.SearchRequest.newBuilder()
|
var request = Service.SearchRequest.newBuilder()
|
||||||
.setBody(body.build());
|
.setBody(body.build());
|
||||||
|
|
||||||
var sessionToken = getOrCreateSession(null);
|
var sessionToken = getOrCreateSession(args, ctx);
|
||||||
|
var protoToken = RequestConstructor.createObjectTokenContext(
|
||||||
sessionToken = RequestConstructor.createObjectTokenContext(
|
|
||||||
sessionToken,
|
sessionToken,
|
||||||
address,
|
address,
|
||||||
frostfs.session.Types.ObjectSessionContext.Verb.SEARCH,
|
frostfs.session.Types.ObjectSessionContext.Verb.SEARCH,
|
||||||
getContext().getKey()
|
getContext().getKey()
|
||||||
);
|
);
|
||||||
|
|
||||||
RequestConstructor.addMetaHeader(request, null, sessionToken);
|
RequestConstructor.addMetaHeader(request, args.getXHeaders(), protoToken);
|
||||||
sign(request, getContext().getKey());
|
sign(request, getContext().getKey());
|
||||||
|
|
||||||
return request.build();
|
return request.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Service.PutRequest createInitPutRequest(Types.ObjectID oid, frostfs.object.Types.Header header) {
|
private Service.PutRequest createInitPutRequest(Types.ObjectID oid,
|
||||||
|
frostfs.object.Types.Header header,
|
||||||
|
PrmObjectPutBase args,
|
||||||
|
CallContext ctx) {
|
||||||
var address = Types.Address.newBuilder()
|
var address = Types.Address.newBuilder()
|
||||||
.setContainerId(header.getContainerId())
|
.setContainerId(header.getContainerId())
|
||||||
.setObjectId(oid)
|
.setObjectId(oid)
|
||||||
|
@ -468,22 +470,23 @@ public class ObjectClientImpl extends ContextAccessor implements ObjectClient {
|
||||||
var request = Service.PutRequest.newBuilder()
|
var request = Service.PutRequest.newBuilder()
|
||||||
.setBody(body);
|
.setBody(body);
|
||||||
|
|
||||||
var sessionToken = getOrCreateSession(null);
|
var sessionToken = getOrCreateSession(args, ctx);
|
||||||
|
var protoToken = RequestConstructor.createObjectTokenContext(
|
||||||
sessionToken = RequestConstructor.createObjectTokenContext(
|
|
||||||
sessionToken,
|
sessionToken,
|
||||||
address,
|
address,
|
||||||
frostfs.session.Types.ObjectSessionContext.Verb.PUT,
|
frostfs.session.Types.ObjectSessionContext.Verb.PUT,
|
||||||
getContext().getKey()
|
getContext().getKey()
|
||||||
);
|
);
|
||||||
|
|
||||||
RequestConstructor.addMetaHeader(request, null, sessionToken);
|
RequestConstructor.addMetaHeader(request, args.getXHeaders(), protoToken);
|
||||||
sign(request, getContext().getKey());
|
sign(request, getContext().getKey());
|
||||||
|
|
||||||
return request.build();
|
return request.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Service.PutSingleRequest createPutSingleRequest(frostfs.object.Types.Object grpcObject) {
|
private Service.PutSingleRequest createPutSingleRequest(frostfs.object.Types.Object grpcObject,
|
||||||
|
PrmObjectSinglePut args,
|
||||||
|
CallContext ctx) {
|
||||||
var address = Types.Address.newBuilder()
|
var address = Types.Address.newBuilder()
|
||||||
.setContainerId(grpcObject.getHeader().getContainerId())
|
.setContainerId(grpcObject.getHeader().getContainerId())
|
||||||
.setObjectId(grpcObject.getObjectId())
|
.setObjectId(grpcObject.getObjectId())
|
||||||
|
@ -494,16 +497,15 @@ public class ObjectClientImpl extends ContextAccessor implements ObjectClient {
|
||||||
var request = Service.PutSingleRequest.newBuilder()
|
var request = Service.PutSingleRequest.newBuilder()
|
||||||
.setBody(body);
|
.setBody(body);
|
||||||
|
|
||||||
var sessionToken = getOrCreateSession(null);
|
var sessionToken = getOrCreateSession(args, ctx);
|
||||||
|
var protoToken = RequestConstructor.createObjectTokenContext(
|
||||||
sessionToken = RequestConstructor.createObjectTokenContext(
|
|
||||||
sessionToken,
|
sessionToken,
|
||||||
address,
|
address,
|
||||||
frostfs.session.Types.ObjectSessionContext.Verb.PUT,
|
frostfs.session.Types.ObjectSessionContext.Verb.PUT,
|
||||||
getContext().getKey()
|
getContext().getKey()
|
||||||
);
|
);
|
||||||
|
|
||||||
RequestConstructor.addMetaHeader(request, null, sessionToken);
|
RequestConstructor.addMetaHeader(request, args.getXHeaders(), protoToken);
|
||||||
sign(request, getContext().getKey());
|
sign(request, getContext().getKey());
|
||||||
|
|
||||||
return request.build();
|
return request.build();
|
||||||
|
|
|
@ -5,6 +5,8 @@ import frostfs.session.SessionServiceGrpc;
|
||||||
import frostfs.session.Types;
|
import frostfs.session.Types;
|
||||||
import info.frostfs.sdk.dto.session.SessionToken;
|
import info.frostfs.sdk.dto.session.SessionToken;
|
||||||
import info.frostfs.sdk.jdo.ClientEnvironment;
|
import info.frostfs.sdk.jdo.ClientEnvironment;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.CallContext;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.session.PrmSessionCreate;
|
||||||
import info.frostfs.sdk.mappers.object.OwnerIdMapper;
|
import info.frostfs.sdk.mappers.object.OwnerIdMapper;
|
||||||
import info.frostfs.sdk.mappers.session.SessionMapper;
|
import info.frostfs.sdk.mappers.session.SessionMapper;
|
||||||
import info.frostfs.sdk.services.ContextAccessor;
|
import info.frostfs.sdk.services.ContextAccessor;
|
||||||
|
@ -13,6 +15,7 @@ import info.frostfs.sdk.tools.RequestConstructor;
|
||||||
import info.frostfs.sdk.tools.Verifier;
|
import info.frostfs.sdk.tools.Verifier;
|
||||||
|
|
||||||
import static info.frostfs.sdk.tools.RequestSigner.sign;
|
import static info.frostfs.sdk.tools.RequestSigner.sign;
|
||||||
|
import static info.frostfs.sdk.utils.DeadLineUtil.deadLineAfter;
|
||||||
|
|
||||||
public class SessionClientImpl extends ContextAccessor implements SessionClient {
|
public class SessionClientImpl extends ContextAccessor implements SessionClient {
|
||||||
private final SessionServiceGrpc.SessionServiceBlockingStub serviceBlockingStub;
|
private final SessionServiceGrpc.SessionServiceBlockingStub serviceBlockingStub;
|
||||||
|
@ -23,16 +26,16 @@ public class SessionClientImpl extends ContextAccessor implements SessionClient
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SessionToken createSession(long expiration) {
|
public SessionToken createSession(PrmSessionCreate args, CallContext ctx) {
|
||||||
var sessionToken = createSessionInternal(expiration);
|
var sessionToken = createSessionInternal(args, ctx);
|
||||||
var token = SessionMapper.serialize(sessionToken);
|
var token = SessionMapper.serialize(sessionToken);
|
||||||
return new SessionToken(token);
|
return new SessionToken(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Types.SessionToken createSessionInternal(long expiration) {
|
public Types.SessionToken createSessionInternal(PrmSessionCreate args, CallContext ctx) {
|
||||||
var body = Service.CreateRequest.Body.newBuilder()
|
var body = Service.CreateRequest.Body.newBuilder()
|
||||||
.setOwnerId(OwnerIdMapper.toGrpcMessage(getContext().getOwnerId()))
|
.setOwnerId(OwnerIdMapper.toGrpcMessage(getContext().getOwnerId()))
|
||||||
.setExpiration(expiration)
|
.setExpiration(args.getExpiration())
|
||||||
.build();
|
.build();
|
||||||
var request = Service.CreateRequest.newBuilder()
|
var request = Service.CreateRequest.newBuilder()
|
||||||
.setBody(body);
|
.setBody(body);
|
||||||
|
@ -40,11 +43,12 @@ public class SessionClientImpl extends ContextAccessor implements SessionClient
|
||||||
RequestConstructor.addMetaHeader(request);
|
RequestConstructor.addMetaHeader(request);
|
||||||
sign(request, getContext().getKey());
|
sign(request, getContext().getKey());
|
||||||
|
|
||||||
return createSession(request.build());
|
return createSession(request.build(), ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Types.SessionToken createSession(Service.CreateRequest request) {
|
private Types.SessionToken createSession(Service.CreateRequest request, CallContext ctx) {
|
||||||
var response = serviceBlockingStub.create(request);
|
var service = deadLineAfter(serviceBlockingStub, ctx.getTimeout(), ctx.getTimeUnit());
|
||||||
|
var response = service.create(request);
|
||||||
|
|
||||||
Verifier.checkResponse(response);
|
Verifier.checkResponse(response);
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
package info.frostfs.sdk.services.impl;
|
package info.frostfs.sdk.services.impl;
|
||||||
|
|
||||||
import frostfs.session.Types;
|
|
||||||
import info.frostfs.sdk.dto.session.SessionToken;
|
import info.frostfs.sdk.dto.session.SessionToken;
|
||||||
|
import info.frostfs.sdk.exceptions.FrostFSException;
|
||||||
import info.frostfs.sdk.jdo.ClientEnvironment;
|
import info.frostfs.sdk.jdo.ClientEnvironment;
|
||||||
import info.frostfs.sdk.mappers.session.SessionMapper;
|
import info.frostfs.sdk.jdo.parameters.CallContext;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.session.PrmSessionCreate;
|
||||||
import info.frostfs.sdk.services.ContextAccessor;
|
import info.frostfs.sdk.services.ContextAccessor;
|
||||||
import info.frostfs.sdk.services.SessionTools;
|
import info.frostfs.sdk.services.SessionTools;
|
||||||
|
|
||||||
|
import static info.frostfs.sdk.constants.ErrorConst.SESSION_CREATE_FAILED;
|
||||||
import static java.util.Objects.isNull;
|
import static java.util.Objects.isNull;
|
||||||
|
|
||||||
public class SessionToolsImpl extends ContextAccessor implements SessionTools {
|
public class SessionToolsImpl extends ContextAccessor implements SessionTools {
|
||||||
|
@ -16,11 +18,18 @@ public class SessionToolsImpl extends ContextAccessor implements SessionTools {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Types.SessionToken getOrCreateSession(SessionToken sessionToken, ClientEnvironment env) {
|
public SessionToken getOrCreateSession(ClientEnvironment env, CallContext ctx) {
|
||||||
if (isNull(sessionToken)) {
|
var token = env.getSessionCache().tryGetValue(env.getSessionKey());
|
||||||
return env.getFrostFSClient().createSessionInternal(-1);
|
|
||||||
|
if (isNull(token)) {
|
||||||
|
token = env.getFrostFSClient().createSession(new PrmSessionCreate(-1), ctx);
|
||||||
|
if (isNull(token)) {
|
||||||
|
throw new FrostFSException(SESSION_CREATE_FAILED);
|
||||||
|
}
|
||||||
|
|
||||||
|
env.getSessionCache().setValue(env.getSessionKey(), token);
|
||||||
}
|
}
|
||||||
|
|
||||||
return SessionMapper.deserializeSessionToken(sessionToken.getToken());
|
return token;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,18 +2,21 @@ package info.frostfs.sdk.services.impl.interceptor;
|
||||||
|
|
||||||
|
|
||||||
import io.prometheus.client.CollectorRegistry;
|
import io.prometheus.client.CollectorRegistry;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class Configuration {
|
public class Configuration {
|
||||||
private static final double[] DEFAULT_LATENCY_BUCKETS =
|
private static final double[] DEFAULT_LATENCY_BUCKETS =
|
||||||
new double[] {.001, .005, .01, .05, 0.075, .1, .25, .5, 1, 2, 5, 10};
|
new double[]{.001, .005, .01, .05, 0.075, .1, .25, .5, 1, 2, 5, 10};
|
||||||
|
|
||||||
private final boolean isIncludeLatencyHistograms;
|
private final boolean isIncludeLatencyHistograms;
|
||||||
private final CollectorRegistry collectorRegistry;
|
private final CollectorRegistry collectorRegistry;
|
||||||
private final double[] latencyBuckets;
|
private final double[] latencyBuckets;
|
||||||
private final List<String> labelHeaders;
|
private final List<String> labelHeaders;
|
||||||
private final boolean isAddCodeLabelToHistograms;
|
private final boolean isAddCodeLabelToHistograms;
|
||||||
|
|
||||||
private Configuration(
|
private Configuration(
|
||||||
boolean isIncludeLatencyHistograms,
|
boolean isIncludeLatencyHistograms,
|
||||||
CollectorRegistry collectorRegistry,
|
CollectorRegistry collectorRegistry,
|
||||||
|
@ -28,7 +31,9 @@ public class Configuration {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Returns a {@link Configuration} for recording all cheap metrics about the rpcs. */
|
/**
|
||||||
|
* Returns a {@link Configuration} for recording all cheap metrics about the rpcs.
|
||||||
|
*/
|
||||||
public static Configuration cheapMetricsOnly() {
|
public static Configuration cheapMetricsOnly() {
|
||||||
return new Configuration(
|
return new Configuration(
|
||||||
false /* isIncludeLatencyHistograms */,
|
false /* isIncludeLatencyHistograms */,
|
||||||
|
@ -119,27 +124,37 @@ public class Configuration {
|
||||||
true /* isAddCodeLabelToHistograms */);
|
true /* isAddCodeLabelToHistograms */);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns whether or not latency histograms for calls should be included. */
|
/**
|
||||||
|
* Returns whether or not latency histograms for calls should be included.
|
||||||
|
*/
|
||||||
public boolean isIncludeLatencyHistograms() {
|
public boolean isIncludeLatencyHistograms() {
|
||||||
return isIncludeLatencyHistograms;
|
return isIncludeLatencyHistograms;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the {@link CollectorRegistry} used to record stats. */
|
/**
|
||||||
|
* Returns the {@link CollectorRegistry} used to record stats.
|
||||||
|
*/
|
||||||
public CollectorRegistry getCollectorRegistry() {
|
public CollectorRegistry getCollectorRegistry() {
|
||||||
return collectorRegistry;
|
return collectorRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the histogram buckets to use for latency metrics. */
|
/**
|
||||||
|
* Returns the histogram buckets to use for latency metrics.
|
||||||
|
*/
|
||||||
public double[] getLatencyBuckets() {
|
public double[] getLatencyBuckets() {
|
||||||
return latencyBuckets;
|
return latencyBuckets;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the configured list of headers to be used as labels. */
|
/**
|
||||||
|
* Returns the configured list of headers to be used as labels.
|
||||||
|
*/
|
||||||
public List<String> getLabelHeaders() {
|
public List<String> getLabelHeaders() {
|
||||||
return labelHeaders;
|
return labelHeaders;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns whether or not status code label should be added to latency histogram. */
|
/**
|
||||||
|
* Returns whether or not status code label should be added to latency histogram.
|
||||||
|
*/
|
||||||
public boolean isAddCodeLabelToHistograms() {
|
public boolean isAddCodeLabelToHistograms() {
|
||||||
return isAddCodeLabelToHistograms;
|
return isAddCodeLabelToHistograms;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
package info.frostfs.sdk.services.impl.rwhelper;
|
||||||
|
|
||||||
|
import frostfs.object.ObjectServiceGrpc;
|
||||||
|
import frostfs.object.Service;
|
||||||
|
import info.frostfs.sdk.exceptions.ProcessFrostFSException;
|
||||||
|
import info.frostfs.sdk.utils.WaitUtil;
|
||||||
|
import io.grpc.stub.StreamObserver;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import static info.frostfs.sdk.constants.ErrorConst.PROTO_MESSAGE_IS_EMPTY_TEMPLATE;
|
||||||
|
import static java.util.Objects.isNull;
|
||||||
|
|
||||||
|
public class ObjectStreamer {
|
||||||
|
private static final long POLL_INTERVAL = 10;
|
||||||
|
private final StreamObserver<Service.PutRequest> requestObserver;
|
||||||
|
private final PutResponseCallback responseObserver;
|
||||||
|
|
||||||
|
public ObjectStreamer(ObjectServiceGrpc.ObjectServiceStub objectServiceStub) {
|
||||||
|
PutResponseCallback responseObserver = new PutResponseCallback();
|
||||||
|
|
||||||
|
this.responseObserver = responseObserver;
|
||||||
|
this.requestObserver = objectServiceStub.put(responseObserver);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(Service.PutRequest request) {
|
||||||
|
if (isNull(request)) {
|
||||||
|
throw new ProcessFrostFSException(
|
||||||
|
String.format(PROTO_MESSAGE_IS_EMPTY_TEMPLATE, Service.PutRequest.class.getName())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
requestObserver.onNext(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Service.PutResponse complete() {
|
||||||
|
requestObserver.onCompleted();
|
||||||
|
|
||||||
|
while (isNull(responseObserver.getResponse())) {
|
||||||
|
WaitUtil.sleep(POLL_INTERVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return responseObserver.getResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private static class PutResponseCallback implements StreamObserver<Service.PutResponse> {
|
||||||
|
private Service.PutResponse response;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNext(Service.PutResponse putResponse) {
|
||||||
|
this.response = putResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(Throwable throwable) {
|
||||||
|
throw new ProcessFrostFSException(throwable);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCompleted() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,63 +1,41 @@
|
||||||
package info.frostfs.sdk.services.impl.rwhelper;
|
package info.frostfs.sdk.services.impl.rwhelper;
|
||||||
|
|
||||||
import frostfs.object.ObjectServiceGrpc;
|
import com.google.protobuf.ByteString;
|
||||||
import frostfs.object.Service;
|
import frostfs.object.Service;
|
||||||
import info.frostfs.sdk.exceptions.ProcessFrostFSException;
|
import info.frostfs.sdk.dto.object.ObjectId;
|
||||||
import info.frostfs.sdk.utils.WaitUtil;
|
import info.frostfs.sdk.jdo.ClientEnvironment;
|
||||||
import io.grpc.stub.StreamObserver;
|
import info.frostfs.sdk.jdo.parameters.object.PrmObjectPutBase;
|
||||||
|
import info.frostfs.sdk.tools.Verifier;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
import static info.frostfs.sdk.constants.ErrorConst.PROTO_MESSAGE_IS_EMPTY_TEMPLATE;
|
import static info.frostfs.sdk.tools.RequestSigner.sign;
|
||||||
import static java.util.Objects.isNull;
|
|
||||||
|
|
||||||
|
//todo specify a deadline for each stream request, not for the entire stream
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
public class ObjectWriter {
|
public class ObjectWriter {
|
||||||
private static final long POLL_INTERVAL = 10;
|
private final ClientEnvironment environment;
|
||||||
private final StreamObserver<Service.PutRequest> requestObserver;
|
private final PrmObjectPutBase args;
|
||||||
private final PutResponseCallback responseObserver;
|
private final ObjectStreamer streamer;
|
||||||
|
|
||||||
public ObjectWriter(ObjectServiceGrpc.ObjectServiceStub objectServiceStub) {
|
public void write(byte[] buffer) {
|
||||||
PutResponseCallback responseObserver = new PutResponseCallback();
|
var body = Service.PutRequest.Body.newBuilder()
|
||||||
|
.setChunk(ByteString.copyFrom(buffer))
|
||||||
|
.build();
|
||||||
|
var chunkRequest = Service.PutRequest.newBuilder()
|
||||||
|
.setBody(body)
|
||||||
|
.clearVerifyHeader();
|
||||||
|
|
||||||
this.responseObserver = responseObserver;
|
sign(chunkRequest, environment.getKey());
|
||||||
this.requestObserver = objectServiceStub.put(responseObserver);
|
|
||||||
|
streamer.write(chunkRequest.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void write(Service.PutRequest request) {
|
public ObjectId complete() {
|
||||||
if (isNull(request)) {
|
var response = streamer.complete();
|
||||||
throw new ProcessFrostFSException(
|
Verifier.checkResponse(response);
|
||||||
String.format(PROTO_MESSAGE_IS_EMPTY_TEMPLATE, Service.PutRequest.class.getName())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
requestObserver.onNext(request);
|
return new ObjectId(response.getBody().getObjectId().getValue().toByteArray());
|
||||||
}
|
|
||||||
|
|
||||||
public Service.PutResponse complete() {
|
|
||||||
requestObserver.onCompleted();
|
|
||||||
|
|
||||||
while (isNull(responseObserver.getResponse())) {
|
|
||||||
WaitUtil.sleep(POLL_INTERVAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
return responseObserver.getResponse();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
private static class PutResponseCallback implements StreamObserver<Service.PutResponse> {
|
|
||||||
private Service.PutResponse response;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onNext(Service.PutResponse putResponse) {
|
|
||||||
this.response = putResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onError(Throwable throwable) {
|
|
||||||
throw new ProcessFrostFSException(throwable);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCompleted() {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,11 @@ 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.dto.response.MetaHeader;
|
import info.frostfs.sdk.dto.response.MetaHeader;
|
||||||
|
import info.frostfs.sdk.dto.session.SessionToken;
|
||||||
import info.frostfs.sdk.exceptions.ValidationFrostFSException;
|
import info.frostfs.sdk.exceptions.ValidationFrostFSException;
|
||||||
import info.frostfs.sdk.jdo.ECDsa;
|
import info.frostfs.sdk.jdo.ECDsa;
|
||||||
import info.frostfs.sdk.mappers.response.MetaHeaderMapper;
|
import info.frostfs.sdk.mappers.response.MetaHeaderMapper;
|
||||||
|
import info.frostfs.sdk.mappers.session.SessionMapper;
|
||||||
import org.apache.commons.collections4.MapUtils;
|
import org.apache.commons.collections4.MapUtils;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -65,13 +67,11 @@ public class RequestConstructor {
|
||||||
setField(request, META_HEADER_FIELD_NAME, metaHeader.build());
|
setField(request, META_HEADER_FIELD_NAME, metaHeader.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Types.SessionToken createObjectTokenContext(Types.SessionToken sessionToken,
|
public static Types.SessionToken createObjectTokenContext(SessionToken sessionToken,
|
||||||
frostfs.refs.Types.Address address,
|
frostfs.refs.Types.Address address,
|
||||||
Types.ObjectSessionContext.Verb verb,
|
Types.ObjectSessionContext.Verb verb,
|
||||||
ECDsa key) {
|
ECDsa key) {
|
||||||
if (isNull(sessionToken) || sessionToken.getBody().getObject().getTarget().getSerializedSize() > 0) {
|
var protoToken = SessionMapper.deserializeSessionToken(sessionToken.getToken());
|
||||||
return sessionToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
var target = Types.ObjectSessionContext.Target.newBuilder()
|
var target = Types.ObjectSessionContext.Target.newBuilder()
|
||||||
.setContainer(address.getContainerId());
|
.setContainer(address.getContainerId());
|
||||||
|
@ -84,25 +84,23 @@ public class RequestConstructor {
|
||||||
.setTarget(target.build())
|
.setTarget(target.build())
|
||||||
.setVerb(verb)
|
.setVerb(verb)
|
||||||
.build();
|
.build();
|
||||||
var body = sessionToken.getBody().toBuilder()
|
var body = protoToken.getBody().toBuilder()
|
||||||
.setObject(ctx)
|
.setObject(ctx)
|
||||||
.setSessionKey(ByteString.copyFrom(key.getPublicKeyByte()))
|
.setSessionKey(ByteString.copyFrom(key.getPublicKeyByte()))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
return sessionToken.toBuilder()
|
return protoToken.toBuilder()
|
||||||
.setSignature(signMessagePart(key, body))
|
.setSignature(signMessagePart(key, body))
|
||||||
.setBody(body)
|
.setBody(body)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Types.SessionToken createContainerTokenContext(Types.SessionToken sessionToken,
|
public static Types.SessionToken createContainerTokenContext(SessionToken sessionToken,
|
||||||
frostfs.refs.Types.ContainerID containerId,
|
frostfs.refs.Types.ContainerID containerId,
|
||||||
Types.ContainerSessionContext.Verb verb,
|
Types.ContainerSessionContext.Verb verb,
|
||||||
frostfs.refs.Types.OwnerID ownerId,
|
frostfs.refs.Types.OwnerID ownerId,
|
||||||
ECDsa key) {
|
ECDsa key) {
|
||||||
if (isNull(sessionToken) || sessionToken.getBody().getContainer().getContainerId().getSerializedSize() > 0) {
|
var protoToken = SessionMapper.deserializeSessionToken(sessionToken.getToken());
|
||||||
return sessionToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
var containerSession = Types.ContainerSessionContext.newBuilder().setVerb(verb);
|
var containerSession = Types.ContainerSessionContext.newBuilder().setVerb(verb);
|
||||||
|
|
||||||
|
@ -112,7 +110,7 @@ public class RequestConstructor {
|
||||||
containerSession.setContainerId(containerId);
|
containerSession.setContainerId(containerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
var bodyBuilder = sessionToken.getBody().toBuilder()
|
var bodyBuilder = protoToken.getBody().toBuilder()
|
||||||
.setContainer(containerSession)
|
.setContainer(containerSession)
|
||||||
.setSessionKey(ByteString.copyFrom(key.getPublicKeyByte()));
|
.setSessionKey(ByteString.copyFrom(key.getPublicKeyByte()));
|
||||||
|
|
||||||
|
@ -122,7 +120,7 @@ public class RequestConstructor {
|
||||||
|
|
||||||
var body = bodyBuilder.build();
|
var body = bodyBuilder.build();
|
||||||
|
|
||||||
return sessionToken.toBuilder()
|
return protoToken.toBuilder()
|
||||||
.setSignature(signMessagePart(key, body))
|
.setSignature(signMessagePart(key, body))
|
||||||
.setBody(body)
|
.setBody(body)
|
||||||
.build();
|
.build();
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
package info.frostfs.sdk.utils;
|
||||||
|
|
||||||
|
import info.frostfs.sdk.exceptions.ValidationFrostFSException;
|
||||||
|
import io.grpc.stub.AbstractStub;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import static info.frostfs.sdk.constants.ErrorConst.PARAM_IS_MISSING_TEMPLATE;
|
||||||
|
import static java.util.Objects.isNull;
|
||||||
|
|
||||||
|
public class DeadLineUtil {
|
||||||
|
private DeadLineUtil() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T extends AbstractStub<T>> T deadLineAfter(T stub, long deadLine, TimeUnit timeUnit) {
|
||||||
|
if (isNull(stub)) {
|
||||||
|
throw new ValidationFrostFSException(
|
||||||
|
String.format(PARAM_IS_MISSING_TEMPLATE, AbstractStub.class.getName())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
timeUnit = isNull(timeUnit) ? TimeUnit.MILLISECONDS : timeUnit;
|
||||||
|
return deadLine > 0 ? stub.withDeadlineAfter(deadLine, timeUnit) : stub;
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,6 +5,7 @@ import frostfs.accounting.Service;
|
||||||
import info.frostfs.sdk.Base58;
|
import info.frostfs.sdk.Base58;
|
||||||
import info.frostfs.sdk.dto.object.OwnerId;
|
import info.frostfs.sdk.dto.object.OwnerId;
|
||||||
import info.frostfs.sdk.jdo.ClientEnvironment;
|
import info.frostfs.sdk.jdo.ClientEnvironment;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.CallContext;
|
||||||
import info.frostfs.sdk.services.impl.AccountingClientImpl;
|
import info.frostfs.sdk.services.impl.AccountingClientImpl;
|
||||||
import info.frostfs.sdk.testgenerator.AccountingGenerator;
|
import info.frostfs.sdk.testgenerator.AccountingGenerator;
|
||||||
import info.frostfs.sdk.tools.RequestConstructor;
|
import info.frostfs.sdk.tools.RequestConstructor;
|
||||||
|
@ -81,11 +82,11 @@ class AccountingClientTest {
|
||||||
when(AccountingServiceClient.balance(captor.capture())).thenReturn(response);
|
when(AccountingServiceClient.balance(captor.capture())).thenReturn(response);
|
||||||
|
|
||||||
//When
|
//When
|
||||||
var result = accountingClient.getBalance();
|
var result = accountingClient.getBalance(new CallContext(0, null));
|
||||||
|
|
||||||
//Then
|
//Then
|
||||||
requestConstructorMock.verify(
|
requestConstructorMock.verify(
|
||||||
() -> RequestConstructor.addMetaHeader(any(Service.BalanceRequest.Builder.class), eq(null)),
|
() -> RequestConstructor.addMetaHeader(any(Service.BalanceRequest.Builder.class)),
|
||||||
times(1)
|
times(1)
|
||||||
);
|
);
|
||||||
requestSignerMock.verify(
|
requestSignerMock.verify(
|
||||||
|
|
|
@ -8,6 +8,10 @@ import info.frostfs.sdk.dto.chain.ChainTarget;
|
||||||
import info.frostfs.sdk.enums.TargetType;
|
import info.frostfs.sdk.enums.TargetType;
|
||||||
import info.frostfs.sdk.exceptions.ValidationFrostFSException;
|
import info.frostfs.sdk.exceptions.ValidationFrostFSException;
|
||||||
import info.frostfs.sdk.jdo.ClientEnvironment;
|
import info.frostfs.sdk.jdo.ClientEnvironment;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.CallContext;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.ape.PrmApeChainAdd;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.ape.PrmApeChainList;
|
||||||
|
import info.frostfs.sdk.jdo.parameters.ape.PrmApeChainRemove;
|
||||||
import info.frostfs.sdk.services.impl.ApeManagerClientImpl;
|
import info.frostfs.sdk.services.impl.ApeManagerClientImpl;
|
||||||
import info.frostfs.sdk.testgenerator.ApeManagerGenerator;
|
import info.frostfs.sdk.testgenerator.ApeManagerGenerator;
|
||||||
import info.frostfs.sdk.tools.RequestConstructor;
|
import info.frostfs.sdk.tools.RequestConstructor;
|
||||||
|
@ -78,6 +82,7 @@ class ApeManagerClientTest {
|
||||||
//Given
|
//Given
|
||||||
Chain chain = generateChain();
|
Chain chain = generateChain();
|
||||||
ChainTarget chainTarget = generateChainTarget();
|
ChainTarget chainTarget = generateChainTarget();
|
||||||
|
PrmApeChainAdd params = new PrmApeChainAdd(chain, chainTarget);
|
||||||
|
|
||||||
var response = ApeManagerGenerator.generateAddChainResponse();
|
var response = ApeManagerGenerator.generateAddChainResponse();
|
||||||
|
|
||||||
|
@ -86,7 +91,7 @@ class ApeManagerClientTest {
|
||||||
when(apeManagerServiceClient.addChain(captor.capture())).thenReturn(response);
|
when(apeManagerServiceClient.addChain(captor.capture())).thenReturn(response);
|
||||||
|
|
||||||
//When
|
//When
|
||||||
var result = apeManagerClient.addChain(chain, chainTarget);
|
var result = apeManagerClient.addChain(params, new CallContext(0, null));
|
||||||
|
|
||||||
//Then
|
//Then
|
||||||
requestConstructorMock.verify(
|
requestConstructorMock.verify(
|
||||||
|
@ -112,11 +117,15 @@ class ApeManagerClientTest {
|
||||||
//Given
|
//Given
|
||||||
Chain chain = generateChain();
|
Chain chain = generateChain();
|
||||||
ChainTarget chainTarget = generateChainTarget();
|
ChainTarget chainTarget = generateChainTarget();
|
||||||
|
PrmApeChainAdd params1 = new PrmApeChainAdd(null, chainTarget);
|
||||||
|
PrmApeChainAdd params2 = new PrmApeChainAdd(chain, null);
|
||||||
|
PrmApeChainAdd params3 = new PrmApeChainAdd(null, null);
|
||||||
|
|
||||||
|
|
||||||
//When + Then
|
//When + Then
|
||||||
assertThrows(ValidationFrostFSException.class, () -> apeManagerClient.addChain(null, chainTarget));
|
assertThrows(ValidationFrostFSException.class, () -> apeManagerClient.addChain(params1, new CallContext()));
|
||||||
assertThrows(ValidationFrostFSException.class, () -> apeManagerClient.addChain(chain, null));
|
assertThrows(ValidationFrostFSException.class, () -> apeManagerClient.addChain(params2, new CallContext()));
|
||||||
assertThrows(ValidationFrostFSException.class, () -> apeManagerClient.addChain(null, null));
|
assertThrows(ValidationFrostFSException.class, () -> apeManagerClient.addChain(params3, new CallContext()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -124,6 +133,7 @@ class ApeManagerClientTest {
|
||||||
//Given
|
//Given
|
||||||
Chain chain = generateChain();
|
Chain chain = generateChain();
|
||||||
ChainTarget chainTarget = generateChainTarget();
|
ChainTarget chainTarget = generateChainTarget();
|
||||||
|
PrmApeChainRemove params = new PrmApeChainRemove(chain, chainTarget);
|
||||||
|
|
||||||
var response = ApeManagerGenerator.generateRemoveChainResponse();
|
var response = ApeManagerGenerator.generateRemoveChainResponse();
|
||||||
|
|
||||||
|
@ -132,7 +142,7 @@ class ApeManagerClientTest {
|
||||||
when(apeManagerServiceClient.removeChain(captor.capture())).thenReturn(response);
|
when(apeManagerServiceClient.removeChain(captor.capture())).thenReturn(response);
|
||||||
|
|
||||||
//When
|
//When
|
||||||
apeManagerClient.removeChain(chain, chainTarget);
|
apeManagerClient.removeChain(params, new CallContext(0, null));
|
||||||
|
|
||||||
//Then
|
//Then
|
||||||
requestConstructorMock.verify(
|
requestConstructorMock.verify(
|
||||||
|
@ -156,17 +166,21 @@ class ApeManagerClientTest {
|
||||||
//Given
|
//Given
|
||||||
Chain chain = generateChain();
|
Chain chain = generateChain();
|
||||||
ChainTarget chainTarget = generateChainTarget();
|
ChainTarget chainTarget = generateChainTarget();
|
||||||
|
PrmApeChainRemove params1 = new PrmApeChainRemove(null, chainTarget);
|
||||||
|
PrmApeChainRemove params2 = new PrmApeChainRemove(chain, null);
|
||||||
|
PrmApeChainRemove params3 = new PrmApeChainRemove(null, null);
|
||||||
|
|
||||||
//When + Then
|
//When + Then
|
||||||
assertThrows(ValidationFrostFSException.class, () -> apeManagerClient.removeChain(null, chainTarget));
|
assertThrows(ValidationFrostFSException.class, () -> apeManagerClient.removeChain(params1, new CallContext()));
|
||||||
assertThrows(ValidationFrostFSException.class, () -> apeManagerClient.removeChain(chain, null));
|
assertThrows(ValidationFrostFSException.class, () -> apeManagerClient.removeChain(params2, new CallContext()));
|
||||||
assertThrows(ValidationFrostFSException.class, () -> apeManagerClient.removeChain(null, null));
|
assertThrows(ValidationFrostFSException.class, () -> apeManagerClient.removeChain(params3, new CallContext()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void listChain_success() {
|
void listChain_success() {
|
||||||
//Given
|
//Given
|
||||||
ChainTarget chainTarget = generateChainTarget();
|
ChainTarget chainTarget = generateChainTarget();
|
||||||
|
PrmApeChainList params = new PrmApeChainList(chainTarget);
|
||||||
|
|
||||||
var response = ApeManagerGenerator.generateListChainsResponse();
|
var response = ApeManagerGenerator.generateListChainsResponse();
|
||||||
|
|
||||||
|
@ -175,7 +189,7 @@ class ApeManagerClientTest {
|
||||||
when(apeManagerServiceClient.listChains(captor.capture())).thenReturn(response);
|
when(apeManagerServiceClient.listChains(captor.capture())).thenReturn(response);
|
||||||
|
|
||||||
//When
|
//When
|
||||||
var result = apeManagerClient.listChains(chainTarget);
|
var result = apeManagerClient.listChains(params, new CallContext(0, null));
|
||||||
|
|
||||||
//Then
|
//Then
|
||||||
requestConstructorMock.verify(
|
requestConstructorMock.verify(
|
||||||
|
@ -202,7 +216,8 @@ class ApeManagerClientTest {
|
||||||
@Test
|
@Test
|
||||||
void listChain_wrongParams() {
|
void listChain_wrongParams() {
|
||||||
//When + Then
|
//When + Then
|
||||||
assertThrows(ValidationFrostFSException.class, () -> apeManagerClient.listChains(null));
|
assertThrows(ValidationFrostFSException.class,
|
||||||
|
() -> apeManagerClient.listChains(new PrmApeChainList(null), new CallContext()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Chain generateChain() {
|
private Chain generateChain() {
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>info.frostfs.sdk</groupId>
|
<groupId>info.frostfs.sdk</groupId>
|
||||||
<artifactId>frostfs-sdk-java</artifactId>
|
<artifactId>frostfs-sdk-java</artifactId>
|
||||||
<version>0.2.0</version>
|
<version>0.3.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>cryptography</artifactId>
|
<artifactId>cryptography</artifactId>
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>info.frostfs.sdk</groupId>
|
<groupId>info.frostfs.sdk</groupId>
|
||||||
<artifactId>exceptions</artifactId>
|
<artifactId>exceptions</artifactId>
|
||||||
<version>0.2.0</version>
|
<version>0.3.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.protobuf</groupId>
|
<groupId>com.google.protobuf</groupId>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>info.frostfs.sdk</groupId>
|
<groupId>info.frostfs.sdk</groupId>
|
||||||
<artifactId>frostfs-sdk-java</artifactId>
|
<artifactId>frostfs-sdk-java</artifactId>
|
||||||
<version>0.2.0</version>
|
<version>0.3.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>exceptions</artifactId>
|
<artifactId>exceptions</artifactId>
|
||||||
|
|
|
@ -46,6 +46,8 @@ public class ErrorConst {
|
||||||
public static final String POOL_CLIENTS_UNHEALTHY = "cannot find alive client";
|
public static final String POOL_CLIENTS_UNHEALTHY = "cannot find alive client";
|
||||||
public static final String POOL_NOT_DIALED = "pool not dialed";
|
public static final String POOL_NOT_DIALED = "pool not dialed";
|
||||||
|
|
||||||
|
public static final String SESSION_CREATE_FAILED = "cannot create session";
|
||||||
|
|
||||||
public static final String FIELDS_DELIMITER_COMMA = ", ";
|
public static final String FIELDS_DELIMITER_COMMA = ", ";
|
||||||
public static final String FIELDS_DELIMITER_OR = " or ";
|
public static final String FIELDS_DELIMITER_OR = " or ";
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>info.frostfs.sdk</groupId>
|
<groupId>info.frostfs.sdk</groupId>
|
||||||
<artifactId>frostfs-sdk-java</artifactId>
|
<artifactId>frostfs-sdk-java</artifactId>
|
||||||
<version>0.2.0</version>
|
<version>0.3.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>models</artifactId>
|
<artifactId>models</artifactId>
|
||||||
|
@ -21,17 +21,17 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>info.frostfs.sdk</groupId>
|
<groupId>info.frostfs.sdk</groupId>
|
||||||
<artifactId>cryptography</artifactId>
|
<artifactId>cryptography</artifactId>
|
||||||
<version>0.2.0</version>
|
<version>0.3.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>info.frostfs.sdk</groupId>
|
<groupId>info.frostfs.sdk</groupId>
|
||||||
<artifactId>protos</artifactId>
|
<artifactId>protos</artifactId>
|
||||||
<version>0.2.0</version>
|
<version>0.3.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>info.frostfs.sdk</groupId>
|
<groupId>info.frostfs.sdk</groupId>
|
||||||
<artifactId>exceptions</artifactId>
|
<artifactId>exceptions</artifactId>
|
||||||
<version>0.2.0</version>
|
<version>0.3.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ public class AppConst {
|
||||||
public static final int OBJECT_CHUNK_SIZE = 3 * MIB;
|
public static final int OBJECT_CHUNK_SIZE = 3 * MIB;
|
||||||
public static final int SHA256_HASH_LENGTH = 32;
|
public static final int SHA256_HASH_LENGTH = 32;
|
||||||
public static final int UUID_BYTE_ARRAY_LENGTH = 16;
|
public static final int UUID_BYTE_ARRAY_LENGTH = 16;
|
||||||
|
public static final int DEFAULT_GRPC_TIMEOUT = 5;
|
||||||
|
|
||||||
private AppConst() {
|
private AppConst() {
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
package info.frostfs.sdk.dto.object;
|
||||||
|
|
||||||
|
import frostfs.object.Types;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class SplitInfo {
|
||||||
|
private final Types.SplitInfo splitInfo;
|
||||||
|
|
||||||
|
private final SplitId splitId;
|
||||||
|
|
||||||
|
private final ObjectId link;
|
||||||
|
|
||||||
|
private final ObjectId lastPart;
|
||||||
|
}
|
|
@ -13,7 +13,6 @@ import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static info.frostfs.sdk.UuidExtension.asBytes;
|
import static info.frostfs.sdk.UuidExtension.asBytes;
|
||||||
import static info.frostfs.sdk.UuidExtension.asUuid;
|
import static info.frostfs.sdk.UuidExtension.asUuid;
|
||||||
import static info.frostfs.sdk.constants.AttributeConst.DISABLE_HOMOMORPHIC_HASHING_ATTRIBUTE;
|
|
||||||
import static info.frostfs.sdk.constants.ErrorConst.UNKNOWN_ENUM_VALUE_TEMPLATE;
|
import static info.frostfs.sdk.constants.ErrorConst.UNKNOWN_ENUM_VALUE_TEMPLATE;
|
||||||
import static java.util.Objects.isNull;
|
import static java.util.Objects.isNull;
|
||||||
|
|
||||||
|
@ -31,7 +30,6 @@ public class ContainerMapper {
|
||||||
.setPlacementPolicy(PlacementPolicyMapper.toGrpcMessage(container.getPlacementPolicy()))
|
.setPlacementPolicy(PlacementPolicyMapper.toGrpcMessage(container.getPlacementPolicy()))
|
||||||
.setNonce(ByteString.copyFrom(asBytes(container.getNonce())));
|
.setNonce(ByteString.copyFrom(asBytes(container.getNonce())));
|
||||||
|
|
||||||
container.getAttributes().putIfAbsent(DISABLE_HOMOMORPHIC_HASHING_ATTRIBUTE, Boolean.TRUE.toString());
|
|
||||||
var attributes = container.getAttributes().entrySet().stream()
|
var attributes = container.getAttributes().entrySet().stream()
|
||||||
.map(entry ->
|
.map(entry ->
|
||||||
Types.Container.Attribute.newBuilder()
|
Types.Container.Attribute.newBuilder()
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
package info.frostfs.sdk.mappers.object;
|
||||||
|
|
||||||
|
import frostfs.object.Types;
|
||||||
|
import info.frostfs.sdk.dto.object.ObjectId;
|
||||||
|
import info.frostfs.sdk.dto.object.SplitId;
|
||||||
|
import info.frostfs.sdk.dto.object.SplitInfo;
|
||||||
|
|
||||||
|
import static info.frostfs.sdk.UuidExtension.asUuid;
|
||||||
|
import static java.util.Objects.isNull;
|
||||||
|
|
||||||
|
public class SplitInfoMapper {
|
||||||
|
private SplitInfoMapper() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SplitInfo toModel(Types.SplitInfo splitInfo) {
|
||||||
|
if (isNull(splitInfo) || splitInfo.getSerializedSize() == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var splitId = new SplitId(asUuid(splitInfo.getSplitId().toByteArray()));
|
||||||
|
var link = splitInfo.getLink().getSerializedSize() == 0
|
||||||
|
? null
|
||||||
|
: new ObjectId(splitInfo.getLink().getValue().toByteArray());
|
||||||
|
var lastPart = splitInfo.getLastPart().getSerializedSize() == 0
|
||||||
|
? null
|
||||||
|
: new ObjectId(splitInfo.getLastPart().getValue().toByteArray());
|
||||||
|
|
||||||
|
return new SplitInfo(splitInfo, splitId, link, lastPart);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
package info.frostfs.sdk.mappers.object;
|
||||||
|
|
||||||
|
import com.google.protobuf.ByteString;
|
||||||
|
import frostfs.object.Types;
|
||||||
|
import info.frostfs.sdk.dto.object.ObjectId;
|
||||||
|
import info.frostfs.sdk.dto.object.SplitId;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
public class SplitInfoMapperTest {
|
||||||
|
@Test
|
||||||
|
void toModel_successLastPart() {
|
||||||
|
//Given
|
||||||
|
var splitId = new SplitId();
|
||||||
|
var objectId = new ObjectId("85orCLKSu3X1jGiTFmwmTUsBU88RBARNwuRwrEy5pyww");
|
||||||
|
var splitInfo = Types.SplitInfo.newBuilder()
|
||||||
|
.setSplitId(ByteString.copyFrom(splitId.toBinary()))
|
||||||
|
.setLastPart(ObjectIdMapper.toGrpcMessage(objectId))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
//When
|
||||||
|
var result = SplitInfoMapper.toModel(splitInfo);
|
||||||
|
|
||||||
|
//Then
|
||||||
|
assertNotNull(result);
|
||||||
|
assertNull(result.getLink());
|
||||||
|
assertThat(result.getSplitInfo()).isEqualTo(splitInfo);
|
||||||
|
assertThat(result.getSplitId().toBinary()).containsExactly(splitId.toBinary());
|
||||||
|
assertEquals(objectId.getValue(), result.getLastPart().getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void toModel_successLink() {
|
||||||
|
//Given
|
||||||
|
var splitId = new SplitId();
|
||||||
|
var objectId = new ObjectId("85orCLKSu3X1jGiTFmwmTUsBU88RBARNwuRwrEy5pyww");
|
||||||
|
var splitInfo = Types.SplitInfo.newBuilder()
|
||||||
|
.setSplitId(ByteString.copyFrom(splitId.toBinary()))
|
||||||
|
.setLink(ObjectIdMapper.toGrpcMessage(objectId))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
//When
|
||||||
|
var result = SplitInfoMapper.toModel(splitInfo);
|
||||||
|
|
||||||
|
//Then
|
||||||
|
assertNotNull(result);
|
||||||
|
assertNull(result.getLastPart());
|
||||||
|
assertThat(result.getSplitInfo()).isEqualTo(splitInfo);
|
||||||
|
assertThat(result.getSplitId().toBinary()).containsExactly(splitId.toBinary());
|
||||||
|
assertEquals(objectId.getValue(), result.getLink().getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void toModel_null() {
|
||||||
|
//When + Then
|
||||||
|
assertNull(SplitInfoMapper.toModel(null));
|
||||||
|
assertNull(SplitInfoMapper.toModel(Types.SplitInfo.getDefaultInstance()));
|
||||||
|
}
|
||||||
|
}
|
2
pom.xml
2
pom.xml
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
<groupId>info.frostfs.sdk</groupId>
|
<groupId>info.frostfs.sdk</groupId>
|
||||||
<artifactId>frostfs-sdk-java</artifactId>
|
<artifactId>frostfs-sdk-java</artifactId>
|
||||||
<version>0.2.0</version>
|
<version>0.3.0</version>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
<modules>
|
<modules>
|
||||||
<module>client</module>
|
<module>client</module>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>info.frostfs.sdk</groupId>
|
<groupId>info.frostfs.sdk</groupId>
|
||||||
<artifactId>frostfs-sdk-java</artifactId>
|
<artifactId>frostfs-sdk-java</artifactId>
|
||||||
<version>0.2.0</version>
|
<version>0.3.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>protos</artifactId>
|
<artifactId>protos</artifactId>
|
||||||
|
|
Loading…
Add table
Reference in a new issue
There are several disadvantages to using Lombok’s @EqualsAndHashCode annotation. First, it can generate unwanted hash code collisions when two objects have different field values but the same hash code.
Second, it may not be compatible with other libraries and frameworks that rely on traditional implementations of equals() and hashCode().
Lastly, it can reduce readability by generating methods that aren’t explicitly defined in the class, making it more difficult to understand the logic of the code.
Unfortunately, a collision cannot be avoided in principle, since the hash code is int and due to the birthday problem we only need 77,163 objects before we have a 50/50 chance of hashCode collision(lombok and Objects hashcode realization very similar, just different multiplier). But I agree about the second one, I’ll correct it.