From c269465351dcc49b292f9e91c650381e125026cf Mon Sep 17 00:00:00 2001 From: Terje Holene Date: Thu, 17 Oct 2024 11:30:48 +0200 Subject: [PATCH 1/5] Add database migration with yuniql --- Dockerfile | 8 +- docker-compose.yml | 5 +- .../Altinn.Profile.Integrations.csproj | 6 +- .../Extensions/ConfigurationExtensions.cs | 26 +++---- .../Extensions/WebApplicationExtensions.cs | 51 ++++++++++++ .../Migration/_draft/README.md | 2 + .../Migration/_erase/README.md | 2 + .../Migration/_init/README.md | 2 + .../Migration/_post/README.md | 2 + .../Migration/_pre/README.md | 2 + .../Migration/v0.00/01-setup-schema.sql | 2 + .../Migration/v0.01/01-setup-grants.sql | 3 + .../02-setup-tables.sql} | 10 --- .../Persistence/ConsoleTraceService.cs | 77 +++++++++++++++++++ .../Persistence/PostgreSQLSettings.cs | 47 +++++++++++ src/Altinn.Profile/Program.cs | 17 +--- .../appsettings.Development.json | 3 + src/Altinn.Profile/appsettings.json | 9 ++- 18 files changed, 228 insertions(+), 46 deletions(-) create mode 100644 src/Altinn.Profile.Integrations/Extensions/WebApplicationExtensions.cs create mode 100644 src/Altinn.Profile.Integrations/Migration/_draft/README.md create mode 100644 src/Altinn.Profile.Integrations/Migration/_erase/README.md create mode 100644 src/Altinn.Profile.Integrations/Migration/_init/README.md create mode 100644 src/Altinn.Profile.Integrations/Migration/_post/README.md create mode 100644 src/Altinn.Profile.Integrations/Migration/_pre/README.md create mode 100644 src/Altinn.Profile.Integrations/Migration/v0.00/01-setup-schema.sql create mode 100644 src/Altinn.Profile.Integrations/Migration/v0.01/01-setup-grants.sql rename src/Altinn.Profile.Integrations/Migration/{profiledb.sql => v0.01/02-setup-tables.sql} (78%) create mode 100644 src/Altinn.Profile.Integrations/Persistence/ConsoleTraceService.cs create mode 100644 src/Altinn.Profile.Integrations/Persistence/PostgreSQLSettings.cs diff --git a/Dockerfile b/Dockerfile index cd108ec..454d158 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,11 +1,11 @@ FROM mcr.microsoft.com/dotnet/sdk:8.0.403-alpine3.20 AS build -WORKDIR Altinn.Profile/ +WORKDIR /app COPY src/Altinn.Profile/*.csproj ./src/Altinn.Profile/ COPY src/Altinn.Profile.Core/*.csproj ./src/Altinn.Profile.Core/ COPY src/Altinn.Profile.Integrations/*.csproj ./src/Altinn.Profile.Integrations/ -RUN dotnet restore ./src/Altinn.Profile/Altinn.Profile.csproj +RUN dotnet restore ./src/Altinn.Profile/Altinn.Profile.csproj COPY src ./src RUN dotnet publish -c Release -o /app_output ./src/Altinn.Profile/Altinn.Profile.csproj @@ -13,10 +13,14 @@ RUN dotnet publish -c Release -o /app_output ./src/Altinn.Profile/Altinn.Profile FROM mcr.microsoft.com/dotnet/aspnet:8.0.10-alpine3.20 AS final EXPOSE 5030 WORKDIR /app + COPY --from=build /app_output . +COPY --from=build /app/src/Altinn.Profile.Integrations/Migration ./Migration + # setup the user and group # the user will have no password, using shell /bin/false and using the group dotnet RUN addgroup -g 3000 dotnet && adduser -u 1000 -G dotnet -D -s /bin/false dotnet + # update permissions of files if neccessary before becoming dotnet user USER dotnet RUN mkdir /tmp/logtelemetry diff --git a/docker-compose.yml b/docker-compose.yml index 43acb2f..139c63a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -12,9 +12,10 @@ services: networks: - altinnplatform_network environment: - - ASPNETCORE_ENVIRONMENT=Development + - ASPNETCORE_ENVIRONMENT=Docker - ASPNETCORE_URLS=http://+:5030 - - GeneralSettings:BridgeApiEndpoint=https://at22.altinn.cloud/sblbridge/profile/api + - PostgreSqlSettings__AdminConnectionString=Host=host.docker.internal;Port=5432;Username=platform_profile_admin;Password={0};Database=profiledb + - PostgreSqlSettings__ConnectionString=Host=host.docker.internal;Port=5432;Username=platform_profile;Password={0};Database=profiledb ports: - "5030:5030" build: diff --git a/src/Altinn.Profile.Integrations/Altinn.Profile.Integrations.csproj b/src/Altinn.Profile.Integrations/Altinn.Profile.Integrations.csproj index 85c1889..ac92314 100644 --- a/src/Altinn.Profile.Integrations/Altinn.Profile.Integrations.csproj +++ b/src/Altinn.Profile.Integrations/Altinn.Profile.Integrations.csproj @@ -11,13 +11,15 @@ + + - + - + all diff --git a/src/Altinn.Profile.Integrations/Extensions/ConfigurationExtensions.cs b/src/Altinn.Profile.Integrations/Extensions/ConfigurationExtensions.cs index f80b7c8..c6890f2 100644 --- a/src/Altinn.Profile.Integrations/Extensions/ConfigurationExtensions.cs +++ b/src/Altinn.Profile.Integrations/Extensions/ConfigurationExtensions.cs @@ -7,9 +7,8 @@ namespace Altinn.Profile.Integrations.Extensions; /// public static class ConfigurationExtensions { - private const string ProfileDbAdminUserNameKey = "PostgreSqlSettings:ProfileDbAdminUserName"; - private const string ProfileDbAdminPasswordKey = "PostgreSqlSettings:ProfileDbAdminPassword"; - private const string ProfileDbConnectionStringKey = "PostgreSqlSettings:ProfileDbConnectionString"; + private const string ConnectionStringKey = "PostgreSqlSettings:ConnectionString"; + private const string ProfileDbPasswordKey = "PostgreSqlSettings:ProfileDbPwd"; /// /// Retrieves the database connection string from the configuration. @@ -17,27 +16,26 @@ public static class ConfigurationExtensions /// The configuration instance containing the connection settings. /// The formatted database connection string if all required settings are present; otherwise, an empty string. /// - /// This method expects the configuration to contain the following keys: + /// This method expects IConfiguration to contain the following keys: /// - /// PostgreSqlSettings--ProfileDbAdminUserName - /// PostgreSqlSettings--ProfileDbAdminPassword - /// PostgreSqlSettings--ProfileDbConnectionString + /// PostgreSqlSettings:ConnectionString + /// PostgreSqlSettings:ProfileDbPwd /// - /// The connection string is formatted using the administrator user name and password. + /// The connection string is expected to contain a placeholder for the password. The password is added to the connection string + /// through string formatting. The connection string value should be provieded as a value in the helm chart for profile. The password + /// is retrieved from the platform KeyVault. The names can therefore not be changed, but must follow the above naming conventions. /// public static string GetDatabaseConnectionString(this IConfiguration config) { - var adminUserName = config[ProfileDbAdminUserNameKey]; - var adminPassword = config[ProfileDbAdminPasswordKey]; - var connectionString = config[ProfileDbConnectionStringKey]; + var connectionString = config[ConnectionStringKey]; + var userPassword = config[ProfileDbPasswordKey]; - if (string.IsNullOrWhiteSpace(adminUserName) || - string.IsNullOrWhiteSpace(adminPassword) || + if (string.IsNullOrWhiteSpace(userPassword) || string.IsNullOrWhiteSpace(connectionString)) { return string.Empty; } - return string.Format(connectionString, adminUserName, adminPassword); + return string.Format(connectionString, userPassword); } } diff --git a/src/Altinn.Profile.Integrations/Extensions/WebApplicationExtensions.cs b/src/Altinn.Profile.Integrations/Extensions/WebApplicationExtensions.cs new file mode 100644 index 0000000..a04d6bf --- /dev/null +++ b/src/Altinn.Profile.Integrations/Extensions/WebApplicationExtensions.cs @@ -0,0 +1,51 @@ +using Altinn.Profile.Integrations.Persistence; + +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.Configuration; + +using Yuniql.AspNetCore; +using Yuniql.PostgreSql; + +namespace Altinn.Profile.Integrations.Extensions; + +/// +/// Extension class for web application +/// +public static class WebApplicationExtensions +{ + /// + /// Configure and set up db + /// + /// app + /// is environment dev + /// the configuration collection + public static void SetUpPostgreSql(this IApplicationBuilder app, bool isDevelopment, IConfiguration config) + { + PostgreSqlSettings? settings = config.GetSection("PostgreSQLSettings") + .Get() + ?? throw new ArgumentNullException(nameof(config), "Required PostgreSQLSettings is missing from application configuration"); + + if (settings.EnableDBConnection) + { + ConsoleTraceService traceService = new() { IsDebugEnabled = true }; + + string connectionString = string.Format(settings.AdminConnectionString, settings.ProfileDbAdminPwd); + + string fullWorkspacePath = isDevelopment ? + Path.Combine(Directory.GetParent(Environment.CurrentDirectory)!.FullName, settings.MigrationScriptPath) : + Path.Combine(Environment.CurrentDirectory, settings.MigrationScriptPath); + + app.UseYuniql( + new PostgreSqlDataService(traceService), + new PostgreSqlBulkImportService(traceService), + traceService, + new Configuration + { + Workspace = fullWorkspacePath, + ConnectionString = connectionString, + IsAutoCreateDatabase = false, + IsDebug = settings.EnableDebug + }); + } + } +} diff --git a/src/Altinn.Profile.Integrations/Migration/_draft/README.md b/src/Altinn.Profile.Integrations/Migration/_draft/README.md new file mode 100644 index 0000000..e2c724f --- /dev/null +++ b/src/Altinn.Profile.Integrations/Migration/_draft/README.md @@ -0,0 +1,2 @@ +# The `_draft` directory +Scripts in progress. Scripts that you are currently working and have not moved to specific version directory yet. Executed every time after the latest version. \ No newline at end of file diff --git a/src/Altinn.Profile.Integrations/Migration/_erase/README.md b/src/Altinn.Profile.Integrations/Migration/_erase/README.md new file mode 100644 index 0000000..9a2a5b3 --- /dev/null +++ b/src/Altinn.Profile.Integrations/Migration/_erase/README.md @@ -0,0 +1,2 @@ +# The `_erase` directory +Database cleanup scripts. Executed once only when you do `yuniql erase`. \ No newline at end of file diff --git a/src/Altinn.Profile.Integrations/Migration/_init/README.md b/src/Altinn.Profile.Integrations/Migration/_init/README.md new file mode 100644 index 0000000..567e2f8 --- /dev/null +++ b/src/Altinn.Profile.Integrations/Migration/_init/README.md @@ -0,0 +1,2 @@ +# The `_init` directory +Initialization scripts. Executed once. This is called the first time you do `yuniql run`. \ No newline at end of file diff --git a/src/Altinn.Profile.Integrations/Migration/_post/README.md b/src/Altinn.Profile.Integrations/Migration/_post/README.md new file mode 100644 index 0000000..3028574 --- /dev/null +++ b/src/Altinn.Profile.Integrations/Migration/_post/README.md @@ -0,0 +1,2 @@ +# The `_post` directory +Post migration scripts. Executed every time and always the last batch to run. \ No newline at end of file diff --git a/src/Altinn.Profile.Integrations/Migration/_pre/README.md b/src/Altinn.Profile.Integrations/Migration/_pre/README.md new file mode 100644 index 0000000..c35c1c4 --- /dev/null +++ b/src/Altinn.Profile.Integrations/Migration/_pre/README.md @@ -0,0 +1,2 @@ +# The `_pre` directory +Pre migration scripts. Executed every time before any version. diff --git a/src/Altinn.Profile.Integrations/Migration/v0.00/01-setup-schema.sql b/src/Altinn.Profile.Integrations/Migration/v0.00/01-setup-schema.sql new file mode 100644 index 0000000..13a54d6 --- /dev/null +++ b/src/Altinn.Profile.Integrations/Migration/v0.00/01-setup-schema.sql @@ -0,0 +1,2 @@ +-- Create schema if it doesn't exist +CREATE SCHEMA IF NOT EXISTS contact_and_reservation; \ No newline at end of file diff --git a/src/Altinn.Profile.Integrations/Migration/v0.01/01-setup-grants.sql b/src/Altinn.Profile.Integrations/Migration/v0.01/01-setup-grants.sql new file mode 100644 index 0000000..9e5d3ea --- /dev/null +++ b/src/Altinn.Profile.Integrations/Migration/v0.01/01-setup-grants.sql @@ -0,0 +1,3 @@ +-- Grant access to the schema +GRANT ALL ON SCHEMA contact_and_reservation TO platform_profile_admin; +GRANT USAGE ON SCHEMA contact_and_reservation TO platform_profile; \ No newline at end of file diff --git a/src/Altinn.Profile.Integrations/Migration/profiledb.sql b/src/Altinn.Profile.Integrations/Migration/v0.01/02-setup-tables.sql similarity index 78% rename from src/Altinn.Profile.Integrations/Migration/profiledb.sql rename to src/Altinn.Profile.Integrations/Migration/v0.01/02-setup-tables.sql index c2382ae..8eb8cb4 100644 --- a/src/Altinn.Profile.Integrations/Migration/profiledb.sql +++ b/src/Altinn.Profile.Integrations/Migration/v0.01/02-setup-tables.sql @@ -1,10 +1,3 @@ --- Create schema if it doesn't exist -CREATE SCHEMA IF NOT EXISTS contact_and_reservation; - --- Grant access to the schema -GRANT ALL ON SCHEMA contact_and_reservation TO platform_profile_admin; -GRANT USAGE ON SCHEMA contact_and_reservation TO platform_profile; - -- Create table MailboxSupplier CREATE TABLE IF NOT EXISTS contact_and_reservation.mailbox_supplier ( mailbox_supplier_id INT GENERATED ALWAYS AS IDENTITY (START WITH 1 INCREMENT BY 1) PRIMARY KEY, @@ -37,6 +30,3 @@ CREATE TABLE IF NOT EXISTS contact_and_reservation.person ( CONSTRAINT fk_mailbox_supplier FOREIGN KEY (mailbox_supplier_id_fk) REFERENCES contact_and_reservation.mailbox_supplier (mailbox_supplier_id), CONSTRAINT chk_language_code CHECK (language_code ~* '^[a-z]{2}$') ); - --- Indexes for performance -CREATE INDEX idx_fnumber_ak ON contact_and_reservation.person (fnumber_ak); diff --git a/src/Altinn.Profile.Integrations/Persistence/ConsoleTraceService.cs b/src/Altinn.Profile.Integrations/Persistence/ConsoleTraceService.cs new file mode 100644 index 0000000..90f39cf --- /dev/null +++ b/src/Altinn.Profile.Integrations/Persistence/ConsoleTraceService.cs @@ -0,0 +1,77 @@ +using System.Diagnostics.CodeAnalysis; + +using Yuniql.Extensibility; + +namespace Altinn.Profile.Integrations.Persistence; + +/// +/// Copied from sample project. +/// +[ExcludeFromCodeCoverage] +public class ConsoleTraceService : ITraceService +{ + /// + /// Debug enabled + /// + public bool IsDebugEnabled { get; set; } = false; + + /// > + public bool IsTraceSensitiveData { get; set; } = false; + + /// > + public bool IsTraceToFile { get; set; } = false; + + /// > + public bool IsTraceToDirectory { get; set; } = false; + + /// > + public string? TraceDirectory { get; set; } + + /// + /// Info + /// + public void Info(string message, object? payload = null) + { + var traceMessage = $"INF {DateTime.UtcNow:o} {message}{Environment.NewLine}"; + Console.Write(traceMessage); + } + + /// + /// Error + /// + public void Error(string message, object? payload = null) + { + var traceMessage = $"ERR {DateTime.UtcNow:o} {message}{Environment.NewLine}"; + Console.Write(traceMessage); + } + + /// + /// Debug + /// + public void Debug(string message, object? payload = null) + { + if (IsDebugEnabled) + { + var traceMessage = $"DBG {DateTime.UtcNow:o} {message}{Environment.NewLine}"; + Console.Write(traceMessage); + } + } + + /// + /// Success + /// + public void Success(string message, object? payload = null) + { + var traceMessage = $"INF {DateTime.UtcNow:u} {message}{Environment.NewLine}"; + Console.Write(traceMessage); + } + + /// + /// Warn + /// + public void Warn(string message, object? payload = null) + { + var traceMessage = $"WRN {DateTime.UtcNow:o} {message}{Environment.NewLine}"; + Console.Write(traceMessage); + } +} diff --git a/src/Altinn.Profile.Integrations/Persistence/PostgreSQLSettings.cs b/src/Altinn.Profile.Integrations/Persistence/PostgreSQLSettings.cs new file mode 100644 index 0000000..8558c52 --- /dev/null +++ b/src/Altinn.Profile.Integrations/Persistence/PostgreSQLSettings.cs @@ -0,0 +1,47 @@ +namespace Altinn.Profile.Integrations.Persistence; + +/// +/// Settings for Postgre database +/// +public class PostgreSqlSettings +{ + /// + /// Boolean indicating if database should be connected + /// + public bool EnableDBConnection { get; set; } = true; + + /// + /// Path to migration scripts + /// + public string MigrationScriptPath { get; set; } = string.Empty; + + /// + /// Connection string for the admin user of postgre db + /// + public string AdminConnectionString { get; set; } = string.Empty; + + /// + /// Password for admin user for the postgre db + /// + public string ProfileDbAdminPwd { get; set; } = string.Empty; + + /// + /// Connection string for app user the postgre db + /// + public string ConnectionString { get; set; } = string.Empty; + + /// + /// Password for app user for the postgre db + /// + public string ProfileDbPwd { get; set; } = string.Empty; + + /// + /// Gets or sets a value indicating whether to include parameter values in logging/tracing + /// + public bool LogParameters { get; set; } = false; + + /// + /// Boolean indicating if connection to db should be in debug mode + /// + public bool EnableDebug { get; set; } = false; +} diff --git a/src/Altinn.Profile/Program.cs b/src/Altinn.Profile/Program.cs index 7c3fa08..2f97e5d 100644 --- a/src/Altinn.Profile/Program.cs +++ b/src/Altinn.Profile/Program.cs @@ -12,6 +12,7 @@ using Altinn.Profile.Filters; using Altinn.Profile.Health; using Altinn.Profile.Integrations; +using Altinn.Profile.Integrations.Extensions; using Altinn.Profile.UseCases; using AltinnCore.Authentication.JwtCookie; @@ -56,6 +57,8 @@ WebApplication app = builder.Build(); +app.SetUpPostgreSql(builder.Environment.IsDevelopment(), builder.Configuration); + Configure(); app.Run(); @@ -76,21 +79,9 @@ async Task SetConfigurationProviders(ConfigurationManager config) { string basePath = Directory.GetParent(Directory.GetCurrentDirectory()).FullName; config.SetBasePath(basePath); - string configJsonFile1 = $"{basePath}/altinn-appsettings/altinn-dbsettings-secret.json"; - string configJsonFile2 = Directory.GetCurrentDirectory() + "/appsettings.json"; - - if (basePath == "/") - { - configJsonFile2 = "/app/appsettings.json"; - } - - config.AddJsonFile(configJsonFile1, optional: true, reloadOnChange: true); - config.AddJsonFile(configJsonFile2, optional: false, reloadOnChange: true); + config.AddJsonFile(basePath + "altinn-appsettings/altinn-dbsettings-secret.json", optional: true, reloadOnChange: true); await ConnectToKeyVaultAndSetApplicationInsights(config); - - config.AddEnvironmentVariables(); - config.AddCommandLine(args); } async Task ConnectToKeyVaultAndSetApplicationInsights(ConfigurationManager config) diff --git a/src/Altinn.Profile/appsettings.Development.json b/src/Altinn.Profile/appsettings.Development.json index e203e94..01d01ec 100644 --- a/src/Altinn.Profile/appsettings.Development.json +++ b/src/Altinn.Profile/appsettings.Development.json @@ -1,4 +1,7 @@ { + "PostgreSqlSettings": { + "MigrationScriptPath": "Altinn.Profile.Integrations/Migration" + }, "Logging": { "LogLevel": { "Default": "Debug", diff --git a/src/Altinn.Profile/appsettings.json b/src/Altinn.Profile/appsettings.json index 40c9f24..e919f04 100644 --- a/src/Altinn.Profile/appsettings.json +++ b/src/Altinn.Profile/appsettings.json @@ -10,8 +10,11 @@ "ProfileCacheLifetimeSeconds": 600 }, "PostgreSqlSettings": { - "ProfileDbAdminUserName": "from keyvault", - "ProfileDbAdminPassword": "from keyvault", - "ProfileDbConnectionString": "Host=localhost;Port=5432;Database=profiledb;Username={0};Password={1};" + "MigrationScriptPath": "Migration", + "AdminConnectionString": "Host=localhost;Port=5432;Username=platform_profile_admin;Password={0};Database=profiledb", + "ConnectionString": "Host=localhost;Port=5432;Username=platform_profile;Password={0};Database=profiledb", + "ProfileDbAdminPwd": "Password", + "ProfileDbPwd": "Password", + "EnableDBConnection": true } } From abdaaadd110b3350f6633e3b30c3cea4c6da6370 Mon Sep 17 00:00:00 2001 From: Terje Holene Date: Thu, 17 Oct 2024 14:57:45 +0200 Subject: [PATCH 2/5] Exclude WebApplicationExtensions from code coverage --- .../Extensions/WebApplicationExtensions.cs | 5 ++++- .../Persistence/ConsoleTraceService.cs | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Altinn.Profile.Integrations/Extensions/WebApplicationExtensions.cs b/src/Altinn.Profile.Integrations/Extensions/WebApplicationExtensions.cs index a04d6bf..0831560 100644 --- a/src/Altinn.Profile.Integrations/Extensions/WebApplicationExtensions.cs +++ b/src/Altinn.Profile.Integrations/Extensions/WebApplicationExtensions.cs @@ -1,4 +1,6 @@ -using Altinn.Profile.Integrations.Persistence; +using System.Diagnostics.CodeAnalysis; + +using Altinn.Profile.Integrations.Persistence; using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.Configuration; @@ -11,6 +13,7 @@ namespace Altinn.Profile.Integrations.Extensions; /// /// Extension class for web application /// +[ExcludeFromCodeCoverage] public static class WebApplicationExtensions { /// diff --git a/src/Altinn.Profile.Integrations/Persistence/ConsoleTraceService.cs b/src/Altinn.Profile.Integrations/Persistence/ConsoleTraceService.cs index 90f39cf..47c36e8 100644 --- a/src/Altinn.Profile.Integrations/Persistence/ConsoleTraceService.cs +++ b/src/Altinn.Profile.Integrations/Persistence/ConsoleTraceService.cs @@ -29,7 +29,7 @@ public class ConsoleTraceService : ITraceService /// /// Info - /// + /// public void Info(string message, object? payload = null) { var traceMessage = $"INF {DateTime.UtcNow:o} {message}{Environment.NewLine}"; From 90a9f55699817d3ea60d2f73aa8fef01a0a57df7 Mon Sep 17 00:00:00 2001 From: Terje Holene Date: Fri, 18 Oct 2024 08:57:18 +0200 Subject: [PATCH 3/5] Turn off db in tests --- .../ServiceCollectionExtensions.cs | 3 ++- .../Altinn.Profile.Tests/Altinn.Profile.Tests.csproj | 12 ++++++++++++ .../Utils/WebApplicationFactorySetup.cs | 8 ++++++++ test/Altinn.Profile.Tests/appsettings.test.json | 5 +++++ 4 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 test/Altinn.Profile.Tests/appsettings.test.json diff --git a/src/Altinn.Profile.Integrations/ServiceCollectionExtensions.cs b/src/Altinn.Profile.Integrations/ServiceCollectionExtensions.cs index 7acbfb4..bfdbcdb 100644 --- a/src/Altinn.Profile.Integrations/ServiceCollectionExtensions.cs +++ b/src/Altinn.Profile.Integrations/ServiceCollectionExtensions.cs @@ -1,5 +1,6 @@ using Altinn.Profile.Core.Integrations; using Altinn.Profile.Integrations.Extensions; +using Altinn.Profile.Integrations.Mappings; using Altinn.Profile.Integrations.Persistence; using Altinn.Profile.Integrations.Repositories; using Altinn.Profile.Integrations.SblBridge; @@ -56,7 +57,7 @@ public static void AddRegisterService(this IServiceCollection services, IConfigu services.AddDbContext(options => options.UseNpgsql(connectionString)); - services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies()); + services.AddAutoMapper(typeof(PersonContactDetailsProfile)); services.AddScoped(); services.AddScoped(); diff --git a/test/Altinn.Profile.Tests/Altinn.Profile.Tests.csproj b/test/Altinn.Profile.Tests/Altinn.Profile.Tests.csproj index 7be8790..524b91e 100644 --- a/test/Altinn.Profile.Tests/Altinn.Profile.Tests.csproj +++ b/test/Altinn.Profile.Tests/Altinn.Profile.Tests.csproj @@ -36,6 +36,18 @@ + + + + + + + Always + true + PreserveNewest + + + $(NoWarn);SA0001;CS1591;SA1600 diff --git a/test/Altinn.Profile.Tests/IntegrationTests/Utils/WebApplicationFactorySetup.cs b/test/Altinn.Profile.Tests/IntegrationTests/Utils/WebApplicationFactorySetup.cs index 08ce151..5331364 100644 --- a/test/Altinn.Profile.Tests/IntegrationTests/Utils/WebApplicationFactorySetup.cs +++ b/test/Altinn.Profile.Tests/IntegrationTests/Utils/WebApplicationFactorySetup.cs @@ -1,3 +1,4 @@ +using System.IO; using System.Net.Http; using Altinn.Common.AccessToken.Services; @@ -7,11 +8,13 @@ using Altinn.Profile.Integrations.SblBridge.User.Profile; using Altinn.Profile.Tests.IntegrationTests.Mocks; using Altinn.Profile.Tests.IntegrationTests.Mocks.Authentication; + using AltinnCore.Authentication.JwtCookie; using Microsoft.AspNetCore.Mvc.Testing; using Microsoft.AspNetCore.TestHost; using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; @@ -50,6 +53,11 @@ public HttpClient GetTestServerClient() return _webApplicationFactory.WithWebHostBuilder(builder => { + builder.ConfigureAppConfiguration((context, config) => + { + config.SetBasePath(Directory.GetCurrentDirectory()); + config.AddJsonFile("appsettings.test.json"); + }); builder.ConfigureTestServices(services => { services.AddSingleton, JwtCookiePostConfigureOptionsStub>(); diff --git a/test/Altinn.Profile.Tests/appsettings.test.json b/test/Altinn.Profile.Tests/appsettings.test.json new file mode 100644 index 0000000..e6e525c --- /dev/null +++ b/test/Altinn.Profile.Tests/appsettings.test.json @@ -0,0 +1,5 @@ +{ + "PostgreSqlSettings": { + "EnableDBConnection": false + } +} From c0176abd24ea67de36cc789256048972928170d4 Mon Sep 17 00:00:00 2001 From: Terje Holene Date: Fri, 18 Oct 2024 11:08:51 +0200 Subject: [PATCH 4/5] Exclude untestable code from code coverage --- .../Extensions/ConfigurationExtensions.cs | 5 ++++- .../ServiceCollectionExtensions.cs | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Altinn.Profile.Integrations/Extensions/ConfigurationExtensions.cs b/src/Altinn.Profile.Integrations/Extensions/ConfigurationExtensions.cs index c6890f2..8617dce 100644 --- a/src/Altinn.Profile.Integrations/Extensions/ConfigurationExtensions.cs +++ b/src/Altinn.Profile.Integrations/Extensions/ConfigurationExtensions.cs @@ -1,10 +1,13 @@ -using Microsoft.Extensions.Configuration; +using System.Diagnostics.CodeAnalysis; + +using Microsoft.Extensions.Configuration; namespace Altinn.Profile.Integrations.Extensions; /// /// Extension class for to add more members. /// +[ExcludeFromCodeCoverage] public static class ConfigurationExtensions { private const string ConnectionStringKey = "PostgreSqlSettings:ConnectionString"; diff --git a/src/Altinn.Profile.Integrations/ServiceCollectionExtensions.cs b/src/Altinn.Profile.Integrations/ServiceCollectionExtensions.cs index bfdbcdb..05dae22 100644 --- a/src/Altinn.Profile.Integrations/ServiceCollectionExtensions.cs +++ b/src/Altinn.Profile.Integrations/ServiceCollectionExtensions.cs @@ -1,4 +1,6 @@ -using Altinn.Profile.Core.Integrations; +using System.Diagnostics.CodeAnalysis; + +using Altinn.Profile.Core.Integrations; using Altinn.Profile.Integrations.Extensions; using Altinn.Profile.Integrations.Mappings; using Altinn.Profile.Integrations.Persistence; @@ -17,6 +19,7 @@ namespace Altinn.Profile.Integrations; /// /// Extension class for /// +[ExcludeFromCodeCoverage] public static class ServiceCollectionExtensions { /// From f5a59a11003b15bba6965639472bb0e34031448c Mon Sep 17 00:00:00 2001 From: Terje Holene Date: Fri, 18 Oct 2024 15:55:25 +0200 Subject: [PATCH 5/5] Add index for person f nr --- .../Migration/v0.00/01-setup-schema.sql | 2 +- .../Migration/v0.01/01-setup-grants.sql | 2 +- .../Migration/v0.01/02-setup-tables.sql | 3 +++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Altinn.Profile.Integrations/Migration/v0.00/01-setup-schema.sql b/src/Altinn.Profile.Integrations/Migration/v0.00/01-setup-schema.sql index 13a54d6..9d2e35d 100644 --- a/src/Altinn.Profile.Integrations/Migration/v0.00/01-setup-schema.sql +++ b/src/Altinn.Profile.Integrations/Migration/v0.00/01-setup-schema.sql @@ -1,2 +1,2 @@ -- Create schema if it doesn't exist -CREATE SCHEMA IF NOT EXISTS contact_and_reservation; \ No newline at end of file +CREATE SCHEMA IF NOT EXISTS contact_and_reservation; diff --git a/src/Altinn.Profile.Integrations/Migration/v0.01/01-setup-grants.sql b/src/Altinn.Profile.Integrations/Migration/v0.01/01-setup-grants.sql index 9e5d3ea..bcbdffd 100644 --- a/src/Altinn.Profile.Integrations/Migration/v0.01/01-setup-grants.sql +++ b/src/Altinn.Profile.Integrations/Migration/v0.01/01-setup-grants.sql @@ -1,3 +1,3 @@ -- Grant access to the schema GRANT ALL ON SCHEMA contact_and_reservation TO platform_profile_admin; -GRANT USAGE ON SCHEMA contact_and_reservation TO platform_profile; \ No newline at end of file +GRANT USAGE ON SCHEMA contact_and_reservation TO platform_profile; diff --git a/src/Altinn.Profile.Integrations/Migration/v0.01/02-setup-tables.sql b/src/Altinn.Profile.Integrations/Migration/v0.01/02-setup-tables.sql index 8eb8cb4..8c647c4 100644 --- a/src/Altinn.Profile.Integrations/Migration/v0.01/02-setup-tables.sql +++ b/src/Altinn.Profile.Integrations/Migration/v0.01/02-setup-tables.sql @@ -30,3 +30,6 @@ CREATE TABLE IF NOT EXISTS contact_and_reservation.person ( CONSTRAINT fk_mailbox_supplier FOREIGN KEY (mailbox_supplier_id_fk) REFERENCES contact_and_reservation.mailbox_supplier (mailbox_supplier_id), CONSTRAINT chk_language_code CHECK (language_code ~* '^[a-z]{2}$') ); + +-- Indexes for performance +CREATE INDEX idx_fnumber_ak ON contact_and_reservation.person (fnumber_ak);