From 1ccb1f2013fed7de92a2437cba968eaa36d5716b Mon Sep 17 00:00:00 2001 From: Ori Bruk Date: Thu, 23 Jan 2025 15:30:38 +0300 Subject: [PATCH] [#34] Provide input parameters for all grpc methods Signed-off-by: Ori Bruk --- README.md | 112 ++++-- client/pom.xml | 8 +- .../java/info/frostfs/sdk/FrostFSClient.java | 110 +++--- .../frostfs/sdk/jdo/ClientEnvironment.java | 30 +- .../frostfs/sdk/jdo/PutObjectParameters.java | 40 -- .../sdk/jdo/parameters/CallContext.java | 23 ++ .../PrmWait.java} | 6 +- .../jdo/parameters/ape/PrmApeChainAdd.java | 27 ++ .../jdo/parameters/ape/PrmApeChainList.java | 23 ++ .../jdo/parameters/ape/PrmApeChainRemove.java | 27 ++ .../container/PrmContainerCreate.java | 33 ++ .../container/PrmContainerDelete.java | 33 ++ .../parameters/container/PrmContainerGet.java | 23 ++ .../container/PrmContainerGetAll.java | 16 + .../object/PrmObjectClientCutPut.java | 28 ++ .../parameters/object/PrmObjectDelete.java | 30 ++ .../jdo/parameters/object/PrmObjectGet.java | 30 ++ .../parameters/object/PrmObjectHeadGet.java | 31 ++ .../jdo/parameters/object/PrmObjectPut.java | 28 ++ .../parameters/object/PrmObjectPutBase.java | 12 + .../parameters/object/PrmObjectSearch.java | 30 ++ .../parameters/object/PrmObjectSinglePut.java | 26 ++ .../parameters/object/PutObjectContext.java | 14 + .../parameters/session/PrmSessionCreate.java | 19 + .../parameters/session/SessionContext.java | 7 + .../sdk/jdo/result/ObjectHeaderResult.java | 15 + .../info/frostfs/sdk/pool/ClientWrapper.java | 17 +- .../main/java/info/frostfs/sdk/pool/Pool.java | 129 +++--- .../info/frostfs/sdk/pool/SessionCache.java | 15 +- .../sdk/services/AccountingClient.java | 3 +- .../sdk/services/ApeManagerClient.java | 11 +- .../frostfs/sdk/services/ContainerClient.java | 13 +- .../frostfs/sdk/services/NetmapClient.java | 7 +- .../frostfs/sdk/services/ObjectClient.java | 22 +- .../frostfs/sdk/services/SessionClient.java | 4 +- .../frostfs/sdk/services/SessionTools.java | 4 +- .../services/impl/AccountingClientImpl.java | 14 +- .../services/impl/ApeManagerClientImpl.java | 81 ++-- .../services/impl/ContainerClientImpl.java | 119 +++--- .../sdk/services/impl/NetmapClientImpl.java | 22 +- .../sdk/services/impl/ObjectClientImpl.java | 370 +++++++++--------- .../sdk/services/impl/SessionClientImpl.java | 18 +- .../sdk/services/impl/SessionToolsImpl.java | 21 +- .../impl/interceptor/Configuration.java | 29 +- .../impl/rwhelper/ObjectStreamer.java | 62 +++ .../services/impl/rwhelper/ObjectWriter.java | 76 ++-- .../frostfs/sdk/tools/RequestConstructor.java | 22 +- .../info/frostfs/sdk/utils/DeadLineUtil.java | 25 ++ .../sdk/services/AccountingClientTest.java | 5 +- .../sdk/services/ApeManagerClientTest.java | 35 +- cryptography/pom.xml | 4 +- exceptions/pom.xml | 2 +- .../frostfs/sdk/constants/ErrorConst.java | 2 + models/pom.xml | 8 +- .../info/frostfs/sdk/constants/AppConst.java | 1 + .../frostfs/sdk/dto/object/SplitInfo.java | 17 + .../mappers/container/ContainerMapper.java | 2 - .../sdk/mappers/object/SplitInfoMapper.java | 30 ++ .../mappers/object/SplitInfoMapperTest.java | 61 +++ pom.xml | 2 +- protos/pom.xml | 2 +- 61 files changed, 1411 insertions(+), 625 deletions(-) delete mode 100644 client/src/main/java/info/frostfs/sdk/jdo/PutObjectParameters.java create mode 100644 client/src/main/java/info/frostfs/sdk/jdo/parameters/CallContext.java rename client/src/main/java/info/frostfs/sdk/jdo/{WaitParameters.java => parameters/PrmWait.java} (86%) create mode 100644 client/src/main/java/info/frostfs/sdk/jdo/parameters/ape/PrmApeChainAdd.java create mode 100644 client/src/main/java/info/frostfs/sdk/jdo/parameters/ape/PrmApeChainList.java create mode 100644 client/src/main/java/info/frostfs/sdk/jdo/parameters/ape/PrmApeChainRemove.java create mode 100644 client/src/main/java/info/frostfs/sdk/jdo/parameters/container/PrmContainerCreate.java create mode 100644 client/src/main/java/info/frostfs/sdk/jdo/parameters/container/PrmContainerDelete.java create mode 100644 client/src/main/java/info/frostfs/sdk/jdo/parameters/container/PrmContainerGet.java create mode 100644 client/src/main/java/info/frostfs/sdk/jdo/parameters/container/PrmContainerGetAll.java create mode 100644 client/src/main/java/info/frostfs/sdk/jdo/parameters/object/PrmObjectClientCutPut.java create mode 100644 client/src/main/java/info/frostfs/sdk/jdo/parameters/object/PrmObjectDelete.java create mode 100644 client/src/main/java/info/frostfs/sdk/jdo/parameters/object/PrmObjectGet.java create mode 100644 client/src/main/java/info/frostfs/sdk/jdo/parameters/object/PrmObjectHeadGet.java create mode 100644 client/src/main/java/info/frostfs/sdk/jdo/parameters/object/PrmObjectPut.java create mode 100644 client/src/main/java/info/frostfs/sdk/jdo/parameters/object/PrmObjectPutBase.java create mode 100644 client/src/main/java/info/frostfs/sdk/jdo/parameters/object/PrmObjectSearch.java create mode 100644 client/src/main/java/info/frostfs/sdk/jdo/parameters/object/PrmObjectSinglePut.java create mode 100644 client/src/main/java/info/frostfs/sdk/jdo/parameters/object/PutObjectContext.java create mode 100644 client/src/main/java/info/frostfs/sdk/jdo/parameters/session/PrmSessionCreate.java create mode 100644 client/src/main/java/info/frostfs/sdk/jdo/parameters/session/SessionContext.java create mode 100644 client/src/main/java/info/frostfs/sdk/jdo/result/ObjectHeaderResult.java create mode 100644 client/src/main/java/info/frostfs/sdk/services/impl/rwhelper/ObjectStreamer.java create mode 100644 client/src/main/java/info/frostfs/sdk/utils/DeadLineUtil.java create mode 100644 models/src/main/java/info/frostfs/sdk/dto/object/SplitInfo.java create mode 100644 models/src/main/java/info/frostfs/sdk/mappers/object/SplitInfoMapper.java create mode 100644 models/src/test/java/info/frostfs/sdk/mappers/object/SplitInfoMapperTest.java diff --git a/README.md b/README.md index 737c204..03f013b 100644 --- a/README.md +++ b/README.md @@ -21,31 +21,40 @@ neo-go wallet export -w -d ### Container operations ```java +import info.frostfs.sdk.FrostFSClient; import info.frostfs.sdk.dto.container.Container; import info.frostfs.sdk.dto.netmap.PlacementPolicy; import info.frostfs.sdk.dto.netmap.Replica; import info.frostfs.sdk.enums.BasicAcl; import info.frostfs.sdk.jdo.ClientSettings; -import info.frostfs.sdk.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 void example() { + var callContext = new CallContext(); ClientSettings clientSettings = new ClientSettings(, ); FrostFSClient frostFSClient = new FrostFSClient(clientSettings); // Create container - var placementPolicy = new PlacementPolicy(new Replica[]{new Replica(1)}, Boolean.TRUE); - var containerId = frostFSClient.createContainer(new Container(BasicAcl.PUBLIC_RW, placementPolicy)); + var placementPolicy = new PlacementPolicy(new Replica[]{new Replica(1)}, true); + var prmContainerCreate = new PrmContainerCreate(new Container(BasicAcl.PUBLIC_RW, placementPolicy)); + var containerId = frostFSClient.createContainer(prmContainerCreate, callContext); // Get container - var container = frostFSClient.getContainer(containerId); + var prmContainerGet = new PrmContainerGet(containerId); + var container = frostFSClient.getContainer(prmContainerGet, callContext); // List containers - var containerIds = frostFSClient.listContainers(); + var containerIds = frostFSClient.listContainers(new PrmContainerGetAll(), callContext); // Delete container - frostFSClient.deleteContainer(containerId); + var prmContainerDelete = new PrmContainerDelete(containerId); + frostFSClient.deleteContainer(prmContainerDelete, callContext); } } ``` @@ -53,45 +62,104 @@ public class ContainerExample { ### Object operations ```java +import info.frostfs.sdk.dto.object.*; import info.frostfs.sdk.enums.ObjectType; -import info.frostfs.sdk.dto.container.ContainerId; -import info.frostfs.sdk.dto.object.ObjectAttribute; -import info.frostfs.sdk.dto.object.ObjectFilter; -import info.frostfs.sdk.dto.object.ObjectHeader; -import info.frostfs.sdk.dto.object.ObjectId; -import info.frostfs.sdk.jdo.PutObjectParameters; -import info.frostfs.sdk.FrostFSClient; +import info.frostfs.sdk.jdo.ClientSettings; +import info.frostfs.sdk.jdo.parameters.CallContext; +import info.frostfs.sdk.jdo.parameters.object.*; +import org.apache.commons.lang3.ArrayUtils; import java.io.FileInputStream; +import java.io.FileOutputStream; import java.io.IOException; +import static java.util.Objects.isNull; + public class ObjectExample { public void example() { + CallContext callContext = new CallContext(); ClientSettings clientSettings = new ClientSettings(, ); FrostFSClient frostFSClient = new FrostFSClient(clientSettings); // Put object ObjectId objectId; - try (FileInputStream fis = new FileInputStream("cat.jpg")) { - var cat = new ObjectHeader( - containerId, ObjectType.REGULAR, new ObjectAttribute[]{new ObjectAttribute("Filename", "cat.jpg")} - ); + try (FileInputStream file = new FileInputStream("/path/to/file/cat.jpg")) { + var attribute = 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); - objectId = frostFSClient.putObject(params); + writer.write(file.readAllBytes()); + objectId = writer.complete(); } catch (IOException e) { throw new RuntimeException(e); } // 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 - var objectHeader = frostFSClient.getObjectHead(containerId, objectId); + var prmObjectHeadGet = new PrmObjectHeadGet(containerId, objectId); + var objectHeader = frostFSClient.getObjectHead(prmObjectHeadGet, callContext); // 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, , 1); + var nodeParam2 = new NodeParameters(1, , 1); + var nodeParam3 = new NodeParameters(1, , 1); + var nodeParam4 = new NodeParameters(1, , 1); + + PoolInitParameters initParameters = new PoolInitParameters(); + initParameters.setKey(new ECDsa()); + initParameters.setNodeParams(new NodeParameters[]{nodeParam1, nodeParam2, nodeParam3, nodeParam4}); + + + Pool pool = new Pool(initParameters); + + //Dial (Required!) + pool.dial(callContext); } } ``` \ No newline at end of file diff --git a/client/pom.xml b/client/pom.xml index e73703d..f907964 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -6,7 +6,7 @@ info.frostfs.sdk frostfs-sdk-java - 0.2.0 + 0.3.0 client @@ -21,17 +21,17 @@ info.frostfs.sdk cryptography - 0.2.0 + 0.3.0 info.frostfs.sdk models - 0.2.0 + 0.3.0 info.frostfs.sdk exceptions - 0.2.0 + 0.3.0 commons-codec diff --git a/client/src/main/java/info/frostfs/sdk/FrostFSClient.java b/client/src/main/java/info/frostfs/sdk/FrostFSClient.java index cb93dbb..31a76b7 100644 --- a/client/src/main/java/info/frostfs/sdk/FrostFSClient.java +++ b/client/src/main/java/info/frostfs/sdk/FrostFSClient.java @@ -2,13 +2,11 @@ package info.frostfs.sdk; import frostfs.accounting.Types; 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.ContainerId; import info.frostfs.sdk.dto.netmap.NetmapSnapshot; import info.frostfs.sdk.dto.netmap.NodeInfo; 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.ObjectHeader; 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.ClientSettings; 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.WrapperPrm; import info.frostfs.sdk.services.CommonClient; import info.frostfs.sdk.services.impl.*; import info.frostfs.sdk.services.impl.interceptor.Configuration; import info.frostfs.sdk.services.impl.interceptor.MonitoringClientInterceptor; +import info.frostfs.sdk.services.impl.rwhelper.ObjectWriter; import info.frostfs.sdk.utils.Validator; import io.grpc.Channel; import io.grpc.ClientInterceptors; @@ -55,8 +64,10 @@ public class FrostFSClient implements CommonClient { : initGrpcChannel(clientSettings); Channel interceptChannel = ClientInterceptors.intercept(channel, MONITORING_CLIENT_INTERCEPTOR); - ClientEnvironment clientEnvironment = - new ClientEnvironment(clientSettings.getKey(), interceptChannel, new Version(), this); + ClientEnvironment clientEnvironment = new ClientEnvironment( + clientSettings.getKey(), interceptChannel, new Version(), this, + new SessionCache(0) + ); Validator.validate(clientEnvironment); @@ -75,7 +86,7 @@ public class FrostFSClient implements CommonClient { Channel interceptChannel = ClientInterceptors.intercept(channel, MONITORING_CLIENT_INTERCEPTOR); ClientEnvironment clientEnvironment = - new ClientEnvironment(prm.getKey(), interceptChannel, new Version(), this); + new ClientEnvironment(prm.getKey(), interceptChannel, new Version(), this, cache); Validator.validate(clientEnvironment); @@ -90,7 +101,7 @@ public class FrostFSClient implements CommonClient { } private void checkFrostFSVersionSupport(Version version) { - var localNodeInfo = netmapClientImpl.getLocalNodeInfo(); + var localNodeInfo = netmapClientImpl.getLocalNodeInfo(new CallContext()); if (!localNodeInfo.getVersion().isSupported(version)) { throw new ProcessFrostFSException( String.format(VERSION_UNSUPPORTED_TEMPLATE, localNodeInfo.getVersion()) @@ -99,92 +110,97 @@ public class FrostFSClient implements CommonClient { } @Override - public Container getContainer(ContainerId cid) { - return containerClientImpl.getContainer(cid); + public Container getContainer(PrmContainerGet args, CallContext ctx) { + return containerClientImpl.getContainer(args, ctx); } @Override - public List listContainers() { - return containerClientImpl.listContainers(); + public List listContainers(PrmContainerGetAll args, CallContext ctx) { + return containerClientImpl.listContainers(args, ctx); } @Override - public ContainerId createContainer(Container container) { - return containerClientImpl.createContainer(container); + public ContainerId createContainer(PrmContainerCreate args, CallContext ctx) { + return containerClientImpl.createContainer(args, ctx); } @Override - public void deleteContainer(ContainerId cid) { - containerClientImpl.deleteContainer(cid); + public void deleteContainer(PrmContainerDelete args, CallContext ctx) { + containerClientImpl.deleteContainer(args, ctx); } @Override - public ObjectHeader getObjectHead(ContainerId containerId, ObjectId objectId) { - return objectClientImpl.getObjectHead(containerId, objectId); + public ObjectHeaderResult getObjectHead(PrmObjectHeadGet args, CallContext ctx) { + return objectClientImpl.getObjectHead(args, ctx); } @Override - public ObjectFrostFS getObject(ContainerId containerId, ObjectId objectId) { - return objectClientImpl.getObject(containerId, objectId); + public ObjectFrostFS getObject(PrmObjectGet args, CallContext ctx) { + return objectClientImpl.getObject(args, ctx); } @Override - public ObjectId putObject(PutObjectParameters parameters) { - return objectClientImpl.putObject(parameters); + public ObjectWriter putObject(PrmObjectPut args, CallContext ctx) { + return objectClientImpl.putObject(args, ctx); } @Override - public ObjectId putSingleObject(ObjectFrostFS objectFrostFS) { - return objectClientImpl.putSingleObject(objectFrostFS); + public ObjectId putClientCutObject(PrmObjectClientCutPut args, CallContext ctx) { + return objectClientImpl.putClientCutObject(args, ctx); } @Override - public void deleteObject(ContainerId containerId, ObjectId objectId) { - objectClientImpl.deleteObject(containerId, objectId); + public ObjectId putSingleObject(PrmObjectSinglePut args, CallContext ctx) { + return objectClientImpl.putSingleObject(args, ctx); } @Override - public Iterable searchObjects(ContainerId cid, ObjectFilter... filters) { - return objectClientImpl.searchObjects(cid, filters); + public void deleteObject(PrmObjectDelete args, CallContext ctx) { + objectClientImpl.deleteObject(args, ctx); } @Override - public byte[] addChain(Chain chain, ChainTarget chainTarget) { - return apeManagerClient.addChain(chain, chainTarget); + public Iterable searchObjects(PrmObjectSearch args, CallContext ctx) { + return objectClientImpl.searchObjects(args, ctx); } @Override - public void removeChain(Chain chain, ChainTarget chainTarget) { - apeManagerClient.removeChain(chain, chainTarget); + public byte[] addChain(PrmApeChainAdd args, CallContext ctx) { + return apeManagerClient.addChain(args, ctx); } @Override - public List listChains(ChainTarget chainTarget) { - return apeManagerClient.listChains(chainTarget); + public void removeChain(PrmApeChainRemove args, CallContext ctx) { + apeManagerClient.removeChain(args, ctx); } @Override - public NetmapSnapshot getNetmapSnapshot() { - return netmapClientImpl.getNetmapSnapshot(); + public List listChains(PrmApeChainList args, CallContext ctx) { + return apeManagerClient.listChains(args, ctx); } @Override - public NodeInfo getLocalNodeInfo() { - return netmapClientImpl.getLocalNodeInfo(); + public NetmapSnapshot getNetmapSnapshot(CallContext ctx) { + return netmapClientImpl.getNetmapSnapshot(ctx); } @Override - public NetworkSettings getNetworkSettings() { - return netmapClientImpl.getNetworkSettings(); + public NodeInfo getLocalNodeInfo(CallContext ctx) { + return netmapClientImpl.getLocalNodeInfo(ctx); } @Override - public SessionToken createSession(long expiration) { - return sessionClientImpl.createSession(expiration); + public NetworkSettings getNetworkSettings(CallContext ctx) { + return netmapClientImpl.getNetworkSettings(ctx); } - public frostfs.session.Types.SessionToken createSessionInternal(long expiration) { - return sessionClientImpl.createSessionInternal(expiration); + @Override + 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 @@ -193,12 +209,12 @@ public class FrostFSClient implements CommonClient { } @Override - public Types.Decimal getBalance() { - return accountingClient.getBalance(); + public Types.Decimal getBalance(CallContext ctx) { + return accountingClient.getBalance(ctx); } - public String dial() { - accountingClient.getBalance(); + public String dial(CallContext ctx) { + accountingClient.getBalance(ctx); return null; } diff --git a/client/src/main/java/info/frostfs/sdk/jdo/ClientEnvironment.java b/client/src/main/java/info/frostfs/sdk/jdo/ClientEnvironment.java index 015ba6d..62e0967 100644 --- a/client/src/main/java/info/frostfs/sdk/jdo/ClientEnvironment.java +++ b/client/src/main/java/info/frostfs/sdk/jdo/ClientEnvironment.java @@ -5,9 +5,14 @@ import info.frostfs.sdk.annotations.NotNull; import info.frostfs.sdk.annotations.Validate; import info.frostfs.sdk.dto.netmap.Version; import info.frostfs.sdk.dto.object.OwnerId; +import info.frostfs.sdk.pool.SessionCache; import io.grpc.Channel; import lombok.Getter; 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 @Setter @@ -15,35 +20,48 @@ public class ClientEnvironment { @NotNull private final OwnerId ownerId; - @NotNull private final Version version; - @NotNull @Validate private final ECDsa key; - @NotNull private final Channel channel; - @NotNull private final FrostFSClient frostFSClient; + private String sessionKey; + private String address; 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.ownerId = new OwnerId(key.getPublicKeyByte()); this.version = version; this.channel = channel; 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.ownerId = new OwnerId(key.getPublicKeyByte()); this.version = version; this.channel = channel; this.frostFSClient = frostFSClient; + this.sessionCache = sessionCache; + } + + public String getSessionKey() { + if (StringUtils.isBlank(sessionKey)) { + this.sessionKey = formCacheKey(address, getHexString(key.getPublicKeyByte())); + } + + return sessionKey; } } diff --git a/client/src/main/java/info/frostfs/sdk/jdo/PutObjectParameters.java b/client/src/main/java/info/frostfs/sdk/jdo/PutObjectParameters.java deleted file mode 100644 index b995eac..0000000 --- a/client/src/main/java/info/frostfs/sdk/jdo/PutObjectParameters.java +++ /dev/null @@ -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; - } -} diff --git a/client/src/main/java/info/frostfs/sdk/jdo/parameters/CallContext.java b/client/src/main/java/info/frostfs/sdk/jdo/parameters/CallContext.java new file mode 100644 index 0000000..4831e99 --- /dev/null +++ b/client/src/main/java/info/frostfs/sdk/jdo/parameters/CallContext.java @@ -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; + } +} + diff --git a/client/src/main/java/info/frostfs/sdk/jdo/WaitParameters.java b/client/src/main/java/info/frostfs/sdk/jdo/parameters/PrmWait.java similarity index 86% rename from client/src/main/java/info/frostfs/sdk/jdo/WaitParameters.java rename to client/src/main/java/info/frostfs/sdk/jdo/parameters/PrmWait.java index 7fdd965..c109bd4 100644 --- a/client/src/main/java/info/frostfs/sdk/jdo/WaitParameters.java +++ b/client/src/main/java/info/frostfs/sdk/jdo/parameters/PrmWait.java @@ -1,4 +1,4 @@ -package info.frostfs.sdk.jdo; +package info.frostfs.sdk.jdo.parameters; import lombok.AllArgsConstructor; import lombok.Getter; @@ -8,14 +8,14 @@ import java.time.LocalDateTime; @Getter @AllArgsConstructor -public class WaitParameters { +public class PrmWait { private static final Duration DEFAULT_TIMEOUT = Duration.ofSeconds(120); private static final Duration DEFAULT_POLL_INTERVAL = Duration.ofSeconds(5); private final Duration timeout; private final Duration pollInterval; - public WaitParameters() { + public PrmWait() { this.timeout = DEFAULT_TIMEOUT; this.pollInterval = DEFAULT_POLL_INTERVAL; } diff --git a/client/src/main/java/info/frostfs/sdk/jdo/parameters/ape/PrmApeChainAdd.java b/client/src/main/java/info/frostfs/sdk/jdo/parameters/ape/PrmApeChainAdd.java new file mode 100644 index 0000000..4692ac2 --- /dev/null +++ b/client/src/main/java/info/frostfs/sdk/jdo/parameters/ape/PrmApeChainAdd.java @@ -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 xHeaders; + + public PrmApeChainAdd(Chain chain, ChainTarget chainTarget) { + this.chain = chain; + this.chainTarget = chainTarget; + } +} diff --git a/client/src/main/java/info/frostfs/sdk/jdo/parameters/ape/PrmApeChainList.java b/client/src/main/java/info/frostfs/sdk/jdo/parameters/ape/PrmApeChainList.java new file mode 100644 index 0000000..70dc193 --- /dev/null +++ b/client/src/main/java/info/frostfs/sdk/jdo/parameters/ape/PrmApeChainList.java @@ -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 xHeaders; + + public PrmApeChainList(ChainTarget chainTarget) { + this.chainTarget = chainTarget; + } +} diff --git a/client/src/main/java/info/frostfs/sdk/jdo/parameters/ape/PrmApeChainRemove.java b/client/src/main/java/info/frostfs/sdk/jdo/parameters/ape/PrmApeChainRemove.java new file mode 100644 index 0000000..93f53d3 --- /dev/null +++ b/client/src/main/java/info/frostfs/sdk/jdo/parameters/ape/PrmApeChainRemove.java @@ -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 xHeaders; + + public PrmApeChainRemove(Chain chain, ChainTarget chainTarget) { + this.chain = chain; + this.chainTarget = chainTarget; + } +} diff --git a/client/src/main/java/info/frostfs/sdk/jdo/parameters/container/PrmContainerCreate.java b/client/src/main/java/info/frostfs/sdk/jdo/parameters/container/PrmContainerCreate.java new file mode 100644 index 0000000..758bfd8 --- /dev/null +++ b/client/src/main/java/info/frostfs/sdk/jdo/parameters/container/PrmContainerCreate.java @@ -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 xHeaders; + + public PrmContainerCreate(Container container, PrmWait waitParams) { + this.container = container; + this.waitParams = waitParams; + } + + public PrmContainerCreate(Container container) { + this.container = container; + } +} diff --git a/client/src/main/java/info/frostfs/sdk/jdo/parameters/container/PrmContainerDelete.java b/client/src/main/java/info/frostfs/sdk/jdo/parameters/container/PrmContainerDelete.java new file mode 100644 index 0000000..c9baeaf --- /dev/null +++ b/client/src/main/java/info/frostfs/sdk/jdo/parameters/container/PrmContainerDelete.java @@ -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 xHeaders; + + public PrmContainerDelete(ContainerId containerId, PrmWait waitParams) { + this.containerId = containerId; + this.waitParams = waitParams; + } + + public PrmContainerDelete(ContainerId containerId) { + this.containerId = containerId; + } +} diff --git a/client/src/main/java/info/frostfs/sdk/jdo/parameters/container/PrmContainerGet.java b/client/src/main/java/info/frostfs/sdk/jdo/parameters/container/PrmContainerGet.java new file mode 100644 index 0000000..aec9924 --- /dev/null +++ b/client/src/main/java/info/frostfs/sdk/jdo/parameters/container/PrmContainerGet.java @@ -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 xHeaders; + + public PrmContainerGet(ContainerId containerId) { + this.containerId = containerId; + } +} diff --git a/client/src/main/java/info/frostfs/sdk/jdo/parameters/container/PrmContainerGetAll.java b/client/src/main/java/info/frostfs/sdk/jdo/parameters/container/PrmContainerGetAll.java new file mode 100644 index 0000000..56b8d7b --- /dev/null +++ b/client/src/main/java/info/frostfs/sdk/jdo/parameters/container/PrmContainerGetAll.java @@ -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 xHeaders; +} diff --git a/client/src/main/java/info/frostfs/sdk/jdo/parameters/object/PrmObjectClientCutPut.java b/client/src/main/java/info/frostfs/sdk/jdo/parameters/object/PrmObjectClientCutPut.java new file mode 100644 index 0000000..9703a4c --- /dev/null +++ b/client/src/main/java/info/frostfs/sdk/jdo/parameters/object/PrmObjectClientCutPut.java @@ -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 xHeaders; +} diff --git a/client/src/main/java/info/frostfs/sdk/jdo/parameters/object/PrmObjectDelete.java b/client/src/main/java/info/frostfs/sdk/jdo/parameters/object/PrmObjectDelete.java new file mode 100644 index 0000000..326834f --- /dev/null +++ b/client/src/main/java/info/frostfs/sdk/jdo/parameters/object/PrmObjectDelete.java @@ -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 xHeaders; + + public PrmObjectDelete(ContainerId containerId, ObjectId objectId) { + this.containerId = containerId; + this.objectId = objectId; + } +} diff --git a/client/src/main/java/info/frostfs/sdk/jdo/parameters/object/PrmObjectGet.java b/client/src/main/java/info/frostfs/sdk/jdo/parameters/object/PrmObjectGet.java new file mode 100644 index 0000000..e8eb3d7 --- /dev/null +++ b/client/src/main/java/info/frostfs/sdk/jdo/parameters/object/PrmObjectGet.java @@ -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 xHeaders; + + public PrmObjectGet(ContainerId containerId, ObjectId objectId) { + this.containerId = containerId; + this.objectId = objectId; + } +} diff --git a/client/src/main/java/info/frostfs/sdk/jdo/parameters/object/PrmObjectHeadGet.java b/client/src/main/java/info/frostfs/sdk/jdo/parameters/object/PrmObjectHeadGet.java new file mode 100644 index 0000000..8263db7 --- /dev/null +++ b/client/src/main/java/info/frostfs/sdk/jdo/parameters/object/PrmObjectHeadGet.java @@ -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 xHeaders; + + public PrmObjectHeadGet(ContainerId containerId, ObjectId objectId) { + this.containerId = containerId; + this.objectId = objectId; + } +} diff --git a/client/src/main/java/info/frostfs/sdk/jdo/parameters/object/PrmObjectPut.java b/client/src/main/java/info/frostfs/sdk/jdo/parameters/object/PrmObjectPut.java new file mode 100644 index 0000000..ac99504 --- /dev/null +++ b/client/src/main/java/info/frostfs/sdk/jdo/parameters/object/PrmObjectPut.java @@ -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 xHeaders; + + public PrmObjectPut(ObjectHeader objectHeader) { + this.objectHeader = objectHeader; + } +} diff --git a/client/src/main/java/info/frostfs/sdk/jdo/parameters/object/PrmObjectPutBase.java b/client/src/main/java/info/frostfs/sdk/jdo/parameters/object/PrmObjectPutBase.java new file mode 100644 index 0000000..7ddfafb --- /dev/null +++ b/client/src/main/java/info/frostfs/sdk/jdo/parameters/object/PrmObjectPutBase.java @@ -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 getXHeaders(); +} diff --git a/client/src/main/java/info/frostfs/sdk/jdo/parameters/object/PrmObjectSearch.java b/client/src/main/java/info/frostfs/sdk/jdo/parameters/object/PrmObjectSearch.java new file mode 100644 index 0000000..0bc414b --- /dev/null +++ b/client/src/main/java/info/frostfs/sdk/jdo/parameters/object/PrmObjectSearch.java @@ -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 xHeaders; + + public PrmObjectSearch(ContainerId containerId, ObjectFilter... filters) { + this.containerId = containerId; + this.filters = filters; + } +} diff --git a/client/src/main/java/info/frostfs/sdk/jdo/parameters/object/PrmObjectSinglePut.java b/client/src/main/java/info/frostfs/sdk/jdo/parameters/object/PrmObjectSinglePut.java new file mode 100644 index 0000000..2965d0c --- /dev/null +++ b/client/src/main/java/info/frostfs/sdk/jdo/parameters/object/PrmObjectSinglePut.java @@ -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 xHeaders; + + public PrmObjectSinglePut(ObjectFrostFS objectFrostFS) { + this.objectFrostFS = objectFrostFS; + } +} diff --git a/client/src/main/java/info/frostfs/sdk/jdo/parameters/object/PutObjectContext.java b/client/src/main/java/info/frostfs/sdk/jdo/parameters/object/PutObjectContext.java new file mode 100644 index 0000000..fc97dd0 --- /dev/null +++ b/client/src/main/java/info/frostfs/sdk/jdo/parameters/object/PutObjectContext.java @@ -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; +} diff --git a/client/src/main/java/info/frostfs/sdk/jdo/parameters/session/PrmSessionCreate.java b/client/src/main/java/info/frostfs/sdk/jdo/parameters/session/PrmSessionCreate.java new file mode 100644 index 0000000..c73dd2b --- /dev/null +++ b/client/src/main/java/info/frostfs/sdk/jdo/parameters/session/PrmSessionCreate.java @@ -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 xHeaders; + + public PrmSessionCreate(long expiration) { + this.expiration = expiration; + } +} diff --git a/client/src/main/java/info/frostfs/sdk/jdo/parameters/session/SessionContext.java b/client/src/main/java/info/frostfs/sdk/jdo/parameters/session/SessionContext.java new file mode 100644 index 0000000..536017a --- /dev/null +++ b/client/src/main/java/info/frostfs/sdk/jdo/parameters/session/SessionContext.java @@ -0,0 +1,7 @@ +package info.frostfs.sdk.jdo.parameters.session; + +import info.frostfs.sdk.dto.session.SessionToken; + +public interface SessionContext { + SessionToken getSessionToken(); +} diff --git a/client/src/main/java/info/frostfs/sdk/jdo/result/ObjectHeaderResult.java b/client/src/main/java/info/frostfs/sdk/jdo/result/ObjectHeaderResult.java new file mode 100644 index 0000000..a3fbb1e --- /dev/null +++ b/client/src/main/java/info/frostfs/sdk/jdo/result/ObjectHeaderResult.java @@ -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; +} diff --git a/client/src/main/java/info/frostfs/sdk/pool/ClientWrapper.java b/client/src/main/java/info/frostfs/sdk/pool/ClientWrapper.java index 0189cc1..54163d1 100644 --- a/client/src/main/java/info/frostfs/sdk/pool/ClientWrapper.java +++ b/client/src/main/java/info/frostfs/sdk/pool/ClientWrapper.java @@ -4,6 +4,7 @@ import info.frostfs.sdk.FrostFSClient; import info.frostfs.sdk.enums.MethodIndex; import info.frostfs.sdk.exceptions.ResponseFrostFSException; import info.frostfs.sdk.exceptions.ValidationFrostFSException; +import info.frostfs.sdk.jdo.parameters.CallContext; import info.frostfs.sdk.utils.WaitUtil; import lombok.AccessLevel; import lombok.Getter; @@ -45,12 +46,12 @@ public class ClientWrapper extends ClientStatusMonitor { } } - public void dial() { + public void dial(CallContext ctx) { FrostFSClient client = getClient(); if (client == null) { throw new ValidationFrostFSException(POOL_CLIENT_UNHEALTHY); } - client.dial(); + client.dial(ctx); } public void handleError(Exception exp) { @@ -77,9 +78,9 @@ public class ClientWrapper extends ClientStatusMonitor { client.close(); } - public CompletableFuture restartIfUnhealthy() { + public CompletableFuture restartIfUnhealthy(CallContext ctx) { try { - client.getLocalNodeInfo(); + client.getLocalNodeInfo(ctx); return CompletableFuture.completedFuture(false); } catch (Exception ignored) { } @@ -88,15 +89,15 @@ public class ClientWrapper extends ClientStatusMonitor { scheduleGracefulClose(); } - return CompletableFuture.completedFuture(restartClient()); + return CompletableFuture.completedFuture(restartClient(ctx)); } - private boolean restartClient() { + private boolean restartClient(CallContext ctx) { FrostFSClient newClient = null; try { newClient = new FrostFSClient(wrapperPrm, sessionCache); - var error = newClient.dial(); + var error = newClient.dial(ctx); if (StringUtils.isNotBlank(error)) { setUnhealthyOnDial(); newClient.close(); @@ -113,7 +114,7 @@ public class ClientWrapper extends ClientStatusMonitor { } try { - client.getLocalNodeInfo(); + client.getLocalNodeInfo(ctx); } catch (Exception exp) { setUnhealthy(); return true; diff --git a/client/src/main/java/info/frostfs/sdk/pool/Pool.java b/client/src/main/java/info/frostfs/sdk/pool/Pool.java index 3306ea5..74143a2 100644 --- a/client/src/main/java/info/frostfs/sdk/pool/Pool.java +++ b/client/src/main/java/info/frostfs/sdk/pool/Pool.java @@ -2,12 +2,14 @@ package info.frostfs.sdk.pool; import frostfs.refs.Types; 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.ContainerId; import info.frostfs.sdk.dto.netmap.NetmapSnapshot; 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.exceptions.FrostFSException; 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.jdo.ECDsa; 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.PoolInitParameters; +import info.frostfs.sdk.jdo.result.ObjectHeaderResult; 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.WaitUtil; 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(); - NetworkSettings networkInfo = client.getNetworkSettings(); + NetworkSettings networkInfo = client.getNetworkSettings(ctx); long epoch = networkInfo.getEpochDuration(); 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; } - public String dial() { + public String dial(CallContext ctx) { InnerPool[] inner = new InnerPool[rebalanceParams.getNodesParams().length]; boolean atLeastOneHealthy = false; int i = 0; @@ -198,10 +211,12 @@ public class Pool implements CommonClient { boolean dialed = false; try { - client.dial(); + client.dial(ctx); dialed = true; - SessionToken token = initSessionForDuration(client, rebalanceParams.getSessionExpirationDuration()); + SessionToken token = initSessionForDuration( + ctx, client, rebalanceParams.getSessionExpirationDuration() + ); String cacheKey = formCacheKey( nodeParams.getAddress().get(j), getHexString(key.getPublicKeyByte()) @@ -236,10 +251,10 @@ public class Pool implements CommonClient { this.innerPools = inner; - NetworkSettings networkSettings = getNetworkSettings(); + NetworkSettings networkSettings = getNetworkSettings(ctx); this.maxObjectSize = networkSettings.getMaxObjectSize(); - startRebalance(); + startRebalance(ctx); 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][]; for (int i = 0; i < rebalanceParams.getNodesParams().length; i++) { @@ -276,24 +291,24 @@ public class Pool implements CommonClient { CompletableFuture.runAsync(() -> { 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]; for (int i = 0; i < innerPools.length; i++) { double[] bufferWeights = buffers[i]; int finalI = i; - tasks[i] = CompletableFuture.runAsync(() -> updateInnerNodesHealth(finalI, bufferWeights)); + tasks[i] = CompletableFuture.runAsync(() -> updateInnerNodesHealth(ctx, finalI, bufferWeights)); } 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) { return; } @@ -311,7 +326,7 @@ public class Pool implements CommonClient { AtomicBoolean changed = new AtomicBoolean(false); int finalJ = j; - tasks[j] = client.restartIfUnhealthy().handle((unused, throwable) -> { + tasks[j] = client.restartIfUnhealthy(ctx).handle((unused, throwable) -> { if (throwable != null) { error.set(throwable.getMessage()); bufferWeights[finalJ] = 0; @@ -398,112 +413,112 @@ public class Pool implements CommonClient { return statistics; } - @Override - public Container getContainer(ContainerId cid) { + public Container getContainer(PrmContainerGet args, CallContext ctx) { ClientWrapper client = connection(); - return client.getClient().getContainer(cid); + return client.getClient().getContainer(args, ctx); } @Override - public List listContainers() { + public List listContainers(PrmContainerGetAll args, CallContext ctx) { ClientWrapper client = connection(); - return client.getClient().listContainers(); + return client.getClient().listContainers(args, ctx); } @Override - public ContainerId createContainer(Container container) { + public ContainerId createContainer(PrmContainerCreate args, CallContext ctx) { ClientWrapper client = connection(); - return client.getClient().createContainer(container); + return client.getClient().createContainer(args, ctx); } @Override - public void deleteContainer(ContainerId cid) { + public void deleteContainer(PrmContainerDelete args, CallContext ctx) { ClientWrapper client = connection(); - client.getClient().deleteContainer(cid); + client.getClient().deleteContainer(args, ctx); } @Override - public ObjectHeader getObjectHead(ContainerId containerId, ObjectId objectId) { + public ObjectHeaderResult getObjectHead(PrmObjectHeadGet args, CallContext ctx) { ClientWrapper client = connection(); - return client.getClient().getObjectHead(containerId, objectId); + return client.getClient().getObjectHead(args, ctx); } @Override - public ObjectFrostFS getObject(ContainerId containerId, ObjectId objectId) { + public ObjectFrostFS getObject(PrmObjectGet args, CallContext ctx) { ClientWrapper client = connection(); - return client.getClient().getObject(containerId, objectId); + return client.getClient().getObject(args, ctx); } @Override - public ObjectId putObject(PutObjectParameters parameters) { + public ObjectWriter putObject(PrmObjectPut args, CallContext ctx) { ClientWrapper client = connection(); - return client.getClient().putObject(parameters); + return client.getClient().putObject(args, ctx); } @Override - public ObjectId putSingleObject(ObjectFrostFS objectFrostFS) { + public ObjectId putClientCutObject(PrmObjectClientCutPut args, CallContext ctx) { ClientWrapper client = connection(); - return client.getClient().putSingleObject(objectFrostFS); + return client.getClient().putClientCutObject(args, ctx); } @Override - public void deleteObject(ContainerId containerId, ObjectId objectId) { + public ObjectId putSingleObject(PrmObjectSinglePut args, CallContext ctx) { ClientWrapper client = connection(); - client.getClient().deleteObject(containerId, objectId); + return client.getClient().putSingleObject(args, ctx); } @Override - public Iterable searchObjects(ContainerId cid, ObjectFilter... filters) { + public void deleteObject(PrmObjectDelete args, CallContext ctx) { ClientWrapper client = connection(); - return client.getClient().searchObjects(cid, filters); + client.getClient().deleteObject(args, ctx); } @Override - public byte[] addChain(Chain chain, ChainTarget chainTarget) { + public Iterable searchObjects(PrmObjectSearch args, CallContext ctx) { ClientWrapper client = connection(); - return client.getClient().addChain(chain, chainTarget); + return client.getClient().searchObjects(args, ctx); } @Override - public void removeChain(Chain chain, ChainTarget chainTarget) { + public byte[] addChain(PrmApeChainAdd args, CallContext ctx) { ClientWrapper client = connection(); - client.getClient().removeChain(chain, chainTarget); + return client.getClient().addChain(args, ctx); } @Override - public List listChains(ChainTarget chainTarget) { + public void removeChain(PrmApeChainRemove args, CallContext ctx) { ClientWrapper client = connection(); - return client.getClient().listChains(chainTarget); + client.getClient().removeChain(args, ctx); } @Override - public NetmapSnapshot getNetmapSnapshot() { + public List listChains(PrmApeChainList args, CallContext ctx) { ClientWrapper client = connection(); - return client.getClient().getNetmapSnapshot(); + return client.getClient().listChains(args, ctx); } @Override - public NodeInfo getLocalNodeInfo() { + public NetmapSnapshot getNetmapSnapshot(CallContext ctx) { ClientWrapper client = connection(); - return client.getClient().getLocalNodeInfo(); + return client.getClient().getNetmapSnapshot(ctx); } @Override - public NetworkSettings getNetworkSettings() { + public NodeInfo getLocalNodeInfo(CallContext ctx) { ClientWrapper client = connection(); - return client.getClient().getNetworkSettings(); + return client.getClient().getLocalNodeInfo(ctx); } @Override - public SessionToken createSession(long expiration) { + public NetworkSettings getNetworkSettings(CallContext ctx) { 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(); - return client.getClient().createSessionInternal(expiration); + return client.getClient().createSession(args, ctx); } @Override @@ -513,8 +528,8 @@ public class Pool implements CommonClient { } @Override - public frostfs.accounting.Types.Decimal getBalance() { + public frostfs.accounting.Types.Decimal getBalance(CallContext ctx) { ClientWrapper client = connection(); - return client.getClient().getBalance(); + return client.getClient().getBalance(ctx); } } diff --git a/client/src/main/java/info/frostfs/sdk/pool/SessionCache.java b/client/src/main/java/info/frostfs/sdk/pool/SessionCache.java index f64865b..998beb6 100644 --- a/client/src/main/java/info/frostfs/sdk/pool/SessionCache.java +++ b/client/src/main/java/info/frostfs/sdk/pool/SessionCache.java @@ -1,6 +1,7 @@ package info.frostfs.sdk.pool; import info.frostfs.sdk.dto.session.SessionToken; +import org.apache.commons.lang3.StringUtils; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -18,18 +19,8 @@ public class SessionCache { return cache.containsKey(key); } - public boolean tryGetValue(String key, SessionToken[] value) { - if (key == null) { - value[0] = null; - return false; - } - - SessionToken token = cache.get(key); - if (token != null) { - value[0] = token; - return true; - } - return false; + public SessionToken tryGetValue(String key) { + return StringUtils.isBlank(key) ? null : cache.get(key); } public void setValue(String key, SessionToken value) { diff --git a/client/src/main/java/info/frostfs/sdk/services/AccountingClient.java b/client/src/main/java/info/frostfs/sdk/services/AccountingClient.java index e29e153..28c2516 100644 --- a/client/src/main/java/info/frostfs/sdk/services/AccountingClient.java +++ b/client/src/main/java/info/frostfs/sdk/services/AccountingClient.java @@ -1,7 +1,8 @@ package info.frostfs.sdk.services; import frostfs.accounting.Types; +import info.frostfs.sdk.jdo.parameters.CallContext; public interface AccountingClient { - Types.Decimal getBalance(); + Types.Decimal getBalance(CallContext ctx); } diff --git a/client/src/main/java/info/frostfs/sdk/services/ApeManagerClient.java b/client/src/main/java/info/frostfs/sdk/services/ApeManagerClient.java index 5c5263c..521d8af 100644 --- a/client/src/main/java/info/frostfs/sdk/services/ApeManagerClient.java +++ b/client/src/main/java/info/frostfs/sdk/services/ApeManagerClient.java @@ -1,14 +1,17 @@ package info.frostfs.sdk.services; 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; 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 listChains(ChainTarget chainTarget); + List listChains(PrmApeChainList args, CallContext ctx); } diff --git a/client/src/main/java/info/frostfs/sdk/services/ContainerClient.java b/client/src/main/java/info/frostfs/sdk/services/ContainerClient.java index d3f7f9c..121bc80 100644 --- a/client/src/main/java/info/frostfs/sdk/services/ContainerClient.java +++ b/client/src/main/java/info/frostfs/sdk/services/ContainerClient.java @@ -2,15 +2,20 @@ package info.frostfs.sdk.services; import info.frostfs.sdk.dto.container.Container; 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; public interface ContainerClient { - Container getContainer(ContainerId cid); + Container getContainer(PrmContainerGet args, CallContext ctx); - List listContainers(); + List 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); } diff --git a/client/src/main/java/info/frostfs/sdk/services/NetmapClient.java b/client/src/main/java/info/frostfs/sdk/services/NetmapClient.java index bc34978..067c836 100644 --- a/client/src/main/java/info/frostfs/sdk/services/NetmapClient.java +++ b/client/src/main/java/info/frostfs/sdk/services/NetmapClient.java @@ -3,11 +3,12 @@ package info.frostfs.sdk.services; import info.frostfs.sdk.dto.netmap.NetmapSnapshot; import info.frostfs.sdk.dto.netmap.NodeInfo; import info.frostfs.sdk.jdo.NetworkSettings; +import info.frostfs.sdk.jdo.parameters.CallContext; public interface NetmapClient { - NetmapSnapshot getNetmapSnapshot(); + NetmapSnapshot getNetmapSnapshot(CallContext ctx); - NodeInfo getLocalNodeInfo(); + NodeInfo getLocalNodeInfo(CallContext ctx); - NetworkSettings getNetworkSettings(); + NetworkSettings getNetworkSettings(CallContext ctx); } diff --git a/client/src/main/java/info/frostfs/sdk/services/ObjectClient.java b/client/src/main/java/info/frostfs/sdk/services/ObjectClient.java index 3a38295..86901b5 100644 --- a/client/src/main/java/info/frostfs/sdk/services/ObjectClient.java +++ b/client/src/main/java/info/frostfs/sdk/services/ObjectClient.java @@ -1,22 +1,24 @@ 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.ObjectHeader; 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 { - 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 searchObjects(ContainerId cid, ObjectFilter... filters); + void deleteObject(PrmObjectDelete args, CallContext ctx); + + Iterable searchObjects(PrmObjectSearch args, CallContext ctx); } diff --git a/client/src/main/java/info/frostfs/sdk/services/SessionClient.java b/client/src/main/java/info/frostfs/sdk/services/SessionClient.java index e9b197c..4e5f0a9 100644 --- a/client/src/main/java/info/frostfs/sdk/services/SessionClient.java +++ b/client/src/main/java/info/frostfs/sdk/services/SessionClient.java @@ -1,7 +1,9 @@ package info.frostfs.sdk.services; 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 { - SessionToken createSession(long expiration); + SessionToken createSession(PrmSessionCreate args, CallContext ctx); } diff --git a/client/src/main/java/info/frostfs/sdk/services/SessionTools.java b/client/src/main/java/info/frostfs/sdk/services/SessionTools.java index 7976592..b389235 100644 --- a/client/src/main/java/info/frostfs/sdk/services/SessionTools.java +++ b/client/src/main/java/info/frostfs/sdk/services/SessionTools.java @@ -1,9 +1,9 @@ package info.frostfs.sdk.services; -import frostfs.session.Types; import info.frostfs.sdk.dto.session.SessionToken; import info.frostfs.sdk.jdo.ClientEnvironment; +import info.frostfs.sdk.jdo.parameters.CallContext; public interface SessionTools { - Types.SessionToken getOrCreateSession(SessionToken token, ClientEnvironment env); + SessionToken getOrCreateSession(ClientEnvironment env, CallContext ctx); } diff --git a/client/src/main/java/info/frostfs/sdk/services/impl/AccountingClientImpl.java b/client/src/main/java/info/frostfs/sdk/services/impl/AccountingClientImpl.java index deab5c2..7aee62b 100644 --- a/client/src/main/java/info/frostfs/sdk/services/impl/AccountingClientImpl.java +++ b/client/src/main/java/info/frostfs/sdk/services/impl/AccountingClientImpl.java @@ -4,6 +4,7 @@ import frostfs.accounting.AccountingServiceGrpc; import frostfs.accounting.Service; import frostfs.accounting.Types; import info.frostfs.sdk.jdo.ClientEnvironment; +import info.frostfs.sdk.jdo.parameters.CallContext; import info.frostfs.sdk.mappers.object.OwnerIdMapper; import info.frostfs.sdk.services.AccountingClient; 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.Verifier; -import java.util.Map; +import static info.frostfs.sdk.utils.DeadLineUtil.deadLineAfter; public class AccountingClientImpl extends ContextAccessor implements AccountingClient { private final AccountingServiceGrpc.AccountingServiceBlockingStub serviceBlockingStub; @@ -22,23 +23,24 @@ public class AccountingClientImpl extends ContextAccessor implements AccountingC } @Override - public Types.Decimal getBalance() { - var request = createGetRequest(null); + public Types.Decimal getBalance(CallContext ctx) { + var request = createGetRequest(); - var response = serviceBlockingStub.balance(request); + var service = deadLineAfter(serviceBlockingStub, ctx.getTimeout(), ctx.getTimeUnit()); + var response = service.balance(request); Verifier.checkResponse(response); return response.getBody().getBalance(); } - private Service.BalanceRequest createGetRequest(Map xHeaders) { + private Service.BalanceRequest createGetRequest() { var body = Service.BalanceRequest.Body.newBuilder() .setOwnerId(OwnerIdMapper.toGrpcMessage(getContext().getOwnerId())) .build(); var request = Service.BalanceRequest.newBuilder() .setBody(body); - RequestConstructor.addMetaHeader(request, xHeaders); + RequestConstructor.addMetaHeader(request); RequestSigner.sign(request, getContext().getKey()); return request.build(); diff --git a/client/src/main/java/info/frostfs/sdk/services/impl/ApeManagerClientImpl.java b/client/src/main/java/info/frostfs/sdk/services/impl/ApeManagerClientImpl.java index 0e5c9f1..7843d65 100644 --- a/client/src/main/java/info/frostfs/sdk/services/impl/ApeManagerClientImpl.java +++ b/client/src/main/java/info/frostfs/sdk/services/impl/ApeManagerClientImpl.java @@ -5,9 +5,11 @@ import frostfs.ape.Types; import frostfs.apemanager.APEManagerServiceGrpc; import frostfs.apemanager.Service; 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.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.ChainTargetMapper; import info.frostfs.sdk.services.ApeManagerClient; @@ -17,10 +19,9 @@ import info.frostfs.sdk.tools.RequestSigner; import info.frostfs.sdk.tools.Verifier; import java.util.List; -import java.util.Map; -import static info.frostfs.sdk.constants.ErrorConst.*; -import static java.util.Objects.isNull; +import static info.frostfs.sdk.utils.DeadLineUtil.deadLineAfter; +import static info.frostfs.sdk.utils.Validator.validate; public class ApeManagerClientImpl extends ContextAccessor implements ApeManagerClient { private final APEManagerServiceGrpc.APEManagerServiceBlockingStub apeManagerServiceClient; @@ -31,19 +32,13 @@ public class ApeManagerClientImpl extends ContextAccessor implements ApeManagerC } @Override - public byte[] addChain(Chain chain, ChainTarget chainTarget) { - if (isNull(chain) || isNull(chainTarget)) { - throw new ValidationFrostFSException( - String.format( - PARAMS_ARE_MISSING_TEMPLATE, - String.join(FIELDS_DELIMITER_COMMA, Chain.class.getName(), ChainTarget.class.getName()) - ) - ); - } + public byte[] addChain(PrmApeChainAdd args, CallContext ctx) { + validate(args); - 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); @@ -51,82 +46,70 @@ public class ApeManagerClientImpl extends ContextAccessor implements ApeManagerC } @Override - public void removeChain(Chain chain, ChainTarget chainTarget) { - if (isNull(chain) || isNull(chainTarget)) { - throw new ValidationFrostFSException( - String.format( - PARAMS_ARE_MISSING_TEMPLATE, - String.join(FIELDS_DELIMITER_COMMA, Chain.class.getName(), ChainTarget.class.getName()) - ) - ); - } + public void removeChain(PrmApeChainRemove args, CallContext ctx) { + validate(args); - 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); } @Override - public List listChains(ChainTarget chainTarget) { - if (isNull(chainTarget)) { - throw new ValidationFrostFSException(String.format(PARAM_IS_MISSING_TEMPLATE, ChainTarget.class.getName())); - } + public List listChains(PrmApeChainList args, CallContext ctx) { + validate(args); - 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); return ChainMapper.toModels(response.getBody().getChainsList()); } - private Service.AddChainRequest createAddChainRequest(Chain chain, - ChainTarget chainTarget, - Map xHeaders) { + private Service.AddChainRequest createAddChainRequest(PrmApeChainAdd args) { var chainGrpc = Types.Chain.newBuilder() - .setRaw(ByteString.copyFrom(chain.getRaw())) + .setRaw(ByteString.copyFrom(args.getChain().getRaw())) .build(); var body = Service.AddChainRequest.Body.newBuilder() .setChain(chainGrpc) - .setTarget(ChainTargetMapper.toGrpcMessage(chainTarget)) + .setTarget(ChainTargetMapper.toGrpcMessage(args.getChainTarget())) .build(); var request = Service.AddChainRequest.newBuilder() .setBody(body); - RequestConstructor.addMetaHeader(request, xHeaders); + RequestConstructor.addMetaHeader(request, args.getXHeaders()); RequestSigner.sign(request, getContext().getKey()); return request.build(); } - private Service.RemoveChainRequest createRemoveChainRequest(Chain chain, - ChainTarget chainTarget, - Map xHeaders) { + private Service.RemoveChainRequest createRemoveChainRequest(PrmApeChainRemove args) { var body = Service.RemoveChainRequest.Body.newBuilder() - .setChainId(ByteString.copyFrom(chain.getRaw())) - .setTarget(ChainTargetMapper.toGrpcMessage(chainTarget)) + .setChainId(ByteString.copyFrom(args.getChain().getRaw())) + .setTarget(ChainTargetMapper.toGrpcMessage(args.getChainTarget())) .build(); var request = Service.RemoveChainRequest.newBuilder() .setBody(body); - RequestConstructor.addMetaHeader(request, xHeaders); + RequestConstructor.addMetaHeader(request, args.getXHeaders()); RequestSigner.sign(request, getContext().getKey()); return request.build(); } - private Service.ListChainsRequest createListChainsRequest(ChainTarget chainTarget, - Map xHeaders) { + private Service.ListChainsRequest createListChainsRequest(PrmApeChainList args) { var body = Service.ListChainsRequest.Body.newBuilder() - .setTarget(ChainTargetMapper.toGrpcMessage(chainTarget)) + .setTarget(ChainTargetMapper.toGrpcMessage(args.getChainTarget())) .build(); var request = Service.ListChainsRequest.newBuilder() .setBody(body); - RequestConstructor.addMetaHeader(request, xHeaders); + RequestConstructor.addMetaHeader(request, args.getXHeaders()); RequestSigner.sign(request, getContext().getKey()); return request.build(); diff --git a/client/src/main/java/info/frostfs/sdk/services/impl/ContainerClientImpl.java b/client/src/main/java/info/frostfs/sdk/services/impl/ContainerClientImpl.java index 77468af..e6c5d31 100644 --- a/client/src/main/java/info/frostfs/sdk/services/impl/ContainerClientImpl.java +++ b/client/src/main/java/info/frostfs/sdk/services/impl/ContainerClientImpl.java @@ -10,9 +10,14 @@ import info.frostfs.sdk.enums.StatusCode; import info.frostfs.sdk.enums.WaitExpects; import info.frostfs.sdk.exceptions.ResponseFrostFSException; import info.frostfs.sdk.exceptions.TimeoutFrostFSException; -import info.frostfs.sdk.exceptions.ValidationFrostFSException; 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.ContainerMapper; import info.frostfs.sdk.mappers.netmap.VersionMapper; @@ -29,8 +34,11 @@ import java.util.List; import java.util.Map; 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.nonNull; public class ContainerClientImpl extends ContextAccessor implements ContainerClient { private final ContainerServiceGrpc.ContainerServiceBlockingStub serviceBlockingStub; @@ -42,29 +50,33 @@ public class ContainerClientImpl extends ContextAccessor implements ContainerCli this.sessionTools = new SessionToolsImpl(clientEnvironment); } - public frostfs.session.Types.SessionToken getOrCreateSession(SessionToken sessionToken) { - return sessionTools.getOrCreateSession(sessionToken, getContext()); + public SessionToken getOrCreateSession(SessionContext sessionContext, CallContext ctx) { + return isNull(sessionContext.getSessionToken()) + ? sessionTools.getOrCreateSession(getContext(), ctx) + : sessionContext.getSessionToken(); } @Override - public Container getContainer(ContainerId cid) { - if (isNull(cid)) { - throw new ValidationFrostFSException(String.format(PARAM_IS_MISSING_TEMPLATE, ContainerId.class.getName())); - } + public Container getContainer(PrmContainerGet args, CallContext ctx) { + validate(args); - 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); return ContainerMapper.toModel(response.getBody().getContainer()); } @Override - public List listContainers() { - var request = createListRequest(null); + public List listContainers(PrmContainerGetAll args, CallContext ctx) { + 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); @@ -74,43 +86,39 @@ public class ContainerClientImpl extends ContextAccessor implements ContainerCli } @Override - public ContainerId createContainer(Container container) { - if (isNull(container)) { - throw new ValidationFrostFSException(String.format(PARAM_IS_MISSING_TEMPLATE, Container.class.getName())); - } + public ContainerId createContainer(PrmContainerCreate args, CallContext ctx) { + validate(args); - var grpcContainer = ContainerMapper.toGrpcMessage(container); - var request = createPutRequest(grpcContainer, null); + var request = createPutRequest(args, ctx); - var response = serviceBlockingStub.put(request); + var service = deadLineAfter(serviceBlockingStub, ctx.getTimeout(), ctx.getTimeUnit()); + var response = service.put(request); 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()); } @Override - public void deleteContainer(ContainerId cid) { - if (isNull(cid)) { - throw new ValidationFrostFSException(String.format(PARAM_IS_MISSING_TEMPLATE, ContainerId.class.getName())); - } + public void deleteContainer(PrmContainerDelete args, CallContext ctx) { + validate(args); - var grpcContainerId = ContainerIdMapper.toGrpcMessage(cid); - var request = createDeleteRequest(grpcContainerId, null); + var request = createDeleteRequest(args, ctx); - var response = serviceBlockingStub.delete(request); + var service = deadLineAfter(serviceBlockingStub, ctx.getTimeout(), ctx.getTimeUnit()); + var response = service.delete(request); 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) { - var request = createGetRequest(id, null); + private void waitForContainer(WaitExpects expect, Types.ContainerID cid, PrmWait waitParams) { + var request = createGetRequest(cid, null); - waitParams = isNull(waitParams) ? new WaitParameters() : waitParams; + waitParams = isNull(waitParams) ? new PrmWait() : waitParams; var deadLine = waitParams.getDeadline(); 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, - Map xHeaders) { + private Service.GetRequest createGetRequest(Types.ContainerID cid, Map xHeaders) { var body = Service.GetRequest.Body.newBuilder() .setContainerId(cid) .build(); @@ -160,22 +171,22 @@ public class ContainerClientImpl extends ContextAccessor implements ContainerCli return request.build(); } - private Service.ListRequest createListRequest(Map xHeaders) { + private Service.ListRequest createListRequest(PrmContainerGetAll args) { var body = Service.ListRequest.Body.newBuilder() .setOwnerId(OwnerIdMapper.toGrpcMessage(getContext().getOwnerId())) .build(); var request = Service.ListRequest.newBuilder() .setBody(body); - RequestConstructor.addMetaHeader(request, xHeaders); + RequestConstructor.addMetaHeader(request, args.getXHeaders()); RequestSigner.sign(request, getContext().getKey()); return request.build(); } - private Service.PutRequest createPutRequest(frostfs.container.Types.Container container, - Map xHeaders) { - container = container.toBuilder() + private Service.PutRequest createPutRequest(PrmContainerCreate args, CallContext ctx) { + syncContainerWithNetwork(args.getContainer(), ctx); + var container = ContainerMapper.toGrpcMessage(args.getContainer()).toBuilder() .setOwnerId(OwnerIdMapper.toGrpcMessage(getContext().getOwnerId())) .setVersion(VersionMapper.toGrpcMessage(getContext().getVersion())) .build(); @@ -187,9 +198,8 @@ public class ContainerClientImpl extends ContextAccessor implements ContainerCli var request = Service.PutRequest.newBuilder() .setBody(body); - var sessionToken = getOrCreateSession(null); - - sessionToken = RequestConstructor.createContainerTokenContext( + var sessionToken = getOrCreateSession(args, ctx); + var protoToken = RequestConstructor.createContainerTokenContext( sessionToken, null, frostfs.session.Types.ContainerSessionContext.Verb.PUT, @@ -197,14 +207,15 @@ public class ContainerClientImpl extends ContextAccessor implements ContainerCli getContext().getKey() ); - RequestConstructor.addMetaHeader(request, xHeaders, sessionToken); + RequestConstructor.addMetaHeader(request, args.getXHeaders(), protoToken); RequestSigner.sign(request, getContext().getKey()); return request.build(); } - private Service.DeleteRequest createDeleteRequest(Types.ContainerID cid, - Map xHeaders) { + private Service.DeleteRequest createDeleteRequest(PrmContainerDelete args, CallContext ctx) { + var cid = ContainerIdMapper.toGrpcMessage(args.getContainerId()); + var body = Service.DeleteRequest.Body.newBuilder() .setContainerId(cid) .setSignature(RequestSigner.signRFC6979(getContext().getKey(), cid.getValue())) @@ -212,9 +223,8 @@ public class ContainerClientImpl extends ContextAccessor implements ContainerCli var request = Service.DeleteRequest.newBuilder() .setBody(body); - var sessionToken = getOrCreateSession(null); - - sessionToken = RequestConstructor.createContainerTokenContext( + var sessionToken = getOrCreateSession(args, ctx); + var protoToken = RequestConstructor.createContainerTokenContext( sessionToken, null, frostfs.session.Types.ContainerSessionContext.Verb.DELETE, @@ -222,9 +232,18 @@ public class ContainerClientImpl extends ContextAccessor implements ContainerCli getContext().getKey() ); - RequestConstructor.addMetaHeader(request, xHeaders, sessionToken); + RequestConstructor.addMetaHeader(request, args.getXHeaders(), protoToken); RequestSigner.sign(request, getContext().getKey()); 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()); + } + } } diff --git a/client/src/main/java/info/frostfs/sdk/services/impl/NetmapClientImpl.java b/client/src/main/java/info/frostfs/sdk/services/impl/NetmapClientImpl.java index 04109ad..a32abac 100644 --- a/client/src/main/java/info/frostfs/sdk/services/impl/NetmapClientImpl.java +++ b/client/src/main/java/info/frostfs/sdk/services/impl/NetmapClientImpl.java @@ -7,6 +7,7 @@ import info.frostfs.sdk.dto.netmap.NetmapSnapshot; import info.frostfs.sdk.dto.netmap.NodeInfo; import info.frostfs.sdk.jdo.ClientEnvironment; 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.NodeInfoMapper; import info.frostfs.sdk.services.ContextAccessor; @@ -17,6 +18,7 @@ import info.frostfs.sdk.tools.Verifier; import java.nio.charset.StandardCharsets; import static info.frostfs.sdk.tools.RequestSigner.sign; +import static info.frostfs.sdk.utils.DeadLineUtil.deadLineAfter; import static java.util.Objects.nonNull; public class NetmapClientImpl extends ContextAccessor implements NetmapClient { @@ -94,12 +96,12 @@ public class NetmapClientImpl extends ContextAccessor implements NetmapClient { } @Override - public NetworkSettings getNetworkSettings() { + public NetworkSettings getNetworkSettings(CallContext ctx) { if (nonNull(getContext().getNetworkSettings())) { return getContext().getNetworkSettings(); } - var info = getNetworkInfo(); + var info = getNetworkInfo(ctx); var settings = new NetworkSettings(); @@ -113,25 +115,28 @@ public class NetmapClientImpl extends ContextAccessor implements NetmapClient { } @Override - public NodeInfo getLocalNodeInfo() { + public NodeInfo getLocalNodeInfo(CallContext ctx) { var request = Service.LocalNodeInfoRequest.newBuilder(); RequestConstructor.addMetaHeader(request); 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); return NodeInfoMapper.toModel(response.getBody()); } - public Service.NetworkInfoResponse getNetworkInfo() { + public Service.NetworkInfoResponse getNetworkInfo(CallContext ctx) { var request = Service.NetworkInfoRequest.newBuilder(); RequestConstructor.addMetaHeader(request); 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); @@ -139,13 +144,14 @@ public class NetmapClientImpl extends ContextAccessor implements NetmapClient { } @Override - public NetmapSnapshot getNetmapSnapshot() { + public NetmapSnapshot getNetmapSnapshot(CallContext ctx) { var request = Service.NetmapSnapshotRequest.newBuilder(); RequestConstructor.addMetaHeader(request); 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); diff --git a/client/src/main/java/info/frostfs/sdk/services/impl/ObjectClientImpl.java b/client/src/main/java/info/frostfs/sdk/services/impl/ObjectClientImpl.java index f85936c..203d1e6 100644 --- a/client/src/main/java/info/frostfs/sdk/services/impl/ObjectClientImpl.java +++ b/client/src/main/java/info/frostfs/sdk/services/impl/ObjectClientImpl.java @@ -6,29 +6,26 @@ import frostfs.object.ObjectServiceGrpc; import frostfs.object.Service; import frostfs.refs.Types; import info.frostfs.sdk.constants.AppConst; -import info.frostfs.sdk.dto.container.ContainerId; import info.frostfs.sdk.dto.object.*; import info.frostfs.sdk.dto.session.SessionToken; import info.frostfs.sdk.enums.ObjectType; import info.frostfs.sdk.exceptions.ProcessFrostFSException; -import info.frostfs.sdk.exceptions.ValidationFrostFSException; import info.frostfs.sdk.jdo.ClientEnvironment; -import info.frostfs.sdk.jdo.PutObjectParameters; 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.object.ObjectFilterMapper; -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.mappers.object.*; import info.frostfs.sdk.services.ContextAccessor; import info.frostfs.sdk.services.ObjectClient; 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.SearchReader; import info.frostfs.sdk.tools.RequestConstructor; import info.frostfs.sdk.tools.Verifier; -import info.frostfs.sdk.utils.Validator; import org.apache.commons.collections4.CollectionUtils; import java.io.IOException; @@ -37,9 +34,12 @@ import java.util.ArrayList; import java.util.List; 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.utils.DeadLineUtil.deadLineAfter; +import static info.frostfs.sdk.utils.Validator.validate; import static java.util.Objects.isNull; +import static java.util.Objects.nonNull; public class ObjectClientImpl extends ContextAccessor implements ObjectClient { private final ObjectServiceGrpc.ObjectServiceBlockingStub objectServiceBlockingClient; @@ -55,87 +55,153 @@ public class ObjectClientImpl extends ContextAccessor implements ObjectClient { this.sessionTools = new SessionToolsImpl(clientEnvironment); } - public frostfs.session.Types.SessionToken getOrCreateSession(SessionToken sessionToken) { - return sessionTools.getOrCreateSession(sessionToken, getContext()); + public SessionToken getOrCreateSession(SessionContext sessionContext, CallContext ctx) { + return isNull(sessionContext.getSessionToken()) + ? sessionTools.getOrCreateSession(getContext(), ctx) + : sessionContext.getSessionToken(); } @Override - public ObjectHeader getObjectHead(ContainerId cid, ObjectId oid) { - if (isNull(cid) || isNull(oid)) { - throw new ValidationFrostFSException( - String.format( - PARAMS_ARE_MISSING_TEMPLATE, - String.join(FIELDS_DELIMITER_COMMA, ContainerId.class.getName(), ObjectId.class.getName()) - ) - ); - } + public ObjectHeaderResult getObjectHead(PrmObjectHeadGet args, CallContext ctx) { + validate(args); - 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); - 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 - public ObjectFrostFS getObject(ContainerId cid, ObjectId oid) { - var request = createGetRequest(ContainerIdMapper.toGrpcMessage(cid), ObjectIdMapper.toGrpcMessage(oid)); + public ObjectFrostFS getObject(PrmObjectGet args, CallContext ctx) { + validate(args); - return getObject(request); + var request = createGetRequest(args, ctx); + + return getObject(request, ctx); } @Override - public void deleteObject(ContainerId cid, ObjectId oid) { - var request = createDeleteRequest(ContainerIdMapper.toGrpcMessage(cid), ObjectIdMapper.toGrpcMessage(oid)); + public void deleteObject(PrmObjectDelete args, CallContext ctx) { + 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); } @Override - public Iterable searchObjects(ContainerId cid, ObjectFilter... filters) { - var request = createSearchRequest(ContainerIdMapper.toGrpcMessage(cid), filters); + public Iterable searchObjects(PrmObjectSearch args, CallContext ctx) { + 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())); } @Override - public ObjectId putObject(PutObjectParameters parameters) { - Validator.validate(parameters); + public ObjectWriter putObject(PrmObjectPut args, CallContext ctx) { + validate(args); - if (parameters.isClientCut()) { - return putClientCutObject(parameters); - } - - if (parameters.getHeader().getPayloadLength() > 0) { - parameters.setFullLength(parameters.getHeader().getPayloadLength()); - } else { - parameters.setFullLength(getStreamSize(parameters.getPayload())); - } - - return putStreamObject(parameters).getObjectId(); + return new ObjectWriter(getContext(), args, getUploadStream(args, ctx)); } @Override - public ObjectId putSingleObject(ObjectFrostFS modelObject) { - var grpcObject = objectToolsImpl.createObject(modelObject); + public ObjectId putClientCutObject(PrmObjectClientCutPut args, CallContext ctx) { + 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 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); return new ObjectId(grpcObject.getObjectId().getValue().toByteArray()); } - private ObjectFrostFS getObject(Service.GetRequest request) { - var reader = getObjectInit(request); + private ObjectFrostFS getObject(Service.GetRequest request, CallContext ctx) { + var reader = getObjectInit(request, ctx); var grpcObject = reader.readHeader(); var modelObject = ObjectFrostFSMapper.toModel(grpcObject); @@ -145,39 +211,41 @@ public class ObjectClientImpl extends ContextAccessor implements ObjectClient { return modelObject; } - private ObjectReaderImpl getObjectInit(Service.GetRequest initRequest) { + private ObjectReaderImpl getObjectInit(Service.GetRequest initRequest, CallContext ctx) { if (initRequest.getSerializedSize() == 0) { throw new ProcessFrostFSException( 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) { - var chunkSize = parameters.getBufferMaxSize() > 0 ? parameters.getBufferMaxSize() : AppConst.OBJECT_CHUNK_SIZE; + private PutObjectResult putMultipartStreamObject(PrmObjectClientCutPut args, CallContext ctx) { + 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); - byte[] chunkBuffer = parameters.getCustomerBuffer() != null - ? parameters.getCustomerBuffer() + byte[] chunkBuffer = args.getCustomerBuffer() != null + ? args.getCustomerBuffer() : new byte[chunkSize];//todo change to pool var sentBytes = 0; // 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) { // send chunks limited to default or user's settings 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) { break; @@ -204,110 +272,40 @@ public class ObjectClientImpl extends ContextAccessor implements ObjectClient { return new PutObjectResult(objectId, sentBytes); } - private ObjectId putClientCutObject(PutObjectParameters parameters) { - var header = parameters.getHeader(); - 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 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(); + private ObjectStreamer getUploadStream(PrmObjectPutBase args, CallContext ctx) { + var header = args.getObjectHeader(); header.setOwnerId(getContext().getOwnerId()); header.setVersion(getContext().getVersion()); 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 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) { throw new ProcessFrostFSException( 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); return writer; } - private Iterable searchObjects(Service.SearchRequest request) { - var reader = getSearchReader(request); + private Iterable searchObjects(Service.SearchRequest request, CallContext ctx) { + var reader = getSearchReader(request, ctx); var ids = reader.read(); List result = new ArrayList<>(); @@ -319,14 +317,15 @@ public class ObjectClientImpl extends ContextAccessor implements ObjectClient { return result;//todo return yield } - private SearchReader getSearchReader(Service.SearchRequest initRequest) { + private SearchReader getSearchReader(Service.SearchRequest initRequest, CallContext ctx) { if (initRequest.getSerializedSize() == 0) { throw new ProcessFrostFSException( 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) { @@ -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() - .setContainerId(cid) - .setObjectId(oid) + .setContainerId(ContainerIdMapper.toGrpcMessage(args.getContainerId())) + .setObjectId(ObjectIdMapper.toGrpcMessage(args.getObjectId())) .build(); var body = Service.HeadRequest.Body.newBuilder() .setAddress(address) + .setRaw(args.isRaw()) .build(); var request = Service.HeadRequest.newBuilder() .setBody(body); - var sessionToken = getOrCreateSession(null); - - sessionToken = RequestConstructor.createObjectTokenContext( + var sessionToken = getOrCreateSession(args, ctx); + var protoToken = RequestConstructor.createObjectTokenContext( sessionToken, address, frostfs.session.Types.ObjectSessionContext.Verb.HEAD, getContext().getKey() ); - RequestConstructor.addMetaHeader(request, null, sessionToken); + RequestConstructor.addMetaHeader(request, args.getXHeaders(), protoToken); sign(request, getContext().getKey()); 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() - .setContainerId(cid) - .setObjectId(oid) + .setContainerId(ContainerIdMapper.toGrpcMessage(args.getContainerId())) + .setObjectId(ObjectIdMapper.toGrpcMessage(args.getObjectId())) .build(); var body = Service.GetRequest.Body.newBuilder() .setAddress(address) @@ -382,25 +382,24 @@ public class ObjectClientImpl extends ContextAccessor implements ObjectClient { var request = Service.GetRequest.newBuilder() .setBody(body); - var sessionToken = getOrCreateSession(null); - - sessionToken = RequestConstructor.createObjectTokenContext( + var sessionToken = getOrCreateSession(args, ctx); + var protoToken = RequestConstructor.createObjectTokenContext( sessionToken, address, frostfs.session.Types.ObjectSessionContext.Verb.GET, getContext().getKey() ); - RequestConstructor.addMetaHeader(request, null, sessionToken); + RequestConstructor.addMetaHeader(request, args.getXHeaders(), protoToken); sign(request, getContext().getKey()); 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() - .setContainerId(cid) - .setObjectId(oid) + .setContainerId(ContainerIdMapper.toGrpcMessage(args.getContainerId())) + .setObjectId(ObjectIdMapper.toGrpcMessage(args.getObjectId())) .build(); var body = Service.DeleteRequest.Body.newBuilder() .setAddress(address) @@ -408,22 +407,23 @@ public class ObjectClientImpl extends ContextAccessor implements ObjectClient { var request = Service.DeleteRequest.newBuilder() .setBody(body); - var sessionToken = getOrCreateSession(null); - - sessionToken = RequestConstructor.createObjectTokenContext( + var sessionToken = getOrCreateSession(args, ctx); + var protoToken = RequestConstructor.createObjectTokenContext( sessionToken, address, frostfs.session.Types.ObjectSessionContext.Verb.DELETE, getContext().getKey() ); - RequestConstructor.addMetaHeader(request, null, sessionToken); + RequestConstructor.addMetaHeader(request, args.getXHeaders(), protoToken); sign(request, getContext().getKey()); 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() .setContainerId(cid) .build(); @@ -432,29 +432,31 @@ public class ObjectClientImpl extends ContextAccessor implements ObjectClient { .setContainerId(cid) .setVersion(1);// TODO: clarify this param - for (ObjectFilter filter : filters) { + for (ObjectFilter filter : args.getFilters()) { body.addFilters(ObjectFilterMapper.toGrpcMessage(filter)); } var request = Service.SearchRequest.newBuilder() .setBody(body.build()); - var sessionToken = getOrCreateSession(null); - - sessionToken = RequestConstructor.createObjectTokenContext( + var sessionToken = getOrCreateSession(args, ctx); + var protoToken = RequestConstructor.createObjectTokenContext( sessionToken, address, frostfs.session.Types.ObjectSessionContext.Verb.SEARCH, getContext().getKey() ); - RequestConstructor.addMetaHeader(request, null, sessionToken); + RequestConstructor.addMetaHeader(request, args.getXHeaders(), protoToken); sign(request, getContext().getKey()); 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() .setContainerId(header.getContainerId()) .setObjectId(oid) @@ -468,22 +470,23 @@ public class ObjectClientImpl extends ContextAccessor implements ObjectClient { var request = Service.PutRequest.newBuilder() .setBody(body); - var sessionToken = getOrCreateSession(null); - - sessionToken = RequestConstructor.createObjectTokenContext( + var sessionToken = getOrCreateSession(args, ctx); + var protoToken = RequestConstructor.createObjectTokenContext( sessionToken, address, frostfs.session.Types.ObjectSessionContext.Verb.PUT, getContext().getKey() ); - RequestConstructor.addMetaHeader(request, null, sessionToken); + RequestConstructor.addMetaHeader(request, args.getXHeaders(), protoToken); sign(request, getContext().getKey()); 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() .setContainerId(grpcObject.getHeader().getContainerId()) .setObjectId(grpcObject.getObjectId()) @@ -494,16 +497,15 @@ public class ObjectClientImpl extends ContextAccessor implements ObjectClient { var request = Service.PutSingleRequest.newBuilder() .setBody(body); - var sessionToken = getOrCreateSession(null); - - sessionToken = RequestConstructor.createObjectTokenContext( + var sessionToken = getOrCreateSession(args, ctx); + var protoToken = RequestConstructor.createObjectTokenContext( sessionToken, address, frostfs.session.Types.ObjectSessionContext.Verb.PUT, getContext().getKey() ); - RequestConstructor.addMetaHeader(request, null, sessionToken); + RequestConstructor.addMetaHeader(request, args.getXHeaders(), protoToken); sign(request, getContext().getKey()); return request.build(); diff --git a/client/src/main/java/info/frostfs/sdk/services/impl/SessionClientImpl.java b/client/src/main/java/info/frostfs/sdk/services/impl/SessionClientImpl.java index 8151fc9..7b999ce 100644 --- a/client/src/main/java/info/frostfs/sdk/services/impl/SessionClientImpl.java +++ b/client/src/main/java/info/frostfs/sdk/services/impl/SessionClientImpl.java @@ -5,6 +5,8 @@ import frostfs.session.SessionServiceGrpc; import frostfs.session.Types; import info.frostfs.sdk.dto.session.SessionToken; 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.session.SessionMapper; import info.frostfs.sdk.services.ContextAccessor; @@ -13,6 +15,7 @@ import info.frostfs.sdk.tools.RequestConstructor; import info.frostfs.sdk.tools.Verifier; import static info.frostfs.sdk.tools.RequestSigner.sign; +import static info.frostfs.sdk.utils.DeadLineUtil.deadLineAfter; public class SessionClientImpl extends ContextAccessor implements SessionClient { private final SessionServiceGrpc.SessionServiceBlockingStub serviceBlockingStub; @@ -23,16 +26,16 @@ public class SessionClientImpl extends ContextAccessor implements SessionClient } @Override - public SessionToken createSession(long expiration) { - var sessionToken = createSessionInternal(expiration); + public SessionToken createSession(PrmSessionCreate args, CallContext ctx) { + var sessionToken = createSessionInternal(args, ctx); var token = SessionMapper.serialize(sessionToken); return new SessionToken(token); } - public Types.SessionToken createSessionInternal(long expiration) { + public Types.SessionToken createSessionInternal(PrmSessionCreate args, CallContext ctx) { var body = Service.CreateRequest.Body.newBuilder() .setOwnerId(OwnerIdMapper.toGrpcMessage(getContext().getOwnerId())) - .setExpiration(expiration) + .setExpiration(args.getExpiration()) .build(); var request = Service.CreateRequest.newBuilder() .setBody(body); @@ -40,11 +43,12 @@ public class SessionClientImpl extends ContextAccessor implements SessionClient RequestConstructor.addMetaHeader(request); sign(request, getContext().getKey()); - return createSession(request.build()); + return createSession(request.build(), ctx); } - private Types.SessionToken createSession(Service.CreateRequest request) { - var response = serviceBlockingStub.create(request); + private Types.SessionToken createSession(Service.CreateRequest request, CallContext ctx) { + var service = deadLineAfter(serviceBlockingStub, ctx.getTimeout(), ctx.getTimeUnit()); + var response = service.create(request); Verifier.checkResponse(response); diff --git a/client/src/main/java/info/frostfs/sdk/services/impl/SessionToolsImpl.java b/client/src/main/java/info/frostfs/sdk/services/impl/SessionToolsImpl.java index 1ee5cbd..c51b673 100644 --- a/client/src/main/java/info/frostfs/sdk/services/impl/SessionToolsImpl.java +++ b/client/src/main/java/info/frostfs/sdk/services/impl/SessionToolsImpl.java @@ -1,12 +1,14 @@ package info.frostfs.sdk.services.impl; -import frostfs.session.Types; import info.frostfs.sdk.dto.session.SessionToken; +import info.frostfs.sdk.exceptions.FrostFSException; 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.SessionTools; +import static info.frostfs.sdk.constants.ErrorConst.SESSION_CREATE_FAILED; import static java.util.Objects.isNull; public class SessionToolsImpl extends ContextAccessor implements SessionTools { @@ -16,11 +18,18 @@ public class SessionToolsImpl extends ContextAccessor implements SessionTools { } @Override - public Types.SessionToken getOrCreateSession(SessionToken sessionToken, ClientEnvironment env) { - if (isNull(sessionToken)) { - return env.getFrostFSClient().createSessionInternal(-1); + public SessionToken getOrCreateSession(ClientEnvironment env, CallContext ctx) { + var token = env.getSessionCache().tryGetValue(env.getSessionKey()); + + 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; } } diff --git a/client/src/main/java/info/frostfs/sdk/services/impl/interceptor/Configuration.java b/client/src/main/java/info/frostfs/sdk/services/impl/interceptor/Configuration.java index d4adcca..cfc9193 100644 --- a/client/src/main/java/info/frostfs/sdk/services/impl/interceptor/Configuration.java +++ b/client/src/main/java/info/frostfs/sdk/services/impl/interceptor/Configuration.java @@ -2,18 +2,21 @@ package info.frostfs.sdk.services.impl.interceptor; import io.prometheus.client.CollectorRegistry; + import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; + public class Configuration { 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 CollectorRegistry collectorRegistry; private final double[] latencyBuckets; private final List labelHeaders; private final boolean isAddCodeLabelToHistograms; + private Configuration( boolean isIncludeLatencyHistograms, 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() { return new Configuration( false /* isIncludeLatencyHistograms */, @@ -119,27 +124,37 @@ public class Configuration { 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() { return isIncludeLatencyHistograms; } - /** Returns the {@link CollectorRegistry} used to record stats. */ + /** + * Returns the {@link CollectorRegistry} used to record stats. + */ public CollectorRegistry getCollectorRegistry() { return collectorRegistry; } - /** Returns the histogram buckets to use for latency metrics. */ + /** + * Returns the histogram buckets to use for latency metrics. + */ public double[] getLatencyBuckets() { 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 getLabelHeaders() { 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() { return isAddCodeLabelToHistograms; } diff --git a/client/src/main/java/info/frostfs/sdk/services/impl/rwhelper/ObjectStreamer.java b/client/src/main/java/info/frostfs/sdk/services/impl/rwhelper/ObjectStreamer.java new file mode 100644 index 0000000..0556fb5 --- /dev/null +++ b/client/src/main/java/info/frostfs/sdk/services/impl/rwhelper/ObjectStreamer.java @@ -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 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 { + 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() { + } + } +} diff --git a/client/src/main/java/info/frostfs/sdk/services/impl/rwhelper/ObjectWriter.java b/client/src/main/java/info/frostfs/sdk/services/impl/rwhelper/ObjectWriter.java index f082507..76327f5 100644 --- a/client/src/main/java/info/frostfs/sdk/services/impl/rwhelper/ObjectWriter.java +++ b/client/src/main/java/info/frostfs/sdk/services/impl/rwhelper/ObjectWriter.java @@ -1,63 +1,41 @@ package info.frostfs.sdk.services.impl.rwhelper; -import frostfs.object.ObjectServiceGrpc; +import com.google.protobuf.ByteString; import frostfs.object.Service; -import info.frostfs.sdk.exceptions.ProcessFrostFSException; -import info.frostfs.sdk.utils.WaitUtil; -import io.grpc.stub.StreamObserver; +import info.frostfs.sdk.dto.object.ObjectId; +import info.frostfs.sdk.jdo.ClientEnvironment; +import info.frostfs.sdk.jdo.parameters.object.PrmObjectPutBase; +import info.frostfs.sdk.tools.Verifier; +import lombok.AllArgsConstructor; import lombok.Getter; -import static info.frostfs.sdk.constants.ErrorConst.PROTO_MESSAGE_IS_EMPTY_TEMPLATE; -import static java.util.Objects.isNull; +import static info.frostfs.sdk.tools.RequestSigner.sign; +//todo specify a deadline for each stream request, not for the entire stream +@Getter +@AllArgsConstructor public class ObjectWriter { - private static final long POLL_INTERVAL = 10; - private final StreamObserver requestObserver; - private final PutResponseCallback responseObserver; + private final ClientEnvironment environment; + private final PrmObjectPutBase args; + private final ObjectStreamer streamer; - public ObjectWriter(ObjectServiceGrpc.ObjectServiceStub objectServiceStub) { - PutResponseCallback responseObserver = new PutResponseCallback(); + public void write(byte[] buffer) { + var body = Service.PutRequest.Body.newBuilder() + .setChunk(ByteString.copyFrom(buffer)) + .build(); + var chunkRequest = Service.PutRequest.newBuilder() + .setBody(body) + .clearVerifyHeader(); - this.responseObserver = responseObserver; - this.requestObserver = objectServiceStub.put(responseObserver); + sign(chunkRequest, environment.getKey()); + + streamer.write(chunkRequest.build()); } - public void write(Service.PutRequest request) { - if (isNull(request)) { - throw new ProcessFrostFSException( - String.format(PROTO_MESSAGE_IS_EMPTY_TEMPLATE, Service.PutRequest.class.getName()) - ); - } + public ObjectId complete() { + var response = streamer.complete(); + Verifier.checkResponse(response); - 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 { - 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() { - } + return new ObjectId(response.getBody().getObjectId().getValue().toByteArray()); } } diff --git a/client/src/main/java/info/frostfs/sdk/tools/RequestConstructor.java b/client/src/main/java/info/frostfs/sdk/tools/RequestConstructor.java index 9ad7457..af2150d 100644 --- a/client/src/main/java/info/frostfs/sdk/tools/RequestConstructor.java +++ b/client/src/main/java/info/frostfs/sdk/tools/RequestConstructor.java @@ -4,9 +4,11 @@ import com.google.protobuf.ByteString; import com.google.protobuf.Message; import frostfs.session.Types; import info.frostfs.sdk.dto.response.MetaHeader; +import info.frostfs.sdk.dto.session.SessionToken; import info.frostfs.sdk.exceptions.ValidationFrostFSException; import info.frostfs.sdk.jdo.ECDsa; import info.frostfs.sdk.mappers.response.MetaHeaderMapper; +import info.frostfs.sdk.mappers.session.SessionMapper; import org.apache.commons.collections4.MapUtils; import java.util.Map; @@ -65,13 +67,11 @@ public class RequestConstructor { 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, Types.ObjectSessionContext.Verb verb, ECDsa key) { - if (isNull(sessionToken) || sessionToken.getBody().getObject().getTarget().getSerializedSize() > 0) { - return sessionToken; - } + var protoToken = SessionMapper.deserializeSessionToken(sessionToken.getToken()); var target = Types.ObjectSessionContext.Target.newBuilder() .setContainer(address.getContainerId()); @@ -84,25 +84,23 @@ public class RequestConstructor { .setTarget(target.build()) .setVerb(verb) .build(); - var body = sessionToken.getBody().toBuilder() + var body = protoToken.getBody().toBuilder() .setObject(ctx) .setSessionKey(ByteString.copyFrom(key.getPublicKeyByte())) .build(); - return sessionToken.toBuilder() + return protoToken.toBuilder() .setSignature(signMessagePart(key, body)) .setBody(body) .build(); } - public static Types.SessionToken createContainerTokenContext(Types.SessionToken sessionToken, + public static Types.SessionToken createContainerTokenContext(SessionToken sessionToken, frostfs.refs.Types.ContainerID containerId, Types.ContainerSessionContext.Verb verb, frostfs.refs.Types.OwnerID ownerId, ECDsa key) { - if (isNull(sessionToken) || sessionToken.getBody().getContainer().getContainerId().getSerializedSize() > 0) { - return sessionToken; - } + var protoToken = SessionMapper.deserializeSessionToken(sessionToken.getToken()); var containerSession = Types.ContainerSessionContext.newBuilder().setVerb(verb); @@ -112,7 +110,7 @@ public class RequestConstructor { containerSession.setContainerId(containerId); } - var bodyBuilder = sessionToken.getBody().toBuilder() + var bodyBuilder = protoToken.getBody().toBuilder() .setContainer(containerSession) .setSessionKey(ByteString.copyFrom(key.getPublicKeyByte())); @@ -122,7 +120,7 @@ public class RequestConstructor { var body = bodyBuilder.build(); - return sessionToken.toBuilder() + return protoToken.toBuilder() .setSignature(signMessagePart(key, body)) .setBody(body) .build(); diff --git a/client/src/main/java/info/frostfs/sdk/utils/DeadLineUtil.java b/client/src/main/java/info/frostfs/sdk/utils/DeadLineUtil.java new file mode 100644 index 0000000..96ea46f --- /dev/null +++ b/client/src/main/java/info/frostfs/sdk/utils/DeadLineUtil.java @@ -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 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; + } +} diff --git a/client/src/test/java/info/frostfs/sdk/services/AccountingClientTest.java b/client/src/test/java/info/frostfs/sdk/services/AccountingClientTest.java index e887223..b137af2 100644 --- a/client/src/test/java/info/frostfs/sdk/services/AccountingClientTest.java +++ b/client/src/test/java/info/frostfs/sdk/services/AccountingClientTest.java @@ -5,6 +5,7 @@ import frostfs.accounting.Service; import info.frostfs.sdk.Base58; import info.frostfs.sdk.dto.object.OwnerId; import info.frostfs.sdk.jdo.ClientEnvironment; +import info.frostfs.sdk.jdo.parameters.CallContext; import info.frostfs.sdk.services.impl.AccountingClientImpl; import info.frostfs.sdk.testgenerator.AccountingGenerator; import info.frostfs.sdk.tools.RequestConstructor; @@ -81,11 +82,11 @@ class AccountingClientTest { when(AccountingServiceClient.balance(captor.capture())).thenReturn(response); //When - var result = accountingClient.getBalance(); + var result = accountingClient.getBalance(new CallContext(0, null)); //Then requestConstructorMock.verify( - () -> RequestConstructor.addMetaHeader(any(Service.BalanceRequest.Builder.class), eq(null)), + () -> RequestConstructor.addMetaHeader(any(Service.BalanceRequest.Builder.class)), times(1) ); requestSignerMock.verify( diff --git a/client/src/test/java/info/frostfs/sdk/services/ApeManagerClientTest.java b/client/src/test/java/info/frostfs/sdk/services/ApeManagerClientTest.java index 7cdfcff..fa09315 100644 --- a/client/src/test/java/info/frostfs/sdk/services/ApeManagerClientTest.java +++ b/client/src/test/java/info/frostfs/sdk/services/ApeManagerClientTest.java @@ -8,6 +8,10 @@ import info.frostfs.sdk.dto.chain.ChainTarget; import info.frostfs.sdk.enums.TargetType; import info.frostfs.sdk.exceptions.ValidationFrostFSException; 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.testgenerator.ApeManagerGenerator; import info.frostfs.sdk.tools.RequestConstructor; @@ -78,6 +82,7 @@ class ApeManagerClientTest { //Given Chain chain = generateChain(); ChainTarget chainTarget = generateChainTarget(); + PrmApeChainAdd params = new PrmApeChainAdd(chain, chainTarget); var response = ApeManagerGenerator.generateAddChainResponse(); @@ -86,7 +91,7 @@ class ApeManagerClientTest { when(apeManagerServiceClient.addChain(captor.capture())).thenReturn(response); //When - var result = apeManagerClient.addChain(chain, chainTarget); + var result = apeManagerClient.addChain(params, new CallContext(0, null)); //Then requestConstructorMock.verify( @@ -112,11 +117,15 @@ class ApeManagerClientTest { //Given Chain chain = generateChain(); ChainTarget chainTarget = generateChainTarget(); + PrmApeChainAdd params1 = new PrmApeChainAdd(null, chainTarget); + PrmApeChainAdd params2 = new PrmApeChainAdd(chain, null); + PrmApeChainAdd params3 = new PrmApeChainAdd(null, null); + //When + Then - assertThrows(ValidationFrostFSException.class, () -> apeManagerClient.addChain(null, chainTarget)); - assertThrows(ValidationFrostFSException.class, () -> apeManagerClient.addChain(chain, null)); - assertThrows(ValidationFrostFSException.class, () -> apeManagerClient.addChain(null, null)); + assertThrows(ValidationFrostFSException.class, () -> apeManagerClient.addChain(params1, new CallContext())); + assertThrows(ValidationFrostFSException.class, () -> apeManagerClient.addChain(params2, new CallContext())); + assertThrows(ValidationFrostFSException.class, () -> apeManagerClient.addChain(params3, new CallContext())); } @Test @@ -124,6 +133,7 @@ class ApeManagerClientTest { //Given Chain chain = generateChain(); ChainTarget chainTarget = generateChainTarget(); + PrmApeChainRemove params = new PrmApeChainRemove(chain, chainTarget); var response = ApeManagerGenerator.generateRemoveChainResponse(); @@ -132,7 +142,7 @@ class ApeManagerClientTest { when(apeManagerServiceClient.removeChain(captor.capture())).thenReturn(response); //When - apeManagerClient.removeChain(chain, chainTarget); + apeManagerClient.removeChain(params, new CallContext(0, null)); //Then requestConstructorMock.verify( @@ -156,17 +166,21 @@ class ApeManagerClientTest { //Given Chain chain = generateChain(); ChainTarget chainTarget = generateChainTarget(); + PrmApeChainRemove params1 = new PrmApeChainRemove(null, chainTarget); + PrmApeChainRemove params2 = new PrmApeChainRemove(chain, null); + PrmApeChainRemove params3 = new PrmApeChainRemove(null, null); //When + Then - assertThrows(ValidationFrostFSException.class, () -> apeManagerClient.removeChain(null, chainTarget)); - assertThrows(ValidationFrostFSException.class, () -> apeManagerClient.removeChain(chain, null)); - assertThrows(ValidationFrostFSException.class, () -> apeManagerClient.removeChain(null, null)); + assertThrows(ValidationFrostFSException.class, () -> apeManagerClient.removeChain(params1, new CallContext())); + assertThrows(ValidationFrostFSException.class, () -> apeManagerClient.removeChain(params2, new CallContext())); + assertThrows(ValidationFrostFSException.class, () -> apeManagerClient.removeChain(params3, new CallContext())); } @Test void listChain_success() { //Given ChainTarget chainTarget = generateChainTarget(); + PrmApeChainList params = new PrmApeChainList(chainTarget); var response = ApeManagerGenerator.generateListChainsResponse(); @@ -175,7 +189,7 @@ class ApeManagerClientTest { when(apeManagerServiceClient.listChains(captor.capture())).thenReturn(response); //When - var result = apeManagerClient.listChains(chainTarget); + var result = apeManagerClient.listChains(params, new CallContext(0, null)); //Then requestConstructorMock.verify( @@ -202,7 +216,8 @@ class ApeManagerClientTest { @Test void listChain_wrongParams() { //When + Then - assertThrows(ValidationFrostFSException.class, () -> apeManagerClient.listChains(null)); + assertThrows(ValidationFrostFSException.class, + () -> apeManagerClient.listChains(new PrmApeChainList(null), new CallContext())); } private Chain generateChain() { diff --git a/cryptography/pom.xml b/cryptography/pom.xml index 606a193..ac56a86 100644 --- a/cryptography/pom.xml +++ b/cryptography/pom.xml @@ -6,7 +6,7 @@ info.frostfs.sdk frostfs-sdk-java - 0.2.0 + 0.3.0 cryptography @@ -21,7 +21,7 @@ info.frostfs.sdk exceptions - 0.2.0 + 0.3.0 com.google.protobuf diff --git a/exceptions/pom.xml b/exceptions/pom.xml index a24f1fc..4cb8bcc 100644 --- a/exceptions/pom.xml +++ b/exceptions/pom.xml @@ -6,7 +6,7 @@ info.frostfs.sdk frostfs-sdk-java - 0.2.0 + 0.3.0 exceptions diff --git a/exceptions/src/main/java/info/frostfs/sdk/constants/ErrorConst.java b/exceptions/src/main/java/info/frostfs/sdk/constants/ErrorConst.java index 26f3eac..62c3eb8 100644 --- a/exceptions/src/main/java/info/frostfs/sdk/constants/ErrorConst.java +++ b/exceptions/src/main/java/info/frostfs/sdk/constants/ErrorConst.java @@ -46,6 +46,8 @@ public class ErrorConst { 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 SESSION_CREATE_FAILED = "cannot create session"; + public static final String FIELDS_DELIMITER_COMMA = ", "; public static final String FIELDS_DELIMITER_OR = " or "; diff --git a/models/pom.xml b/models/pom.xml index 08dbdc6..32cade4 100644 --- a/models/pom.xml +++ b/models/pom.xml @@ -6,7 +6,7 @@ info.frostfs.sdk frostfs-sdk-java - 0.2.0 + 0.3.0 models @@ -21,17 +21,17 @@ info.frostfs.sdk cryptography - 0.2.0 + 0.3.0 info.frostfs.sdk protos - 0.2.0 + 0.3.0 info.frostfs.sdk exceptions - 0.2.0 + 0.3.0 diff --git a/models/src/main/java/info/frostfs/sdk/constants/AppConst.java b/models/src/main/java/info/frostfs/sdk/constants/AppConst.java index 67a2422..35d64c6 100644 --- a/models/src/main/java/info/frostfs/sdk/constants/AppConst.java +++ b/models/src/main/java/info/frostfs/sdk/constants/AppConst.java @@ -12,6 +12,7 @@ public class AppConst { public static final int OBJECT_CHUNK_SIZE = 3 * MIB; public static final int SHA256_HASH_LENGTH = 32; public static final int UUID_BYTE_ARRAY_LENGTH = 16; + public static final int DEFAULT_GRPC_TIMEOUT = 5; private AppConst() { } diff --git a/models/src/main/java/info/frostfs/sdk/dto/object/SplitInfo.java b/models/src/main/java/info/frostfs/sdk/dto/object/SplitInfo.java new file mode 100644 index 0000000..cbd9e17 --- /dev/null +++ b/models/src/main/java/info/frostfs/sdk/dto/object/SplitInfo.java @@ -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; +} diff --git a/models/src/main/java/info/frostfs/sdk/mappers/container/ContainerMapper.java b/models/src/main/java/info/frostfs/sdk/mappers/container/ContainerMapper.java index 9b9dd72..f0a8196 100644 --- a/models/src/main/java/info/frostfs/sdk/mappers/container/ContainerMapper.java +++ b/models/src/main/java/info/frostfs/sdk/mappers/container/ContainerMapper.java @@ -13,7 +13,6 @@ import java.util.stream.Collectors; import static info.frostfs.sdk.UuidExtension.asBytes; 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 java.util.Objects.isNull; @@ -31,7 +30,6 @@ public class ContainerMapper { .setPlacementPolicy(PlacementPolicyMapper.toGrpcMessage(container.getPlacementPolicy())) .setNonce(ByteString.copyFrom(asBytes(container.getNonce()))); - container.getAttributes().putIfAbsent(DISABLE_HOMOMORPHIC_HASHING_ATTRIBUTE, Boolean.TRUE.toString()); var attributes = container.getAttributes().entrySet().stream() .map(entry -> Types.Container.Attribute.newBuilder() diff --git a/models/src/main/java/info/frostfs/sdk/mappers/object/SplitInfoMapper.java b/models/src/main/java/info/frostfs/sdk/mappers/object/SplitInfoMapper.java new file mode 100644 index 0000000..ac5f6ae --- /dev/null +++ b/models/src/main/java/info/frostfs/sdk/mappers/object/SplitInfoMapper.java @@ -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); + } +} diff --git a/models/src/test/java/info/frostfs/sdk/mappers/object/SplitInfoMapperTest.java b/models/src/test/java/info/frostfs/sdk/mappers/object/SplitInfoMapperTest.java new file mode 100644 index 0000000..3e9ca2b --- /dev/null +++ b/models/src/test/java/info/frostfs/sdk/mappers/object/SplitInfoMapperTest.java @@ -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())); + } +} diff --git a/pom.xml b/pom.xml index 2c9f30e..72eb9eb 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ info.frostfs.sdk frostfs-sdk-java - 0.2.0 + 0.3.0 pom client diff --git a/protos/pom.xml b/protos/pom.xml index d08ae98..d3a2b3b 100644 --- a/protos/pom.xml +++ b/protos/pom.xml @@ -6,7 +6,7 @@ info.frostfs.sdk frostfs-sdk-java - 0.2.0 + 0.3.0 protos