Skip to content
Closed
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
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

namespace Turnierplan.App.Endpoints.Documents;

internal sealed class CreateDocumentEndpoint : EndpointBase<DocumentDto>
internal sealed partial class CreateDocumentEndpoint : EndpointBase<DocumentDto>
{
protected override HttpMethod Method => HttpMethod.Post;

Expand Down Expand Up @@ -53,7 +53,7 @@ private static async Task<IResult> Handle(

if (!documentTypeRegistry.TryGetDocumentDefaultConfiguration(request.Type, out var configuration))
{
logger.LogCritical("Could not get the default document configuration for document type {DocumentType}.", request.Type);
CouldNotGetDefaultDocumentConfiguration(logger, request.Type);

return Results.InternalServerError();
}
Expand Down Expand Up @@ -85,4 +85,7 @@ private Validator()
.NotEmpty();
}
}

[LoggerMessage(LogLevel.Critical, "Could not get the default document configuration for document type {DocumentType}.", EventId = 101)]
private static partial void CouldNotGetDefaultDocumentConfiguration(ILogger<CreateDocumentEndpoint> logger, DocumentType documentType);
}
13 changes: 10 additions & 3 deletions src/Turnierplan.App/Endpoints/Documents/GetDocumentPdfEndpoint.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Microsoft.AspNetCore.Mvc;
using Turnierplan.App.OpenApi;
using Turnierplan.App.Security;
using Turnierplan.Core.Document;
using Turnierplan.Core.PublicId;
using Turnierplan.Dal.Extensions;
using Turnierplan.Dal.Repositories;
Expand All @@ -10,7 +11,7 @@

namespace Turnierplan.App.Endpoints.Documents;

internal sealed class GetDocumentPdfEndpoint : EndpointBase
internal sealed partial class GetDocumentPdfEndpoint : EndpointBase
{
protected override HttpMethod Method => HttpMethod.Get;

Expand Down Expand Up @@ -59,7 +60,7 @@ private static async Task<IResult> Handle(

if (!documentTypeRegistry.TryParseDocumentConfiguration(document.Type, document.Configuration, out var configuration))
{
logger.LogError("Failed to parse the document configuration of document with type '{DocumentType}'.", document.Type);
FailedToParseDocumentConfiguration(logger, document.Type);

return Results.InternalServerError();
}
Expand All @@ -68,7 +69,7 @@ private static async Task<IResult> Handle(

if (renderer is null)
{
logger.LogCritical("No document renderer available for document type '{DocumentType}'.", document.Type);
NoRendererAvailableForDocumentType(logger, document.Type);

return Results.InternalServerError();
}
Expand All @@ -95,4 +96,10 @@ private static async Task<IResult> Handle(

return Results.File(stream.ToArray(), "application/pdf");
}

[LoggerMessage(LogLevel.Error, "Failed to parse the document configuration of document with type '{DocumentType}'.", EventId = 101)]
private static partial void FailedToParseDocumentConfiguration(ILogger<GetDocumentPdfEndpoint> logger, DocumentType documentType);

[LoggerMessage(LogLevel.Critical, "No document renderer available for document type '{DocumentType}'.", EventId = 102)]
private static partial void NoRendererAvailableForDocumentType(ILogger<GetDocumentPdfEndpoint> logger, DocumentType documentType);
}
6 changes: 3 additions & 3 deletions src/Turnierplan.App/Helpers/ApplicationUrlProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ namespace Turnierplan.App.Helpers;
internal sealed class ApplicationUrlProvider : IApplicationUrlProvider
{
private readonly IOptionsMonitor<TurnierplanOptions> _options;
private readonly ILogger<ApplicationUrlProvider> _logger;
private readonly ApplicationUrlProviderLogger _logger;

public ApplicationUrlProvider(IOptionsMonitor<TurnierplanOptions> options, ILogger<ApplicationUrlProvider> logger)
{
_options = options;
_logger = logger;
_logger = new ApplicationUrlProviderLogger(logger);
}

public string GetApplicationUrl()
Expand All @@ -21,7 +21,7 @@ public string GetApplicationUrl()

if (string.IsNullOrWhiteSpace(url))
{
_logger.LogWarning("The ApplicationUrl is not specified. Please check your application configuration.");
_logger.ApplicationUrlNotSpecified();

return string.Empty;
}
Expand Down
14 changes: 14 additions & 0 deletions src/Turnierplan.App/Helpers/ApplicationUrlProviderLogger.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace Turnierplan.App.Helpers;

internal sealed partial class ApplicationUrlProviderLogger
{
private readonly ILogger<ApplicationUrlProvider> _logger;

public ApplicationUrlProviderLogger(ILogger<ApplicationUrlProvider> logger)
{
_logger = logger;
}

[LoggerMessage(LogLevel.Warning, "The 'ApplicationUrl' is not specified. Please check your application configuration.", EventId = 101)]
public partial void ApplicationUrlNotSpecified();
}
8 changes: 4 additions & 4 deletions src/Turnierplan.App/Helpers/DeletionHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ internal sealed class DeletionHelper : IDeletionHelper
private readonly IPlanningRealmRepository _planningRealmRepository;
private readonly IImageRepository _imageRepository;
private readonly IImageStorage _imageStorage;
private readonly ILogger<DeletionHelper> _logger;
private readonly DeletionHelperLogger _logger;

public DeletionHelper(
IOrganizationRepository organizationRepository,
Expand All @@ -34,7 +34,7 @@ public DeletionHelper(
_planningRealmRepository = planningRealmRepository;
_imageRepository = imageRepository;
_imageStorage = imageStorage;
_logger = logger;
_logger = new DeletionHelperLogger(logger);
}

public async Task<bool> DeleteOrganizationAsync(Organization organization, CancellationToken cancellationToken)
Expand All @@ -57,14 +57,14 @@ public async Task<bool> DeleteOrganizationAsync(Organization organization, Cance
}
catch (Exception ex)
{
_logger.LogError(ex, "Image with id '{ImageId}' was successfully deleted from image storage but the deletion from the database failed.", image.Id);
_logger.ImageDeletedButDatabaseRemovalFailed(ex, image.Id);

return false;
}
}
else
{
_logger.LogError("Failed to delete image with id '{ImageId}' from image storage while deleting organization with id '{OrganizationId}'.", image.Id, organization.Id);
_logger.ImageDeletionFromStorageFailed(image.Id, organization.Id);

hasNonDeletedImages = true;
}
Expand Down
17 changes: 17 additions & 0 deletions src/Turnierplan.App/Helpers/DeletionHelperLogger.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
namespace Turnierplan.App.Helpers;

internal sealed partial class DeletionHelperLogger
{
private readonly ILogger<DeletionHelper> _logger;

public DeletionHelperLogger(ILogger<DeletionHelper> logger)
{
_logger = logger;
}

[LoggerMessage(LogLevel.Error, "Image with id '{ImageId}' was successfully deleted from image storage but the deletion from the database failed.", EventId = 101)]
public partial void ImageDeletedButDatabaseRemovalFailed(Exception exception, long imageId);

[LoggerMessage(LogLevel.Error, "Failed to delete image with id '{ImageId}' from image storage while deleting organization with id '{OrganizationId}'.", EventId = 102)]
public partial void ImageDeletionFromStorageFailed(long imageId, long organizationId);
}
3 changes: 2 additions & 1 deletion src/Turnierplan.App/Security/SigningKeyProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ public SigningKeyProvider(IOptions<IdentityOptions> options, ILogger<SigningKeyP

if (!Directory.Exists(storagePath))
{
logger.LogCritical("The directory for identity storage does not exist and could not be created.");
var customLogger = new SigningKeyProviderLogger(logger);
customLogger.IdentityDirectoryCreationFailed();
}

var signingKeyFile = Path.Join(storagePath, "jwt-signing-key.bin");
Expand Down
14 changes: 14 additions & 0 deletions src/Turnierplan.App/Security/SigningKeyProviderLogger.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace Turnierplan.App.Security;

internal sealed partial class SigningKeyProviderLogger
{
private readonly ILogger<SigningKeyProvider> _logger;

public SigningKeyProviderLogger(ILogger<SigningKeyProvider> logger)
{
_logger = logger;
}

[LoggerMessage(LogLevel.Critical, "The directory for identity storage does not exist and could not be created.", EventId = 101)]
public partial void IdentityDirectoryCreationFailed();
}
10 changes: 5 additions & 5 deletions src/Turnierplan.Dal/TurnierplanContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ public sealed class TurnierplanContext : DbContext, IUnitOfWork
{
public const string Schema = "turnierplan";

private readonly ILogger<TurnierplanContext> _logger;
private readonly TurnierplanContextLogger _logger;

private IDbContextTransaction? _activeTransaction;

public TurnierplanContext(DbContextOptions<TurnierplanContext> options, ILogger<TurnierplanContext> logger)
: base(options)
{
_logger = logger;
_logger = new TurnierplanContextLogger(logger);
}

public DbSet<ApiKey> ApiKeys { get; set; } = null!;
Expand Down Expand Up @@ -95,7 +95,7 @@ public async Task BeginTransactionAsync()
throw new InvalidOperationException("Transaction already started.");
}

_logger.LogInformation("Beginning database transaction");
_logger.BeginningTransaction();

_activeTransaction = await Database.BeginTransactionAsync();
}
Expand All @@ -107,7 +107,7 @@ public async Task CommitTransactionAsync()
throw new InvalidOperationException("Transaction not started.");
}

_logger.LogInformation("Committing database transaction");
_logger.CommittingTransaction();

await _activeTransaction.CommitAsync();
await _activeTransaction.DisposeAsync();
Expand All @@ -122,7 +122,7 @@ public async Task RollbackTransactionAsync()
throw new InvalidOperationException("Transaction not started.");
}

_logger.LogInformation("Rolling back database transaction");
_logger.RollingBackTransaction();

await _activeTransaction.RollbackAsync();
await _activeTransaction.DisposeAsync();
Expand Down
22 changes: 22 additions & 0 deletions src/Turnierplan.Dal/TurnierplanContextLogger.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Microsoft.Extensions.Logging;

namespace Turnierplan.Dal;

internal sealed partial class TurnierplanContextLogger
{
private readonly ILogger<TurnierplanContext> _logger;

public TurnierplanContextLogger(ILogger<TurnierplanContext> logger)
{
_logger = logger;
}

[LoggerMessage(LogLevel.Information, "Beginning database transaction", EventId = 101)]
public partial void BeginningTransaction();

[LoggerMessage(LogLevel.Information, "Committing database transaction", EventId = 102)]
public partial void CommittingTransaction();

[LoggerMessage(LogLevel.Information, "Rolling back database transaction", EventId = 103)]
public partial void RollingBackTransaction();
}
18 changes: 9 additions & 9 deletions src/Turnierplan.ImageStorage/Azure/AzureImageStorage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,22 @@ namespace Turnierplan.ImageStorage.Azure;

internal sealed class AzureImageStorage : IImageStorage
{
private readonly ILogger<AzureImageStorage> _logger;
private readonly AzureImageStorageLogger _logger;
private readonly BlobContainerClient _client;
private readonly string _storageAccountUrl;
private readonly string _containerName;

public AzureImageStorage(IOptions<AzureImageStorageOptions> options, ILogger<AzureImageStorage> logger)
{
_logger = logger;
_logger = new AzureImageStorageLogger(logger);

ArgumentException.ThrowIfNullOrWhiteSpace(options.Value.StorageAccountName);
ArgumentException.ThrowIfNullOrWhiteSpace(options.Value.ContainerName);

_storageAccountUrl = $"https://{options.Value.StorageAccountName}.blob.core.windows.net";
var storageAccountUri = new Uri(_storageAccountUrl);

_logger.LogInformation("Initializing Azure Blob Storage client for storage account '{StorageAccountUrl}'.", _storageAccountUrl);
_logger.InitializingAzureBlobStorageClient(_storageAccountUrl);

BlobServiceClient blobServiceClient;

Expand All @@ -38,7 +38,7 @@ public AzureImageStorage(IOptions<AzureImageStorageOptions> options, ILogger<Azu

ArgumentException.ThrowIfNullOrWhiteSpace(options.Value.AccountKey);

_logger.LogInformation("Using account key authentication for Azure Blob Storage");
_logger.UsingAccountKeyAuthentication();

var credential = new StorageSharedKeyCredential(options.Value.StorageAccountName, options.Value.AccountKey);
blobServiceClient = new BlobServiceClient(storageAccountUri, credential);
Expand All @@ -53,13 +53,13 @@ public AzureImageStorage(IOptions<AzureImageStorageOptions> options, ILogger<Azu
ArgumentException.ThrowIfNullOrWhiteSpace(options.Value.ClientId);
ArgumentException.ThrowIfNullOrWhiteSpace(options.Value.ClientSecret);

_logger.LogInformation("Using ClientSecretCredential for Azure Blob Storage");
_logger.UsingClientSecretCredential();

credential = new ClientSecretCredential(options.Value.TenantId, options.Value.ClientId, options.Value.ClientSecret);
}
else
{
_logger.LogInformation("Using DefaultAzureCredential for Azure Blob Storage");
_logger.UsingDefaultAzureCredential();

credential = new DefaultAzureCredential();
}
Expand Down Expand Up @@ -91,7 +91,7 @@ public async Task<bool> SaveImageAsync(Image image, MemoryStream imageData)
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to upload image '{BlobName}' to Azure Blob Storage because of an exception.", blobName);
_logger.FailedToUploadImage(ex, blobName);
}

return false;
Expand All @@ -110,7 +110,7 @@ public async Task<Stream> GetImageAsync(Image image)
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to read image '{BlobName}' from Azure Blob Storage because of an exception.", blobName);
_logger.FailedToReadImage(ex, blobName);

throw new InvalidOperationException("Failed to read image from Azure Blob Storage.", ex);
}
Expand All @@ -129,7 +129,7 @@ public async Task<bool> DeleteImageAsync(Image image)
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to delete image '{BlobName}' from Azure Blob Storage because of an exception.", blobName);
_logger.FailedToDeleteImage(ex, blobName);
}

return false;
Expand Down
34 changes: 34 additions & 0 deletions src/Turnierplan.ImageStorage/Azure/AzureImageStorageLogger.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using Microsoft.Extensions.Logging;

namespace Turnierplan.ImageStorage.Azure;

internal sealed partial class AzureImageStorageLogger
{
private readonly ILogger<AzureImageStorage> _logger;

public AzureImageStorageLogger(ILogger<AzureImageStorage> logger)

Check warning on line 9 in src/Turnierplan.ImageStorage/Azure/AzureImageStorageLogger.cs

View workflow job for this annotation

GitHub Actions / Validate

Update this logger to use its enclosing type. (https://rules.sonarsource.com/csharp/RSPEC-6672)
{
_logger = logger;
}

[LoggerMessage(LogLevel.Information, "Initializing Azure Blob Storage client for storage account '{StorageAccountUrl}'.", EventId = 101)]
public partial void InitializingAzureBlobStorageClient(string storageAccountUrl);

[LoggerMessage(LogLevel.Information, "Using account key authentication for Azure Blob Storage", EventId = 102)]
public partial void UsingAccountKeyAuthentication();

[LoggerMessage(LogLevel.Information, "Using ClientSecretCredential for Azure Blob Storage", EventId = 103)]
public partial void UsingClientSecretCredential();

[LoggerMessage(LogLevel.Information, "Using DefaultAzureCredential for Azure Blob Storage", EventId = 104)]
public partial void UsingDefaultAzureCredential();

[LoggerMessage(LogLevel.Error, "Failed to upload image '{BlobName}' to Azure Blob Storage because of an exception.", EventId = 105)]
public partial void FailedToUploadImage(Exception exception, string blobName);

[LoggerMessage(LogLevel.Error, "Failed to read image '{BlobName}' from Azure Blob Storage because of an exception.", EventId = 106)]
public partial void FailedToReadImage(Exception exception, string blobName);

[LoggerMessage(LogLevel.Error, "Failed to delete image '{BlobName}' from Azure Blob Storage because of an exception.", EventId = 107)]
public partial void FailedToDeleteImage(Exception exception, string blobName);
}
Loading
Loading