Skip to content

feat(floci): model Service Bus as a child resource of AddFlociAzure - #1555

Draft
thomhurst wants to merge 2 commits into
CommunityToolkit:mainfrom
thomhurst:floci-servicebus-reference
Draft

feat(floci): model Service Bus as a child resource of AddFlociAzure#1555
thomhurst wants to merge 2 commits into
CommunityToolkit:mainfrom
thomhurst:floci-servicebus-reference

Conversation

@thomhurst

Copy link
Copy Markdown
Contributor

Fixes #1552

Draft — blocked on a floci-az release. The emulator half (eager namespace start, START_ON_BOOT) is floci-io/floci-az#249, implemented in floci-io/floci-az#250 but not yet in a tagged floci-az release; the .NET Service Bus data-plane fixes (batched sends, admin-client routing) are merged upstream on main and also awaiting a release. Ready for review on shape; should merge only alongside a floci-az tag bump that carries them.

What

WithServiceBus() models the floci-az Service Bus AMQP data plane as a child resource of AddFlociAzure, mirroring the WithCosmos() shape from #1546:

var azure = builder.AddFlociAzure("floci-az")
    .WithDockerSocket();                    // the Artemis sidecar is a sibling container
var serviceBus = azure.WithServiceBus();    // enables the data plane, pins free host ports

builder.AddProject<MyApi>("api")
    .WithReference(serviceBus)              // ConnectionStrings__servicebus
    .WaitFor(azure);

App side is the standard flow: builder.AddAzureServiceBusClient("servicebus").

Why the shape is different from Blob/Cosmos

floci-az serves Service Bus AMQP from an Artemis sidecar container it starts itself via Docker — not from the modeled container's :4577 endpoint — so there is no EndpointReference to build a connection string from (the floci-io/floci-az#249 analysis). What is controllable is the sidecar's published host ports (FLOCI_AZ_SERVICES_SERVICE_BUS_AMQP_PORT/_AMQP_TLS_PORT) and, with floci-io/floci-az#250, that the namespace is listening at boot (START_ON_BOOT=true). So WithServiceBus:

  • enables the data plane (FLOCI_AZ_SERVICES_SERVICE_BUS_MOCKED=false — the image default is mocked) and eager start,
  • allocates free host ports by default (held-open double-listener allocation so the two ports are distinct), so concurrent AppHosts don't collide; explicit amqpPort/amqpTlsPort are honored,
  • returns a FlociAzureServiceBusResource (IResourceWithConnectionString) whose connection string is the official emulator's shape: Endpoint=sb://localhost:{amqpPort};SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=SAS_KEY_VALUE;UseDevelopmentEmulator=true;.

One child per emulator (the ports configure the parent's environment): a second WithServiceBus() returns the existing child; conflicting ports throw.

Known limitations, called out in the docs: the endpoint is host-relative (localhost) since the sidecar publishes outside Aspire's endpoint model — sibling-container consumers would need the Docker-network address; and ServiceBusAdministrationClient stays on the base emulator endpoint (WithReference(azure)), as the two planes live on different ports.

Tests

AzureServiceBusResourceTests — 7 tests: child creation + parent relationship, random distinct ports, explicit ports, parent env enablement, connection-string shape, idempotent second call + port-conflict throw, WithReference injection on a consumer. All green locally; TypeScriptAppHostTests.TypeScriptAppHostCompilesAndStarts fails identically on an unmodified checkout here (local Aspire CLI 13.5.2 vs SDK 13.5.0), so deferring to CI for that one.

API surface regenerated (-t:GenAPIGenerateReferenceAssemblySource), README updated with C# + TypeScript examples.

https://claude.ai/code/session_01K8waTF6dPtQNUmXz3i8xnG

WithServiceBus() adds a FlociAzureServiceBusResource child that enables the
floci-az Service Bus data plane (MOCKED=false, START_ON_BOOT=true) and pins
the host ports its Artemis sidecar publishes — free ports by default so
concurrent AppHosts don't collide. Referencing the child with Aspire's
standard WithReference injects the official emulator's connection-string
shape (Endpoint=sb://localhost:{port};...;UseDevelopmentEmulator=true;) so
AddAzureServiceBusClient works unchanged.

The sidecar publishes directly on the Docker host, outside Aspire's endpoint
model, so the endpoint is host-relative; the management plane stays on the
base endpoint from WithReference(azure).

Blocked on a floci-az release with start-on-boot support
(floci-io/floci-az#249, PR floci-io/floci-az#250).

Fixes CommunityToolkit#1552

Claude-Session: https://claude.ai/code/session_01K8waTF6dPtQNUmXz3i8xnG
Comment thread src/CommunityToolkit.Aspire.Hosting.Floci/FlociHostingExtension.Azure.cs Outdated
@aaronpowell

Copy link
Copy Markdown
Member

@thomhurst - are you interested in being added as a contributor and being given the CODEOWNER for the floci integration?

Model sidecar ports as proxyless endpoints so DCP allocates them before the Floci container environment resolves.
@thomhurst

Copy link
Copy Markdown
Contributor Author

Happy to be added as a contributor but not sure I'll have time to be a code owner and review all the changes if it gets busy

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.

[Feature]: CommunityToolkit.Aspire.Hosting.Floci — Service Bus connection string helper for AddFlociAzure

2 participants