Skip to content

Commit b409ed7

Browse files
authored
Merge pull request #10 from lreb/aws-s3
Aws s3 feature to upload and download files
2 parents 21397a1 + 01dd412 commit b409ed7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+1396
-38
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -434,4 +434,5 @@ $RECYCLE.BIN/
434434

435435

436436
# Facware Base API
437-
FacwareBase.API/AWSLambda/
437+
FacwareBase.API/AWSLambda/
438+
FacwareBase.API/PublishAWSLambda/
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
using FacwareBase.API.Services.Amazon.S3.Core.Bucket;
2+
using FacwareBase.API.Services.Amazon.S3.Core.Interfaces;
3+
using Microsoft.AspNetCore.Mvc;
4+
using System.Collections.Generic;
5+
using System.Threading.Tasks;
6+
7+
namespace FacwareBase.API.Controllers.Document
8+
{
9+
[Route("api/bucket")]
10+
[ApiController]
11+
public class BucketController : ControllerBase
12+
{
13+
private readonly IBucketRepository _bucketRepository;
14+
15+
public BucketController(IBucketRepository bucketRepository)
16+
{
17+
_bucketRepository = bucketRepository;
18+
}
19+
20+
/// <summary>
21+
/// create a new s3 bucket
22+
/// </summary>
23+
/// <param name="bucketName"></param>
24+
/// <returns></returns>
25+
[HttpPost]
26+
[Route("create/{bucketName}")]
27+
public async Task<ActionResult<CreateBucketResponse>> CreateS3Bucket([FromRoute] string bucketName)
28+
{
29+
var bucketExists = await _bucketRepository.DoesS3BucketExist(bucketName);
30+
31+
if (bucketExists)
32+
{
33+
return BadRequest("S3 bucket already exists");
34+
}
35+
36+
var result = await _bucketRepository.CreateBucket(bucketName);
37+
38+
if (result == null)
39+
{
40+
return BadRequest();
41+
}
42+
43+
return Ok(result);
44+
}
45+
46+
/// <summary>
47+
/// list all s3 buckets
48+
/// </summary>
49+
/// <returns></returns>
50+
[HttpGet]
51+
[Route("list")]
52+
public async Task<ActionResult<IEnumerable<ListS3BucketsResponse>>> ListS3Buckets()
53+
{
54+
var result = await _bucketRepository.ListBuckets();
55+
56+
if (result == null)
57+
{
58+
return NotFound();
59+
}
60+
61+
return Ok(result);
62+
}
63+
64+
65+
/// <summary>
66+
/// delete a s3 bucket
67+
/// </summary>
68+
/// <param name="bucketName"></param>
69+
/// <returns></returns>
70+
[HttpDelete]
71+
[Route("delete/{bucketName}")]
72+
public async Task<IActionResult> DeleteS3Bucket(string bucketName)
73+
{
74+
await _bucketRepository.DeleteBucket(bucketName);
75+
76+
return Ok();
77+
}
78+
}
79+
}
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
using FacwareBase.API.Core.File.Management;
2+
using FacwareBase.API.Helpers.FileManagement;
3+
using FacwareBase.API.Services.Amazon.S3.Core.File;
4+
using FacwareBase.API.Services.Amazon.S3.Core.Interfaces;
5+
using Microsoft.AspNetCore.Http;
6+
using Microsoft.AspNetCore.Mvc;
7+
using Microsoft.Extensions.Options;
8+
using System.Collections.Generic;
9+
using System.Threading.Tasks;
10+
11+
namespace FacwareBase.API.Controllers.Document
12+
{
13+
[Route("api/file")]
14+
[ApiController]
15+
public class FileController : ControllerBase
16+
{
17+
private readonly IFilesRepository _filesRepository;
18+
private readonly IFileManagement _fileManagement;
19+
private readonly FileStorageOptions _fileStorageOptions;
20+
21+
public FileController(IFilesRepository filesRepository,
22+
IFileManagement fileManagement,
23+
IOptions<FileStorageOptions> fileStorageOptions)
24+
{
25+
_filesRepository = filesRepository;
26+
_fileManagement = fileManagement;
27+
_fileStorageOptions = fileStorageOptions.Value;
28+
}
29+
30+
/// <summary>
31+
/// Add new file
32+
/// </summary>
33+
/// <param name="bucketName">bucket name</param>
34+
/// <param name="key">s3 key</param>
35+
/// <param name="formFiles">file</param>
36+
/// <returns></returns>
37+
[HttpPost]
38+
[Route("{bucketName}/add/{key}")]
39+
public async Task<ActionResult<AddFileResponse>> AddFiles(string bucketName, string key, IList<IFormFile> formFiles)
40+
{
41+
if (formFiles == null)
42+
{
43+
return BadRequest("The request doesn't contain any files to be uploaded.");
44+
}
45+
46+
var response = await _filesRepository.UploadFiles(bucketName, formFiles, key);
47+
48+
if (response == null)
49+
{
50+
return BadRequest();
51+
}
52+
53+
return Ok(response);
54+
}
55+
56+
/// <summary>
57+
/// List keys in a s3 bucket
58+
/// </summary>
59+
/// <param name="bucketName"></param>
60+
/// <returns></returns>
61+
[HttpGet]
62+
[Route("{bucketName}/list")]
63+
public async Task<ActionResult<IEnumerable<ListFilesResponse>>> ListFiles(string bucketName)
64+
{
65+
var response = await _filesRepository.ListFiles(bucketName);
66+
67+
return Ok(response);
68+
}
69+
70+
/// <summary>
71+
/// Download file from s3 bucket
72+
/// </summary>
73+
/// <param name="bucketName"></param>
74+
/// <param name="fileName"></param>
75+
/// <returns></returns>
76+
[HttpGet]
77+
[Route("{bucketName}/download/{fileName}")]
78+
public async Task<IActionResult> DownloadFile(string bucketName, string fileName)
79+
{
80+
var temporalPath = _fileStorageOptions.TemporalStorage;
81+
82+
await _filesRepository.DownloadFile(bucketName, fileName, temporalPath);
83+
84+
var memoryFile = _fileManagement.ReadFileAsync(temporalPath, fileName).Result;
85+
86+
_fileManagement.RemoveFile(temporalPath, fileName);
87+
88+
var mimeType = _fileManagement.GetMimeType(fileName);
89+
90+
return File(memoryFile, mimeType, fileName);
91+
92+
//return Ok();
93+
}
94+
95+
/// <summary>
96+
/// Delete file from s3 bucket
97+
/// </summary>
98+
/// <param name="bucketName">Bucket name</param>
99+
/// <param name="fileName">file name</param>
100+
/// <returns></returns>
101+
[HttpDelete]
102+
[Route("{bucketName}/delete/{fileName}")]
103+
public async Task<ActionResult<DeleteFileResponse>> DeleteFile(string bucketName, string fileName)
104+
{
105+
var response = await _filesRepository.DeleteFile(bucketName, fileName);
106+
107+
return Ok(response);
108+
}
109+
110+
/// <summary>
111+
/// Add json object to s3 bucket
112+
/// </summary>
113+
/// <param name="bucketName">bucket</param>
114+
/// <param name="request">json object</param>
115+
/// <returns></returns>
116+
[HttpPost]
117+
[Route("{bucketName}/addjsonobject")]
118+
public async Task<IActionResult> AddJsonObject(string bucketName, AddJsonObjectRequest request)
119+
{
120+
await _filesRepository.AddJsonObject(bucketName, request);
121+
122+
return Ok();
123+
}
124+
125+
/// <summary>
126+
/// Get json object
127+
/// </summary>
128+
/// <param name="bucketName"></param>
129+
/// <param name="fileName"></param>
130+
/// <returns></returns>
131+
[HttpGet]
132+
[Route("{bucketName}/getjsonobject")]
133+
public async Task<ActionResult<GetJsonObjectResponse>> GetJsonObject(string bucketName, string fileName)
134+
{
135+
var response = await _filesRepository.GetJsonObject(bucketName, fileName);
136+
137+
return Ok(response);
138+
}
139+
}
140+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
using Microsoft.AspNetCore.StaticFiles;
2+
using System.IO;
3+
using System.Threading.Tasks;
4+
5+
namespace FacwareBase.API.Core.File.Management
6+
{
7+
public class FileManagement : IFileManagement
8+
{
9+
/// <summary>
10+
/// Read file from a temporal path
11+
/// </summary>
12+
/// <param name="path">temporal path</param>
13+
/// <param name="fileName">file name</param>
14+
/// <returns><see cref="MemoryStream"/>Memory stream</returns>
15+
public async Task<MemoryStream> ReadFileAsync(string path, string fileName)
16+
{
17+
string fullPath = Path.Combine(path, fileName);
18+
19+
if (!System.IO.File.Exists(fullPath))
20+
{
21+
throw new FileNotFoundException();
22+
}
23+
24+
var memory = new MemoryStream();
25+
await using (var stream = new FileStream(fullPath, FileMode.Open))
26+
{
27+
await stream.CopyToAsync(memory);
28+
}
29+
memory.Position = 0;
30+
31+
return memory;
32+
}
33+
34+
/// <summary>
35+
/// Get mime type
36+
/// </summary>
37+
/// <param name="fileName">file name</param>
38+
/// <returns>string mime type</returns>
39+
public string GetMimeType(string fileName)
40+
{
41+
var provider = new FileExtensionContentTypeProvider();
42+
if (!provider.TryGetContentType(fileName, out var contentType))
43+
{
44+
contentType = "application/octet-stream";
45+
}
46+
return contentType;
47+
}
48+
49+
/// <summary>
50+
/// Remove file from a location
51+
/// </summary>
52+
/// <param name="path">file path</param>
53+
/// <param name="fileName">file name</param>
54+
public void RemoveFile(string path, string fileName)
55+
{
56+
var fullPath = Path.Combine(path, fileName);
57+
58+
if (System.IO.File.Exists(fullPath))
59+
System.IO.File.Delete(fullPath);
60+
}
61+
62+
/// <summary>
63+
/// Move file to different location
64+
/// </summary>
65+
/// <param name="originPath">original path</param>
66+
/// <param name="originFileName">origin file name</param>
67+
/// <param name="targetPath">target path</param>
68+
/// <param name="targetFileName">target file name</param>
69+
/// <returns>full target path</returns>
70+
public string MoveFile(string originPath, string originFileName, string targetPath, string targetFileName)
71+
{
72+
var fullOriginPath = Path.Combine(originPath, originFileName);
73+
var fullTargetPath = Path.Combine(targetPath, targetFileName);
74+
75+
if (!Directory.Exists(targetPath))
76+
{
77+
Directory.CreateDirectory(targetPath);
78+
}
79+
80+
if (System.IO.File.Exists(fullOriginPath))
81+
{
82+
if (System.IO.File.Exists(fullTargetPath))
83+
System.IO.File.Delete(fullTargetPath);
84+
85+
System.IO.File.Move(fullOriginPath, fullTargetPath);
86+
}
87+
return fullTargetPath;
88+
}
89+
}
90+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
using System.IO;
2+
using System.Threading.Tasks;
3+
4+
namespace FacwareBase.API.Core.File.Management
5+
{
6+
public interface IFileManagement
7+
{
8+
/// <summary>
9+
/// Read file from a temporal path
10+
/// </summary>
11+
/// <param name="temporalPath">temporal path</param>
12+
/// <param name="fileName">file name</param>
13+
/// <returns><see cref="MemoryStream"/>Memory stream</returns>
14+
Task<MemoryStream> ReadFileAsync(string temporalPath, string fileName);
15+
16+
/// <summary>
17+
/// Get mime type
18+
/// </summary>
19+
/// <param name="fileName">file name</param>
20+
/// <returns>string mime type</returns>
21+
string GetMimeType(string fileName);
22+
23+
/// <summary>
24+
/// Remove file from a location
25+
/// </summary>
26+
/// <param name="path">file path</param>
27+
/// <param name="fileName">file name</param>
28+
void RemoveFile(string path, string fileName);
29+
30+
/// <summary>
31+
/// Move file to different location
32+
/// </summary>
33+
/// <param name="originPath">original path</param>
34+
/// <param name="originFileName">origin file name</param>
35+
/// <param name="targetPath">target path</param>
36+
/// <param name="targetFileName">target file name</param>
37+
/// <returns>full target path</returns>
38+
string MoveFile(string originPath, string originFileName, string targetPath, string targetFileName);
39+
}
40+
}

FacwareBase.API/Extensions/Cors/CorsExtension.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public static class CorsExtension
1111
/// <summary>
1212
/// Policy cors name
1313
/// </summary>
14-
public static readonly string QSSAllowSpecificOrigins = "QSSAllowSpecificOrigins";
14+
public static readonly string AllowSpecificOrigins = "AllowSpecificOrigins";
1515

1616
/// <summary>
1717
/// CORS configurations
@@ -22,7 +22,7 @@ public static void ConfigureCors(this IServiceCollection services, IConfiguratio
2222
{
2323
services.AddCors(options =>
2424
{
25-
options.AddPolicy(QSSAllowSpecificOrigins,
25+
options.AddPolicy(AllowSpecificOrigins,
2626
builder =>
2727
{
2828
builder.WithOrigins(configuration.GetSection("Cors:AllowedOrigin").Get<string[]>())

FacwareBase.API/Extensions/Database/DatabaseExtension.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public static void UseInMemoryDatabase(this IServiceCollection serviceCollection
3131
public static void UseSqlServer(this IServiceCollection serviceCollection, string applicationConfigurationConnectionString)
3232
{
3333
// TODO: use your context
34-
//serviceCollection.AddDbContext<QSSContext>(o => o.UseSqlServer(applicationConfigurationConnectionString));
34+
//serviceCollection.AddDbContext<Context>(o => o.UseSqlServer(applicationConfigurationConnectionString));
3535
}
3636

3737
/// <summary>
@@ -45,7 +45,7 @@ public static void UsePostgreSqlServer(this IServiceCollection serviceCollection
4545
// https://www.npgsql.org/efcore/index.html#additional-configuration-for-aspnet-core-applications
4646

4747
// TODO: use your context
48-
//serviceCollection.AddDbContext<QSSContext>(options => options.UseNpgsql(applicationConfigurationConnectionString));
48+
//serviceCollection.AddDbContext<Context>(options => options.UseNpgsql(applicationConfigurationConnectionString));
4949
}
5050

5151
}

0 commit comments

Comments
 (0)