Skip to content

Commit

Permalink
Merge pull request #10 from lreb/aws-s3
Browse files Browse the repository at this point in the history
Aws s3 feature to upload and download files
  • Loading branch information
lreb authored Oct 23, 2020
2 parents 21397a1 + 01dd412 commit b409ed7
Show file tree
Hide file tree
Showing 48 changed files with 1,396 additions and 38 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -434,4 +434,5 @@ $RECYCLE.BIN/


# Facware Base API
FacwareBase.API/AWSLambda/
FacwareBase.API/AWSLambda/
FacwareBase.API/PublishAWSLambda/
79 changes: 79 additions & 0 deletions FacwareBase.API/Controllers/Document/BucketController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
using FacwareBase.API.Services.Amazon.S3.Core.Bucket;
using FacwareBase.API.Services.Amazon.S3.Core.Interfaces;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace FacwareBase.API.Controllers.Document
{
[Route("api/bucket")]
[ApiController]
public class BucketController : ControllerBase
{
private readonly IBucketRepository _bucketRepository;

public BucketController(IBucketRepository bucketRepository)
{
_bucketRepository = bucketRepository;
}

/// <summary>
/// create a new s3 bucket
/// </summary>
/// <param name="bucketName"></param>
/// <returns></returns>
[HttpPost]
[Route("create/{bucketName}")]
public async Task<ActionResult<CreateBucketResponse>> CreateS3Bucket([FromRoute] string bucketName)
{
var bucketExists = await _bucketRepository.DoesS3BucketExist(bucketName);

if (bucketExists)
{
return BadRequest("S3 bucket already exists");
}

var result = await _bucketRepository.CreateBucket(bucketName);

if (result == null)
{
return BadRequest();
}

return Ok(result);
}

/// <summary>
/// list all s3 buckets
/// </summary>
/// <returns></returns>
[HttpGet]
[Route("list")]
public async Task<ActionResult<IEnumerable<ListS3BucketsResponse>>> ListS3Buckets()
{
var result = await _bucketRepository.ListBuckets();

if (result == null)
{
return NotFound();
}

return Ok(result);
}


/// <summary>
/// delete a s3 bucket
/// </summary>
/// <param name="bucketName"></param>
/// <returns></returns>
[HttpDelete]
[Route("delete/{bucketName}")]
public async Task<IActionResult> DeleteS3Bucket(string bucketName)
{
await _bucketRepository.DeleteBucket(bucketName);

return Ok();
}
}
}
140 changes: 140 additions & 0 deletions FacwareBase.API/Controllers/Document/FileController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
using FacwareBase.API.Core.File.Management;
using FacwareBase.API.Helpers.FileManagement;
using FacwareBase.API.Services.Amazon.S3.Core.File;
using FacwareBase.API.Services.Amazon.S3.Core.Interfaces;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace FacwareBase.API.Controllers.Document
{
[Route("api/file")]
[ApiController]
public class FileController : ControllerBase
{
private readonly IFilesRepository _filesRepository;
private readonly IFileManagement _fileManagement;
private readonly FileStorageOptions _fileStorageOptions;

public FileController(IFilesRepository filesRepository,
IFileManagement fileManagement,
IOptions<FileStorageOptions> fileStorageOptions)
{
_filesRepository = filesRepository;
_fileManagement = fileManagement;
_fileStorageOptions = fileStorageOptions.Value;
}

/// <summary>
/// Add new file
/// </summary>
/// <param name="bucketName">bucket name</param>
/// <param name="key">s3 key</param>
/// <param name="formFiles">file</param>
/// <returns></returns>
[HttpPost]
[Route("{bucketName}/add/{key}")]
public async Task<ActionResult<AddFileResponse>> AddFiles(string bucketName, string key, IList<IFormFile> formFiles)
{
if (formFiles == null)
{
return BadRequest("The request doesn't contain any files to be uploaded.");
}

var response = await _filesRepository.UploadFiles(bucketName, formFiles, key);

if (response == null)
{
return BadRequest();
}

return Ok(response);
}

/// <summary>
/// List keys in a s3 bucket
/// </summary>
/// <param name="bucketName"></param>
/// <returns></returns>
[HttpGet]
[Route("{bucketName}/list")]
public async Task<ActionResult<IEnumerable<ListFilesResponse>>> ListFiles(string bucketName)
{
var response = await _filesRepository.ListFiles(bucketName);

return Ok(response);
}

/// <summary>
/// Download file from s3 bucket
/// </summary>
/// <param name="bucketName"></param>
/// <param name="fileName"></param>
/// <returns></returns>
[HttpGet]
[Route("{bucketName}/download/{fileName}")]
public async Task<IActionResult> DownloadFile(string bucketName, string fileName)
{
var temporalPath = _fileStorageOptions.TemporalStorage;

await _filesRepository.DownloadFile(bucketName, fileName, temporalPath);

var memoryFile = _fileManagement.ReadFileAsync(temporalPath, fileName).Result;

_fileManagement.RemoveFile(temporalPath, fileName);

var mimeType = _fileManagement.GetMimeType(fileName);

return File(memoryFile, mimeType, fileName);

//return Ok();
}

/// <summary>
/// Delete file from s3 bucket
/// </summary>
/// <param name="bucketName">Bucket name</param>
/// <param name="fileName">file name</param>
/// <returns></returns>
[HttpDelete]
[Route("{bucketName}/delete/{fileName}")]
public async Task<ActionResult<DeleteFileResponse>> DeleteFile(string bucketName, string fileName)
{
var response = await _filesRepository.DeleteFile(bucketName, fileName);

return Ok(response);
}

/// <summary>
/// Add json object to s3 bucket
/// </summary>
/// <param name="bucketName">bucket</param>
/// <param name="request">json object</param>
/// <returns></returns>
[HttpPost]
[Route("{bucketName}/addjsonobject")]
public async Task<IActionResult> AddJsonObject(string bucketName, AddJsonObjectRequest request)
{
await _filesRepository.AddJsonObject(bucketName, request);

return Ok();
}

/// <summary>
/// Get json object
/// </summary>
/// <param name="bucketName"></param>
/// <param name="fileName"></param>
/// <returns></returns>
[HttpGet]
[Route("{bucketName}/getjsonobject")]
public async Task<ActionResult<GetJsonObjectResponse>> GetJsonObject(string bucketName, string fileName)
{
var response = await _filesRepository.GetJsonObject(bucketName, fileName);

return Ok(response);
}
}
}
90 changes: 90 additions & 0 deletions FacwareBase.API/Core/File/Management/FileManagement.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
using Microsoft.AspNetCore.StaticFiles;
using System.IO;
using System.Threading.Tasks;

namespace FacwareBase.API.Core.File.Management
{
public class FileManagement : IFileManagement
{
/// <summary>
/// Read file from a temporal path
/// </summary>
/// <param name="path">temporal path</param>
/// <param name="fileName">file name</param>
/// <returns><see cref="MemoryStream"/>Memory stream</returns>
public async Task<MemoryStream> ReadFileAsync(string path, string fileName)
{
string fullPath = Path.Combine(path, fileName);

if (!System.IO.File.Exists(fullPath))
{
throw new FileNotFoundException();
}

var memory = new MemoryStream();
await using (var stream = new FileStream(fullPath, FileMode.Open))
{
await stream.CopyToAsync(memory);
}
memory.Position = 0;

return memory;
}

/// <summary>
/// Get mime type
/// </summary>
/// <param name="fileName">file name</param>
/// <returns>string mime type</returns>
public string GetMimeType(string fileName)
{
var provider = new FileExtensionContentTypeProvider();
if (!provider.TryGetContentType(fileName, out var contentType))
{
contentType = "application/octet-stream";
}
return contentType;
}

/// <summary>
/// Remove file from a location
/// </summary>
/// <param name="path">file path</param>
/// <param name="fileName">file name</param>
public void RemoveFile(string path, string fileName)
{
var fullPath = Path.Combine(path, fileName);

if (System.IO.File.Exists(fullPath))
System.IO.File.Delete(fullPath);
}

/// <summary>
/// Move file to different location
/// </summary>
/// <param name="originPath">original path</param>
/// <param name="originFileName">origin file name</param>
/// <param name="targetPath">target path</param>
/// <param name="targetFileName">target file name</param>
/// <returns>full target path</returns>
public string MoveFile(string originPath, string originFileName, string targetPath, string targetFileName)
{
var fullOriginPath = Path.Combine(originPath, originFileName);
var fullTargetPath = Path.Combine(targetPath, targetFileName);

if (!Directory.Exists(targetPath))
{
Directory.CreateDirectory(targetPath);
}

if (System.IO.File.Exists(fullOriginPath))
{
if (System.IO.File.Exists(fullTargetPath))
System.IO.File.Delete(fullTargetPath);

System.IO.File.Move(fullOriginPath, fullTargetPath);
}
return fullTargetPath;
}
}
}
40 changes: 40 additions & 0 deletions FacwareBase.API/Core/File/Management/IFileManagement.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using System.IO;
using System.Threading.Tasks;

namespace FacwareBase.API.Core.File.Management
{
public interface IFileManagement
{
/// <summary>
/// Read file from a temporal path
/// </summary>
/// <param name="temporalPath">temporal path</param>
/// <param name="fileName">file name</param>
/// <returns><see cref="MemoryStream"/>Memory stream</returns>
Task<MemoryStream> ReadFileAsync(string temporalPath, string fileName);

/// <summary>
/// Get mime type
/// </summary>
/// <param name="fileName">file name</param>
/// <returns>string mime type</returns>
string GetMimeType(string fileName);

/// <summary>
/// Remove file from a location
/// </summary>
/// <param name="path">file path</param>
/// <param name="fileName">file name</param>
void RemoveFile(string path, string fileName);

/// <summary>
/// Move file to different location
/// </summary>
/// <param name="originPath">original path</param>
/// <param name="originFileName">origin file name</param>
/// <param name="targetPath">target path</param>
/// <param name="targetFileName">target file name</param>
/// <returns>full target path</returns>
string MoveFile(string originPath, string originFileName, string targetPath, string targetFileName);
}
}
4 changes: 2 additions & 2 deletions FacwareBase.API/Extensions/Cors/CorsExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public static class CorsExtension
/// <summary>
/// Policy cors name
/// </summary>
public static readonly string QSSAllowSpecificOrigins = "QSSAllowSpecificOrigins";
public static readonly string AllowSpecificOrigins = "AllowSpecificOrigins";

/// <summary>
/// CORS configurations
Expand All @@ -22,7 +22,7 @@ public static void ConfigureCors(this IServiceCollection services, IConfiguratio
{
services.AddCors(options =>
{
options.AddPolicy(QSSAllowSpecificOrigins,
options.AddPolicy(AllowSpecificOrigins,
builder =>
{
builder.WithOrigins(configuration.GetSection("Cors:AllowedOrigin").Get<string[]>())
Expand Down
4 changes: 2 additions & 2 deletions FacwareBase.API/Extensions/Database/DatabaseExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public static void UseInMemoryDatabase(this IServiceCollection serviceCollection
public static void UseSqlServer(this IServiceCollection serviceCollection, string applicationConfigurationConnectionString)
{
// TODO: use your context
//serviceCollection.AddDbContext<QSSContext>(o => o.UseSqlServer(applicationConfigurationConnectionString));
//serviceCollection.AddDbContext<Context>(o => o.UseSqlServer(applicationConfigurationConnectionString));
}

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

// TODO: use your context
//serviceCollection.AddDbContext<QSSContext>(options => options.UseNpgsql(applicationConfigurationConnectionString));
//serviceCollection.AddDbContext<Context>(options => options.UseNpgsql(applicationConfigurationConnectionString));
}

}
Expand Down
Loading

0 comments on commit b409ed7

Please sign in to comment.