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} and DELETE /opt/{id} return 409 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 /opt returns an empty array and GET /opt/{id} returns 404. Templates remain fully resolvable for mapping; they are simply not addressable through the engine’s admin API. Query the CDR directly to list them,

  • *.opt files in the bootstrap directory are skipped with a warning and reported with the outcome UNCHANGED. The rest of the scan (model mappers, context mappers, concept maps) is unaffected, and GET /health still 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

OPENFHIR_CDR_ENABLED

false

Enables CDR-only mode. When false, the engine behaves exactly as before and serves templates from its own database.

OPENFHIR_CDR_BASE_URL

—

Base URL of the openEHR REST API, e.g. http://localhost:8081/ehrbase/rest/openehr/v1. Required when enabled.

OPENFHIR_CDR_AUTH

NONE

Authentication scheme: NONE, BASIC or OAUTH2 (client credentials).

OPENFHIR_CDR_USERNAME / OPENFHIR_CDR_PASSWORD

—

Credentials used when auth is BASIC.

OPENFHIR_CDR_TOKEN_URL

—

Token endpoint used when auth is OAUTH2.

OPENFHIR_CDR_CLIENT_ID / OPENFHIR_CDR_CLIENT_SECRET

—

Client credentials used when auth is OAUTH2.

OPENFHIR_CDR_SCOPE

—

Optional scope requested with the client-credentials grant.

OPENFHIR_CDR_CONNECT_TIMEOUT_MS

5000

Connection timeout, in milliseconds, when talking to the CDR.

OPENFHIR_CDR_READ_TIMEOUT_MS

15000

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