Integrations
Note
This page describes what openFHIR Engine can integrate to for support in its mappings. If you’re looking for instructions on how to invoke openFHIR Engine itself and how to integrate engine into your flow, see Architecture.
openEHR Repository
openFHIR Engine can be integrated with an existing openEHR Repository (CDR) for the purpose of getting operational templates needed for the mappings. In this case, operational templates do not need to be populated as part of the state configuration.
Without this integration, every operational template has to be uploaded into the engine’s own database (POST /opt) before any mapping
can run, which means an operator running openFHIR next to an existing openEHR CDR maintains two copies of the same template and has to keep
them in sync. Drift between the two is silent, and only surfaces later as a mapping failure. With the integration enabled, the CDR stays the
single source of truth and openFHIR holds no template state of its own.
Note
This is an enterprise-only feature. The open source engine always resolves templates from its own database.
CDR-only mode
When the integration is enabled the engine runs in CDR-only mode. This is deliberately all-or-nothing: the local opt collection is
not consulted for mapping reads at all, so that the engine can never silently serve a stale local copy of a template that has since changed
in the CDR.
Concretely, when CDR-only mode is on:
operational templates are fetched from the CDR on demand, for every mapping direction as well as for AQL generation, validation and Atlas,
POST /opt,PUT /opt/{id}andDELETE /opt/{id}return409 Conflict— templates are owned by the CDR and must be loaded there directly. The engine is read-only towards the CDR and never pushes, updates or deletes a template in it,GET /optreturns an empty array andGET /opt/{id}returns404. Templates remain fully resolvable for mapping; they are simply not addressable through the engine’s admin API. Query the CDR directly to list them,*.optfiles in the bootstrap directory are skipped with a warning and reported with the outcomeUNCHANGED. The rest of the scan (model mappers, context mappers, concept maps) is unaffected, andGET /healthstill opens normally,if the CDR is unreachable, a mapping request fails with a clear “CDR is unreachable” error rather than falling back to whatever happens to be stored locally.
Configuration
The integration is disabled by default. It is configured under openfhir.cdr:
openfhir:
cdr:
enabled: true
base-url: http://localhost:8081/ehrbase/rest/openehr/v1
auth: BASIC # NONE | BASIC | OAUTH2
username: ehrbase-user
password: SuperSecretPassword
Environment variable |
Default |
Description |
|---|---|---|
|
|
Enables CDR-only mode. When |
|
— |
Base URL of the openEHR REST API, e.g. |
|
|
Authentication scheme: |
|
— |
Credentials used when |
|
— |
Token endpoint used when |
|
— |
Client credentials used when |
|
— |
Optional scope requested with the client-credentials grant. |
|
|
Connection timeout, in milliseconds, when talking to the CDR. |
|
|
Read timeout, in milliseconds, when talking to the CDR. |
Only ADL 1.4 operational templates are fetched, over
GET {base-url}/definition/template/adl1.4/{template_id}. Credentials and OAuth2 tokens are never written to the log.
Note
CDR template ids are case-sensitive, while openFHIR normalizes template ids internally (lowercasing them and replacing spaces with
underscores). The engine therefore sends the template id as written in your FHIR Connect context mapper (context.template.id), and
only falls back to the normalized form if that is not found. Keep context.template.id identical to the template id in the CDR.
Caching
Fetched templates go through the same OPT cache described in Caching, which matters more here than in the local case: a single mapping request looks the same template up twice, so without the cache every request would cost two round-trips to the CDR.
Warning
The default OPENFHIR_CACHE_OPT_TTL is -1, meaning entries never expire and are only evicted when a template is upserted through
the API. CDR-only mode has no local upsert, so a cached template would never refresh on its own. Set a finite
OPENFHIR_CACHE_OPT_TTL when running in CDR-only mode, or evict explicitly with POST /opt/$refresh?templateId=... after a template
changes in the CDR. The engine logs a warning at startup if CDR-only mode is on while the TTL is infinite.
POST /opt/$refresh?templateId=... evicts a single template cluster-wide, so the next mapping request re-fetches it from the CDR. It
returns 204 No Content, or 409 Conflict when the engine is not in CDR-only mode (where templates are evicted automatically on upsert).
Per-tenant configuration
The block above is the global default. An individual tenant can point at a different CDR, or opt out of the integration entirely, through the
cdr_opt_source tenant property — see Multitenancy.
Verifying the integration
GET /status reports the resolved configuration together with a liveness probe, so the wiring can be confirmed without firing a mapping
request at the engine:
{
"cdr": {
"enabled": true,
"baseUrl": "http://localhost:8081/ehrbase/rest/openehr/v1",
"reachable": true
}
}
reachable is only probed when the integration is enabled.
Terminology server
As describe in the Terminology, an important aspect to efficient mapping is access to a terminology service providing bidirectional mappings between openEHR and FHIR terminologies. For this purpose, openFHIR Engine can be integrated with an external FHIR terminology server compliant with the following IG https://build.fhir.org/terminology-service.html
Required operations that the external terminology server needs to support are:
$translate
// todo