{"id":22508244,"url":"https://github.com/Altinn/dialogporten","last_synced_at":"2025-08-03T13:30:54.680Z","repository":{"id":65907179,"uuid":"595805446","full_name":"digdir/dialogporten","owner":"digdir","description":"Dialogporten - common API and and metadata state store for digital dialogs","archived":false,"fork":false,"pushed_at":"2024-10-29T09:43:23.000Z","size":5387,"stargazers_count":1,"open_issues_count":87,"forks_count":3,"subscribers_count":6,"default_branch":"main","last_synced_at":"2024-10-29T10:59:45.849Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://docs.altinn.studio/dialogporten","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/digdir.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-01-31T21:03:08.000Z","updated_at":"2024-10-29T09:27:01.000Z","dependencies_parsed_at":"2023-12-24T01:20:56.373Z","dependency_job_id":"35c5c7e1-be23-4c4f-88d3-5409c7b2fb15","html_url":"https://github.com/digdir/dialogporten","commit_stats":null,"previous_names":[],"tags_count":59,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digdir%2Fdialogporten","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digdir%2Fdialogporten/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digdir%2Fdialogporten/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digdir%2Fdialogporten/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/digdir","download_url":"https://codeload.github.com/digdir/dialogporten/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228545147,"owners_count":17934700,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-07T01:18:58.148Z","updated_at":"2025-08-03T13:30:54.642Z","avatar_url":"https://github.com/digdir.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Dialogporten\n\n## Getting started with local development\n\n### Mac \n\n#### Prerequisites\n\n- [.NET 9 SDK](https://dotnet.microsoft.com/en-us/download/dotnet/9.0) (see [global.json](global.json) for the currently required version)\n\n#### Installing Podman (Mac)\n\n1. Install [Podman](https://podman.io/)\n\n2. Install dependencies:\n```bash\nbrew tap cfergeau/crc\n# https://github.com/containers/podman/issues/21064\nbrew install vfkit\nbrew install docker-compose\n```\n\n3. Restart your Mac\n\n4. Finish setup in Podman Desktop\n\n5. Check that `Docker Compatibility mode` is enabled, see the bottom left corner\n\n6. Enable privileged [testcontainers-dotnet](https://github.com/testcontainers/testcontainers-dotnet/issues/876#issuecomment-1930397928)  \n`echo \"ryuk.container.privileged = true\" \u003e\u003e $HOME/.testcontainers.properties`\n\n### Windows \n\n#### Prerequisites\n\n- [Git](https://git-scm.com/download/win)\n- [.NET 9 SDK](https://dotnet.microsoft.com/en-us/download/dotnet/9.0)\n- [WSL2](https://docs.microsoft.com/en-us/windows/wsl/install) (To install, open a PowerShell admin window and run `wsl --install`)\n- [Virtual Machine Platform](https://support.microsoft.com/en-us/windows/enable-virtualization-on-windows-11-pcs-c5578302-6e43-4b4b-a449-8ced115f58e1) (Installs with WSL2, see the link above)\n\n#### Installing Podman (Windows)\n\n1. Install [Podman Desktop](https://podman.io/getting-started/installation).\n \n2. Start Podman Desktop and follow instructions to install Podman.\n\n3. Follow instructions in Podman Desktop to create and start a Podman machine.\n\n4. In Podman Desktop, go to Settings → Resources and run setup for the Compose Extension. This will install docker-compose.\n\n### Running the project\n\nYou can run the entire project locally using `podman compose`. (This uses docker-compose behind the scenes.)\n```powershell\npodman compose up\n```\n\nThe following GUI services should now be available:\n* WebAPI/SwaggerUI: [localhost:7124/swagger](https://localhost:7214/swagger/index.html)\n* GraphQl/BananaCakePop: [localhost:7215/graphql](https://localhost:7214/swagger/index.html)\n* Redis/Insight: [localhost:7216](https://localhost:7214/swagger/index.html)\n\nThe WebAPI and GraphQl services are behind a nginx proxy, and you can change the number of replicas by setting the `scale` property in the `docker-compose.yml` file.\n\n\n### Running the WebApi/GraphQl in an IDE\nIf you need do debug the WebApi/GraphQl projects in an IDE, you can alternatively run `podman compose` without the WebAPI/GraphQl.  \nFirst, create a dotnet user secret for the DB connection string.\n\n```powershell\ndotnet user-secrets set -p \"./src/Digdir.Domain.Dialogporten.WebApi\" \"Infrastructure:DialogDbConnectionString\" \"Server=localhost;Port=5432;Database=dialogporten;User ID=postgres;Password=supersecret;Include Error Detail=True;\"\n```\n\nThen run `podman compose` without the WebAPI/GraphQl projects.\n```powershell\npodman compose -f docker-compose-no-webapi.yml up \n```\n\n## DB development\nThis project uses Entity Framework core to manage DB migrations. DB development can either be done through Visual Studios Package Manager Console (PMC) or through the CLI. \n\n### DB development through PMC\nSet Digdir.Domain.Dialogporten.Infrastructure as the startup project in Visual Studio's solution explorer, and as the default project in PMC. You are now ready to use [EF core tools through PMC](https://learn.microsoft.com/en-us/ef/core/cli/powershell). \nRun the following command for more information:\n```powershell\nGet-Help about_EntityFrameworkCore\n```\n\n### DB development through CLI\nInstall the CLI tool with the following command:\n```powershell\ndotnet tool install --global dotnet-ef\n```\n\nYou are now ready to use [EF core tools through CLI](https://learn.microsoft.com/en-us/ef/core/cli/dotnet). Run the following command for more information:\n```powershell\ndotnet ef --help\n```\n\nRemember to target `Digdir.Domain.Dialogporten.Infrastructure` project when running the CLI commands. Either target it through the command using the `-p` option, i.e.\n```powershell\ndotnet ef migrations add -p .\\src\\Digdir.Domain.Dialogporten.Infrastructure\\ TestMigration\n```\n\nOr change your directory to the infrastructure project and then run the command.\n```powershell\ncd .\\src\\Digdir.Domain.Dialogporten.Infrastructure\\\ndotnet ef migrations add TestMigration\n```\n\n### Restoring a database from an Azure backup\nSee [docs/RestoreDatabase.md](docs/RestoreDatabase.md)\n\n## Testing\n\nBesides ordinary unit and integration tests, there are test suites for both functional and non-functional end-to-end tests implemented with [K6](https://k6.io/).\n\nSee [tests/k6/README.md](tests/k6/README.md) for more information.\n\n## Health Checks\n\nThe project includes integrated health checks that are exposed through standard endpoints:\n- `/health/startup` - Dependency checks\n- `/health/liveness` - Self checks\n- `/health/readiness` - Critical service checks\n- `/health` - General health status\n- `/health/deep` - Comprehensive health check including external services\n\nThese health checks are integrated with Azure Container Apps' health probe system and are used to monitor the application's health status.\n\n## Observability with OpenTelemetry\n\nThis project uses OpenTelemetry for distributed tracing, metrics collection, and logging. The setup includes:\n\n### Core Features\n- Distributed tracing across services\n- Runtime and application metrics\n- Log aggregation and correlation\n- Integration with Azure Monitor/Application Insights\n- Support for both OTLP and Azure Monitor exporters\n- Automatic instrumentation for:\n  - ASP.NET Core\n  - HTTP clients\n  - Entity Framework Core\n  - PostgreSQL\n  - FusionCache\n\n### Configuration\n\nOpenTelemetry is configured through environment variables that are automatically provided by Azure Container Apps in production environments:\n\n```json\n{\n    \"OTEL_SERVICE_NAME\": \"your-service-name\",\n    \"OTEL_EXPORTER_OTLP_ENDPOINT\": \"http://your-collector:4317\",\n    \"OTEL_EXPORTER_OTLP_PROTOCOL\": \"grpc\",\n    \"OTEL_RESOURCE_ATTRIBUTES\": \"key1=value1,key2=value2\",\n    \"APPLICATIONINSIGHTS_CONNECTION_STRING\": \"your-connection-string\"\n}\n```\n\n### Local Development\n\nFor local development, the project includes a docker-compose setup with:\n- OpenTelemetry Collector (ports 4317/4318 for OTLP receivers)\n- Grafana (port 3000)\n- Jaeger (port 16686)\n- Loki (port 3100)\n- Prometheus (port 9090)\n\nTo run the local observability stack:\n```bash\npodman compose -f docker-compose-otel.yml up\n```\n\n### Accessing Observability Tools\n\nOnce the local stack is running, you can access the following tools:\n\n#### Distributed Tracing with Jaeger\n- URL: http://localhost:16686\n- Features:\n  - View distributed traces across services\n  - Search by service, operation, or trace ID\n  - Analyze timing and dependencies\n  - Debug request flows and errors\n\n#### Metrics with Prometheus\n- URL: http://localhost:9090\n- Features:\n  - Query raw metrics data\n  - View metric targets and service discovery\n  - Debug metric collection\n\n#### Log Aggregation with Loki\n- Direct URL: http://localhost:3100\n- Grafana Integration: http://localhost:3000 (preferred interface)\n- Features:\n  - Search and filter logs across all services\n  - Correlate logs with traces using trace IDs\n  - Create log-based alerts and dashboards\n  - Use LogQL to query logs:\n    ```logql\n    # Example: Find all error logs\n    {container=\"web-api\"} |= \"error\"\n    \n    # Example: Find logs with specific trace ID\n    {container=~\"web-api|graphql\"} |~ \"trace_id=([a-f0-9]{32})\"\n    ```\n\n#### Metrics and Dashboards in Grafana\n- URL: http://localhost:3000\n- Features:\n  - Pre-configured dashboards for:\n    - Application metrics\n    - Runtime metrics\n    - HTTP request metrics\n  - Data sources:\n    - Prometheus (metrics)\n    - Loki (logs)\n    - Jaeger (traces)\n  - Create custom dashboards\n  - Set up alerts\n\n#### OpenTelemetry Collector Endpoints\n- OTLP gRPC receiver: localhost:4317\n- OTLP HTTP receiver: localhost:4318\n- Prometheus metrics: localhost:8888\n- Prometheus exporter metrics: localhost:8889\n\n### Request Filtering\n\nThe telemetry setup includes smart filtering to:\n- Exclude health check endpoints from tracing\n- Filter out duplicate traces from Azure SDK clients\n- Only record relevant HTTP client calls\n\nFor more details about the OpenTelemetry setup, see the `ConfigureTelemetry` method in `AspNetUtilitiesExtensions.cs`.\n\n## Updating the SDK in global.json\nWhen RenovateBot updates `global.json` or base image versions in Dockerfiles, make sure they match. \nThe `global.json` file should always have the same SDK version as the base image in the Dockerfiles. \nThis is to ensure that the SDK version used in the local development environment matches the SDK version used in the CI/CD pipeline. \n`global.json` is used when building the solution in CI/CD.\n\n## Development in local and test environments\nTo generate test tokens, see https://github.com/Altinn/AltinnTestTools. There is a request in the Postman collection for this.\n\n### Local development settings\nWe are able to toggle some external resources in local development. This is done through the `appsettings.Development.json` file. The following settings are available:\n```json\n\"LocalDevelopment\": {\n    \"UseLocalDevelopmentUser\": true,\n    \"UseLocalDevelopmentResourceRegister\": true,\n    \"UseLocalDevelopmentOrganizationRegister\": true,\n    \"UseLocalDevelopmentNameRegister\": true,\n    \"UseLocalDevelopmentAltinnAuthorization\": true,\n    \"UseLocalDevelopmentCloudEventBus\": true,\n    \"UseLocalDevelopmentCompactJwsGenerator\": true,\n    \"DisableCache\": true,\n    \"DisableAuth\": true,\n    \"UseInMemoryServiceBusTransport\": true,\n    \"DisableSubjectResourceSyncOnStartup\": false,\n    \"DisablePolicyInformationSyncOnStartup\": true\n}\n```\nToggling these flags will enable/disable the external resources. The `DisableAuth` flag, for example, will disable authentication in the WebAPI project. This is useful when debugging the WebAPI project in an IDE. These settings will only be respected in the `Development` environment.\n\n### Using `appsettings.local.json`\n\nDuring local development, it is natural to tweak configurations. Some of these configurations are _meant_ to be shared through git, such as the endpoint for a new integration that may be used during local development. Other configurations are only meant for a specific debug session or a developer's personal preferences, which _should not be shared_ through git, such as lowering the log level below warning.\n\nThe configuration in the `appsettings.local.json` file takes precedence over **all** other configurations and is only loaded in the **Development environment**. Additionally, it is ignored by git through the `.gitignore` file.\n\nIf developers need to add configuration that should be shared, they should use `appsettings.Development.json`. If the configuration is not meant to be shared, they can create an `appsettings.local.json` file to override the desired settings.\n\nHere is an example of enabling debug logging only locally:\n```json5\n// appsettings.local.json\n{\n    \"Serilog\": {\n        \"WriteTo\": [\n            {\n                \"Name\": \"Console\",\n                \"Args\": {\n                    \"outputTemplate\": \"[{Timestamp:HH:mm:ss.fff} {Level:u3}] {Message:lj}{NewLine}{Exception}\"\n                }\n            }\n        ],\n        \"MinimumLevel\": {\n            \"Default\": \"Debug\"\n        }\n    }\n}\n```\n\n#### Adding `appsettings.local.json` to new projects\nAdd the following to the `Program.cs` file to load the `appsettings.local.json` file:\n```csharp\nvar builder = WebApplication.CreateBuilder(args);\n// or var builder = CoconaApp.CreateBuilder(args);\n// or var builder = Host.CreateApplicationBuilder(args);\n// or some other builder implementing IHostApplicationBuilder\n\n// Left out for brevity\nbuilder.Configuration\n    // Add local configuration as the last configuration source to override other configurations\n    //.AddSomeOtherConfiguration()\n    .AddLocalConfiguration(builder.Environment);\n\n// Left out for brevity\n```\n\n## Pull requests\nFor pull requests, the title must follow [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/).\nThe title of the PR will be used as the commit message when squashing/merging the pull request, and the body of the PR will be used as the description.\n\nThis title will be used to generate the changelog (using [Release Please](https://github.com/googleapis/release-please-action))\nUsing `fix` will add to \"Bug Fixes\", `feat` will add to \"Features\", `chore` will add to \"Miscellaneous Chores\". All the others, `test`, `ci`, `trivial` etc., will be ignored. ([Example release](https://github.com/altinn/dialogporten/releases/tag/v1.12.0))\n\n## Deployment\n\nThis repository contains code for both infrastructure and applications. Configurations for infrastructure are located in `.azure/infrastructure`. Application configuration is in `.azure/applications`. \n\n### Deployment process / GitHub actions\n\nSee [docs/CI-CD.md](docs/CI-CD.md)\n\n### Infrastructure\n\nInfrastructure definitions for the project are located in the `.azure/infrastructure` folder. To add new infrastructure components, follow the existing pattern found within this directory. This involves creating new Bicep files or modifying existing ones to define the necessary infrastructure resources.\n\nFor example, to add a new storage account, you would:\n- Create or update a Bicep file within the `.azure/infrastructure` folder to include the storage account resource definition.\n- Ensure that the Bicep file is referenced correctly in `.azure/infrastructure/infrastructure.bicep` to be included in the deployment process.\n\nRefer to [docs/Infrastructure.md](docs/Infrastructure.md) for more detailed information.\n\n### Applications\n\nAll application Bicep definitions are located in the `.azure/applications` folder. To add a new application, follow the existing pattern found within this directory. This involves creating a new folder for your application under `.azure/applications` and adding the necessary Bicep files (`main.bicep` and environment-specific parameter files, e.g., `test.bicepparam`, `staging.bicepparam`).\n\nFor example, to add a new application named `web-api-new`, you would:\n- Create a new folder: `.azure/applications/web-api-new`\n- Add a `main.bicep` file within this folder to define the application's infrastructure.\n- Use the appropriate `Bicep`-modules within this file. There is one for `Container apps` which you most likely would use.\n- Add parameter files for each environment (e.g., `test.bicepparam`, `staging.bicepparam`) to specify environment-specific values.\n\nRefer to the existing applications like `web-api-so` and `web-api-eu` as templates.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAltinn%2Fdialogporten","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FAltinn%2Fdialogporten","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAltinn%2Fdialogporten/lists"}