Пример #1
0
        public async Task <(SessionDescriptor SessionDescriptor, AuthorInfo AuthorInfo, DateTime ExpiresAt)> GetSessionDescriptor(Guid sessionId)
        {
            var result =
                await _memoryCache.GetOrCreateAsync(
                    sessionId,
                    async entry =>
            {
                try
                {
                    using (var objectResponse = await _cephS3Client.GetObjectAsync(_filesBucketName, sessionId.AsS3ObjectKey(Tokens.SessionPostfix)))
                    {
                        var metadataWrapper = MetadataCollectionWrapper.For(objectResponse.Metadata);
                        var expiresAt       = metadataWrapper.Read <DateTime>(MetadataElement.ExpiresAt);
                        var author          = metadataWrapper.Read <string>(MetadataElement.Author);
                        var authorLogin     = metadataWrapper.Read <string>(MetadataElement.AuthorLogin);
                        var authorName      = metadataWrapper.Read <string>(MetadataElement.AuthorName);

                        string json;
                        using (var reader = new StreamReader(objectResponse.ResponseStream, Encoding.UTF8))
                        {
                            json = reader.ReadToEnd();
                        }

                        var sessionDescriptor = JsonConvert.DeserializeObject <SessionDescriptor>(json, SerializerSettings.Default);
                        var tuple             = (SessionDescriptor : sessionDescriptor, AuthorInfo : new AuthorInfo(author, authorLogin, authorName), ExpiresAt : expiresAt);

                        entry.SetValue(tuple)
                        .SetAbsoluteExpiration(expiresAt);

                        return(tuple);
                    }
                }
                catch (AmazonS3Exception ex) when(ex.StatusCode == HttpStatusCode.NotFound)
                {
                    throw new ObjectNotFoundException($"Session '{sessionId}' does not exist");
                }
                catch (SessionExpiredException)
                {
                    throw;
                }
                catch (Exception ex)
                {
                    throw new S3Exception(ex);
                }
            });

            if (SessionDescriptor.IsSessionExpired(result.ExpiresAt))
            {
                throw new SessionExpiredException(sessionId, result.ExpiresAt);
            }

            return(result);
        }
Пример #2
0
        public async Task UploadFilePart(MultipartUploadSession uploadSession, Stream inputStream, int templateCode)
        {
            if (SessionDescriptor.IsSessionExpired(uploadSession.SessionExpiresAt))
            {
                throw new SessionExpiredException(uploadSession.SessionId, uploadSession.SessionExpiresAt);
            }

            if (uploadSession.NextPartNumber == 1)
            {
                var sessionDescriptor = uploadSession.SessionDescriptor;
                var elementDescriptor = uploadSession.ElementDescriptor;
                EnsureFileHeaderIsValid(
                    templateCode,
                    uploadSession.ElementDescriptor.Type,
                    elementDescriptor.Constraints.For(sessionDescriptor.Language),
                    inputStream,
                    uploadSession.UploadedFileMetadata);
            }

            var key = uploadSession.SessionId.AsS3ObjectKey(uploadSession.FileKey);

            inputStream.Position = 0;

            var response = await _cephS3Client.UploadPartAsync(
                new UploadPartRequest
            {
                BucketName  = _filesBucketName,
                Key         = key,
                UploadId    = uploadSession.UploadId,
                InputStream = inputStream,
                PartNumber  = uploadSession.NextPartNumber
            });

            uploadSession.AddPart(response.ETag);
        }
Пример #3
0
        public async Task <string> CompleteMultipartUpload(MultipartUploadSession uploadSession)
        {
            var uploadKey      = uploadSession.SessionId.AsS3ObjectKey(uploadSession.FileKey);
            var partETags      = uploadSession.Parts.Select(x => new PartETag(x.PartNumber, x.Etag)).ToList();
            var uploadResponse = await _cephS3Client.CompleteMultipartUploadAsync(
                new CompleteMultipartUploadRequest
            {
                BucketName = _filesBucketName,
                Key        = uploadKey,
                UploadId   = uploadSession.UploadId,
                PartETags  = partETags
            });

            uploadSession.Complete();

            if (SessionDescriptor.IsSessionExpired(uploadSession.SessionExpiresAt))
            {
                throw new SessionExpiredException(uploadSession.SessionId, uploadSession.SessionExpiresAt);
            }

            try
            {
                using (var getResponse = await _cephS3Client.GetObjectAsync(_filesBucketName, uploadKey))
                {
                    var memoryStream = new MemoryStream();
                    using (getResponse.ResponseStream)
                    {
                        getResponse.ResponseStream.CopyTo(memoryStream);
                        memoryStream.Position = 0;
                    }

                    using (memoryStream)
                    {
                        var sessionDescriptor = uploadSession.SessionDescriptor;
                        var elementDescriptor = uploadSession.ElementDescriptor;
                        EnsureFileContentIsValid(
                            elementDescriptor.TemplateCode,
                            elementDescriptor.Type,
                            elementDescriptor.Constraints.For(sessionDescriptor.Language),
                            memoryStream,
                            uploadSession.UploadedFileMetadata);
                    }

                    var metadataWrapper = MetadataCollectionWrapper.For(getResponse.Metadata);
                    var fileName        = metadataWrapper.Read <string>(MetadataElement.Filename);

                    var fileExtension = Path.GetExtension(fileName).ToLowerInvariant();
                    var fileKey       = Path.ChangeExtension(uploadSession.SessionId.AsS3ObjectKey(uploadResponse.ETag), fileExtension);
                    var copyRequest   = new CopyObjectRequest
                    {
                        ContentType       = uploadSession.UploadedFileMetadata.ContentType,
                        SourceBucket      = _filesBucketName,
                        SourceKey         = uploadKey,
                        DestinationBucket = _filesBucketName,
                        DestinationKey    = fileKey,
                        MetadataDirective = S3MetadataDirective.REPLACE,
                        CannedACL         = S3CannedACL.PublicRead
                    };
                    foreach (var metadataKey in getResponse.Metadata.Keys)
                    {
                        copyRequest.Metadata.Add(metadataKey, getResponse.Metadata[metadataKey]);
                    }

                    await _cephS3Client.CopyObjectAsync(copyRequest);

                    _uploadedBinariesMetric.Inc();

                    _memoryCache.Set(fileKey, new BinaryMetadata(fileName, getResponse.ContentLength), uploadSession.SessionExpiresAt);

                    return(fileKey);
                }
            }
            finally
            {
                await _cephS3Client.DeleteObjectAsync(_filesBucketName, uploadKey);
            }
        }