feat: CommunityToolkit.Aspire.Hosting.Floci — Floci cloud emulator hosing integration#1448
feat: CommunityToolkit.Aspire.Hosting.Floci — Floci cloud emulator hosing integration#1448edmondshtogu wants to merge 13 commits into
CommunityToolkit.Aspire.Hosting.Floci — Floci cloud emulator hosing integration#1448Conversation
…ting integration
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/CommunityToolkit/Aspire/main/eng/scripts/dogfood-pr.sh | bash -s -- 1448Or
iex "& { $(irm https://raw.githubusercontent.com/CommunityToolkit/Aspire/main/eng/scripts/dogfood-pr.ps1) } 1448" |
There was a problem hiding this comment.
Pull request overview
This PR introduces a new CommunityToolkit.Aspire.Hosting.Floci hosting integration that models the Floci AWS emulator as an Aspire container resource, plus accompanying examples (C# + TypeScript AppHost) and automated tests to validate resource wiring and startup.
Changes:
- Added
AddFloci+ related fluent configuration APIs (data persistence, Docker socket, config file, TLS wiring) and theFlociContainerResourcemodel. - Added an end-to-end example (
examples/floci) including a minimal API service usingAWSSDK.S3, plus a TypeScript AppHost for polyglot surface validation. - Added integration and model-level tests and registered the new projects in the solution and root README integration list.
Reviewed changes
Copilot reviewed 21 out of 22 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/CommunityToolkit.Aspire.Hosting.Floci.Tests/TypeScriptAppHostTests.cs | Adds an integration test ensuring the TypeScript AppHost compiles and starts required resources. |
| tests/CommunityToolkit.Aspire.Hosting.Floci.Tests/ContainerResourceCreationTests.cs | Adds unit tests validating resource construction, image metadata, env var wiring, and mount annotations. |
| tests/CommunityToolkit.Aspire.Hosting.Floci.Tests/CommunityToolkit.Aspire.Hosting.Floci.Tests.csproj | Introduces the Floci test project and references to the integration and examples. |
| tests/CommunityToolkit.Aspire.Hosting.Floci.Tests/AppHostTests.cs | Adds a Docker-required integration test asserting the Floci resource becomes healthy. |
| src/CommunityToolkit.Aspire.Hosting.Floci/README.md | Provides usage documentation and examples for the new Floci hosting integration. |
| src/CommunityToolkit.Aspire.Hosting.Floci/FlociHostingExtension.cs | Implements the hosting integration extension methods (AddFloci and configuration helpers). |
| src/CommunityToolkit.Aspire.Hosting.Floci/FlociContainerResource.cs | Adds the Floci container resource model and connection string/connection properties. |
| src/CommunityToolkit.Aspire.Hosting.Floci/FlociContainerImageTags.cs | Defines the default container image coordinates for Floci. |
| src/CommunityToolkit.Aspire.Hosting.Floci/CommunityToolkit.Aspire.Hosting.Floci.csproj | Adds the new integration package project and dependencies. |
| README.md | Adds Floci to the repository’s integrations table and link references. |
| examples/floci/CommunityToolkit.Aspire.Hosting.Floci.AppHost/Program.cs | Adds a sample AppHost wiring Floci + ApiService with health checks and references. |
| examples/floci/CommunityToolkit.Aspire.Hosting.Floci.AppHost/CommunityToolkit.Aspire.Hosting.Floci.AppHost.csproj | Adds the example C# AppHost project for Floci. |
| examples/floci/CommunityToolkit.Aspire.Hosting.Floci.AppHost.TypeScript/tsconfig.json | TypeScript compiler configuration for the polyglot AppHost example. |
| examples/floci/CommunityToolkit.Aspire.Hosting.Floci.AppHost.TypeScript/package.json | Defines the TypeScript AppHost example’s scripts, dependencies, and Node engine constraints. |
| examples/floci/CommunityToolkit.Aspire.Hosting.Floci.AppHost.TypeScript/package-lock.json | Locks dependencies for the TypeScript AppHost example. |
| examples/floci/CommunityToolkit.Aspire.Hosting.Floci.AppHost.TypeScript/eslint.config.mjs | Adds ESLint configuration for the TypeScript AppHost example. |
| examples/floci/CommunityToolkit.Aspire.Hosting.Floci.AppHost.TypeScript/aspire.config.json | Adds Aspire config for the TypeScript AppHost example and local package wiring. |
| examples/floci/CommunityToolkit.Aspire.Hosting.Floci.AppHost.TypeScript/apphost.mts | Implements the TypeScript AppHost example covering runtime and compile-only scenarios. |
| examples/floci/CommunityToolkit.Aspire.Hosting.Floci.ApiService/Properties/launchSettings.json | Adds launch settings for the example API service. |
| examples/floci/CommunityToolkit.Aspire.Hosting.Floci.ApiService/Program.cs | Adds a minimal API demonstrating S3 access against the emulator using injected env vars. |
| examples/floci/CommunityToolkit.Aspire.Hosting.Floci.ApiService/CommunityToolkit.Aspire.Hosting.Floci.ApiService.csproj | Adds the example API service project and AWSSDK.S3 dependency. |
| CommunityToolkit.Aspire.slnx | Registers the new integration, tests, and example projects in the solution. |
Files not reviewed (1)
- examples/floci/CommunityToolkit.Aspire.Hosting.Floci.AppHost.TypeScript/package-lock.json: Generated file
…ls — re-declaring any of them with const triggers the SyntaxError: Identifier already declared at parse time before any of the script logic runs
|
@aaronpowell can you please take a look here? |
Runs the floci/floci-ui container as a first-class Aspire child resource of the Floci container, wired to the emulator over the container network via FLOCI_ENDPOINT, mirroring the WithKafkaUI / WithOpenWebUI companion pattern. Avoids Floci's built-in UI sidecar mechanism, which relies on Docker socket access and self-discovered endpoints that don't play well with Aspire's DCP-managed networking. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
@aaronpowell I included the Floci UI changes from @slang25 along with some additional changes for enabling multi-cloud support from my end (added Azure + GCP along with AWS). I had to fix the restore issue for the security vulnerabilities caused by The PR is ready for you review, so please take a look and let me know if you have any concern. |
CommunityToolkit.Aspire.Hosting.Floci — Floci cloud emulator hosing integration
Note
Moved to #1479
Closes floci-io/floci#1242
Adds
CommunityToolkit.Aspire.Hosting.Floci— a hosting integration for Floci, a family of high-performance local cloud emulators (floci/flocifor AWS,floci/floci-azfor Azure,floci/floci-gcpfor GCP) that run as containers inside the Aspire AppHost.What's included
Core integration (
src/CommunityToolkit.Aspire.Hosting.Floci/)AddFlociAws(name, port?, defaultRegion?, defaultAccountId?)— adds the Floci AWS container with an HTTP health check at/_floci/infoAddFlociAzure(name, port?)— adds the Floci Azure container (floci/floci-az), health check at/_floci/healthAddFlociGcp(name, port?, defaultProjectId?)— adds the Floci GCP container (floci/floci-gcp), health check at/_floci-gcp/healthFlociContainerResource) that holds endpoint/connection-string plumbing, soHost,Port,PrimaryEndpoint, andConnectionStringExpressionare implemented once and inherited — not duplicated per cloudWithReferenceautomatically injects the standardConnectionStrings__<name>plus provider-specific env vars via aBeforeStartEventsubscriber; host processes receivelocalhost:{port}, containers receivehost.docker.internal:{port}:AWS_ENDPOINT_URL,AWS_DEFAULT_REGION,AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEYAZURE_STORAGE_CONNECTION_STRING(well-knowndevstoreaccount1dev credentials)PUBSUB_EMULATOR_HOST,FIRESTORE_EMULATOR_HOST,DATASTORE_EMULATOR_HOST,STORAGE_EMULATOR_HOST,SECRET_MANAGER_EMULATOR_HOST,GOOGLE_CLOUD_PROJECT,CLOUDSDK_CORE_PROJECTWithDataVolume/WithDataBindMount— switches Floci from in-memory to persistent storage mode; implemented once and shared across all three cloudsWithDockerSocket— mounts the Docker socket so Lambda / Azure Functions / Cloud Run and other container-backed services can launch sibling containers; adds--add-host=host.docker.internal:host-gatewayto container dependents; shared across all three cloudsWithConfigFile(hostPath)— bind-mounts a Quarkusapplication.ymloverride at/deployments/config/application.ymlfor advanced configuration (AWS only — Azure/GCP images don't expose this)Floci UI web console (
WithFlociUI/WithPluggedCloud)WithFlociUI(configureContainer?, containerName?)— available on all three cloud resource types, adds a single sharedFlociUIContainerResourcerunningdocker.io/floci/floci-ui:0.2.0:FLOCI_ENDPOINTfor AWS,FLOCI_AZURE_ENDPOINTfor Azure,FLOCI_GCP_ENDPOINTfor GCP)/; excluded from manifest (ExcludeFromManifest())WithFlociUItwice re-configures the existing UI container instead of adding a duplicateWithPluggedCloud(cloud)— attaches an additional cloud resource to an already-created UI console, so one console can browse AWS + Azure + GCP at once instead of spinning up three separate UI containers. In C# this is a single overloaded method name; the generated TypeScript bindings expose it aswithPluggedCloudAws/withPluggedCloudAzure/withPluggedCloudGcpsince the polyglot export generator needs distinct names when all three overloads share the same target typeWithHostPort(int?)on the UI resource builder to pin the host portExamples and tests
aws.WithFlociUI(configureContainer: ui => { ui.WithPluggedCloud(azure); ui.WithPluggedCloud(gcp); }))ApiServiceexercises all three clouds end-to-end: S3 (AWS SDK), Blob Storage (Azure SDK), and Cloud Storage (GCP SDK), each with its own health check (floci-s3,floci-azure-blob,floci-gcp-storage) and a hosted service that creates a demo bucket/container on startupWithPluggedCloudattaches correctly, single UI container, correct env vars per attached cloud), the TypeScript AppHost, and Docker-gated AppHost integration tests asserting all three cloud resources and the UI resource become healthyConnectionStrings__<name>behavior alongside each cloud's provider-specific env varsPR Checklist
Other information
floci/floci,floci/floci-az,floci/floci-gcp) expose certificate-based configuration the way the earlier AWS-only prototype assumed, so that support was removed rather than shipped half-workingAWS_ENDPOINT_URLis the standard SDK v4 env var; noAmazonS3Config.RegionEndpointshould be set alongsideServiceURL(triggers aNullReferenceExceptionin the v4 endpoint rule engine — documented in the example)StorageClientis built withEmulatorDetection.EmulatorOnlyso it readsSTORAGE_EMULATOR_HOSTand skips real GCP credential resolution entirelyASPIREATS001experimental diagnostic (polyglot export attributes) is suppressed at file level in the hosting extension files