Skip to content

Add technology-based infrastructure connection strings - #2273

Draft
niemyjski with Copilot wants to merge 13 commits into
mainfrom
copilot/how-to-use-rabbitmq-as-messagebus
Draft

Add technology-based infrastructure connection strings#2273
niemyjski with Copilot wants to merge 13 commits into
mainfrom
copilot/how-to-use-rabbitmq-as-messagebus

Conversation

Copilot AI commented May 31, 2026

Copy link
Copy Markdown
Contributor

Closes #1526

Summary

Infrastructure configuration is now technology-based: declare Redis, RabbitMQ, AzureQueues, SQS, AzureStorage, S3, Aliyun, or Folder once and Exceptionless selects only compatible roles.

Role Automatic priority
Cache Redis, then local
MessageBus RabbitMQ, then Redis, then local
Queue AzureQueues, then SQS, then Redis, then local
Storage AzureStorage, then S3, then Aliyun, then Folder, then local

Existing Cache, MessageBus, Queue, and Storage selectors remain supported as compatibility overrides. New installations can use technology-only connection strings; existing self-hosted deployments do not need to change.

What changed

  • Added one capability-aware resolver with an explicit provider allowlist, aliases, native formats, and fixed priorities.
  • Preserved raw amqp:// and amqps:// RabbitMQ URIs, including encoded credentials, virtual hosts, query options, quotes, named values, inline values, and legacy server= selectors.
  • Treats native Redis and AMQP strings as atomic values. Valid option-first StackExchange.Redis strings are preserved; malformed Redis strings fail during startup registration without exposing their contents.
  • Added local as an explicit in-memory role override; blank legacy role values remain absent.
  • Made EX_ variables deterministically override ordinary/Aspire variables with the same normalized key.
  • Added an exact-string Redis connection registry that deduplicates equal endpoints, isolates different role endpoints, owns disposal, preserves the cache IConnectionMultiplexer registration, and keeps WebSocket mapping on the cache connection.
  • Enabled Redis telemetry whenever Cache, MessageBus, or Queue uses Redis.
  • Kept Elasticsearch, email, derived locks, and Metrics outside the resolver.

Aspire and deployment compatibility

The AppHost references remain Redis, AzureStorage, and AzureQueues for both API and Jobs. Aspire injects ConnectionStrings__{resource-name}, so those existing names match the resolver without role selectors.

The current Helm chart intentionally remains in legacy-selector mode. Its explicit role values continue to win, including folder Storage and existing PVC behavior. A rolling version-only upgrade is mixed-version compatible when every rendered role selector and exact effective connection string remains unchanged.

This PR also prevents bundled Redis and Elasticsearch pods from restarting merely because the app ConfigMap or chart package version changed: their pod templates no longer include the unrelated app-config checksum or version-bearing chart label. Application and job workloads retain their config checksums.

Removing a selector is safe only when the inferred provider and exact effective connection string are identical before and after removal. A real MessageBus, Queue, Storage, Cache, or endpoint change is a separate infrastructure migration and is not a zero-downtime rolling cleanup; use a bridge/dual-read-write strategy or a quiesce-and-drain maintenance procedure.

With the current chart, configure RabbitMQ through the compatibility value:

messagebus:
  connectionString: 'provider=rabbitmq;server="amqps://user:password@rabbitmq:5671/%2F"'

A named RabbitMQ string alone is intentionally shadowed by the chart's explicit MessageBus selector.

Documentation

Added a canonical self-hosting guide and four rendered diagrams covering:

  • configuration-source precedence and EX_ overrides
  • technology-to-role priorities
  • Redis connection ownership and isolation
  • safe version-only Helm rollout versus provider migration
  • Redis-only, Redis plus RabbitMQ, durable storage, Folder, and local
  • Aspire resource naming, Helm legacy-selector mode, rollback order, and replicated-role warnings

The Docker, Kubernetes, self-hosting index, and upgrade guides link to the canonical configuration contract.

Verification

Exact local head: 30c62e6db.

  • dotnet test Exceptionless.slnx --configuration Release --no-build --no-restore: 2,759 total; 2,757 passed; 2 intentional performance-test skips; 0 failed.
  • dotnet build Exceptionless.slnx --configuration Release --no-restore: 0 warnings, 0 errors.
  • Focused provider, RabbitMQ, Redis registry, Bootstrapper, environment-precedence, and sensitive-logging tests passed.
  • Scoped dotnet format --verify-no-changes: passed.
  • Documentation site build, 4 tests, telemetry verification, and local link/anchor/asset checks: passed.
  • All four SVG diagrams passed XML validation and visual inspection.
  • git diff --check: passed.
  • Exact-head GitHub Actions: Website and Build succeeded. Build includes API coverage, client checks, Docker image builds, AppHost/Aspire resource and endpoint verification, and Playwright E2E.

No Helm, Kubernetes, Docker, Aspire, container, deployment-script, or deployment command was run locally. Helm safety was audited statically.

Copilot AI linked an issue May 31, 2026 that may be closed by this pull request
@CLAassistant

CLAassistant commented May 31, 2026

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
1 out of 2 committers have signed the CLA.

✅ niemyjski
❌ Copilot
You have signed the CLA already but the status is still pending? Let us recheck it.

Co-authored-by: niemyjski <1020579+niemyjski@users.noreply.github.com>
Copilot AI changed the title [WIP] Add example usage of RabbitMQ as message bus Support RabbitMQ URI connection strings for MessageBus configuration Jun 1, 2026
Copilot AI requested a review from niemyjski June 1, 2026 00:01
@niemyjski

Copy link
Copy Markdown
Member

Follow-up reviewer and thermo-nuclear audit complete at 202f7c2185ef41449164f8dcab3fb6b08395b3c8.

Feedback inventory:

  • GitHub currently exposes 0 review threads, 0 inline review comments, and 0 submitted reviews from human, Codex, or Copilot reviewers. There are therefore no reviewer threads to reply to or resolve.
  • The coverage bot comment is current but informational; it reports 77% changed-line coverage and does not identify a defect.
  • The CLAassistant comment is current and externally blocked: the Copilot co-author has not signed the CLA. This is not addressable in repository code.

Validation and RCA:

  • The original failure comes from routing an AMQP URI through the generic key/value connection-string parser and builder, which interpret URI delimiters as configuration syntax and rebuild a different value.
  • The current fix isolates raw URI handling at the MessageBus configuration boundary only when the provider selector resolves to RabbitMQ. It preserves the exact inline or named amqp/amqps URI, normalizes the provider for existing case-sensitive registration, supplies the legacy Data["server"] view, and leaves Redis/key-value parsing unchanged.
  • Focused coverage proves inline and named URIs, quotes, whitespace and mixed-case selectors, encoded credentials/vhosts, URI query parameters, a trailing selector separator, and both legacy Redis forms.

Thermo-nuclear review:

  • Audited the complete 9-file origin/main...HEAD diff under the strict structural bar. No file approaches or crosses 1,000 lines; the RabbitMQ exception is contained in one configuration helper; no canonical helper is duplicated; no cross-layer type leak, non-atomic update, needless sequencing, or spaghetti branch growth remains. A broader refactor would add risk without deleting meaningful complexity.

Verification:

  • dotnet test tests/Exceptionless.Tests/Exceptionless.Tests.csproj --configuration Release -- --filter-class Exceptionless.Tests.Configuration.MessageBusOptionsTests — 9/9 passed.
  • dotnet format Exceptionless.slnx --no-restore --verify-no-changes --include src/Exceptionless.Core/Configuration/MessageBusOptions.cs tests/Exceptionless.Tests/Configuration/MessageBusOptionsTests.cs — passed.
  • dotnet build Exceptionless.slnx --no-restore --configuration Release — succeeded with 0 warnings and 0 errors.
  • git diff --check origin/main...HEAD — clean.
  • Live CI: version, test-api, test-client, test-e2e, and docker-build all pass. Expected publish/deploy/preview jobs are skipped.

No additional code change or push was needed in this follow-up. The only remaining merge blocker is administrative: the PR is still draft and license/cla remains pending for the Copilot co-author.

@niemyjski niemyjski changed the title Support RabbitMQ URI connection strings for MessageBus configuration Add technology-based infrastructure connection strings Aug 12, 2026
@niemyjski

Copy link
Copy Markdown
Member

Final live follow-up completed at head 980301b.

Feedback disposition:

  • 0 review threads, 0 inline comments, and 0 submitted reviews; nothing required a code change, reply, or resolution.
  • The coverage comment is informational and reports 78% overall coverage without identifying a defect.
  • The remaining license/cla pending status is external: the Copilot co-author has not signed the CLA.

Current verification:

  • Focused configuration tests: 54/54 passed.
  • Focused bootstrapper tests: 3/3 passed.
  • Release solution build: passed with 0 warnings and 0 errors.
  • Docs verify: site build, 4/4 tests, telemetry check, and local link/anchor/asset audit passed.
  • git diff --check origin/main...HEAD: clean.
  • Live CI: Build website, version, test-api, test-client, test-e2e, and docker-build pass; publish/deploy/preview jobs are expected skips.

No commit or push was made because the live feedback and effective-diff audit found no surgical change to apply. The PR remains draft and BLOCKED only by the pending CLA status.

@github-actions

Copy link
Copy Markdown

Code Coverage

Package Line Rate Branch Rate Complexity Health
Exceptionless.Insulation 47% 42% 316
Exceptionless.Core 75% 67% 10079
Exceptionless.Web 85% 69% 7024
Exceptionless.AppHost 38% 40% 139
Summary 78% (23742 / 30497) 67% (11132 / 16626) 17558

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

how to use rabbitmq as messagebus or queue?

3 participants