Skip to content

Commit

Permalink
IHS-57 List image tags handler (#79)
Browse files Browse the repository at this point in the history
* log assigning tags

* add listing image tags

* delete caching setup dotnet on ci
  • Loading branch information
adedw authored Sep 22, 2024
1 parent a0871d6 commit e68bbfb
Show file tree
Hide file tree
Showing 9 changed files with 84 additions and 22 deletions.
1 change: 0 additions & 1 deletion .github/workflows/codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ jobs:
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.0.x
cache: true

- name: Restore dependencies
run: dotnet restore
Expand Down
7 changes: 2 additions & 5 deletions launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@
"Docker Compose": {
"commandName": "DockerCompose",
"commandVersion": "1.0",
"composeLaunchAction": "LaunchBrowser",
"composeLaunchServiceName": "storage-webapi",
"composeLaunchUrl": "{Scheme}://localhost:{ServicePort}",
"serviceActions": {
"kafka-init-categories": "StartWithoutDebugging",
"kafka": "StartWithoutDebugging",
Expand All @@ -14,9 +11,9 @@
"minio": "StartWithoutDebugging",
"postgres": "StartWithoutDebugging",
"resizer": "StartWithoutDebugging",
"image-tagger": "StartDebugging",
"image-tagger": "StartWithoutDebugging",
"recognizer": "StartWithoutDebugging",
"storage-webapi": "StartDebugging"
"storage-webapi": "DoNotStart"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ public static class ImageHostingEvents
public const int MessagePublished = 1002;
public const int RemoveFile = 1003;
public const int MetadataDeleted = 1004;
public const int ImageTagAssigned = 2000;
}
6 changes: 6 additions & 0 deletions src/ImageHosting.Storage.Infrastructure/Logging/Log.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,10 @@ public static partial class Log
Level = LogLevel.Information,
Message = "Message published with imageId {ImageId} and bucketId {BucketId}.")]
public static partial void LogMessagePublished(this ILogger logger, ImageId imageId, UserId bucketId);

[LoggerMessage(
EventId = ImageHostingEvents.ImageTagAssigned,
Level = LogLevel.Information,
Message = "Tags {Tags} are assigned to image {ImageId}.")]
public static partial void LogImageTagsAssigned(this ILogger logger, IEnumerable<string> tags, ImageId imageId);
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
using ImageHosting.Storage.Application.Services;
using ImageHosting.Storage.Domain.ValueTypes;
using ImageHosting.Storage.Infrastructure.DbContexts;
using ImageHosting.Storage.Infrastructure.Logging;
using ImageHosting.Storage.Infrastructure.Options;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

namespace ImageHosting.Storage.Infrastructure.Services;

public class AssignTagsService(IImageHostingDbContext dbContext, IOptions<AssignTagsOptions> options)
public class AssignTagsService(IImageHostingDbContext dbContext, IOptions<AssignTagsOptions> options, ILogger<AssignTagsService> logger)
: IAssignTagsService
{
private readonly double _threshold = options.Value.Threshold;
private readonly LogTags _logTags = new(logger);

public async Task AssignTagsAsync(Dictionary<ImageId, Dictionary<string, double>> categories,
CancellationToken cancellationToken = default)
Expand All @@ -23,11 +26,34 @@ public async Task AssignTagsAsync(Dictionary<ImageId, Dictionary<string, double>

foreach (var image in images)
{
image.AddTags(categories[image.Id]
var tags = categories[image.Id]
.Where(category => category.Value > _threshold)
.Select(category => category.Key));
.Select(category => category.Key)
.ToArray();

image.AddTags(tags);
_logTags.Add(image.Id, tags);
}

await dbContext.SaveChangesAsync(cancellationToken);
_logTags.Log();
}

private sealed class LogTags(ILogger<AssignTagsService> logger)
{
private readonly Dictionary<ImageId, IEnumerable<string>> _imageTags = [];

public void Add(ImageId imageId, IEnumerable<string> tags)
{
_imageTags.Add(imageId, tags);
}

public void Log()
{
foreach (var (imageId, tags) in _imageTags)
{
logger.LogImageTagsAssigned(tags, imageId);
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
using System.Security.Claims;
using ImageHosting.Storage.Domain.ValueTypes;
using ImageHosting.Storage.WebApi.Features.Images.Handlers;
using ImageHosting.Storage.WebApi.Features.Images.Models;
using ImageHosting.Storage.WebApi.Filters;
using Microsoft.AspNetCore.Mvc;
using System.Security.Claims;

namespace ImageHosting.Storage.WebApi.Features.Images.Endpoints;

Expand Down Expand Up @@ -98,10 +98,19 @@ public static RouteGroupBuilder MapImagesEndpoints(this IEndpointRouteBuilder ro
await deleteTagsHandler.DeleteAsync(id, tag, cancellationToken);
return TypedResults.Ok();
})
.WithName("DeleteTags")
.WithName("BatchDeleteTags")
.WithTags("Tags")
.MapToApiVersion(1);

tags.MapGet("", async ([FromRoute] ImageId id, [FromServices] IGetAllImageTagsHandler getAllImageTagsHandler, CancellationToken ct) =>
{
var tags = await getAllImageTagsHandler.GetTagsAsync(id, ct);
return TypedResults.Ok(tags);
})
.WithName("GetImageTags")
.WithTags("Tags")
.MapToApiVersion(1);

return images;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@ public static IServiceCollection AddImageServices(this IServiceCollection servic
.BindConfiguration(ImagesOptions.SectionName)
.ValidateDataAnnotations();


return services
.AddTransient<IFileUploadCommandFactory, FileUploadCommandFactory>()
.AddTransient<IMetadataUploadCommandFactory, MetadataUploadCommandFactory>()
.AddTransient<IPublishNewMessageCommandFactory, PublishNewMessageCommandFactory>()
.AddTransient<IUploadFileHandler, UploadFileHandler>()
.AddTransient<IGetImageAssetHandler, GetImageAssetHandler>()
.AddTransient<IGetImageHandler, GetImageHandler>()
.AddTransient<IUpdateNameHandler, UpdateNameHandler>()
.AddTransient<IAddTagsHandler, AddTagsHandler>()
.AddTransient<IDeleteTagsHandler, DeleteTagsHandler>();
.AddScoped<IFileUploadCommandFactory, FileUploadCommandFactory>()
.AddScoped<IMetadataUploadCommandFactory, MetadataUploadCommandFactory>()
.AddScoped<IPublishNewMessageCommandFactory, PublishNewMessageCommandFactory>()
.AddScoped<IUploadFileHandler, UploadFileHandler>()
.AddScoped<IGetImageAssetHandler, GetImageAssetHandler>()
.AddScoped<IGetImageHandler, GetImageHandler>()
.AddScoped<IUpdateNameHandler, UpdateNameHandler>()
.AddScoped<IAddTagsHandler, AddTagsHandler>()
.AddScoped<IDeleteTagsHandler, DeleteTagsHandler>()
.AddScoped<IGetAllImageTagsHandler, GetAllImageTagsHandler>();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using ImageHosting.Storage.Domain.ValueTypes;
using ImageHosting.Storage.Infrastructure.DbContexts;
using Microsoft.EntityFrameworkCore;

namespace ImageHosting.Storage.WebApi.Features.Images.Handlers;

public class GetAllImageTagsHandler(IImageHostingDbContext dbContext) : IGetAllImageTagsHandler
{
public Task<List<string>> GetTagsAsync(ImageId imageId, CancellationToken ct = default)
{
return dbContext.ImageTags
.Where(it => it.ImageId == imageId)
.Select(it => it.TagName)
.ToListAsync(ct);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using ImageHosting.Storage.Domain.ValueTypes;

namespace ImageHosting.Storage.WebApi.Features.Images.Handlers;

public interface IGetAllImageTagsHandler
{
Task<List<string>> GetTagsAsync(ImageId imageId, CancellationToken ct = default);
}

0 comments on commit e68bbfb

Please sign in to comment.