Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

create ci workflows #4

Merged
merged 19 commits into from
May 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .github/workflows/docker-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: ci

on:
push:
branches-ignore:
- "main"
# paths:
# - "MediaFileMetadataCheckerAPI/**"

env:
TEST_TAG: user/app:test
LATEST_TAG: user/app:latest
METADATA_API_CONFIG_CONNECTION_STRING: ${{ secrets.APP_CONFIG_CONNECTION_STRING }}

jobs:
docker:
runs-on: ubuntu-latest
steps:
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and export to local images
uses: docker/build-push-action@v5
with:
context: "{{defaultContext}}:MediaFileMetadataCheckerAPI"
load: true
tags: ${{ env.TEST_TAG }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Test running image
run: |
docker run --rm ${{ env.TEST_TAG }} -e METADATA_API_CONFIG_CONNECTION_STRING="${{ env.METADATA_API_CONFIG_CONNECTION_STRING }}" -e METADATA_API_CONFIG_CACHE_EXPIRATION="1" --stop-timeout 30
25 changes: 9 additions & 16 deletions MediaFileMetadataCheckerAPI/Controllers/FileUploadController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.Net.Http.Headers;
using System.IO;
using System.Threading.Tasks;
Expand All @@ -21,11 +22,13 @@ namespace MediaFileMetadataCheckerAPI.Controllers
[Route("[controller]")]
public class FileUploadController : ControllerBase
{
private readonly Settings _settings;
private readonly ILogger<FileUploadController> _logger;

public FileUploadController(ILogger<FileUploadController> logger)
public FileUploadController(ILogger<FileUploadController> logger, IOptionsSnapshot<Settings> settings)
{
_logger = logger;
_settings = settings.Value;
}

/// <summary>
Expand All @@ -39,15 +42,14 @@ public FileUploadController(ILogger<FileUploadController> logger)
[HttpPost]
[Route(nameof(UploadLargeFileForMetadata))]
[ProducesResponseType(typeof(FileStreamResult), 200, "application/json")]
// [Produces("application/json", "application/json")]
[DisableFormValueModelBinding]
public async Task<IActionResult> UploadLargeFileForMetadata()
{
var request = HttpContext.Request;

// validation of Content-Type
// 1. first, it must be a form-data request
// 2. a boundary should be found in the Content-Type
// Validation of Content-Type
// 1. First, it must be a form-data request
// 2. A boundary should be found in the Content-Type
if (!request.HasFormContentType ||
!MediaTypeHeaderValue.TryParse(request.ContentType, out var mediaTypeHeader) ||
string.IsNullOrEmpty(mediaTypeHeader.Boundary.Value))
Expand All @@ -59,8 +61,6 @@ public async Task<IActionResult> UploadLargeFileForMetadata()
var reader = new MultipartReader(boundary, request.Body);
var section = await reader.ReadNextSectionAsync();

// This sample try to get the first file from request and save it
// Make changes according to your needs in actual use
while (section != null)
{
var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition,
Expand All @@ -70,11 +70,6 @@ public async Task<IActionResult> UploadLargeFileForMetadata()
if (hasContentDispositionHeader && contentDisposition.DispositionType.Equals("form-data") &&
!string.IsNullOrEmpty(contentDisposition.FileName.Value))
{
// Don't trust any file name, file extension, and file data from the request unless you trust them completely
// Otherwise, it is very likely to cause problems such as virus uploading, disk filling, etc
// In short, it is necessary to restrict and verify the upload
// Here, we just use the temporary folder and a random file name

// Get the temporary folder, and combine a random file name with it
var fileName = Path.GetRandomFileName();
var saveToPath = Path.Combine(Path.GetTempPath(), fileName);
Expand All @@ -88,7 +83,8 @@ public async Task<IActionResult> UploadLargeFileForMetadata()

if (mediaInfo is not null)
{
HashSet<string> returnProperties = Settings.ReturnProperties.Split(";").ToHashSet();
// Get return properties from App Config and only return configured properties
HashSet<string> returnProperties = _settings.ReturnProperties.Split(";").ToHashSet();

var File = new FileUploadItem();
File.Duration = returnProperties.Contains("Duration") ? mediaInfo.Duration : null;
Expand All @@ -105,12 +101,9 @@ public async Task<IActionResult> UploadLargeFileForMetadata()
}

}
#pragma warning restore CS8602 // Dereference of a possibly null reference.

section = await reader.ReadNextSectionAsync();
}

// If the code runs to this location, it means that no files have been saved
return BadRequest("No files data in the request.");
}
}
Expand Down
28 changes: 0 additions & 28 deletions MediaFileMetadataCheckerAPI/Filters/FileFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,10 @@ public void Apply(OpenApiOperation operation, OperationFilterContext context)

if (formParameters.Any())
{
// already taken care by swashbuckle. no need to add explicitly.
return;
}
if (operation.RequestBody != null)
{
// NOT required for form type
return;
}
if (context.ApiDescription.HttpMethod == HttpMethod.Post.Method)
Expand Down Expand Up @@ -64,29 +62,3 @@ internal static bool IsFromForm(this ApiParameterDescription apiParameter)
return (elementType != null && typeof(IFormFile).IsAssignableFrom(elementType));
}
}

public class FileDownloadFilter : IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
if (context.ApiDescription.SupportedResponseTypes.Any(x =>
x.Type == typeof(FileStreamResult) ||
x.Type == typeof(FileResult)))

if (operation.RequestBody == null)
{
return;
}

// See https://github.com/Azure/autorest.csharp/issues/197
foreach (var content in operation.RequestBody.Content)
foreach (var contentProperty in content.Value.Schema.Properties)
{
var schema = contentProperty.Value;
if (schema.Format == "binary")
{
schema.Type = "file";
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Options" Version="8.0.2" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="8.0.2" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
</ItemGroup>
Expand Down
7 changes: 5 additions & 2 deletions MediaFileMetadataCheckerAPI/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using MediaFileMetadataCheckerAPI.Filters;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Azure.AppConfiguration.AspNetCore;
using Microsoft.Extensions.Configuration;

var builder = WebApplication.CreateBuilder(args);

Expand All @@ -13,7 +14,7 @@
opt.UseInMemoryDatabase("FileUploadList"));
// Get connection string from Environment variables
string? connectionString = Environment.GetEnvironmentVariable("METADATA_API_CONFIG_CONNECTION_STRING");
double? configCacheExpiration = Convert.ToDouble(Environment.GetEnvironmentVariable("METADATA_API_CONFIG_CACHE_EXPIRATION"));
double configCacheExpiration = Convert.ToDouble(Environment.GetEnvironmentVariable("METADATA_API_CONFIG_CACHE_EXPIRATION"));

// Load configuration from Azure App Configuration
builder.Configuration.AddAzureAppConfiguration(options =>
Expand All @@ -24,8 +25,10 @@
// Configure to reload configuration if the registered sentinel key is modified
.ConfigureRefresh(refreshOptions =>
refreshOptions.Register("MetadataApp:Settings:Sentinel", refreshAll: true)
.SetCacheExpiration(TimeSpan.FromHours(configCacheExpiration ?? 1)));
.SetCacheExpiration(TimeSpan.FromHours(configCacheExpiration)));
});
// Add Azure App Configuration middleware to the container of services.
builder.Services.AddAzureAppConfiguration();
// Bind configuration "MetadataApp:Settings" section to the Settings object
builder.Services.Configure<MetadataAppConfig.Settings>(builder.Configuration.GetSection("MetadataApp:Settings"));
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
Expand Down
2 changes: 1 addition & 1 deletion MediaFileMetadataCheckerAPI/Settings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ namespace MetadataAppConfig
{
public class Settings
{
public static string? ReturnProperties { get; set; }
public string? ReturnProperties { get; set; }
}
}
10 changes: 9 additions & 1 deletion scripts/docker-run.zsh
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
#!/usr/bin/env zsh
# doc: https://github.com/dotnet/dotnet-docker/blob/main/samples/run-aspnetcore-https-development.md
docker run --rm -it -p 8000:80 -p 8001:443 -e ASPNETCORE_URLS="https://+;http://+" -e ASPNETCORE_HTTPS_PORTS=8001 -e ASPNETCORE_Kestrel__Certificates__Default__Password=$pass -e ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx -e ASPNETCORE_ENVIRONMENT=Development -v ${HOME}/.aspnet/https:/https/ mediametadata
docker run --rm -it -p 8000:80 -p 8001:443 /
-e ASPNETCORE_URLS="https://+;http://+" /
-e ASPNETCORE_HTTPS_PORTS=8001 /
-e ASPNETCORE_Kestrel__Certificates__Default__Password=$pass /
-e ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx /
-e ASPNETCORE_ENVIRONMENT=Development /
-e METADATA_API_CONFIG_CACHE_EXPIRATION=1 /
-e METADATA_API_CONFIG_CONNECTION_STRING=$connectionString /
-v ${HOME}/.aspnet/https:/https/ mediametadata
Loading