Skip to content

Commit eabd708

Browse files
authored
feat: use redis in web api (#527)
Related to #275 Using Redis for IDistributedCache. Will start using FusionCache as an alternative to this, but now we have a functioning distributed cache backed by Redis.
1 parent ceb204c commit eabd708

9 files changed

+94
-22
lines changed

docker-compose-no-webapi.yml

+12-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,18 @@ services:
3030
interval: 5s
3131
timeout: 20s
3232
retries: 5
33-
33+
34+
dialogporten-redis:
35+
image: redis:7.0-alpine
36+
restart: always
37+
ports:
38+
- "6379:6379"
39+
healthcheck:
40+
test: ["CMD", "redis-cli", "ping"]
41+
interval: 10s
42+
timeout: 5s
43+
retries: 5
44+
3445
dialogporten-service:
3546
build:
3647
context: .

docker-compose.yml

+3-1
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@ services:
1010
depends_on:
1111
dialogporten-postgres:
1212
condition: service_healthy
13-
13+
dialogporten-redis:
14+
condition: service_healthy
1415
environment:
16+
- Infrastructure:Redis:ConnectionString=dialogporten-redis:6379
1517
- Infrastructure:DialogDbConnectionString=${DB_CONNECTION_STRING}
1618
- Serilog__WriteTo__0__Name=Console
1719
- Serilog__MinimumLevel__Default=Debug

src/Digdir.Domain.Dialogporten.Infrastructure/Digdir.Domain.Dialogporten.Infrastructure.csproj

+6-3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
<ItemGroup>
1111
<PackageReference Include="Altinn.ApiClients.Maskinporten" Version="9.1.0" />
12+
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="8.0.2" />
1213
<PackageReference Include="Altinn.Authorization.ABAC" Version="0.0.8" />
1314
<PackageReference Include="Bogus" Version="35.4.1" />
1415
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.0" />
@@ -24,13 +25,15 @@
2425
</ItemGroup>
2526

2627
<ItemGroup>
27-
<ProjectReference Include="..\Digdir.Domain.Dialogporten.Application\Digdir.Domain.Dialogporten.Application.csproj" />
28-
<ProjectReference Include="..\Digdir.Library.Entity.EntityFrameworkCore\Digdir.Library.Entity.EntityFrameworkCore.csproj" />
28+
<ProjectReference
29+
Include="..\Digdir.Domain.Dialogporten.Application\Digdir.Domain.Dialogporten.Application.csproj" />
30+
<ProjectReference
31+
Include="..\Digdir.Library.Entity.EntityFrameworkCore\Digdir.Library.Entity.EntityFrameworkCore.csproj" />
2932
</ItemGroup>
3033

3134
<ItemGroup>
3235
<InternalsVisibleTo Include="Digdir.Domain.Dialogporten.Application.Integration.Tests" />
3336
<InternalsVisibleTo Include="Digdir.Domain.Dialogporten.Infrastructure.Unit.Tests" />
3437
</ItemGroup>
3538

36-
</Project>
39+
</Project>

src/Digdir.Domain.Dialogporten.Infrastructure/InfrastructureExtensions.cs

+24-3
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
using Digdir.Domain.Dialogporten.Infrastructure.Altinn.Events;
2727
using Digdir.Domain.Dialogporten.Infrastructure.Altinn.OrganizationRegistry;
2828
using Digdir.Domain.Dialogporten.Infrastructure.Altinn.ResourceRegistry;
29+
using StackExchange.Redis;
2930

3031
namespace Digdir.Domain.Dialogporten.Infrastructure;
3132

@@ -51,11 +52,31 @@ public static IServiceCollection AddInfrastructure(this IServiceCollection servi
5152
.ValidateOnStart();
5253

5354
var thisAssembly = Assembly.GetExecutingAssembly();
55+
5456
services
5557
// Framework
56-
.AddValidatorsFromAssembly(thisAssembly, ServiceLifetime.Transient, includeInternalTypes: true)
57-
.AddDistributedMemoryCache()
58-
.AddDbContext<DialogDbContext>((services, options) =>
58+
.AddValidatorsFromAssembly(thisAssembly, ServiceLifetime.Transient, includeInternalTypes: true);
59+
60+
var infrastructureSettings = infrastructureConfigurationSection.Get<InfrastructureSettings>()
61+
?? throw new InvalidOperationException("Failed to get Redis settings. Infrastructure settings must not be null.");
62+
63+
if (infrastructureSettings.Redis.Enabled == true)
64+
{
65+
services.AddStackExchangeRedisCache(options =>
66+
{
67+
var infrastructureSettings = infrastructureConfigurationSection.Get<InfrastructureSettings>()
68+
?? throw new InvalidOperationException("Failed to get Redis connection string. Infrastructure settings must not be null.");
69+
var connectionString = infrastructureSettings.Redis.ConnectionString;
70+
options.Configuration = connectionString;
71+
options.InstanceName = "Redis";
72+
});
73+
}
74+
else
75+
{
76+
services.AddDistributedMemoryCache();
77+
}
78+
79+
services.AddDbContext<DialogDbContext>((services, options) =>
5980
{
6081
var connectionString = services.GetRequiredService<IOptions<InfrastructureSettings>>()
6182
.Value.DialogDbConnectionString;

src/Digdir.Domain.Dialogporten.Infrastructure/InfrastructureSettings.cs

+22-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ public sealed class InfrastructureSettings
99
public const string ConfigurationSectionName = "Infrastructure";
1010

1111
public required string DialogDbConnectionString { get; init; }
12+
public required RedisSettings Redis { get; init; }
1213
public required AltinnPlatformSettings Altinn { get; init; }
1314
public required AltinnCdnPlatformSettings AltinnCdn { get; init; }
1415
public required MaskinportenSettings Maskinporten { get; init; }
@@ -26,12 +27,19 @@ public sealed class AltinnCdnPlatformSettings
2627
public required Uri BaseUri { get; init; }
2728
}
2829

30+
public sealed class RedisSettings
31+
{
32+
public required bool? Enabled { get; init; }
33+
public required string ConnectionString { get; init; }
34+
}
35+
2936
internal sealed class InfrastructureSettingsValidator : AbstractValidator<InfrastructureSettings>
3037
{
3138
public InfrastructureSettingsValidator(
3239
IValidator<AltinnPlatformSettings> altinnPlatformSettingsValidator,
3340
IValidator<AltinnCdnPlatformSettings> altinnCdnPlatformSettingsValidator,
34-
IValidator<MaskinportenSettings> maskinportenSettingsValidator)
41+
IValidator<MaskinportenSettings> maskinportenSettingsValidator,
42+
IValidator<RedisSettings> redisSettingsValidator)
3543
{
3644
RuleFor(x => x.DialogDbConnectionString)
3745
.NotEmpty();
@@ -47,6 +55,10 @@ public InfrastructureSettingsValidator(
4755
RuleFor(x => x.Maskinporten)
4856
.NotEmpty()
4957
.SetValidator(maskinportenSettingsValidator);
58+
59+
RuleFor(x => x.Redis)
60+
.NotEmpty()
61+
.SetValidator(redisSettingsValidator);
5062
}
5163
}
5264

@@ -76,3 +88,12 @@ public MaskinportenSettingsValidator()
7688
RuleFor(x => x.EncodedJwk).NotEmpty();
7789
}
7890
}
91+
92+
internal sealed class RedisSettingsValidator : AbstractValidator<RedisSettings>
93+
{
94+
public RedisSettingsValidator()
95+
{
96+
RuleFor(x => x.Enabled).Must(x => x is false or true);
97+
RuleFor(x => x.ConnectionString).NotEmpty();
98+
}
99+
}

src/Digdir.Domain.Dialogporten.WebApi/Digdir.Domain.Dialogporten.WebApi.csproj

+15-13
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,23 @@
1212
</PropertyGroup>
1313

1414
<ItemGroup>
15-
<PackageReference Include="Azure.Identity" Version="1.10.4"/>
16-
<PackageReference Include="FastEndpoints.Swagger" Version="5.22.0"/>
17-
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.22.0"/>
18-
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.2"/>
19-
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.2"/>
20-
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.2"/>
21-
<PackageReference Include="Microsoft.Azure.AppConfiguration.AspNetCore" Version="7.1.0"/>
22-
<PackageReference Include="Serilog.AspNetCore" Version="8.0.1"/>
23-
<PackageReference Include="Serilog.Sinks.ApplicationInsights" Version="4.0.0"/>
24-
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0"/>
15+
<PackageReference Include="Azure.Identity" Version="1.10.4" />
16+
<PackageReference Include="FastEndpoints.Swagger" Version="5.22.0" />
17+
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.22.0" />
18+
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.2" />
19+
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.2" />
20+
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.2" />
21+
<PackageReference Include="Microsoft.Azure.AppConfiguration.AspNetCore" Version="7.1.0" />
22+
<PackageReference Include="Serilog.AspNetCore" Version="8.0.1" />
23+
<PackageReference Include="Serilog.Sinks.ApplicationInsights" Version="4.0.0" />
24+
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
2525
</ItemGroup>
2626

2727
<ItemGroup>
28-
<ProjectReference Include="..\Digdir.Domain.Dialogporten.Application\Digdir.Domain.Dialogporten.Application.csproj"/>
29-
<ProjectReference Include="..\Digdir.Domain.Dialogporten.Infrastructure\Digdir.Domain.Dialogporten.Infrastructure.csproj"/>
28+
<ProjectReference
29+
Include="..\Digdir.Domain.Dialogporten.Application\Digdir.Domain.Dialogporten.Application.csproj" />
30+
<ProjectReference
31+
Include="..\Digdir.Domain.Dialogporten.Infrastructure\Digdir.Domain.Dialogporten.Infrastructure.csproj" />
3032
</ItemGroup>
3133

32-
</Project>
34+
</Project>

src/Digdir.Domain.Dialogporten.WebApi/appsettings.Development.json

+4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
}
77
},
88
"Infrastructure": {
9+
"Redis": {
10+
"Enabled": true,
11+
"ConnectionString": "localhost:6379"
12+
},
913
"DialogDbConnectionString": "TODO: Add to local secrets",
1014
// Settings from appsettings.json, environment variables or other configuration providers.
1115
// The first three are always mandatory for all client definitions types

src/Digdir.Domain.Dialogporten.WebApi/appsettings.staging.json

+4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
}
77
},
88
"Infrastructure": {
9+
"Redis":{
10+
"Enabled": true,
11+
"ConnectionString": "TODO: Add to local secrets"
12+
},
913
"DialogDbConnectionString": "TODO: Add to local secrets",
1014
// Settings from appsettings.json, environment variables or other configuration providers.
1115
// The first three are always mandatory for all client definitions types

src/Digdir.Domain.Dialogporten.WebApi/appsettings.test.json

+4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
}
77
},
88
"Infrastructure": {
9+
"Redis":{
10+
"Enabled": true,
11+
"ConnectionString": "TODO: Add to local secrets"
12+
},
913
"DialogDbConnectionString": "TODO: Add to local secrets",
1014
// Settings from appsettings.json, environment variables or other configuration providers.
1115
// The first three are always mandatory for all client definitions types

0 commit comments

Comments
 (0)