[#1] Define SDK main functional #1
26 changed files with 868 additions and 302 deletions
README.md
client
pom.xml
src/main/java/info/FrostFS/sdk
modelsV2/src/main/java/info/FrostFS/sdk
|
@ -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;
|
||||
|
|
|
@ -23,26 +23,11 @@
|
|||
<artifactId>cryptography</artifactId>
|
||||
<version>0.1.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>info.FrostFS.sdk</groupId>
|
||||
<artifactId>protosV2</artifactId>
|
||||
<version>0.1.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>info.FrostFS.sdk</groupId>
|
||||
<artifactId>modelsV2</artifactId>
|
||||
<version>0.1.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-api</artifactId>
|
||||
<version>2.7</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-slf4j-impl</artifactId>
|
||||
<version>2.7</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -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;
|
||||
}
|
||||
}
|
57
client/src/main/java/info/FrostFS/sdk/ClientSettings.java
Normal file
57
client/src/main/java/info/FrostFS/sdk/ClientSettings.java
Normal file
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
54
client/src/main/java/info/FrostFS/sdk/Main.java
Normal file
54
client/src/main/java/info/FrostFS/sdk/Main.java
Normal file
|
@ -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<ContainerId> containerIds = frostFSClient.listContainersAsync();
|
||||
/*
|
||||
frostFSClient.deleteContainerAsync(containerId);
|
||||
*/
|
||||
containerIds = frostFSClient.listContainersAsync();
|
||||
System.out.println();
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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<ContainerId> 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<ObjectId> 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;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package info.FrostFS.sdk.services;
|
||||
|
||||
import info.FrostFS.sdk.jdo.SessionToken;
|
||||
|
||||
public interface SessionClient {
|
||||
|
||||
SessionToken createSessionAsync(long expiration);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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<ContainerId> 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());
|
||||
|
||||
|
|
|
@ -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<ContainerId> 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<ObjectId> searchObjectsAsync(ContainerId cid, ObjectFilter... filters) {
|
||||
return objectService.searchObjectsAsync(cid, filters);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
143
client/src/main/java/info/FrostFS/sdk/tools/NetworkSettings.java
Normal file
143
client/src/main/java/info/FrostFS/sdk/tools/NetworkSettings.java
Normal file
|
@ -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<String, Object> 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<String, Object> getUnnamedSettings() {
|
||||
return unnamedSettings;
|
||||
}
|
||||
|
||||
public void setUnnamedSettings(Map<String, Object> unnamedSettings) {
|
||||
this.unnamedSettings = unnamedSettings;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package info.FrostFS.sdk.jdo.netmap;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class NetmapSnapshot {
|
||||
public Long epoch;
|
||||
public List<NodeInfo> nodeInfoCollection;
|
||||
|
||||
public NetmapSnapshot(Long epoch, List<NodeInfo> nodeInfoCollection) {
|
||||
this.epoch = epoch;
|
||||
this.nodeInfoCollection = nodeInfoCollection;
|
||||
}
|
||||
|
||||
public Long getEpoch() {
|
||||
return epoch;
|
||||
}
|
||||
|
||||
public List<NodeInfo> getNodeInfoCollection() {
|
||||
return nodeInfoCollection;
|
||||
}
|
||||
}
|
|
@ -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<String> addresses;
|
||||
public Map<String, String> attributes;
|
||||
public byte[] publicKey;
|
||||
|
||||
public NodeInfo(NodeState state, Version version, List<String> addresses,
|
||||
Map<String, String> 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<String, String> getAttributes() {
|
||||
return attributes;
|
||||
}
|
||||
|
||||
public List<String> getAddresses() {
|
||||
return addresses;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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())
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue