SARA (Storage and Analysis of Robot Acquired plant data) is an ASP.NET Core
Web API that indexes inspection data published by ISAR and orchestrates
Argo-based analysis workflows on it, exposing the results to Flotilla. Each
incoming inspection becomes an InspectionRecord; one or more records are
grouped into an Analysis (the use-case), which executes as an AnalysisRun
made up of one or more sequential Workflow steps.
When running locally the endpoint is reachable at https://localhost:8100
(/ redirects to Swagger).
InspectionRecord-- one row per ISAR inspection result, persisted on receipt of anisar/+/inspection_resultMQTT message.Analysis->AnalysisRun->Workflow-- three-tier model where an Analysis describes the use-case, an AnalysisRun is one execution attempt, and each Workflow is a single Argo step.AnalysisGroup-- lets a single Analysis span multiple InspectionRecords. The group is buffered until all expected records arrive orAnalysisGroupTimeoutMinuteselapses.- Workflow chains run sequentially. By default each step's output blob
becomes the next step's input; per-workflow rewiring lives in the matching
IWorkflowResultHandler. - The Argo trigger payload has a stable core (
workflowId,inputBlobStorageLocations,outputBlobStorageLocation) plus anextrasobject populated byITriggerPayloadEnricherimplementations matched on workflow type. - The trigger's
outputBlobStorageLocationis a requested destination, not a confirmed upload. Successful workflows report it in their JSONresultonly after uploading, with nonblankstorageAccount,blobContainer, andblobNamestrings. SARA persists only valid reported locations; omission ornullmeans no output. Malformed locations are logged and withheld without discarding metrics. - Result handling is split:
WorkflowResultHandlers/runs per step,AnalysisResultHandlers/runs once the whole Analysis is done.
make run # or: dotnet run --project apiCloud deployments authenticate via Azure Workload Identity (federated
credentials on the sara app registration). Locally you have two options,
selected by ASPNETCORE_ENVIRONMENT:
-
Local(default formake run) — usesappsettings.Local.jsonwithAllowedAuthMethods: ["AzureCliBootstrap", "ClientSecret"]. Requiresaz loginfirst; the developer's Azure CLI session is used to bootstrap Key Vault access, and the app registration's client secret is loaded from Key Vault for subsequent Azure calls. -
Development(mimics deployed dev) — usesappsettings.Development.jsonwithAllowedAuthMethods: ["WorkloadIdentity", "ClientSecret"]. Workload Identity is unavailable outside AKS, so the chain falls through toClientSecretCredential. Provide the secret via anapi/.envfile (gitignored):AzureAd__ClientSecret=<value of AzureAd--ClientSecret in saradev-kv>Then run:
ASPNETCORE_ENVIRONMENT=Development dotnet run --project api
Use Local for normal day-to-day development. Use Development when
you need behaviour identical to the deployed dev pod (real Postgres,
real OpenTelemetry export, etc.).
-
Keycloak (no Azure sign-in) — both options above need Azure credentials to authenticate:
Localneedsaz loginto reachsaradev-kv,Developmentneeds a client secret from it. SettingAuthentication:ProvidertoOidcpoints token validation at any conformant OpenID Connect issuer instead.docker compose --profile keycloak up keycloak
Keycloak comes up on
http://localhost:8080with the same realm the armada integration tests use. The realm is read from../armada/robotics_integration_tests/custom_realms; setKEYCLOAK_REALM_DIRif armada is not checked out beside this repository.Then add to
api/.env:Authentication__Provider=Oidc AzureAd__Authority=http://localhost:8080/realms/robotics AzureAd__ClientId=sara-test AzureAd__AllowedAuthMethods__0=WorkloadIdentity KeyVault__UseKeyVault=false Database__UseInMemoryDatabase=trueA token for calling the API directly, or from Swagger:
curl -s -X POST http://localhost:8080/realms/robotics/protocol/openid-connect/token \ -d grant_type=client_credentials \ -d client_id=integration-tests \ -d client_secret=integration-tests-secret \ -d scope=sara-api | jq -r .access_tokenThis covers sign-in only.
AzureAd:AllowedAuthMethodsis a separate concern — theTokenCredentialused for blob storage and Microsoft Graph — so any code path reaching those still needs Azure. The frontend also still signs in against Entra ID.The armada integration tests run SARA against the same realm, under
ASPNETCORE_ENVIRONMENT=IntegrationTest. That environment has no appsettings file here on purpose: its configuration is passed in as environment variables fromarmada/robotics_integration_tests/custom_containers/sara.py, alongside the realm that defines the clients and scopes. Change it there, not here.
make test # xUnit; integration tests use Postgres Testcontainers (Docker required)
make format # CSharpier- Register the workflow under
Analysis:Workflowsinappsettings.jsonwith itsWorkflowTemplateName,OutputStorageAccount,OutputBlobContainerand (optionally)OutputFileExtension. - Reference it from one or more chains under
Analysis:Analyses, e.g."my-analysis": { "Workflows": ["anonymizer", "my-workflow"] }. - Add an
IWorkflowResultHandlerinapi/Services/ResultHandlers/WorkflowResultHandlers/that matches the new workflow type. - If the analyzer needs per-workflow parameters in the Argo Workflow arguments
payload, add an
ITriggerPayloadEnricherthat populatesextras. - Add the matching Argo
WorkflowTemplatein robotics-infrastructure and an analyzer image repo that implements the generic CLI contract (--input-blob-storage-locations,--output-blob-storage-location,--extras).
- sara-anonymizer -- anonymizes images
- sara-thermal-reading -- extracts temperatures from thermal images
- sara-fence-detection -- detects fence breaches
- sara-constant-level-oiler -- reads constant-level oiler spherical glasses
- sara-timeseries -- timeseries ingestion
- sara-sap -- SAP integration
We currently have 3 environments (Development, Staging, and Production) deployed to Aurora.
| Environment | Deployment |
|---|---|
| Development | Frontend Backend |
| Staging | Frontend Backend |
| Production | Frontend Backend |