-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathFileStorageService.cs
More file actions
103 lines (87 loc) · 3.27 KB
/
FileStorageService.cs
File metadata and controls
103 lines (87 loc) · 3.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using App.Configuration;
using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Specialized;
namespace App.Services
{
public class FileStorageService : IFileStorageService
{
private readonly BlobStorageConfig blobStorageConfig;
public FileStorageService(BlobStorageConfig blobStorageConfig)
{
this.blobStorageConfig = blobStorageConfig;
}
public async Task UploadBlockAsync(Guid fileId, long blockId, Stream block)
{
var client = CreateBlockClient(fileId);
using (var md5 = MD5.Create())
{
var hash = md5.ComputeHash(block);
block.Position = 0;
await client.StageBlockAsync(
GenerateBlobBlockId(blockId),
block,
hash
);
}
}
public async Task CommitBlocksAsync(Guid fileId, FileMetadata metadata)
{
var client = CreateBlockClient(fileId);
var blockList = await client.GetBlockListAsync();
var blobBlockIds = blockList.Value.UncommittedBlocks
.Select(item => item.Name);
await client.CommitBlockListAsync(
OrderBlobBlockIds(blobBlockIds),
null,
metadata.ToStorageMetadata()
);
}
public async Task<(Stream Stream, FileMetadata Metadata)> DownloadAsync(Guid fileId)
{
var client = CreateBlockClient(fileId);
var blob = await client.DownloadAsync();
var properties = await client.GetPropertiesAsync();
return (
Stream: blob.Value.Content,
Metadata: FileMetadata.FromStorageMetadata(properties.Value.Metadata)
);
}
public async Task CreateContainerAsync()
{
var serviceClient = new BlobServiceClient(blobStorageConfig.ConnectionString);
var blobClient = serviceClient.GetBlobContainerClient(blobStorageConfig.ContainerName);
await blobClient.CreateIfNotExistsAsync();
}
private string GenerateBlobBlockId(long blockId)
{
return Convert.ToBase64String(
Encoding.UTF8.GetBytes(
blockId.ToString("d20")
)
);
}
private IEnumerable<string> OrderBlobBlockIds(IEnumerable<string> blobBlockIds)
{
return blobBlockIds.Select(Convert.FromBase64String)
.Select(Encoding.UTF8.GetString)
.Select(long.Parse)
.OrderBy(_ => _)
.Select(GenerateBlobBlockId)
.ToArray();
}
private BlockBlobClient CreateBlockClient(Guid fileId)
{
var serviceClient = new BlobServiceClient(blobStorageConfig.ConnectionString);
var blobClient = serviceClient.GetBlobContainerClient(blobStorageConfig.ContainerName);
return new BlockBlobClient(
blobStorageConfig.ConnectionString, blobStorageConfig.ContainerName, fileId.ToString());
}
}
}