Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* aws * Added Managed Identity for Azure Storage * Release alpha version * base controller * Add methods from StorageFromFileExt and StorageExt (#46) Co-authored-by: Hurko Volodymyr <hurko@managed-code.com> * prototype * test containsers azure + aws * checks * actions * test containsers * test * rename * #54 * refactoring * tests * tests * tests * fix all tests * naming * fix test container for google * ndepend * Upload chunks (#69) * add integration tests project * add client * add test controller and controller tests * fix * add IStorageClient * fix storage client * accept file and content names in client method * add content name property * return status code when request is failed * add test for file upload from file info * move tests * add tests for upload methods with azure * fix tests * return downloaded file as stream * return localFile from download method * return result on download * add base test classes for controller tests * add methods upload in chunk --------- Co-authored-by: TRybina132 <rybina@managed-code.com> * add stream tests classes * Add integration tests (#70) * add integration tests project * add client * add test controller and controller tests * fix * add IStorageClient * fix storage client * accept file and content names in client method * add content name property * return status code when request is failed * add test for file upload from file info * move tests * add tests for upload methods with azure * fix tests * return downloaded file as stream * return localFile from download method * return result on download * add base test classes for controller tests * use another controller for base controller * use another method for crc calculation * remove duplicated controller * remove local folder path and replace it with path from method --------- Co-authored-by: TRybina132 <rybina@managed-code.com> Co-authored-by: Olexandr Ivanitskyi <6saaanchik6@gmail.com> * fix azure blob stream lenght * fix tests * add write test for azure blob * add seek test * Updated code coverage in pipeline (#74) * Temporarily removed some code from dotnet.yml pipeline * codecoverage * Modified test csproj * Rollbacked changes to csproj * Added stopIfQGFailed: false * Updated dotnet.yml * Updated dotnet.yml * Modified pipeline * Fixed type and temporarily removed some code * Added ndepend * Brought back missing code * Added --no-build flag --------- Co-authored-by: Kostiantyn Bondarenko <bondarenko@managed-code.com> Co-authored-by: ksemenenko <KSemenenko@users.noreply.github.com> * add properties variable --------- Co-authored-by: dtymakhov <dtymakhov@gmail.com> Co-authored-by: Alexandr Ivanitskyi <6saaanchik6@gmail.com> Co-authored-by: Hurko Volodymyr <92858780+Hurko-Volodymyr@users.noreply.github.com> Co-authored-by: Hurko Volodymyr <hurko@managed-code.com> Co-authored-by: Eduard <eduard@managed-code.com> Co-authored-by: Alexandr Ivanitskyi <91984393+Sanyyazzz@users.noreply.github.com> Co-authored-by: TRybina132 <rybina@managed-code.com> Co-authored-by: TRybina132 <98330987+TRybina132@users.noreply.github.com> Co-authored-by: Kostiantyn Bondarenko <92333402+techcat18@users.noreply.github.com> Co-authored-by: Kostiantyn Bondarenko <bondarenko@managed-code.com>
- Loading branch information
1 parent
9b91d02
commit cf6b55e
Showing
32 changed files
with
1,160 additions
and
86 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
using System.IO; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using ManagedCode.Communication; | ||
using ManagedCode.Storage.Core.Models; | ||
|
||
namespace ManagedCode.Storage.Client; | ||
|
||
public interface IStorageClient | ||
{ | ||
Task<Result<BlobMetadata>> UploadFile(Stream stream, string apiUrl, string contentName, CancellationToken cancellationToken = default); | ||
Task<Result<BlobMetadata>> UploadFile(FileInfo fileInfo, string apiUrl, string contentName, CancellationToken cancellationToken = default); | ||
Task<Result<BlobMetadata>> UploadFile(byte[] bytes, string apiUrl, string contentName, CancellationToken cancellationToken = default); | ||
Task<Result<BlobMetadata>> UploadFile(string base64, string apiUrl, string contentName, CancellationToken cancellationToken = default); | ||
Task<Result> UploadFileInChunks(Stream file, string apiUrl, int chunkSize, CancellationToken cancellationToken = default); | ||
Task<Result<LocalFile>> DownloadFile(string fileName, string apiUrl, string? path = null, CancellationToken cancellationToken = default); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,162 @@ | ||
using System; | ||
using System.IO; | ||
using System.Net; | ||
using System.Net.Http; | ||
using System.Net.Http.Json; | ||
using System.Net.Http.Headers; | ||
using System.Net.Http.Json; | ||
using System.Net.Http.Json; | ||
using System.Text.Json; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using ManagedCode.Communication; | ||
using ManagedCode.Storage.Core; | ||
using ManagedCode.Storage.Core.Models; | ||
|
||
namespace ManagedCode.Storage.Client; | ||
|
||
public class StorageClient : IStorageClient | ||
{ | ||
private readonly HttpClient _httpClient; | ||
|
||
public StorageClient(HttpClient httpClient) | ||
{ | ||
_httpClient = httpClient; | ||
} | ||
|
||
public async Task<Result<BlobMetadata>> UploadFile(Stream stream, string apiUrl, string contentName, CancellationToken cancellationToken = default) | ||
{ | ||
var streamContent = new StreamContent(stream); | ||
|
||
using (var formData = new MultipartFormDataContent()) | ||
{ | ||
formData.Add(streamContent, contentName, contentName); | ||
|
||
var response = await _httpClient.PostAsync(apiUrl, formData, cancellationToken); | ||
|
||
if (response.IsSuccessStatusCode) | ||
{ | ||
var result = await response.Content.ReadFromJsonAsync<Result<BlobMetadata>>(cancellationToken: cancellationToken); | ||
return result; | ||
} | ||
|
||
string content = await response.Content.ReadAsStringAsync(cancellationToken: cancellationToken); | ||
|
||
return Result<BlobMetadata>.Fail(response.StatusCode, content); | ||
} | ||
} | ||
|
||
public async Task<Result<BlobMetadata>> UploadFile(FileInfo fileInfo, string apiUrl, string contentName, CancellationToken cancellationToken = default) | ||
{ | ||
using var streamContent = new StreamContent(fileInfo.OpenRead()); | ||
|
||
using (var formData = new MultipartFormDataContent()) | ||
{ | ||
formData.Add(streamContent, contentName, contentName); | ||
|
||
var response = await _httpClient.PostAsync(apiUrl, formData, cancellationToken); | ||
|
||
if (response.IsSuccessStatusCode) | ||
{ | ||
var result = await response.Content.ReadFromJsonAsync<Result<BlobMetadata>>(cancellationToken: cancellationToken); | ||
return result; | ||
} | ||
|
||
return Result<BlobMetadata>.Fail(response.StatusCode); | ||
} | ||
} | ||
|
||
public async Task<Result<BlobMetadata>> UploadFile(byte[] bytes, string apiUrl, string contentName, CancellationToken cancellationToken = default) | ||
{ | ||
using (var stream = new MemoryStream()) | ||
{ | ||
stream.Write(bytes, 0, bytes.Length); | ||
|
||
using var streamContent = new StreamContent(stream); | ||
|
||
using (var formData = new MultipartFormDataContent()) | ||
{ | ||
formData.Add(streamContent, contentName, contentName); | ||
|
||
var response = await _httpClient.PostAsync(apiUrl, formData, cancellationToken); | ||
|
||
if (response.IsSuccessStatusCode) | ||
{ | ||
var result = await response.Content.ReadFromJsonAsync<Result<BlobMetadata>>(cancellationToken: cancellationToken); | ||
return result; | ||
} | ||
|
||
return Result<BlobMetadata>.Fail(response.StatusCode); | ||
} | ||
} | ||
} | ||
|
||
public async Task<Result<BlobMetadata>> UploadFile(string base64, string apiUrl, string contentName, CancellationToken cancellationToken = default) | ||
{ | ||
byte[] fileAsBytes = Convert.FromBase64String(base64); | ||
using var fileContent = new ByteArrayContent(fileAsBytes); | ||
|
||
using var formData = new MultipartFormDataContent(); | ||
|
||
formData.Add(fileContent, contentName, contentName); | ||
|
||
var response = await _httpClient.PostAsync(apiUrl, formData, cancellationToken); | ||
|
||
if (response.IsSuccessStatusCode) | ||
{ | ||
return await response.Content.ReadFromJsonAsync<Result<BlobMetadata>>(cancellationToken: cancellationToken); | ||
} | ||
|
||
return Result<BlobMetadata>.Fail(response.StatusCode); | ||
} | ||
|
||
public async Task<Result<LocalFile>> DownloadFile(string fileName, string apiUrl, string? path = null, CancellationToken cancellationToken = default) | ||
{ | ||
try | ||
{ | ||
var response = await _httpClient.GetStreamAsync($"{apiUrl}/{fileName}", cancellationToken); | ||
|
||
var localFile = path is null ? await LocalFile.FromStreamAsync(response, fileName) : await LocalFile.FromStreamAsync(response, path, fileName); | ||
|
||
return Result<LocalFile>.Succeed(localFile); | ||
} | ||
catch (HttpRequestException e) | ||
{ | ||
return Result<LocalFile>.Fail(e.StatusCode ?? HttpStatusCode.InternalServerError); | ||
} | ||
} | ||
|
||
public async Task<Result> UploadFileInChunks(Stream file, string apiUrl, int chunkSize, CancellationToken cancellationToken) | ||
{ | ||
var buffer = new byte[chunkSize]; | ||
int bytesRead; | ||
int chunkIndex = 0; | ||
|
||
while ((bytesRead = await file.ReadAsync(buffer, 0, buffer.Length, cancellationToken)) > 0) | ||
{ | ||
// Create a MemoryStream for the current chunk. | ||
using (var memoryStream = new MemoryStream(buffer, 0, bytesRead)) | ||
{ | ||
var content = new StreamContent(memoryStream); | ||
|
||
using (var chunk = new MultipartFormDataContent()) | ||
{ | ||
chunk.Add(content, "file", "file"); | ||
|
||
var byteArrayContent = new ByteArrayContent(await chunk.ReadAsByteArrayAsync(cancellationToken)); | ||
// Send the current chunk to the API endpoint. | ||
var response = await _httpClient.PostAsync(apiUrl, byteArrayContent, cancellationToken); | ||
|
||
if (!response.IsSuccessStatusCode) | ||
{ | ||
return Result.Fail(); | ||
} | ||
} | ||
} | ||
} | ||
|
||
var mergeResult = await _httpClient.PostAsync(apiUrl + "/complete", JsonContent.Create("file")); | ||
|
||
return await mergeResult.Content.ReadFromJsonAsync<Result>(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 13 additions & 0 deletions
13
ManagedCode.Storage.IntegrationTests/Constants/ApiEndpoints.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
namespace ManagedCode.Storage.IntegrationTests.Constants; | ||
|
||
public static class ApiEndpoints | ||
{ | ||
public const string Azure = "azure"; | ||
|
||
public static class Base | ||
{ | ||
public const string UploadFile = "{0}/upload"; | ||
public const string UploadFileChunks = "{0}/upload-chunks"; | ||
public const string DownloadFile = "{0}/download"; | ||
} | ||
} |
Oops, something went wrong.