Configuring .NET Services

Swagger

Property Description Required Default Value Secret?
EnableSwagger Enable Swagger spec and UI No false No

Azure App Config Environment Variables

The following should be specified as environment variables when launching the service:

Name Description Required Default Value Secret?
ExternalConfigurationSource Specifies the configuration source to use Yes None No
ConnectionStrings__AzureAppConfiguration Connection string for Azure App Configuration Yes (if using Azure) None Yes

Blob Storage

Name Description Required Default Value Secret?
InternalBlobStorage__ConnectionString Connection string for internal ABS Yes (if using ABS) None Yes
InternalBlobStorage__BlobContainerName Blob container name for internal ABS Yes (if using ABS) None No
InternalBlobStorage__BlobRoot Blob root (name prefix) for internal ABS No None No
ExternalBlobStorage__ConnectionString Connection string for external ABS No None Yes
ExternalBlobStorage__BlobContainerName Blob container name for external ABS Yes (if using ABS) None No
ExternalBlobStorage__BlobRoot Blob root (name prefix) for external ABS Yes (if using ABS) None No

Kafka

Name Description Required Default Value Secret?
KafkaConnection__BootstrapServers__0 Kafka broker address Yes None No
KafkaConnection__GroupId Consumer group identifier Yes None No
KafkaConnection__ClientId Unique client identifier Yes None No
KafkaConnection__SaslProtocolEnabled Whether to enable SASL auth No false No
KafkaConnection__Mechanism SASL mechanism No Plain No
KafkaConnection__Protocol SASL protocol No SaslPlaintext No

Note: Mechanism and Protocol are only used when SASL authentication is enabled.

Options for Mechanism:

  • Plain
  • Gssapi
  • ScramSHA256
  • ScramSHA512
  • OAuthBearer

Options for Protocol:

  • SaslPlaintext
  • Plaintext
  • Ssl
  • SaslSsl

SASL Plain Text Authentication

Include the following configuration properties to connecto to Kafka that requires SASL_PLAINTEXT authentication:

Name Value Secret?
KafkaConnection__SaslProtocolEnabled true No
KafkaConnection__SaslUsername <username> No
KafkaConnection__SaslPassword <password> Yes

Kafka Consumer Settings

Name Description Secret?
ConsumerSettings__ConsumerRetryDuration A list of strings representing retry duration intervals for consumers No
ConsumerSettings__DisableRetryConsumer A boolean flag to enable/disable the retry mechanism for consumers No
ConsumerSettings__DisableConsumer A boolean flag to completely enable/disable the consumer No

CORS

Property Description Required Default Secret?
CORS__AllowAllOrigins Allow all origins No false No
CORS__AllowedOrigins Array of allowed origins No [] No
CORS__AllowAllMethods Allow all HTTP methods No true No
CORS__AllowedMethods Array of allowed HTTP methods No ["GET", "POST", "PUT", "DELETE", "OPTIONS"] No
CORS__AllowAllHeaders Allow all headers No true No
CORS__MaxAge Preflight cache duration (seconds) No 600 No

Token Service Settings

TODO: Describe what the purpose of the token endpoint is

Property Type Description Default Value Secret?
LinkTokenService__EnableTokenGenerationEndpoint bool Controls whether the token generation endpoint is enabled false No
LinkTokenService__Authority string The authority URL used for token validation/generation Required (no default) No
LinkTokenService__LinkAdminEmail string? Email address for Link administration null No
LinkTokenService__TokenLifespan int The lifespan of generated tokens in minutes 10 No
LinkTokenService__SigningKey string? The key used for signing tokens null Yes
LinkTokenService__LogToken bool Controls whether token logging is enabled false No

Service Authentication

Property Description Required Default Value Secret?
Authentication__EnableAnonymousAccess Enable anonymous access to the service No false No
Authentication__Schemas__LinkBearer__Authority Authority URL for Link Bearer authentication Yes None No
Authentication__Schemas__LinkBearer__ValidateToken Validate the token on each request No true No
DataProtection__Enabled Enable data protection for sensitive data No false No

Redis

Name Description Required Secret?
ConnectionStrings__Redis Redis connection string Yes (if caching enabled) Yes
Redis__Password Redis Password Yes (if caching enabled) Yes
Cache__Enabled Toggle for Redis caching No No

Telemetry

Name Description Required Secret?
Telemetry__EnableTelemetry Enable Telemetry Yes (bool) No
Telemetry__EnableTracing Enable tracing Yes (bool) No
Telemetry__EnableOtelCollector Enable Otel collector Yes (bool) No
Telemetry__OtelCollectorEndpoint Otel collector endpoint Yes (uri) No

Service Registry

The Service Registry section contains URLs and configurations for all microservices in the Link Cloud ecosystem. Configuration key: ServiceRegistry

Not all services use every URL. The configuration is provided for completeness and future-proofing. If using Azure App Configuration, all service URLs should be specified, and each service will use only the URLs it needs.

Service URLs

Property Required Description
ServiceRegistry__AccountServiceUrl Yes Base URL for the Account service
ServiceRegistry__PublicAccountServiceUrl No Public base URL for the Account service
ServiceRegistry__AuditServiceUrl Yes Base URL for the Audit service
ServiceRegistry__PublicAuditServiceUrl No Public base URL for the Audit service
ServiceRegistry__CensusServiceUrl Yes Base URL for the Census service
ServiceRegistry__PublicCensusServiceUrl No Public base URL for the Census service
ServiceRegistry__DataAcquisitionServiceUrl Yes Base URL for the Data Acquisition service
ServiceRegistry__PublicDataAcquisitionServiceUrl No Public base URL for the Data Acquisition service
ServiceRegistry__MeasureServiceUrl Yes Base URL for the Measure service
ServiceRegistry__PublicMeasureServiceUrl No Public base URL for the Measure service
ServiceRegistry__NormalizationServiceUrl Yes Base URL for the Normalization service
ServiceRegistry__PublicNormalizationServiceUrl No Public base URL for the Normalization service
ServiceRegistry__NotificationServiceUrl Yes Base URL for the Notification service
ServiceRegistry__PublicNotificationServiceUrl No Public base URL for the Notification service
ServiceRegistry__QueryDispatchServiceUrl Yes Base URL for the Query Dispatch service
ServiceRegistry__PublicQueryDispatchServiceUrl No Public base URL for the Query Dispatch service
ServiceRegistry__ReportServiceUrl Yes Base URL for the Report service
ServiceRegistry__PublicReportServiceUrl No Public base URL for the Report service
ServiceRegistry__SubmissionServiceUrl Yes Base URL for the Submission service
ServiceRegistry__PublicSubmissionServiceUrl No Public base URL for the Submission service
ServiceRegistry__ValidationServiceUrl Yes Base URL for the Validation service
ServiceRegistry__PublicValidationServiceUrl No Public base URL for the Validation service
ServiceRegistry__TerminologyServiceUrl Yes Base URL for the Terminology service
ServiceRegistry__PublicTerminologyServiceUrl No Public base URL for the Terminology service
ServiceRegistry__TenantService__TenantServiceUrl Yes Base URL for the Tenant service
ServiceRegistry__TenantService__PublicTenantServiceUrl No Public base URL for the Tenant service
ServiceRegistry__TenantService__CheckIfTenantExists No Whether to validate tenant's existence in other services such as Data Acquisition
ServiceRegistry__TenantService__GetTenantRelativeEndpoint No Relative endpoint path for tenant retrieval in other services such as Data Acquisition; excluding "/api"

Example Configuration in JSON

{
  "ServiceRegistry": {
    "AccountServiceUrl": "http://localhost:8060",
    "AuditServiceUrl": "http://localhost:8062",
    "CensusServiceUrl": "http://localhost:8064",
    "DataAcquisitionServiceUrl": "http://localhost:8065",
    "MeasureServiceUrl": "http://localhost:8067",
    "NormalizationServiceUrl": "http://localhost:8068",
    "NotificationServiceUrl": "http://localhost:7434",
    "QueryDispatchServiceUrl": "http://localhost:8071",
    "ReportServiceUrl": "http://localhost:8072",
    "SubmissionServiceUrl": "http://localhost:8073",
    "TenantService": {
      "TenantServiceUrl": "http://localhost:8074",
      "CheckIfTenantExists": true,
      "GetTenantRelativeEndpoint": "facility/"
    },
    "ValidationServiceUrl": "http://localhost:8075",
    "TerminologyServiceUrl": "http://localhost:8076"
  }
}

Tenant Service Configuration

Property Description Required Default
TenantService__TenantServiceUrl Base URL for the Tenant service Yes None
TenantService__CheckIfTenantExists Whether to validate tenant existence No true
TenantService__GetTenantRelativeEndpoint Relative endpoint path for tenant retrieval No "facility/"
FacilityIdSettings__NumericOnlyFacilityId Enforce NHSN ORG ID format (5 digits) No PRD ONLY false

Data Acquisition Service Configuration

The following settings are specific to the Data Acquisition service.

Property Description Required Default Value Secret?
AcquisitionJobSettings__CronSchedule Cron schedule for the data acquisition background job (e.g., "0/10 * * * * ?" for every 10s) No "0/10 * * * * ?" No

Databases

SQL Server Database

Name Description Required Default Value Secret?
DatabaseProvider Database provider to use No SqlServer No
ConnectionStrings__DatabaseConnection MSSQL connection string Yes None Yes
AutoMigrate Automatically migrate the database schema No false No

Mongo Database

Name Description Required Default Value Secret?
MongoDB__ConnectionString MongoDB connection string Yes None Yes
MongoDB__DatabaseName MongoDB database name Yes None No \

Service Information

The ServiceInformation configuration allows exposing build, version and deployment information through the /api/XXX/info (i.e. /api/audit/info) endpoint of each service. This information is automatically populated from assembly metadata and git information during build time.

Property Description Required Default Value Secret?
ServiceInformation__ServiceName Display name of the service No Varies service by service No
ServiceInformation__Version Version of the service No Assembly ver. No
ServiceInformation__ProductVersion Version of the product as a whole No N/A No
ServiceInformation__Build Build number from CI/CD pipeline No "dev" when using Docker Compose No
ServiceInformation__Commit Git commit hash of deployed version No None No

The service automatically extracts information from .NET assembly version in the AssemblyInfo.cs file or project file

EF Core Query Logging

Configure EF Core to log queries, including sensitive data, by setting up the appsettings.json file and adjusting the Program.cs file. This allows dynamic adjustment of logging levels in Serilog based on the EnableEnhancedQueryLogging setting.

Configuration in appsettings.json

Add the following section to enable enhanced query logging:

"EnhancedQueryLoggingSettings": {
  "EnableEnhancedQueryLogging": false
}
Property Description Required Default Value Secret?
EnhancedQueryLoggingSettings__EnableEnhancedQueryLogging Flag to enable detailed EF Core query logging (Information level) No false No

Configuration in Program.cs

In Program.cs, configure Serilog to dynamically set log levels for EF Core namespaces and enable EF Core logging in the DbContext setup.

For Serilog configuration (e.g., in a ConfigureLogging method):

// Bind the enhanced logging settings
var enhancedLoggingSettings = builder.Configuration.GetRequiredSection(nameof(EnhancedQueryLoggingSettings)).Get<EnhancedQueryLoggingSettings>();

// Create Serilog logger configuration
var loggerConfig = new LoggerConfiguration()
    .ReadFrom.Configuration(builder.Configuration)
    // ... other enrichers and filters ...

// Conditionally override EF Core log levels
var efCoreLogLevel = enhancedLoggingSettings != null && enhancedLoggingSettings.EnableEnhancedQueryLogging
    ? LogEventLevel.Information
    : LogEventLevel.Warning;

loggerConfig
    .MinimumLevel.Override("Microsoft.EntityFrameworkCore", efCoreLogLevel)
    .MinimumLevel.Override("Microsoft.EntityFrameworkCore.Database.Command", efCoreLogLevel);

Log.Logger = loggerConfig.CreateLogger();
builder.Logging.AddSerilog();

For DbContext registration (e.g., when using MongoDB provider for EF Core):

builder.Services.AddDbContext<MongoDbContext>((sp, options) =>
{
    var querySettings = builder.Configuration.GetRequiredSection(nameof(EnhancedQueryLoggingSettings)).Get<EnhancedQueryLoggingSettings>();

    // ... client and settings setup ...

    if (querySettings != null && querySettings.EnableEnhancedQueryLogging)
    {
        var loggerFactory = sp.GetRequiredService<ILoggerFactory>();
        options.UseMongoDB(client, mongoSettings.DatabaseName)
            .UseLoggerFactory(loggerFactory)
            .EnableSensitiveDataLogging();
    }
    else
    {
        options.UseMongoDB(client, mongoSettings.DatabaseName);
    }
});

Relationships

flowchart LR
ndotnet_704D25B0["Design: Configuring .NET Services"]