diff --git a/pom.xml b/pom.xml
index 19133602..147eafe6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
ru.kontur.diadoc
diadocsdk
- 3.23.0-dev.5429.28650
+ 3.20.0-dev.5429.28865
jar
diff --git a/proto/FileToUpload.proto b/proto/FileToUpload.proto
deleted file mode 100644
index b87ce37f..00000000
--- a/proto/FileToUpload.proto
+++ /dev/null
@@ -1,6 +0,0 @@
-package Diadoc.Api.Proto;
-
-message FileToUpload {
- required bytes Content = 1;
- optional string FileExtension = 2;
-}
\ No newline at end of file
diff --git a/src/main/java/Diadoc/Api/shelf/ShelfClient.java b/src/main/java/Diadoc/Api/shelf/ShelfClient.java
index bc383d52..688ebb9a 100644
--- a/src/main/java/Diadoc/Api/shelf/ShelfClient.java
+++ b/src/main/java/Diadoc/Api/shelf/ShelfClient.java
@@ -9,6 +9,7 @@
import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ByteArrayEntity;
+import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.net.URISyntaxException;
@@ -36,6 +37,11 @@ public int getShelfUploadMaxAttemptsCount() {
return SHELF_MAX_ATTEMPTS;
}
+ /**
+ * Use shelfDownload instead
+ */
+
+ @Deprecated
public byte[] shelfDownload(String nameOnShelf) throws DiadocSdkException {
if (!nameOnShelf.contains(SHELF_PATH_PREFIX))
nameOnShelf = SHELF_PATH_PREFIX + "/" + nameOnShelf;
@@ -51,6 +57,24 @@ public byte[] shelfDownload(String nameOnShelf) throws DiadocSdkException {
}
}
+ public byte[] shelfDownloadV2(String fileName) throws DiadocSdkException {
+ try {
+ var request = RequestBuilder.get(
+ new URIBuilder(diadocHttpClient.getBaseUrl())
+ .setPath("/V2/ShelfDownload")
+ .addParameter("fileName", fileName)
+ .build());
+ return diadocHttpClient.performRequest(request);
+ } catch (URISyntaxException | IOException e) {
+ throw new DiadocSdkException(e);
+ }
+ }
+
+ /**
+ * Use uploadFileToShelfV2 or uploadLargeFileToShelf instead
+ */
+
+ @Deprecated
public String uploadFileToShelf(byte[] data) throws DiadocSdkException {
if (data == null)
throw new IllegalArgumentException("data");
@@ -64,7 +88,7 @@ public String uploadFileToShelf(byte[] data) throws DiadocSdkException {
var httpErrors = new ArrayList();
int attempts = 0;
- while (missingParts.size() > 0) {
+ while (!missingParts.isEmpty()) {
if (++attempts > SHELF_MAX_ATTEMPTS)
throw new DiadocSdkException("Reached the limit of attempts to send a file. " + formatHttpErrors(httpErrors));
@@ -84,38 +108,187 @@ public String uploadFileToShelf(byte[] data) throws DiadocSdkException {
return nameOnShelf;
}
-// public String uploadFileToShelfV2(FileToUpload file) throws DiadocSdkException {
-// if (file == null)
-// throw new IllegalArgumentException("file");
-//
-// var url = new URIBuilder(diadocHttpClient.getBaseUrl()).setPath("/V2/ShelfUpload");
-//
-// try {
-// var response = diadocHttpClient.getResponse(RequestBuilder.post(url.build()).setEntity(new ByteArrayEntity(file.toByteArray())));
-// if (response.getStatusCode() != HttpStatus.SC_OK) {
-// if (SHELF_NON_RETRIABLE_STATUS_CODES.contains(response.getStatusCode())) {
-// throw new DiadocException(formatResponseMessage(response.getReason(), response.getStatusCode()), response.getStatusCode());
-// }
-//
-// httpErrors.add(new DiadocException(formatResponseMessage(response.getReason(), response.getStatusCode()), response.getStatusCode()));
-// return null;
-// }
-//
-// responseContent = response.getContent();
-//
-// } catch (IOException e) {
-// httpErrors.add(e);
-// return null;
-// }
-//
-// if (responseContent == null || responseContent.length == 0)
-// return null;
-//
-// String responseString = new String(responseContent, StandardCharsets.UTF_8);
-//
-// int[] missingParts = new Gson().fromJson(responseString, int[].class);
-// return Arrays.stream(missingParts).boxed().collect(Collectors.toList());
-// }
+ public String uploadFileToShelfV2(byte[] content, @Nullable String fileExtension) throws DiadocSdkException, URISyntaxException, DiadocException {
+ if (content == null)
+ throw new IllegalArgumentException("content");
+
+ var httpErrors = new ArrayList();
+ var url = new URIBuilder(diadocHttpClient.getBaseUrl())
+ .setPath("/V2/ShelfUpload")
+ .addParameter("fileExtension", fileExtension);
+
+ byte[] responseContent;
+ for (var i = 0; i < SHELF_MAX_ATTEMPTS; i++)
+ {
+ try {
+ var response = diadocHttpClient.getResponse(RequestBuilder.post(url.build()).setEntity(new ByteArrayEntity(content)));
+ if (response.getStatusCode() != HttpStatus.SC_OK) {
+ if (SHELF_NON_RETRIABLE_STATUS_CODES.contains(response.getStatusCode())) {
+ throw new DiadocException(formatResponseMessage(response.getReason(), response.getStatusCode()), response.getStatusCode());
+ }
+
+ httpErrors.add(new DiadocException(formatResponseMessage(response.getReason(), response.getStatusCode()), response.getStatusCode()));
+ }
+
+ responseContent = response.getContent();
+ if (responseContent == null || responseContent.length == 0) {
+ continue;
+ }
+
+ return new String(responseContent, StandardCharsets.UTF_8);
+ }
+ catch (IOException e) {
+ httpErrors.add(e);
+ }
+ }
+
+ throw new DiadocSdkException("Reached the limit of attempts to send a file. " + formatHttpErrors(httpErrors));
+ }
+
+ public String uploadLargeFileToShelf(byte[] content, @Nullable String fileExtension) throws DiadocSdkException, URISyntaxException, DiadocException {
+ if (content == null)
+ throw new IllegalArgumentException("content");
+
+ var parts = splitDataIntoParts(content);
+ List missingParts = new ArrayList<>();
+
+ for (int i = 0; i < parts.size(); i++)
+ missingParts.add(i);
+
+ var httpErrors = new ArrayList();
+ int attempts = 0;
+ String fileName = null;
+
+ while (!missingParts.isEmpty()) {
+ if (++attempts > SHELF_MAX_ATTEMPTS){
+ throw new DiadocSdkException("Reached the limit of attempts to send a file. " + formatHttpErrors(httpErrors));
+ }
+
+ int partsCount = parts.size();
+ int lastPartIndex = partsCount - 1;
+ //always add last part for stability
+ if (!missingParts.contains(lastPartIndex))
+ missingParts.add(lastPartIndex);
+
+ try {
+ if (fileName == null) {
+ fileName = shelfUploadPartInit(parts.get(0), missingParts, httpErrors, fileExtension);
+ }
+
+ if (fileName != null) {
+ missingParts = shelfUploadParts(fileName, parts, missingParts, httpErrors);
+ }
+ } catch (URISyntaxException | DiadocException e) {
+ e.printStackTrace();
+ throw new DiadocSdkException(e);
+ }
+ }
+ return fileName;
+ }
+
+ private String shelfUploadPartInit(
+ ByteArraySegment firstPart,
+ List missingParts,
+ List httpErrors,
+ @Nullable String fileExtension) throws URISyntaxException, DiadocException {
+ var url = new URIBuilder(diadocHttpClient.getBaseUrl())
+ .setPath("/ShelfUploadPartInit")
+ .addParameter("fileExtension", fileExtension);
+ if (missingParts.size() == 1)
+ {
+ url.addParameter("isLastPart", "true");
+ }
+
+ try
+ {
+ var response = diadocHttpClient.getResponse(RequestBuilder.post(url.build()).setEntity(new ByteArrayEntity(firstPart.getBytes())));
+ if (response.getStatusCode() != HttpStatus.SC_OK) {
+ if (SHELF_NON_RETRIABLE_STATUS_CODES.contains(response.getStatusCode())) {
+ throw new DiadocException(formatResponseMessage(response.getReason(), response.getStatusCode()), response.getStatusCode());
+ }
+
+ httpErrors.add(new DiadocException(formatResponseMessage(response.getReason(), response.getStatusCode()), response.getStatusCode()));
+ }
+
+ var responseContent = response.getContent();
+ if (responseContent == null || responseContent.length == 0)
+ return null;
+
+ missingParts.remove(0);
+ return new String(responseContent, StandardCharsets.UTF_8);
+
+ } catch (IOException e) {
+ httpErrors.add(e);
+ }
+
+ return null;
+ }
+
+ private List shelfUploadParts(
+ String fileName,
+ List parts,
+ List missingParts,
+ List httpErrors) throws URISyntaxException, DiadocException {
+ Set lastMissingParts = new HashSet<>(missingParts);
+ int maxProcessedPartIndex = -1;
+
+ for (int partIndex : missingParts) {
+ boolean isLastPart = partIndex == parts.size() - 1;
+ List newMissingParts = uploadPart(fileName, parts.get(partIndex), partIndex, isLastPart, httpErrors);
+ if (newMissingParts != null) {
+ if (partIndex > maxProcessedPartIndex) {
+ lastMissingParts.clear();
+ lastMissingParts.addAll(newMissingParts);
+
+ maxProcessedPartIndex = partIndex;
+ }
+ } else {
+ lastMissingParts.add(partIndex);
+ }
+ }
+ return new ArrayList<>(lastMissingParts);
+ }
+
+ private List uploadPart(
+ String fileName,
+ ByteArraySegment part,
+ Integer partIndex,
+ Boolean isLast,
+ List httpErrors) throws URISyntaxException, DiadocException {
+ var url = new URIBuilder(diadocHttpClient.getBaseUrl())
+ .setPath("/ShelfUploadPart")
+ .addParameter("fileName", fileName)
+ .addParameter("partIndex", Integer.toString(partIndex))
+ .addParameter("isLastPart", Boolean.toString(isLast));
+
+ byte[] responseContent;
+
+ try {
+ var response = diadocHttpClient.getResponse(RequestBuilder.post(url.build()).setEntity(new ByteArrayEntity(part.getBytes())));
+ if (response.getStatusCode() != HttpStatus.SC_OK) {
+ if (SHELF_NON_RETRIABLE_STATUS_CODES.contains(response.getStatusCode())) {
+ throw new DiadocException(formatResponseMessage(response.getReason(), response.getStatusCode()), response.getStatusCode());
+ }
+
+ httpErrors.add(new DiadocException(formatResponseMessage(response.getReason(), response.getStatusCode()), response.getStatusCode()));
+ return null;
+ }
+
+ responseContent = response.getContent();
+
+ } catch (IOException e) {
+ httpErrors.add(e);
+ return null;
+ }
+
+ if (responseContent == null || responseContent.length == 0)
+ return null;
+
+ String responseString = new String(responseContent, StandardCharsets.UTF_8);
+
+ int[] missingParts = new Gson().fromJson(responseString, int[].class);
+ return Arrays.stream(missingParts).boxed().collect(Collectors.toList());
+ }
private String createNameOnShelf() {
return String.format("java_api-%s", UUID.randomUUID().toString().replaceAll("-", ""));