mirror of
https://github.com/valitydev/file-storage.git
synced 2024-11-06 08:45:16 +00:00
add generateMultipartDownloadUrl method (#22)
Co-authored-by: ggmaleva <ggmaleva@yandex.ru>
This commit is contained in:
parent
c0205a2290
commit
769c158620
2
pom.xml
2
pom.xml
@ -30,7 +30,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>dev.vality</groupId>
|
<groupId>dev.vality</groupId>
|
||||||
<artifactId>file-storage-proto</artifactId>
|
<artifactId>file-storage-proto</artifactId>
|
||||||
<version>1.47-0f31e02</version>
|
<version>1.48-4569cea</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>dev.vality</groupId>
|
<groupId>dev.vality</groupId>
|
||||||
|
@ -92,6 +92,22 @@ public class FileStorageHandler implements FileStorageSrv.Iface {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String generateMultipartDownloadUrl(String fileDataId, String expiresAt) throws TException {
|
||||||
|
try {
|
||||||
|
log.info("Receive request for generate download url with fileDataId={}", fileDataId);
|
||||||
|
CheckerUtil.checkString(fileDataId, "Bad request parameter, fileDataId required and not empty arg");
|
||||||
|
CheckerUtil.checkString(expiresAt, "Bad request parameter, expiresAt required and not empty arg");
|
||||||
|
Instant instant = TypeUtil.stringToInstant(expiresAt);
|
||||||
|
URL url = storageService.generateMultipartDownloadUrl(fileDataId, instant);
|
||||||
|
log.info("Successfully generate download url with fileDataId={}", fileDataId);
|
||||||
|
log.debug("Generated download url={}", url);
|
||||||
|
return url.toString();
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
throw fileNotFound(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private FileNotFound fileNotFound(FileNotFoundException e) {
|
private FileNotFound fileNotFound(FileNotFoundException e) {
|
||||||
log.warn("File not found", e);
|
log.warn("File not found", e);
|
||||||
return new FileNotFound();
|
return new FileNotFound();
|
||||||
|
@ -134,6 +134,11 @@ public class S3Service implements StorageService {
|
|||||||
throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
|
throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public URL generateMultipartDownloadUrl(String fileDataId, Instant expirationTime) {
|
||||||
|
throw new UnsupportedOperationException(METHOD_NOT_SUPPORTED);
|
||||||
|
}
|
||||||
|
|
||||||
@PreDestroy
|
@PreDestroy
|
||||||
public void terminate() {
|
public void terminate() {
|
||||||
transferManager.shutdownNow(true);
|
transferManager.shutdownNow(true);
|
||||||
|
@ -20,6 +20,7 @@ import software.amazon.awssdk.services.s3.S3Client;
|
|||||||
import software.amazon.awssdk.services.s3.model.*;
|
import software.amazon.awssdk.services.s3.model.*;
|
||||||
import software.amazon.awssdk.services.s3.presigner.S3Presigner;
|
import software.amazon.awssdk.services.s3.presigner.S3Presigner;
|
||||||
import software.amazon.awssdk.services.s3.presigner.model.GetObjectPresignRequest;
|
import software.amazon.awssdk.services.s3.presigner.model.GetObjectPresignRequest;
|
||||||
|
import software.amazon.awssdk.services.s3.presigner.model.PresignedGetObjectRequest;
|
||||||
import software.amazon.awssdk.services.s3.presigner.model.PutObjectPresignRequest;
|
import software.amazon.awssdk.services.s3.presigner.model.PutObjectPresignRequest;
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
@ -66,18 +67,7 @@ public class S3V2Service implements StorageService {
|
|||||||
var versions = getObjectVersions(fileId);
|
var versions = getObjectVersions(fileId);
|
||||||
checkFileExist(fileId, versions);
|
checkFileExist(fileId, versions);
|
||||||
var fileVersionId = getFileVersionId(fileId, versions);
|
var fileVersionId = getFileVersionId(fileId, versions);
|
||||||
var presignRequest = GetObjectPresignRequest.builder()
|
PresignedGetObjectRequest presignedRequest = getPresignedRequest(fileId, expirationTime, fileVersionId);
|
||||||
.signatureDuration(Duration.between(Instant.now(), expirationTime))
|
|
||||||
.getObjectRequest(GetObjectRequest.builder()
|
|
||||||
.bucket(s3SdkV2Properties.getBucketName())
|
|
||||||
.key(fileId)
|
|
||||||
.versionId(fileVersionId)
|
|
||||||
.build())
|
|
||||||
.build();
|
|
||||||
var presignedRequest = s3Presigner.presignGetObject(presignRequest);
|
|
||||||
log.info("Download url was presigned, fileId={}, bucketName={}, isBrowserExecutable={}",
|
|
||||||
fileId, s3SdkV2Properties.getBucketName(), presignedRequest.isBrowserExecutable());
|
|
||||||
log.debug("Presigned http request={}", presignedRequest.httpRequest().toString());
|
|
||||||
return presignedRequest.url();
|
return presignedRequest.url();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -510,6 +500,36 @@ public class S3V2Service implements StorageService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public URL generateMultipartDownloadUrl(String fileId, Instant expirationTime) {
|
||||||
|
var versions = getObjectVersions(fileId);
|
||||||
|
if (CollectionUtils.isEmpty(versions)) {
|
||||||
|
throw new FileNotFoundException(String.format(
|
||||||
|
"Failed to check object version with file on exist, fileId=%s, bucketName=%s ",
|
||||||
|
fileId,
|
||||||
|
s3SdkV2Properties.getBucketName()));
|
||||||
|
}
|
||||||
|
var fileVersionId = getFileVersionId(fileId, versions);
|
||||||
|
PresignedGetObjectRequest presignedRequest = getPresignedRequest(fileId, expirationTime, fileVersionId);
|
||||||
|
return presignedRequest.url();
|
||||||
|
}
|
||||||
|
|
||||||
|
private PresignedGetObjectRequest getPresignedRequest(String fileId, Instant expirationTime, String fileVersionId) {
|
||||||
|
var presignRequest = GetObjectPresignRequest.builder()
|
||||||
|
.signatureDuration(Duration.between(Instant.now(), expirationTime))
|
||||||
|
.getObjectRequest(GetObjectRequest.builder()
|
||||||
|
.bucket(s3SdkV2Properties.getBucketName())
|
||||||
|
.key(fileId)
|
||||||
|
.versionId(fileVersionId)
|
||||||
|
.build())
|
||||||
|
.build();
|
||||||
|
var presignedRequest = s3Presigner.presignGetObject(presignRequest);
|
||||||
|
log.info("Download url was presigned, fileId={}, bucketName={}, isBrowserExecutable={}",
|
||||||
|
fileId, s3SdkV2Properties.getBucketName(), presignedRequest.isBrowserExecutable());
|
||||||
|
log.debug("Presigned http request={}", presignedRequest.httpRequest().toString());
|
||||||
|
return presignedRequest;
|
||||||
|
}
|
||||||
|
|
||||||
private software.amazon.awssdk.services.s3.model.CompleteMultipartUploadRequest buildRequest(
|
private software.amazon.awssdk.services.s3.model.CompleteMultipartUploadRequest buildRequest(
|
||||||
CompleteMultipartUploadRequest request,
|
CompleteMultipartUploadRequest request,
|
||||||
String fileId,
|
String fileId,
|
||||||
|
@ -23,4 +23,6 @@ public interface StorageService {
|
|||||||
|
|
||||||
CompleteMultipartUploadResult completeMultipartUpload(CompleteMultipartUploadRequest request);
|
CompleteMultipartUploadResult completeMultipartUpload(CompleteMultipartUploadRequest request);
|
||||||
|
|
||||||
|
URL generateMultipartDownloadUrl(String fileDataId, Instant expirationTime);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@ import java.nio.file.Files;
|
|||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.nio.file.StandardCopyOption;
|
import java.nio.file.StandardCopyOption;
|
||||||
|
import java.time.Instant;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
@ -425,4 +426,30 @@ public abstract class FileStorageTest {
|
|||||||
assertNotNull(multipartFileData.getCreatedAt());
|
assertNotNull(multipartFileData.getCreatedAt());
|
||||||
assertNotNull(multipartFileData.getMetadata());
|
assertNotNull(multipartFileData.getMetadata());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void generateMultipartDownloadUrl() throws Exception {
|
||||||
|
dev.vality.msgpack.Value value = new dev.vality.msgpack.Value();
|
||||||
|
String fileName = "test_registry.csv";
|
||||||
|
value.setStr(fileName);
|
||||||
|
Map<String, dev.vality.msgpack.Value> metadata = Map.of("filename", value);
|
||||||
|
CreateMultipartUploadResult createResult = fileStorageClient.createMultipartUpload(metadata);
|
||||||
|
assertNotNull(createResult.getFileDataId());
|
||||||
|
assertNotNull(createResult.getMultipartUploadId());
|
||||||
|
|
||||||
|
List<CompletedMultipart> completedParts = new ArrayList<>();
|
||||||
|
processMultipartUpload(createResult, completedParts);
|
||||||
|
|
||||||
|
var completeRequest = new CompleteMultipartUploadRequest()
|
||||||
|
.setMultipartUploadId(createResult.getMultipartUploadId())
|
||||||
|
.setFileDataId(createResult.getFileDataId())
|
||||||
|
.setCompletedParts(completedParts);
|
||||||
|
|
||||||
|
fileStorageClient.completeMultipartUpload(completeRequest);
|
||||||
|
|
||||||
|
String expiredTime = Instant.now().toString();
|
||||||
|
String url = fileStorageClient.generateMultipartDownloadUrl(createResult.getFileDataId(), expiredTime);
|
||||||
|
|
||||||
|
assertNotNull(url);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user