diff --git a/FictionArchive.Service.UserNovelDataService/Dockerfile b/FictionArchive.Service.UserNovelDataService/Dockerfile new file mode 100644 index 0000000..8d7ad0d --- /dev/null +++ b/FictionArchive.Service.UserNovelDataService/Dockerfile @@ -0,0 +1,23 @@ +FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base +USER $APP_UID +WORKDIR /app +EXPOSE 8080 +EXPOSE 8081 + +FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build +ARG BUILD_CONFIGURATION=Release +WORKDIR /src +COPY ["FictionArchive.Service.UserNovelDataService/FictionArchive.Service.UserNovelDataService.csproj", "FictionArchive.Service.UserNovelDataService/"] +RUN dotnet restore "FictionArchive.Service.UserNovelDataService/FictionArchive.Service.UserNovelDataService.csproj" +COPY . . +WORKDIR "/src/FictionArchive.Service.UserNovelDataService" +RUN dotnet build "./FictionArchive.Service.UserNovelDataService.csproj" -c $BUILD_CONFIGURATION -o /app/build + +FROM build AS publish +ARG BUILD_CONFIGURATION=Release +RUN dotnet publish "./FictionArchive.Service.UserNovelDataService.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "FictionArchive.Service.UserNovelDataService.dll"] diff --git a/FictionArchive.Service.UserNovelDataService/FictionArchive.Service.UserNovelDataService.csproj b/FictionArchive.Service.UserNovelDataService/FictionArchive.Service.UserNovelDataService.csproj new file mode 100644 index 0000000..6bee3ff --- /dev/null +++ b/FictionArchive.Service.UserNovelDataService/FictionArchive.Service.UserNovelDataService.csproj @@ -0,0 +1,20 @@ + + + + net8.0 + enable + enable + Linux + + + + + .dockerignore + + + + + + + + diff --git a/FictionArchive.Service.UserNovelDataService/GraphQL/Mutation.cs b/FictionArchive.Service.UserNovelDataService/GraphQL/Mutation.cs new file mode 100644 index 0000000..5810b81 --- /dev/null +++ b/FictionArchive.Service.UserNovelDataService/GraphQL/Mutation.cs @@ -0,0 +1,6 @@ +namespace FictionArchive.Service.UserNovelDataService.GraphQL; + +public class Mutation +{ + +} \ No newline at end of file diff --git a/FictionArchive.Service.UserNovelDataService/GraphQL/Query.cs b/FictionArchive.Service.UserNovelDataService/GraphQL/Query.cs new file mode 100644 index 0000000..7ad2845 --- /dev/null +++ b/FictionArchive.Service.UserNovelDataService/GraphQL/Query.cs @@ -0,0 +1,6 @@ +namespace FictionArchive.Service.UserNovelDataService.GraphQL; + +public class Query +{ + +} \ No newline at end of file diff --git a/FictionArchive.Service.UserNovelDataService/Program.cs b/FictionArchive.Service.UserNovelDataService/Program.cs new file mode 100644 index 0000000..166735f --- /dev/null +++ b/FictionArchive.Service.UserNovelDataService/Program.cs @@ -0,0 +1,75 @@ +using FictionArchive.Common.Extensions; +using FictionArchive.Service.Shared; +using FictionArchive.Service.Shared.Extensions; +using FictionArchive.Service.Shared.Services.EventBus.Implementations; +using FictionArchive.Service.UserNovelDataService.GraphQL; +using FictionArchive.Service.UserNovelDataService.Services; + +namespace FictionArchive.Service.UserNovelDataService; + +public class Program +{ + public static void Main(string[] args) + { + var builder = WebApplication.CreateBuilder(args); + + var isSchemaExport = SchemaExportDetector.IsSchemaExportMode(args); + + builder.AddLocalAppsettings(); + + builder.Services.AddMemoryCache(); + builder.Services.AddHealthChecks(); + + #region Event Bus + + if (!isSchemaExport) + { + builder.Services.AddRabbitMQ(opt => + { + builder.Configuration.GetSection("RabbitMQ").Bind(opt); + }); + } + + #endregion + + #region GraphQL + + builder.Services.AddDefaultGraphQl() + .AddAuthorization(); + + #endregion + + #region Database + + builder.Services.RegisterDbContext( + builder.Configuration.GetConnectionString("DefaultConnection"), + skipInfrastructure: isSchemaExport); + + #endregion + + // Authentication & Authorization + builder.Services.AddOidcAuthentication(builder.Configuration); + builder.Services.AddFictionArchiveAuthorization(); + + var app = builder.Build(); + + // Update database (skip in schema export mode) + if (!isSchemaExport) + { + using var scope = app.Services.CreateScope(); + var dbContext = scope.ServiceProvider.GetRequiredService(); + dbContext.UpdateDatabase(); + } + + app.UseHttpsRedirection(); + + app.MapHealthChecks("/healthz"); + + app.UseAuthentication(); + app.UseAuthorization(); + + app.MapGraphQL(); + + app.RunWithGraphQLCommands(args); + } +} \ No newline at end of file diff --git a/FictionArchive.Service.UserNovelDataService/Properties/launchSettings.json b/FictionArchive.Service.UserNovelDataService/Properties/launchSettings.json new file mode 100644 index 0000000..7d694ee --- /dev/null +++ b/FictionArchive.Service.UserNovelDataService/Properties/launchSettings.json @@ -0,0 +1,38 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:26318", + "sslPort": 44303 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "http://localhost:5130", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://localhost:7298;http://localhost:5130", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/FictionArchive.Service.UserNovelDataService/Services/UserNovelDataServiceDbContext.cs b/FictionArchive.Service.UserNovelDataService/Services/UserNovelDataServiceDbContext.cs new file mode 100644 index 0000000..78383ca --- /dev/null +++ b/FictionArchive.Service.UserNovelDataService/Services/UserNovelDataServiceDbContext.cs @@ -0,0 +1,11 @@ +using FictionArchive.Service.Shared.Services.Database; +using Microsoft.EntityFrameworkCore; + +namespace FictionArchive.Service.UserNovelDataService.Services; + +public class UserNovelDataServiceDbContext : FictionArchiveDbContext +{ + public UserNovelDataServiceDbContext(DbContextOptions options, ILogger logger) : base(options, logger) + { + } +} \ No newline at end of file diff --git a/FictionArchive.Service.UserNovelDataService/appsettings.Development.json b/FictionArchive.Service.UserNovelDataService/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/FictionArchive.Service.UserNovelDataService/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/FictionArchive.Service.UserNovelDataService/appsettings.json b/FictionArchive.Service.UserNovelDataService/appsettings.json new file mode 100644 index 0000000..baea518 --- /dev/null +++ b/FictionArchive.Service.UserNovelDataService/appsettings.json @@ -0,0 +1,16 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "ConnectionStrings": { + "DefaultConnection": "Host=localhost;Database=FictionArchive_UserNovelDataService;Username=postgres;password=postgres" + }, + "RabbitMQ": { + "ConnectionString": "amqp://localhost", + "ClientIdentifier": "UserNovelDataService" + }, + "AllowedHosts": "*" +} diff --git a/FictionArchive.sln b/FictionArchive.sln index 6a0e6ef..8d09302 100644 --- a/FictionArchive.sln +++ b/FictionArchive.sln @@ -1,6 +1,6 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# +# Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FictionArchive.Common", "FictionArchive.Common\FictionArchive.Common.csproj", "{ABF1BA10-9E76-45BE-9947-E20445A68147}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FictionArchive.API", "FictionArchive.API\FictionArchive.API.csproj", "{420CC1A1-9DBC-40EC-B9E3-D4B25D71B9A9}" @@ -21,6 +21,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FictionArchive.Service.Nove EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FictionArchive.Service.UserService.Tests", "FictionArchive.Service.UserService.Tests\FictionArchive.Service.UserService.Tests.csproj", "{10C38C89-983D-4544-8911-F03099F66AB8}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FictionArchive.Service.UserNovelDataService", "FictionArchive.Service.UserNovelDataService\FictionArchive.Service.UserNovelDataService.csproj", "{A278565B-D440-4AB9-B2E2-41BA3B3AD82A}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -67,5 +69,9 @@ Global {10C38C89-983D-4544-8911-F03099F66AB8}.Debug|Any CPU.Build.0 = Debug|Any CPU {10C38C89-983D-4544-8911-F03099F66AB8}.Release|Any CPU.ActiveCfg = Release|Any CPU {10C38C89-983D-4544-8911-F03099F66AB8}.Release|Any CPU.Build.0 = Release|Any CPU + {A278565B-D440-4AB9-B2E2-41BA3B3AD82A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A278565B-D440-4AB9-B2E2-41BA3B3AD82A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A278565B-D440-4AB9-B2E2-41BA3B3AD82A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A278565B-D440-4AB9-B2E2-41BA3B3AD82A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal