From 520b49bb6fd1780512459f742bedcb9bcce2de5e Mon Sep 17 00:00:00 2001 From: Bruk Ori Date: Tue, 16 Jul 2024 15:00:17 +0300 Subject: [PATCH] [#XX] Refactor client structure add session logic add network logic Signed-off-by: Ori Bruk --- README.md | 4 +- client/pom.xml | 15 -- .../main/java/info/FrostFS/sdk/Client.java | 36 ----- .../java/info/FrostFS/sdk/ClientSettings.java | 57 +++++++ .../java/info/FrostFS/sdk/GrpcClient.java | 81 ++-------- .../src/main/java/info/FrostFS/sdk/Main.java | 54 +++++++ .../java/info/FrostFS/sdk/RequestSigner.java | 27 +++- .../main/java/info/FrostFS/sdk/Verifier.java | 14 +- .../FrostFS/sdk/services/ContextAccessor.java | 19 +++ .../FrostFS/sdk/services/FrostFSClient.java | 134 ++++++++++++++++ .../FrostFS/sdk/services/NetmapClient.java | 14 ++ .../FrostFS/sdk/services/SessionClient.java | 8 + .../FrostFS/sdk/services/ToolsClient.java | 8 + .../sdk/services/impl/ContainerService.java | 48 +++--- .../sdk/services/impl/FrostFSClient.java | 85 ----------- .../sdk/services/impl/NetmapService.java | 139 +++++++++++++++-- .../sdk/services/impl/ObjectService.java | 54 +++---- .../sdk/services/impl/SessionService.java | 30 ++-- .../FrostFS/sdk/tools/ClientEnvironment.java | 60 ++++++++ .../FrostFS/sdk/tools/NetworkSettings.java | 143 ++++++++++++++++++ .../info/FrostFS/sdk/jdo/SessionToken.java | 19 +++ .../sdk/jdo/netmap/NetmapSnapshot.java | 21 +++ .../info/FrostFS/sdk/jdo/netmap/NodeInfo.java | 30 +++- .../FrostFS/sdk/mappers/SessionMapper.java | 31 ++++ .../mappers/netmap/NetmapSnapshotMapper.java | 18 +++ .../sdk/mappers/netmap/NodeInfoMapper.java | 21 ++- 26 files changed, 868 insertions(+), 302 deletions(-) delete mode 100644 client/src/main/java/info/FrostFS/sdk/Client.java create mode 100644 client/src/main/java/info/FrostFS/sdk/ClientSettings.java create mode 100644 client/src/main/java/info/FrostFS/sdk/Main.java create mode 100644 client/src/main/java/info/FrostFS/sdk/services/ContextAccessor.java create mode 100644 client/src/main/java/info/FrostFS/sdk/services/FrostFSClient.java create mode 100644 client/src/main/java/info/FrostFS/sdk/services/NetmapClient.java create mode 100644 client/src/main/java/info/FrostFS/sdk/services/SessionClient.java create mode 100644 client/src/main/java/info/FrostFS/sdk/services/ToolsClient.java delete mode 100644 client/src/main/java/info/FrostFS/sdk/services/impl/FrostFSClient.java create mode 100644 client/src/main/java/info/FrostFS/sdk/tools/ClientEnvironment.java create mode 100644 client/src/main/java/info/FrostFS/sdk/tools/NetworkSettings.java create mode 100644 modelsV2/src/main/java/info/FrostFS/sdk/jdo/SessionToken.java create mode 100644 modelsV2/src/main/java/info/FrostFS/sdk/jdo/netmap/NetmapSnapshot.java create mode 100644 modelsV2/src/main/java/info/FrostFS/sdk/mappers/SessionMapper.java create mode 100644 modelsV2/src/main/java/info/FrostFS/sdk/mappers/netmap/NetmapSnapshotMapper.java diff --git a/README.md b/README.md index 26697ca..2883006 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ import info.FrostFS.sdk.enums.BasicAcl; import info.FrostFS.sdk.jdo.Container; import info.FrostFS.sdk.jdo.netmap.PlacementPolicy; import info.FrostFS.sdk.jdo.netmap.Replica; -import info.FrostFS.sdk.services.impl.FrostFSClient; +import info.FrostFS.sdk.services.FrostFSClient; public class ContainerExample { @@ -58,7 +58,7 @@ import info.FrostFS.sdk.jdo.ContainerId; import info.FrostFS.sdk.jdo.ObjectAttribute; import info.FrostFS.sdk.jdo.ObjectFilter; import info.FrostFS.sdk.jdo.ObjectHeader; -import info.FrostFS.sdk.services.impl.FrostFSClient; +import info.FrostFS.sdk.services.FrostFSClient; import java.io.FileInputStream; import java.io.IOException; diff --git a/client/pom.xml b/client/pom.xml index f748035..b416ee4 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -23,26 +23,11 @@ cryptography 0.1.0 - - info.FrostFS.sdk - protosV2 - 0.1.0 - info.FrostFS.sdk modelsV2 0.1.0 - - org.apache.logging.log4j - log4j-api - 2.7 - - - org.apache.logging.log4j - log4j-slf4j-impl - 2.7 - \ No newline at end of file diff --git a/client/src/main/java/info/FrostFS/sdk/Client.java b/client/src/main/java/info/FrostFS/sdk/Client.java deleted file mode 100644 index 2d254b9..0000000 --- a/client/src/main/java/info/FrostFS/sdk/Client.java +++ /dev/null @@ -1,36 +0,0 @@ -package info.FrostFS.sdk; - -import info.FrostFS.sdk.jdo.OwnerId; -import info.FrostFS.sdk.jdo.Version; - -import static info.FrostFS.sdk.KeyExtension.getPrivateKeyFromWIF; -import static info.FrostFS.sdk.KeyExtension.loadPublicKey; - -public class Client { - private final OwnerId ownerId; - private final Version version = new Version(2, 13); - private final byte[] privateKey; - private final byte[] publicKey; - - public Client(String key) { - this.privateKey = getPrivateKeyFromWIF(key); - this.publicKey = loadPublicKey(privateKey); - this.ownerId = OwnerId.fromKey(publicKey); - } - - public OwnerId getOwnerId() { - return ownerId; - } - - public Version getVersion() { - return version; - } - - public byte[] getPrivateKey() { - return privateKey; - } - - public byte[] getPublicKey() { - return publicKey; - } -} diff --git a/client/src/main/java/info/FrostFS/sdk/ClientSettings.java b/client/src/main/java/info/FrostFS/sdk/ClientSettings.java new file mode 100644 index 0000000..3b09497 --- /dev/null +++ b/client/src/main/java/info/FrostFS/sdk/ClientSettings.java @@ -0,0 +1,57 @@ +package info.FrostFS.sdk; + +import io.grpc.ChannelCredentials; +import org.apache.commons.lang3.StringUtils; + +public class ClientSettings { + private static final String ERROR_TEMPLATE = "%s is required parameter."; + + public String key; + public String host; + public ChannelCredentials creds; + + public ClientSettings(String key, String host) { + this.key = key; + this.host = host; + } + + public ChannelCredentials getCreds() { + return creds; + } + + public void setCreds(ChannelCredentials creds) { + this.creds = creds; + } + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public void validate() { + StringBuilder errorMessage = new StringBuilder(); + + if (StringUtils.isEmpty(key)) { + errorMessage.append(String.format(ERROR_TEMPLATE, "Key")).append(System.lineSeparator()); + } + + if (StringUtils.isEmpty(host)) { + errorMessage.append(String.format(ERROR_TEMPLATE, "Host")).append(System.lineSeparator()); + } + + if (errorMessage.length() != 0) { + throw new IllegalArgumentException(errorMessage.toString()); + } + } +} diff --git a/client/src/main/java/info/FrostFS/sdk/GrpcClient.java b/client/src/main/java/info/FrostFS/sdk/GrpcClient.java index 0b32277..9062017 100644 --- a/client/src/main/java/info/FrostFS/sdk/GrpcClient.java +++ b/client/src/main/java/info/FrostFS/sdk/GrpcClient.java @@ -1,89 +1,26 @@ package info.FrostFS.sdk; -import frostFS.container.ContainerServiceGrpc; -import frostFS.netmap.NetmapServiceGrpc; -import frostFS.object.ObjectServiceGrpc; -import frostFS.session.SessionServiceGrpc; import io.grpc.Channel; -import io.grpc.netty.GrpcSslContexts; +import io.grpc.ChannelCredentials; import io.grpc.netty.NettyChannelBuilder; -import io.netty.handler.ssl.util.InsecureTrustManagerFactory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import javax.net.ssl.SSLException; import java.net.URI; import java.net.URISyntaxException; +import static java.util.Objects.isNull; + public class GrpcClient { - private static final Logger log = LoggerFactory.getLogger(GrpcClient.class); - private final ContainerServiceGrpc.ContainerServiceBlockingStub containerServiceBlockingClient; - private final NetmapServiceGrpc.NetmapServiceBlockingStub netmapServiceBlockingClient; - private final ObjectServiceGrpc.ObjectServiceBlockingStub objectServiceBlockingClient; - private final ObjectServiceGrpc.ObjectServiceStub objectServiceClient; - private final SessionServiceGrpc.SessionServiceBlockingStub sessionServiceBlockingClient; - - public GrpcClient(String host) { - Channel channel = initGrpcChannel(host); - this.containerServiceBlockingClient = ContainerServiceGrpc.newBlockingStub(channel); - this.netmapServiceBlockingClient = NetmapServiceGrpc.newBlockingStub(channel); - this.objectServiceBlockingClient = ObjectServiceGrpc.newBlockingStub(channel); - this.objectServiceClient = ObjectServiceGrpc.newStub(channel); - this.sessionServiceBlockingClient = SessionServiceGrpc.newBlockingStub(channel); - } - - public static Channel initGrpcChannel(String host) { - URI uri; + public static Channel initGrpcChannel(String host, ChannelCredentials creds) { try { - uri = new URI(host); + URI uri = new URI(host); + var channelBuilder = isNull(creds) ? NettyChannelBuilder.forAddress(uri.getHost(), uri.getPort()) + : NettyChannelBuilder.forAddress(uri.getHost(), uri.getPort(), creds); + + return channelBuilder.usePlaintext().build(); } catch (URISyntaxException exp) { var message = String.format("Host %s has invalid format. Error: %s", host, exp.getMessage()); - log.error(message); throw new IllegalArgumentException(message); } - - var channelBuilder = NettyChannelBuilder.forAddress(uri.getHost(), uri.getPort()) - .usePlaintext(); - - switch (uri.getScheme()) { - case "https": - try { - channelBuilder.sslContext( - GrpcSslContexts.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE).build() - ); - } catch (SSLException e) { - throw new RuntimeException(e); - } - break; - case "http": - break; - default: - var message = String.format("Host %s has invalid URI scheme: %s", host, uri.getScheme()); - log.error(message); - throw new IllegalArgumentException(message); - } - - return channelBuilder.build(); - } - - public ContainerServiceGrpc.ContainerServiceBlockingStub getContainerServiceBlockingClient() { - return containerServiceBlockingClient; - } - - public NetmapServiceGrpc.NetmapServiceBlockingStub getNetmapServiceBlockingClient() { - return netmapServiceBlockingClient; - } - - public ObjectServiceGrpc.ObjectServiceBlockingStub getObjectServiceBlockingClient() { - return objectServiceBlockingClient; - } - - public ObjectServiceGrpc.ObjectServiceStub getObjectServiceClient() { - return objectServiceClient; - } - - public SessionServiceGrpc.SessionServiceBlockingStub getSessionServiceBlockingClient() { - return sessionServiceBlockingClient; } } diff --git a/client/src/main/java/info/FrostFS/sdk/Main.java b/client/src/main/java/info/FrostFS/sdk/Main.java new file mode 100644 index 0000000..d16f06e --- /dev/null +++ b/client/src/main/java/info/FrostFS/sdk/Main.java @@ -0,0 +1,54 @@ +package info.FrostFS.sdk; + +import info.FrostFS.sdk.enums.BasicAcl; +import info.FrostFS.sdk.enums.ObjectType; +import info.FrostFS.sdk.jdo.*; +import info.FrostFS.sdk.jdo.netmap.PlacementPolicy; +import info.FrostFS.sdk.jdo.netmap.Replica; +import info.FrostFS.sdk.services.FrostFSClient; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.util.List; + +public class Main { + public static void main(String[] args) throws Exception { + ClientSettings clientSettings = new ClientSettings("KwHDAJ66o8FoLBjVbjP2sWBmgBMGjt7Vv4boA7xQrBoAYBE397Aq", "http://localhost:8080"); + FrostFSClient frostFSClient = new FrostFSClient(clientSettings); +/* + var res2 = frostFSClient.searchObjectsAsync(new ContainerId("EQGx2QeYHJb53uRwYGzcQaW191sZpdNrjutk6veUSV2R")); +*/ + + ObjectFrostFs res3 = frostFSClient + .getObjectAsync(new ContainerId("EQGx2QeYHJb53uRwYGzcQaW191sZpdNrjutk6veUSV2R"), new ObjectId("85orCLKSu3X1jGiTFmwmTUsBU88RBARNwuRwrEy5pyww")); + + + var ttttt = frostFSClient.getNetworkSettingsAsync(); + Container container2 = frostFSClient.getContainerAsync(new ContainerId("EQGx2QeYHJb53uRwYGzcQaW191sZpdNrjutk6veUSV2R")); + + + var placementPolicy = new PlacementPolicy(true, new Replica[]{new Replica(1)}); + var containerId = frostFSClient.createContainerAsync(new Container(BasicAcl.PUBLIC_RW, placementPolicy)); + Thread.sleep(1000); + + FileInputStream file = null; + try { + file = new FileInputStream("/home/ori/Desktop/cat.jpg"); + var cat = new ObjectHeader(containerId, ObjectType.REGULAR, new ObjectAttribute[]{new ObjectAttribute("Filename", "cat.jpg")}); + frostFSClient.putObjectAsync(cat, file); + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } + + var res = frostFSClient.searchObjectsAsync(containerId); + + + Container container = frostFSClient.getContainerAsync(containerId); + List containerIds = frostFSClient.listContainersAsync(); +/* + frostFSClient.deleteContainerAsync(containerId); +*/ + containerIds = frostFSClient.listContainersAsync(); + System.out.println(); + } +} \ No newline at end of file diff --git a/client/src/main/java/info/FrostFS/sdk/RequestSigner.java b/client/src/main/java/info/FrostFS/sdk/RequestSigner.java index 264d52a..962a421 100644 --- a/client/src/main/java/info/FrostFS/sdk/RequestSigner.java +++ b/client/src/main/java/info/FrostFS/sdk/RequestSigner.java @@ -62,21 +62,27 @@ public class RequestSigner { return signature; } - public static frostFS.refs.Types.SignatureRFC6979 signRFC6979(byte[] publicKey, byte[] privateKey, AbstractMessage message) { + public static frostFS.refs.Types.SignatureRFC6979 signRFC6979(byte[] publicKey, + byte[] privateKey, + AbstractMessage message) { return frostFS.refs.Types.SignatureRFC6979.newBuilder() .setKey(ByteString.copyFrom(publicKey)) .setSign(ByteString.copyFrom(signRFC6979(privateKey, message.toByteArray()))) .build(); } - public static frostFS.refs.Types.SignatureRFC6979 signRFC6979(byte[] publicKey, byte[] privateKey, ByteString data) { + public static frostFS.refs.Types.SignatureRFC6979 signRFC6979(byte[] publicKey, + byte[] privateKey, + ByteString data) { return frostFS.refs.Types.SignatureRFC6979.newBuilder() .setKey(ByteString.copyFrom(publicKey)) .setSign(ByteString.copyFrom(signRFC6979(privateKey, data.toByteArray()))) .build(); } - public static frostFS.refs.Types.Signature signMessagePart(byte[] publicKey, byte[] privateKey, AbstractMessage data) { + public static frostFS.refs.Types.Signature signMessagePart(byte[] publicKey, + byte[] privateKey, + AbstractMessage data) { var data2Sign = data.getSerializedSize() == 0 ? new byte[]{} : data.toByteArray(); return frostFS.refs.Types.Signature.newBuilder() @@ -101,13 +107,22 @@ public class RequestSigner { var verifyOrigin = (AbstractMessage) verify.getField(verify.getDescriptorForType().findFieldByName("origin")); if (verifyOrigin.getSerializedSize() == 0) { - verifyBuilder.setField(verifyBuilder.getDescriptorForType().findFieldByName("body_signature"), signMessagePart(publicKey, privateKey, body)); + verifyBuilder.setField( + verifyBuilder.getDescriptorForType().findFieldByName("body_signature"), + signMessagePart(publicKey, privateKey, body) + ); } else { verifyBuilder.setField(verifyBuilder.getDescriptorForType().findFieldByName("origin"), verifyOrigin); } - verifyBuilder.setField(verifyBuilder.getDescriptorForType().findFieldByName("meta_signature"), signMessagePart(publicKey, privateKey, meta)); - verifyBuilder.setField(verifyBuilder.getDescriptorForType().findFieldByName("origin_signature"), signMessagePart(publicKey, privateKey, verifyOrigin)); + verifyBuilder.setField( + verifyBuilder.getDescriptorForType().findFieldByName("meta_signature"), + signMessagePart(publicKey, privateKey, meta) + ); + verifyBuilder.setField( + verifyBuilder.getDescriptorForType().findFieldByName("origin_signature"), + signMessagePart(publicKey, privateKey, verifyOrigin) + ); request.setField(request.getDescriptorForType().findFieldByName("verify_header"), verifyBuilder.build()); } diff --git a/client/src/main/java/info/FrostFS/sdk/Verifier.java b/client/src/main/java/info/FrostFS/sdk/Verifier.java index 657be82..7a1b136 100644 --- a/client/src/main/java/info/FrostFS/sdk/Verifier.java +++ b/client/src/main/java/info/FrostFS/sdk/Verifier.java @@ -22,10 +22,12 @@ import static org.bouncycastle.crypto.util.DigestFactory.createSHA256; import static org.bouncycastle.util.BigIntegers.fromUnsignedByteArray; public class Verifier { - public static final int RFC6979_SIGNATURE_SIZE = 64; + public static final int RFC6979_SIG_SIZE = 64; public static boolean verifyRFC6979(Types.SignatureRFC6979 signature, AbstractMessage message) { - return verifyRFC6979(signature.getKey().toByteArray(), message.toByteArray(), signature.getSign().toByteArray()); + return verifyRFC6979( + signature.getKey().toByteArray(), message.toByteArray(), signature.getSign().toByteArray() + ); } public static boolean verifyRFC6979(byte[] publicKey, byte[] data, byte[] sig) { @@ -45,17 +47,17 @@ public class Verifier { } private static BigInteger[] decodeSignature(byte[] sig) { - if (sig.length != RFC6979_SIGNATURE_SIZE) { + if (sig.length != RFC6979_SIG_SIZE) { throw new IllegalArgumentException( String.format("Wrong signature size. Expected length=%s, actual=%s", - RFC6979_SIGNATURE_SIZE, sig.length) + RFC6979_SIG_SIZE, sig.length) ); } var rs = new BigInteger[2]; - rs[0] = fromUnsignedByteArray(Arrays.copyOfRange(sig, 0, (RFC6979_SIGNATURE_SIZE / 2) - 1)); - rs[1] = fromUnsignedByteArray(Arrays.copyOfRange(sig, RFC6979_SIGNATURE_SIZE / 2, RFC6979_SIGNATURE_SIZE - 1)); + rs[0] = fromUnsignedByteArray(Arrays.copyOfRange(sig, 0, (RFC6979_SIG_SIZE / 2) - 1)); + rs[1] = fromUnsignedByteArray(Arrays.copyOfRange(sig, RFC6979_SIG_SIZE / 2, RFC6979_SIG_SIZE - 1)); return rs; } diff --git a/client/src/main/java/info/FrostFS/sdk/services/ContextAccessor.java b/client/src/main/java/info/FrostFS/sdk/services/ContextAccessor.java new file mode 100644 index 0000000..6985310 --- /dev/null +++ b/client/src/main/java/info/FrostFS/sdk/services/ContextAccessor.java @@ -0,0 +1,19 @@ +package info.FrostFS.sdk.services; + +import info.FrostFS.sdk.tools.ClientEnvironment; + +public class ContextAccessor { + protected ClientEnvironment context; + + public ContextAccessor(ClientEnvironment context) { + this.context = context; + } + + public ClientEnvironment getContext() { + return context; + } + + public void setContext(ClientEnvironment context) { + this.context = context; + } +} diff --git a/client/src/main/java/info/FrostFS/sdk/services/FrostFSClient.java b/client/src/main/java/info/FrostFS/sdk/services/FrostFSClient.java new file mode 100644 index 0000000..44a0388 --- /dev/null +++ b/client/src/main/java/info/FrostFS/sdk/services/FrostFSClient.java @@ -0,0 +1,134 @@ +package info.FrostFS.sdk.services; + +import frostFS.session.Types; +import info.FrostFS.sdk.ClientSettings; +import info.FrostFS.sdk.jdo.*; +import info.FrostFS.sdk.jdo.netmap.NetmapSnapshot; +import info.FrostFS.sdk.jdo.netmap.NodeInfo; +import info.FrostFS.sdk.services.impl.ContainerService; +import info.FrostFS.sdk.services.impl.NetmapService; +import info.FrostFS.sdk.services.impl.ObjectService; +import info.FrostFS.sdk.services.impl.SessionService; +import info.FrostFS.sdk.tools.ClientEnvironment; +import info.FrostFS.sdk.tools.NetworkSettings; +import io.grpc.Channel; + +import java.io.FileInputStream; +import java.util.List; + +import static info.FrostFS.sdk.GrpcClient.initGrpcChannel; +import static java.util.Objects.isNull; + +public class FrostFSClient implements ContainerClient, ObjectClient, NetmapClient, SessionClient, ToolsClient { + private final ContainerService containerService; + private final NetmapService netmapService; + private final ObjectService objectService; + private final SessionService sessionService; + private final ClientEnvironment clientEnvironment; + + public FrostFSClient(ClientSettings clientSettings) { + if (isNull(clientSettings)) { + throw new IllegalArgumentException("Options must be initialized"); + } + + clientSettings.validate(); + Channel channel = initGrpcChannel(clientSettings.getHost(), clientSettings.getCreds()); + + this.clientEnvironment = + new ClientEnvironment(clientSettings.getKey(), channel, new Version(2, 13), this); + + this.containerService = new ContainerService(clientEnvironment); + this.netmapService = new NetmapService(clientEnvironment); + this.sessionService = new SessionService(clientEnvironment); + this.objectService = new ObjectService(clientEnvironment); + checkFrostFsVersionSupport(clientEnvironment.getVersion()); + } + + private void checkFrostFsVersionSupport(Version version) { + var localNodeInfo = netmapService.getLocalNodeInfoAsync(); + if (!localNodeInfo.getVersion().isSupported(version)) { + var msg = String.format("FrostFS %s is not supported.", localNodeInfo.getVersion()); + System.out.println(msg); + throw new IllegalArgumentException(msg); + } + } + + @Override + public Container getContainerAsync(ContainerId cid) { + return containerService.getContainerAsync(cid); + } + + @Override + public List listContainersAsync() { + return containerService.listContainersAsync(); + } + + @Override + public ContainerId createContainerAsync(Container container) { + return containerService.createContainerAsync(container); + } + + @Override + public void deleteContainerAsync(ContainerId cid) { + containerService.deleteContainerAsync(cid); + } + + @Override + public ObjectHeader getObjectHeadAsync(ContainerId containerId, ObjectId objectId) { + return objectService.getObjectHeadAsync(containerId, objectId); + } + + @Override + public ObjectFrostFs getObjectAsync(ContainerId containerId, ObjectId objectId) { + return objectService.getObjectAsync(containerId, objectId); + } + + @Override + public ObjectId putObjectAsync(ObjectHeader header, FileInputStream payload) { + return objectService.putObjectAsync(header, payload); + } + + @Override + public ObjectId putObjectAsync(ObjectHeader header, byte[] payload) { + return objectService.putObjectAsync(header, payload); + } + + @Override + public void deleteObjectAsync(ContainerId containerId, ObjectId objectId) { + objectService.deleteObjectAsync(containerId, objectId); + } + + @Override + public Iterable searchObjectsAsync(ContainerId cid, ObjectFilter... filters) { + return objectService.searchObjectsAsync(cid, filters); + } + + @Override + public NetmapSnapshot getNetmapSnapshotAsync() { + return netmapService.getNetmapSnapshotAsync(); + } + + @Override + public NodeInfo getLocalNodeInfoAsync() { + return netmapService.getLocalNodeInfoAsync(); + } + + @Override + public NetworkSettings getNetworkSettingsAsync() { + return netmapService.getNetworkSettingsAsync(); + } + + @Override + public SessionToken createSessionAsync(long expiration) { + return sessionService.createSessionAsync(expiration); + } + + public Types.SessionToken createSessionInternalAsync(long expiration) { + return sessionService.createSessionInternalAsync(expiration); + } + + @Override + public ObjectId CalculateObjectId(ObjectHeader header) { + return null; + } +} diff --git a/client/src/main/java/info/FrostFS/sdk/services/NetmapClient.java b/client/src/main/java/info/FrostFS/sdk/services/NetmapClient.java new file mode 100644 index 0000000..f6e9401 --- /dev/null +++ b/client/src/main/java/info/FrostFS/sdk/services/NetmapClient.java @@ -0,0 +1,14 @@ +package info.FrostFS.sdk.services; + +import info.FrostFS.sdk.jdo.netmap.NetmapSnapshot; +import info.FrostFS.sdk.jdo.netmap.NodeInfo; +import info.FrostFS.sdk.tools.NetworkSettings; + +public interface NetmapClient { + + NetmapSnapshot getNetmapSnapshotAsync(); + + NodeInfo getLocalNodeInfoAsync(); + + NetworkSettings getNetworkSettingsAsync(); +} diff --git a/client/src/main/java/info/FrostFS/sdk/services/SessionClient.java b/client/src/main/java/info/FrostFS/sdk/services/SessionClient.java new file mode 100644 index 0000000..ffd1f0a --- /dev/null +++ b/client/src/main/java/info/FrostFS/sdk/services/SessionClient.java @@ -0,0 +1,8 @@ +package info.FrostFS.sdk.services; + +import info.FrostFS.sdk.jdo.SessionToken; + +public interface SessionClient { + + SessionToken createSessionAsync(long expiration); +} diff --git a/client/src/main/java/info/FrostFS/sdk/services/ToolsClient.java b/client/src/main/java/info/FrostFS/sdk/services/ToolsClient.java new file mode 100644 index 0000000..62dffc2 --- /dev/null +++ b/client/src/main/java/info/FrostFS/sdk/services/ToolsClient.java @@ -0,0 +1,8 @@ +package info.FrostFS.sdk.services; + +import info.FrostFS.sdk.jdo.ObjectHeader; +import info.FrostFS.sdk.jdo.ObjectId; + +public interface ToolsClient { + ObjectId CalculateObjectId(ObjectHeader header); +} diff --git a/client/src/main/java/info/FrostFS/sdk/services/impl/ContainerService.java b/client/src/main/java/info/FrostFS/sdk/services/impl/ContainerService.java index 782c218..824f967 100644 --- a/client/src/main/java/info/FrostFS/sdk/services/impl/ContainerService.java +++ b/client/src/main/java/info/FrostFS/sdk/services/impl/ContainerService.java @@ -2,7 +2,6 @@ package info.FrostFS.sdk.services.impl; import frostFS.container.ContainerServiceGrpc; import frostFS.container.Service; -import info.FrostFS.sdk.Client; import info.FrostFS.sdk.Verifier; import info.FrostFS.sdk.jdo.Container; import info.FrostFS.sdk.jdo.ContainerId; @@ -11,6 +10,8 @@ import info.FrostFS.sdk.mappers.ContainerMapper; import info.FrostFS.sdk.mappers.OwnerIdMapper; import info.FrostFS.sdk.mappers.VersionMapper; import info.FrostFS.sdk.services.ContainerClient; +import info.FrostFS.sdk.services.ContextAccessor; +import info.FrostFS.sdk.tools.ClientEnvironment; import java.util.List; import java.util.stream.Collectors; @@ -19,23 +20,24 @@ import static info.FrostFS.sdk.RequestConstructor.addMetaHeader; import static info.FrostFS.sdk.RequestSigner.sign; import static info.FrostFS.sdk.RequestSigner.signRFC6979; -public class ContainerService implements ContainerClient { +public class ContainerService extends ContextAccessor implements ContainerClient { private final ContainerServiceGrpc.ContainerServiceBlockingStub containerServiceAsyncClient; - private final Client client; - public ContainerService(ContainerServiceGrpc.ContainerServiceBlockingStub containerServiceAsyncClient, Client client) { - this.containerServiceAsyncClient = containerServiceAsyncClient; - this.client = client; + public ContainerService(ClientEnvironment clientEnvironment) { + super(clientEnvironment); + this.containerServiceAsyncClient = ContainerServiceGrpc.newBlockingStub(clientEnvironment.getChannel()); } public Container getContainerAsync(ContainerId cid) { var request = Service.GetRequest.newBuilder() .setBody( - Service.GetRequest.Body.newBuilder().setContainerId(ContainerIdMapper.toGrpcMessage(cid)).build() + Service.GetRequest.Body.newBuilder() + .setContainerId(ContainerIdMapper.toGrpcMessage(cid)) + .build() ); - addMetaHeader(request, null); - sign(request, client.getPublicKey(), client.getPrivateKey()); + addMetaHeader(request); + sign(request, context.getPublicKey(), context.getPrivateKey()); var response = containerServiceAsyncClient.get(request.build()); @@ -46,11 +48,13 @@ public class ContainerService implements ContainerClient { public List listContainersAsync() { var request = Service.ListRequest.newBuilder() .setBody( - Service.ListRequest.Body.newBuilder().setOwnerId(OwnerIdMapper.toGrpcMessage(client.getOwnerId())).build() + Service.ListRequest.Body.newBuilder() + .setOwnerId(OwnerIdMapper.toGrpcMessage(context.getOwnerId())) + .build() ); - addMetaHeader(request, null); - sign(request, client.getPublicKey(), client.getPrivateKey()); + addMetaHeader(request); + sign(request, context.getPublicKey(), context.getPrivateKey()); var response = containerServiceAsyncClient.list(request.build()); @@ -65,20 +69,22 @@ public class ContainerService implements ContainerClient { var grpcContainer = ContainerMapper.toGrpcMessage(container); grpcContainer = grpcContainer.toBuilder() - .setOwnerId(OwnerIdMapper.toGrpcMessage(client.getOwnerId())) - .setVersion(VersionMapper.toGrpcMessage(client.getVersion())) + .setOwnerId(OwnerIdMapper.toGrpcMessage(context.getOwnerId())) + .setVersion(VersionMapper.toGrpcMessage(context.getVersion())) .build(); var request = Service.PutRequest.newBuilder() .setBody( Service.PutRequest.Body.newBuilder() .setContainer(grpcContainer) - .setSignature(signRFC6979(client.getPublicKey(), client.getPrivateKey(), grpcContainer)) + .setSignature( + signRFC6979(context.getPublicKey(), context.getPrivateKey(), grpcContainer) + ) .build() ); - addMetaHeader(request, null); - sign(request, client.getPublicKey(), client.getPrivateKey()); + addMetaHeader(request); + sign(request, context.getPublicKey(), context.getPrivateKey()); var response = containerServiceAsyncClient.put(request.build()); @@ -93,12 +99,14 @@ public class ContainerService implements ContainerClient { .setBody( Service.DeleteRequest.Body.newBuilder() .setContainerId(grpcContainerId) - .setSignature(signRFC6979(client.getPublicKey(), client.getPrivateKey(), grpcContainerId.getValue())) + .setSignature(signRFC6979( + context.getPublicKey(), context.getPrivateKey(), grpcContainerId.getValue() + )) .build() ); - addMetaHeader(request, null); - sign(request, client.getPublicKey(), client.getPrivateKey()); + addMetaHeader(request); + sign(request, context.getPublicKey(), context.getPrivateKey()); var response = containerServiceAsyncClient.delete(request.build()); diff --git a/client/src/main/java/info/FrostFS/sdk/services/impl/FrostFSClient.java b/client/src/main/java/info/FrostFS/sdk/services/impl/FrostFSClient.java deleted file mode 100644 index a720d4c..0000000 --- a/client/src/main/java/info/FrostFS/sdk/services/impl/FrostFSClient.java +++ /dev/null @@ -1,85 +0,0 @@ -package info.FrostFS.sdk.services.impl; - -import info.FrostFS.sdk.Client; -import info.FrostFS.sdk.GrpcClient; -import info.FrostFS.sdk.jdo.*; -import info.FrostFS.sdk.services.ContainerClient; -import info.FrostFS.sdk.services.ObjectClient; - -import java.io.FileInputStream; -import java.util.List; - -public class FrostFSClient implements ContainerClient, ObjectClient { - private final ContainerService containerService; - private final NetmapService netmapService; - private final ObjectService objectService; - - public FrostFSClient(GrpcClient grpcClient, Client client) { - this.containerService = new ContainerService(grpcClient.getContainerServiceBlockingClient(), client); - this.netmapService = new NetmapService(grpcClient.getNetmapServiceBlockingClient(), client); - SessionService sessionService = new SessionService(grpcClient.getSessionServiceBlockingClient(), client); - this.objectService = new ObjectService( - grpcClient.getObjectServiceBlockingClient(), grpcClient.getObjectServiceClient(), sessionService, client - ); - checkFrostFsVersionSupport(client); - } - - private void checkFrostFsVersionSupport(Client client) { - var localNodeInfo = netmapService.getLocalNodeInfoAsync(); - if (!localNodeInfo.getVersion().isSupported(client.getVersion())) { - var msg = String.format("FrostFS %s is not supported.", localNodeInfo.getVersion()); - System.out.println(msg); - throw new IllegalArgumentException(msg); - } - } - - @Override - public Container getContainerAsync(ContainerId cid) { - return containerService.getContainerAsync(cid); - } - - @Override - public List listContainersAsync() { - return containerService.listContainersAsync(); - } - - @Override - public ContainerId createContainerAsync(Container container) { - return containerService.createContainerAsync(container); - } - - @Override - public void deleteContainerAsync(ContainerId cid) { - containerService.deleteContainerAsync(cid); - } - - @Override - public ObjectHeader getObjectHeadAsync(ContainerId containerId, ObjectId objectId) { - return objectService.getObjectHeadAsync(containerId, objectId); - } - - @Override - public ObjectFrostFs getObjectAsync(ContainerId containerId, ObjectId objectId) { - return objectService.getObjectAsync(containerId, objectId); - } - - @Override - public ObjectId putObjectAsync(ObjectHeader header, FileInputStream payload) { - return objectService.putObjectAsync(header, payload); - } - - @Override - public ObjectId putObjectAsync(ObjectHeader header, byte[] payload) { - return objectService.putObjectAsync(header, payload); - } - - @Override - public void deleteObjectAsync(ContainerId containerId, ObjectId objectId) { - objectService.deleteObjectAsync(containerId, objectId); - } - - @Override - public Iterable searchObjectsAsync(ContainerId cid, ObjectFilter... filters) { - return objectService.searchObjectsAsync(cid, filters); - } -} diff --git a/client/src/main/java/info/FrostFS/sdk/services/impl/NetmapService.java b/client/src/main/java/info/FrostFS/sdk/services/impl/NetmapService.java index eafc40f..b2ccf23 100644 --- a/client/src/main/java/info/FrostFS/sdk/services/impl/NetmapService.java +++ b/client/src/main/java/info/FrostFS/sdk/services/impl/NetmapService.java @@ -2,30 +2,124 @@ package info.FrostFS.sdk.services.impl; import frostFS.netmap.NetmapServiceGrpc; import frostFS.netmap.Service; -import info.FrostFS.sdk.Client; +import frostFS.netmap.Types; +import info.FrostFS.sdk.Verifier; +import info.FrostFS.sdk.jdo.netmap.NetmapSnapshot; import info.FrostFS.sdk.jdo.netmap.NodeInfo; +import info.FrostFS.sdk.mappers.netmap.NetmapSnapshotMapper; import info.FrostFS.sdk.mappers.netmap.NodeInfoMapper; +import info.FrostFS.sdk.services.ContextAccessor; +import info.FrostFS.sdk.services.NetmapClient; +import info.FrostFS.sdk.tools.ClientEnvironment; +import info.FrostFS.sdk.tools.NetworkSettings; + +import java.nio.charset.StandardCharsets; import static info.FrostFS.sdk.RequestConstructor.addMetaHeader; import static info.FrostFS.sdk.RequestSigner.sign; +import static java.util.Objects.nonNull; -public class NetmapService { - private final NetmapServiceGrpc.NetmapServiceBlockingStub netmapServiceAsyncClient; - private final Client client; +public class NetmapService extends ContextAccessor implements NetmapClient { + private final NetmapServiceGrpc.NetmapServiceBlockingStub netmapServiceClient; - public NetmapService(NetmapServiceGrpc.NetmapServiceBlockingStub netmapServiceAsyncClient, Client client) { - this.netmapServiceAsyncClient = netmapServiceAsyncClient; - this.client = client; + public NetmapService(ClientEnvironment clientEnvironment) { + super(clientEnvironment); + this.netmapServiceClient = NetmapServiceGrpc.newBlockingStub(context.getChannel()); } + private static boolean getBoolValue(byte[] bytes) { + for (var byteValue : bytes) { + if (byteValue != 0) return true; + } + + return false; + } + + private static long getLongValue(byte[] bytes) { + long val = 0; + for (var i = bytes.length - 1; i >= 0; i--) { + val = (val << 8) + bytes[i]; + } + + return val; + } + + private static void setNetworksParam(Types.NetworkConfig.Parameter param, NetworkSettings settings) { + var key = new String(param.getKey().toByteArray(), StandardCharsets.UTF_8); + + var valueBytes = param.getValue().toByteArray(); + switch (key) { + case "AuditFee": + settings.setAuditFee(getLongValue(valueBytes)); + break; + case "BasicIncomeRate": + settings.setBasicIncomeRate(getLongValue(valueBytes)); + break; + case "ContainerFee": + settings.setContainerFee(getLongValue(valueBytes)); + break; + case "ContainerAliasFee": + settings.setContainerAliasFee(getLongValue(valueBytes)); + break; + case "EpochDuration": + settings.setEpochDuration(getLongValue(valueBytes)); + break; + case "InnerRingCandidateFee": + settings.setiRCandidateFee(getLongValue(valueBytes)); + break; + case "MaxECDataCount": + settings.setMaxECDataCount(getLongValue(valueBytes)); + break; + case "MaxECParityCount": + settings.setMaxECParityCount(getLongValue(valueBytes)); + break; + case "MaxObjectSize": + settings.setMaxObjectSize(getLongValue(valueBytes)); + break; + case "WithdrawFee": + settings.setWithdrawalFee(getLongValue(valueBytes)); + break; + case "HomomorphicHashingDisabled": + settings.setHomomorphicHashingDisabled(getBoolValue(valueBytes)); + break; + case "MaintenanceModeAllowed": + settings.setMaintenanceModeAllowed(getBoolValue(valueBytes)); + break; + default: + settings.getUnnamedSettings().put(key, valueBytes); + break; + } + } + + @Override + public NetworkSettings getNetworkSettingsAsync() { + if (nonNull(context.getNetworkSettings())) { + return context.getNetworkSettings(); + } + + var info = getNetworkInfoAsync(); + + var settings = new NetworkSettings(); + + for (var param : info.getBody().getNetworkInfo().getNetworkConfig().getParametersList()) { + setNetworksParam(param, settings); + } + + context.setNetworkSettings(settings); + + return settings; + } + + @Override public NodeInfo getLocalNodeInfoAsync() { var request = Service.LocalNodeInfoRequest.newBuilder() .setBody(Service.LocalNodeInfoRequest.Body.newBuilder().build()); - addMetaHeader(request, null); - sign(request, client.getPublicKey(), client.getPrivateKey()); + addMetaHeader(request); + sign(request, context.getPublicKey(), context.getPrivateKey()); - var response = netmapServiceAsyncClient.localNodeInfo(request.build()); + var response = netmapServiceClient.localNodeInfo(request.build()); + Verifier.checkResponse(response); return NodeInfoMapper.toModel(response.getBody()); } @@ -34,9 +128,28 @@ public class NetmapService { var request = Service.NetworkInfoRequest.newBuilder() .setBody(Service.NetworkInfoRequest.Body.newBuilder().build()); - addMetaHeader(request, null); - sign(request, client.getPublicKey(), client.getPrivateKey()); + addMetaHeader(request); + sign(request, context.getPublicKey(), context.getPrivateKey()); - return netmapServiceAsyncClient.networkInfo(request.build()); + var response = netmapServiceClient.networkInfo(request.build()); + + Verifier.checkResponse(response); + + return response; + } + + @Override + public NetmapSnapshot getNetmapSnapshotAsync() { + var request = Service.NetmapSnapshotRequest.newBuilder() + .setBody(Service.NetmapSnapshotRequest.Body.newBuilder().build()); + + addMetaHeader(request); + sign(request, context.getPublicKey(), context.getPrivateKey()); + + var response = netmapServiceClient.netmapSnapshot(request.build()); + + Verifier.checkResponse(response); + + return NetmapSnapshotMapper.toModel(response); } } diff --git a/client/src/main/java/info/FrostFS/sdk/services/impl/ObjectService.java b/client/src/main/java/info/FrostFS/sdk/services/impl/ObjectService.java index f90fe84..9ef6a6d 100644 --- a/client/src/main/java/info/FrostFS/sdk/services/impl/ObjectService.java +++ b/client/src/main/java/info/FrostFS/sdk/services/impl/ObjectService.java @@ -5,11 +5,12 @@ import com.google.protobuf.ByteString; import frostFS.object.ObjectServiceGrpc; import frostFS.object.Service; import frostFS.refs.Types; -import info.FrostFS.sdk.Client; import info.FrostFS.sdk.Verifier; import info.FrostFS.sdk.jdo.*; import info.FrostFS.sdk.mappers.*; +import info.FrostFS.sdk.services.ContextAccessor; import info.FrostFS.sdk.services.ObjectClient; +import info.FrostFS.sdk.tools.ClientEnvironment; import java.io.ByteArrayInputStream; import java.io.FileInputStream; @@ -25,21 +26,14 @@ import static info.FrostFS.sdk.RequestConstructor.addObjectSessionToken; import static info.FrostFS.sdk.RequestSigner.sign; import static java.util.Objects.nonNull; -public class ObjectService implements ObjectClient { +public class ObjectService extends ContextAccessor implements ObjectClient { private final ObjectServiceGrpc.ObjectServiceBlockingStub objectServiceBlockingClient; private final ObjectServiceGrpc.ObjectServiceStub objectServiceClient; - private final SessionService sessionService; - private final Client client; - - public ObjectService(ObjectServiceGrpc.ObjectServiceBlockingStub objectServiceAsyncClient, - ObjectServiceGrpc.ObjectServiceStub objectServiceClient, - SessionService sessionService, - Client client) { - this.objectServiceBlockingClient = objectServiceAsyncClient; - this.objectServiceClient = objectServiceClient; - this.client = client; - this.sessionService = sessionService; + public ObjectService(ClientEnvironment clientEnvironment) { + super(clientEnvironment); + this.objectServiceBlockingClient = ObjectServiceGrpc.newBlockingStub(context.getChannel()); + this.objectServiceClient = ObjectServiceGrpc.newStub(context.getChannel()); } @Override @@ -55,8 +49,8 @@ public class ObjectService implements ObjectClient { ).build() ); - addMetaHeader(request, null); - sign(request, client.getPublicKey(), client.getPrivateKey()); + addMetaHeader(request); + sign(request, context.getPublicKey(), context.getPrivateKey()); var response = objectServiceBlockingClient.head(request.build()); Verifier.checkResponse(response); @@ -66,7 +60,7 @@ public class ObjectService implements ObjectClient { @Override public ObjectFrostFs getObjectAsync(ContainerId cid, ObjectId oid) { - var sessionToken = sessionService.createSessionAsync(-1); + var sessionToken = context.getFrostFSClient().createSessionInternalAsync(-1); var request = Service.GetRequest.newBuilder() .setBody( @@ -81,12 +75,12 @@ public class ObjectService implements ObjectClient { .build() ); - addMetaHeader(request, null); + addMetaHeader(request); addObjectSessionToken( request, sessionToken, ContainerIdMapper.toGrpcMessage(cid), ObjectIdMapper.toGrpcMessage(oid), - frostFS.session.Types.ObjectSessionContext.Verb.GET, client.getPublicKey(), client.getPrivateKey() + frostFS.session.Types.ObjectSessionContext.Verb.GET, context.getPublicKey(), context.getPrivateKey() ); - sign(request, client.getPublicKey(), client.getPrivateKey()); + sign(request, context.getPublicKey(), context.getPrivateKey()); var obj = getObject(request.build()); @@ -106,8 +100,8 @@ public class ObjectService implements ObjectClient { ) .build()); - addMetaHeader(request, null); - sign(request, client.getPublicKey(), client.getPrivateKey()); + addMetaHeader(request); + sign(request, context.getPublicKey(), context.getPrivateKey()); var response = objectServiceBlockingClient.delete(request.build()); Verifier.checkResponse(response); @@ -136,8 +130,8 @@ public class ObjectService implements ObjectClient { var request = Service.SearchRequest.newBuilder() .setBody(body.build()); - addMetaHeader(request, null); - sign(request, client.getPublicKey(), client.getPrivateKey()); + addMetaHeader(request); + sign(request, context.getPublicKey(), context.getPrivateKey()); var objectsIds = searchObjects(request.build()); @@ -169,12 +163,12 @@ public class ObjectService implements ObjectClient { } private ObjectId putObject(ObjectHeader header, InputStream payload) { - var sessionToken = sessionService.createSessionAsync(-1); + var sessionToken = context.getFrostFSClient().createSessionInternalAsync(-1); var hdr = ObjectHeaderMapper.toGrpcMessage(header); hdr = hdr.toBuilder() - .setOwnerId(OwnerIdMapper.toGrpcMessage(client.getOwnerId())) - .setVersion(VersionMapper.toGrpcMessage(client.getVersion())) + .setOwnerId(OwnerIdMapper.toGrpcMessage(context.getOwnerId())) + .setVersion(VersionMapper.toGrpcMessage(context.getVersion())) .build(); var oid = Types.ObjectID.newBuilder().setValue(getSha256(hdr)).build(); @@ -187,12 +181,12 @@ public class ObjectService implements ObjectClient { ).build() ); - addMetaHeader(request, null); + addMetaHeader(request); addObjectSessionToken( request, sessionToken, hdr.getContainerId(), oid, frostFS.session.Types.ObjectSessionContext.Verb.PUT, - client.getPublicKey(), client.getPrivateKey() + context.getPublicKey(), context.getPrivateKey() ); - sign(request, client.getPublicKey(), client.getPrivateKey()); + sign(request, context.getPublicKey(), context.getPrivateKey()); var writer = putObjectInit(request.build()); @@ -208,7 +202,7 @@ public class ObjectService implements ObjectClient { .build() ) .clearVerifyHeader(); - sign(request, client.getPublicKey(), client.getPrivateKey()); + sign(request, context.getPublicKey(), context.getPrivateKey()); writer.write(request.build()); bufferLength = payload.readNBytes(buffer, 0, Constants.OBJECT_CHUNK_SIZE); } diff --git a/client/src/main/java/info/FrostFS/sdk/services/impl/SessionService.java b/client/src/main/java/info/FrostFS/sdk/services/impl/SessionService.java index 832dc52..3406acf 100644 --- a/client/src/main/java/info/FrostFS/sdk/services/impl/SessionService.java +++ b/client/src/main/java/info/FrostFS/sdk/services/impl/SessionService.java @@ -3,31 +3,41 @@ package info.FrostFS.sdk.services.impl; import frostFS.session.Service; import frostFS.session.SessionServiceGrpc; import frostFS.session.Types; -import info.FrostFS.sdk.Client; +import info.FrostFS.sdk.jdo.SessionToken; import info.FrostFS.sdk.mappers.OwnerIdMapper; +import info.FrostFS.sdk.mappers.SessionMapper; +import info.FrostFS.sdk.services.ContextAccessor; +import info.FrostFS.sdk.services.SessionClient; +import info.FrostFS.sdk.tools.ClientEnvironment; import static info.FrostFS.sdk.RequestConstructor.addMetaHeader; import static info.FrostFS.sdk.RequestSigner.sign; -public class SessionService { +public class SessionService extends ContextAccessor implements SessionClient { private final SessionServiceGrpc.SessionServiceBlockingStub sessionServiceAsyncClient; - private final Client client; - public SessionService(SessionServiceGrpc.SessionServiceBlockingStub sessionServiceAsyncClient, Client client) { - this.sessionServiceAsyncClient = sessionServiceAsyncClient; - this.client = client; + public SessionService(ClientEnvironment clientEnvironment) { + super(clientEnvironment); + this.sessionServiceAsyncClient = SessionServiceGrpc.newBlockingStub(context.getChannel()); } - protected Types.SessionToken createSessionAsync(long expiration) { + @Override + public SessionToken createSessionAsync(long expiration) { + var sessionToken = createSessionInternalAsync(expiration); + var token = SessionMapper.serialize(sessionToken); + return new SessionToken(new byte[]{}, token); + } + + public Types.SessionToken createSessionInternalAsync(long expiration) { var request = Service.CreateRequest.newBuilder() .setBody( Service.CreateRequest.Body.newBuilder() - .setOwnerId(OwnerIdMapper.toGrpcMessage(client.getOwnerId())) + .setOwnerId(OwnerIdMapper.toGrpcMessage(context.getOwnerId())) .setExpiration(expiration).build() ); - addMetaHeader(request, null); - sign(request, client.getPublicKey(), client.getPrivateKey()); + addMetaHeader(request); + sign(request, context.getPublicKey(), context.getPrivateKey()); return createSession(request.build()); } diff --git a/client/src/main/java/info/FrostFS/sdk/tools/ClientEnvironment.java b/client/src/main/java/info/FrostFS/sdk/tools/ClientEnvironment.java new file mode 100644 index 0000000..93019ca --- /dev/null +++ b/client/src/main/java/info/FrostFS/sdk/tools/ClientEnvironment.java @@ -0,0 +1,60 @@ +package info.FrostFS.sdk.tools; + +import info.FrostFS.sdk.jdo.OwnerId; +import info.FrostFS.sdk.jdo.Version; +import info.FrostFS.sdk.services.FrostFSClient; +import io.grpc.Channel; + +import static info.FrostFS.sdk.KeyExtension.getPrivateKeyFromWIF; +import static info.FrostFS.sdk.KeyExtension.loadPublicKey; + +public class ClientEnvironment { + private final OwnerId ownerId; + private final Version version; + private final byte[] privateKey; + private final byte[] publicKey; + private final Channel channel; + private final FrostFSClient frostFSClient; + private NetworkSettings networkSettings; + + public ClientEnvironment(String key, Channel channel, Version version, FrostFSClient frostFSClient) { + this.privateKey = getPrivateKeyFromWIF(key); + this.publicKey = loadPublicKey(privateKey); + this.ownerId = OwnerId.fromKey(publicKey); + this.version = version; + this.channel = channel; + this.frostFSClient = frostFSClient; + } + + public Channel getChannel() { + return channel; + } + + public NetworkSettings getNetworkSettings() { + return networkSettings; + } + + public void setNetworkSettings(NetworkSettings networkSettings) { + this.networkSettings = networkSettings; + } + + public FrostFSClient getFrostFSClient() { + return frostFSClient; + } + + public OwnerId getOwnerId() { + return ownerId; + } + + public Version getVersion() { + return version; + } + + public byte[] getPrivateKey() { + return privateKey; + } + + public byte[] getPublicKey() { + return publicKey; + } +} diff --git a/client/src/main/java/info/FrostFS/sdk/tools/NetworkSettings.java b/client/src/main/java/info/FrostFS/sdk/tools/NetworkSettings.java new file mode 100644 index 0000000..d6971b3 --- /dev/null +++ b/client/src/main/java/info/FrostFS/sdk/tools/NetworkSettings.java @@ -0,0 +1,143 @@ +package info.FrostFS.sdk.tools; + +import java.util.HashMap; +import java.util.Map; + +public class NetworkSettings { + + public Long auditFee; + public Long basicIncomeRate; + public Long containerFee; + public Long containerAliasFee; + public Long innerRingCandidateFee; + public Long withdrawFee; + public Long epochDuration; + public Long iRCandidateFee; + public Long maxObjectSize; + public Long maxECDataCount; + public Long maxECParityCount; + public Long withdrawalFee; + public Boolean homomorphicHashingDisabled; + public Boolean maintenanceModeAllowed; + public Map unnamedSettings = new HashMap<>(); + + public Long getAuditFee() { + return auditFee; + } + + public void setAuditFee(Long auditFee) { + this.auditFee = auditFee; + } + + public Long getBasicIncomeRate() { + return basicIncomeRate; + } + + public void setBasicIncomeRate(Long basicIncomeRate) { + this.basicIncomeRate = basicIncomeRate; + } + + public long getContainerFee() { + return containerFee; + } + + public void setContainerFee(long containerFee) { + this.containerFee = containerFee; + } + + public long getContainerAliasFee() { + return containerAliasFee; + } + + public void setContainerAliasFee(long containerAliasFee) { + this.containerAliasFee = containerAliasFee; + } + + public long getInnerRingCandidateFee() { + return innerRingCandidateFee; + } + + public void setInnerRingCandidateFee(long innerRingCandidateFee) { + this.innerRingCandidateFee = innerRingCandidateFee; + } + + public long getWithdrawFee() { + return withdrawFee; + } + + public void setWithdrawFee(long withdrawFee) { + this.withdrawFee = withdrawFee; + } + + public long getEpochDuration() { + return epochDuration; + } + + public void setEpochDuration(long epochDuration) { + this.epochDuration = epochDuration; + } + + public long getiRCandidateFee() { + return iRCandidateFee; + } + + public void setiRCandidateFee(long iRCandidateFee) { + this.iRCandidateFee = iRCandidateFee; + } + + public long getMaxObjectSize() { + return maxObjectSize; + } + + public void setMaxObjectSize(long maxObjectSize) { + this.maxObjectSize = maxObjectSize; + } + + public long getMaxECDataCount() { + return maxECDataCount; + } + + public void setMaxECDataCount(long maxECDataCount) { + this.maxECDataCount = maxECDataCount; + } + + public long getMaxECParityCount() { + return maxECParityCount; + } + + public void setMaxECParityCount(long maxECParityCount) { + this.maxECParityCount = maxECParityCount; + } + + public long getWithdrawalFee() { + return withdrawalFee; + } + + public void setWithdrawalFee(long withdrawalFee) { + this.withdrawalFee = withdrawalFee; + } + + public boolean isHomomorphicHashingDisabled() { + return homomorphicHashingDisabled; + } + + public void setHomomorphicHashingDisabled(boolean homomorphicHashingDisabled) { + this.homomorphicHashingDisabled = homomorphicHashingDisabled; + } + + public boolean isMaintenanceModeAllowed() { + return maintenanceModeAllowed; + } + + public void setMaintenanceModeAllowed(boolean maintenanceModeAllowed) { + this.maintenanceModeAllowed = maintenanceModeAllowed; + } + + public Map getUnnamedSettings() { + return unnamedSettings; + } + + public void setUnnamedSettings(Map unnamedSettings) { + this.unnamedSettings = unnamedSettings; + } +} diff --git a/modelsV2/src/main/java/info/FrostFS/sdk/jdo/SessionToken.java b/modelsV2/src/main/java/info/FrostFS/sdk/jdo/SessionToken.java new file mode 100644 index 0000000..bd4f7b0 --- /dev/null +++ b/modelsV2/src/main/java/info/FrostFS/sdk/jdo/SessionToken.java @@ -0,0 +1,19 @@ +package info.FrostFS.sdk.jdo; + +public class SessionToken { + public byte[] id; + public byte[] sessionKey; + + public SessionToken(byte[] id, byte[] sessionKey) { + this.id = id; + this.sessionKey = sessionKey; + } + + public byte[] getId() { + return id; + } + + public byte[] getSessionKey() { + return sessionKey; + } +} diff --git a/modelsV2/src/main/java/info/FrostFS/sdk/jdo/netmap/NetmapSnapshot.java b/modelsV2/src/main/java/info/FrostFS/sdk/jdo/netmap/NetmapSnapshot.java new file mode 100644 index 0000000..7fd344e --- /dev/null +++ b/modelsV2/src/main/java/info/FrostFS/sdk/jdo/netmap/NetmapSnapshot.java @@ -0,0 +1,21 @@ +package info.FrostFS.sdk.jdo.netmap; + +import java.util.List; + +public class NetmapSnapshot { + public Long epoch; + public List nodeInfoCollection; + + public NetmapSnapshot(Long epoch, List nodeInfoCollection) { + this.epoch = epoch; + this.nodeInfoCollection = nodeInfoCollection; + } + + public Long getEpoch() { + return epoch; + } + + public List getNodeInfoCollection() { + return nodeInfoCollection; + } +} diff --git a/modelsV2/src/main/java/info/FrostFS/sdk/jdo/netmap/NodeInfo.java b/modelsV2/src/main/java/info/FrostFS/sdk/jdo/netmap/NodeInfo.java index fe65459..5b060f1 100644 --- a/modelsV2/src/main/java/info/FrostFS/sdk/jdo/netmap/NodeInfo.java +++ b/modelsV2/src/main/java/info/FrostFS/sdk/jdo/netmap/NodeInfo.java @@ -1,11 +1,26 @@ package info.FrostFS.sdk.jdo.netmap; -import info.FrostFS.sdk.jdo.Version; import info.FrostFS.sdk.enums.NodeState; +import info.FrostFS.sdk.jdo.Version; + +import java.util.List; +import java.util.Map; public class NodeInfo { public NodeState state; public Version version; + public List addresses; + public Map attributes; + public byte[] publicKey; + + public NodeInfo(NodeState state, Version version, List addresses, + Map attributes, byte[] publicKey) { + this.state = state; + this.version = version; + this.addresses = addresses; + this.attributes = attributes; + this.publicKey = publicKey; + } public NodeState getState() { return state; @@ -23,8 +38,15 @@ public class NodeInfo { this.version = version; } - public NodeInfo(NodeState state, Version version) { - this.state = state; - this.version = version; + public byte[] getPublicKey() { + return publicKey; + } + + public Map getAttributes() { + return attributes; + } + + public List getAddresses() { + return addresses; } } diff --git a/modelsV2/src/main/java/info/FrostFS/sdk/mappers/SessionMapper.java b/modelsV2/src/main/java/info/FrostFS/sdk/mappers/SessionMapper.java new file mode 100644 index 0000000..f9d7ecd --- /dev/null +++ b/modelsV2/src/main/java/info/FrostFS/sdk/mappers/SessionMapper.java @@ -0,0 +1,31 @@ +package info.FrostFS.sdk.mappers; + +import com.google.protobuf.CodedOutputStream; +import com.google.protobuf.InvalidProtocolBufferException; +import frostFS.session.Types; + +import java.io.IOException; + +public class SessionMapper { + + public static byte[] serialize(Types.SessionToken token) + { + try { + byte[] bytes = new byte[token.getSerializedSize()]; + CodedOutputStream stream = CodedOutputStream.newInstance(bytes); + token.writeTo(stream); + return bytes; + } catch (IOException e) { + throw new IllegalArgumentException(e); + } + } + + public static Types.SessionToken deserializeSessionToken(byte[] bytes) + { + try { + return Types.SessionToken.newBuilder().mergeFrom(bytes).build(); + } catch (InvalidProtocolBufferException exp) { + throw new IllegalArgumentException(); + } + } +} diff --git a/modelsV2/src/main/java/info/FrostFS/sdk/mappers/netmap/NetmapSnapshotMapper.java b/modelsV2/src/main/java/info/FrostFS/sdk/mappers/netmap/NetmapSnapshotMapper.java new file mode 100644 index 0000000..9d9eb27 --- /dev/null +++ b/modelsV2/src/main/java/info/FrostFS/sdk/mappers/netmap/NetmapSnapshotMapper.java @@ -0,0 +1,18 @@ +package info.FrostFS.sdk.mappers.netmap; + +import frostFS.netmap.Service; +import info.FrostFS.sdk.jdo.netmap.NetmapSnapshot; + +import java.util.stream.Collectors; + +public class NetmapSnapshotMapper { + + public static NetmapSnapshot toModel(Service.NetmapSnapshotResponse netmap) { + return new NetmapSnapshot( + netmap.getBody().getNetmap().getEpoch(), + netmap.getBody().getNetmap().getNodesList().stream() + .map(t -> NodeInfoMapper.toModel(t, netmap.getMetaHeader().getVersion())) + .collect(Collectors.toList()) + ); + } +} diff --git a/modelsV2/src/main/java/info/FrostFS/sdk/mappers/netmap/NodeInfoMapper.java b/modelsV2/src/main/java/info/FrostFS/sdk/mappers/netmap/NodeInfoMapper.java index 934d60f..6c9e25c 100644 --- a/modelsV2/src/main/java/info/FrostFS/sdk/mappers/netmap/NodeInfoMapper.java +++ b/modelsV2/src/main/java/info/FrostFS/sdk/mappers/netmap/NodeInfoMapper.java @@ -1,21 +1,36 @@ package info.FrostFS.sdk.mappers.netmap; import frostFS.netmap.Service; +import frostFS.netmap.Types.NodeInfo.Attribute; +import frostFS.refs.Types; import info.FrostFS.sdk.enums.NodeState; import info.FrostFS.sdk.jdo.netmap.NodeInfo; import info.FrostFS.sdk.mappers.VersionMapper; +import java.util.stream.Collectors; + import static java.util.Objects.isNull; public class NodeInfoMapper { public static NodeInfo toModel(Service.LocalNodeInfoResponse.Body nodeInfo) { - var nodeState = NodeState.get(nodeInfo.getNodeInfo().getState().getNumber()); + return toModel(nodeInfo.getNodeInfo(), nodeInfo.getVersion()); + } + + public static NodeInfo toModel(frostFS.netmap.Types.NodeInfo nodeInfo, Types.Version version) { + NodeState nodeState = NodeState.get(nodeInfo.getState().getNumber()); + if (isNull(nodeState)) { throw new IllegalArgumentException( - String.format("Unknown NodeState. Value: %s.", nodeInfo.getNodeInfo().getState()) + String.format("Unknown NodeState. Value: %s.", nodeInfo.getState()) ); } - return new NodeInfo(nodeState, VersionMapper.toModel(nodeInfo.getVersion())); + return new NodeInfo( + nodeState, + VersionMapper.toModel(version), + nodeInfo.getAddressesList(), + nodeInfo.getAttributesList().stream().collect(Collectors.toMap(Attribute::getKey, Attribute::getValue)), + nodeInfo.getPublicKey().toByteArray() + ); } }