Skip to main content

Configuration

Environment variables

Required in all environments

VariableDescriptionExample
DB_URLPostgreSQL JDBC URLjdbc:postgresql://localhost:5432/ajfhir_referral
DB_USERDatabase usernameajfhir
DB_PASSDatabase password
FHIR_BASE_URLHAPI FHIR server URLhttp://localhost:8080/fhir
CONSENT_MANAGER_URLConsent Manager base URLhttp://localhost:8082

Required in production

VariableDescriptionHow to get it
FHIR_SERVICE_TOKENService-account token for HAPI writesAuth server client_credentials grant
CONSENT_SERVICE_TOKENSYSTEM-scoped token for consent gateAuth server client_credentials grant with SYSTEM scope
JWT_EXPECTED_ISSUERAuth server issuer URLAuth server issuer config
JWT_EXPECTED_AUDIENCEExpected aud claimFHIR server URL
CONSENT_SERVICE_TOKEN is required

If this variable is blank in a non-test profile, the application throws IllegalStateException at startup and refuses to start. Without it the consent gate cannot function and no referral can ever be sent.

application.yml properties

referral:
fhir-base-url: http://localhost:8080/fhir
fhir-service-token: ${FHIR_SERVICE_TOKEN:}
consent-manager-url: http://localhost:8082
consent-service-token: ${CONSENT_SERVICE_TOKEN:}
expected-issuer: ${JWT_EXPECTED_ISSUER:}
expected-audience: ${JWT_EXPECTED_AUDIENCE:}

Database

The Referral Module requires its own PostgreSQL database — separate from the Consent Manager and Auth Server databases.

CREATE DATABASE ajfhir_referral OWNER ajfhir;

Flyway creates on first startup:

  • referral_record — the referral store
  • referral_task — workflow steps
  • referral_reason_code — reason code collection
  • referral_shared_resource — resource types for consent gate
  • referral_supporting_info — attached document references
  • referral_audit_event — IHE ATNA audit rows

Async executor

Thread pool: referralAsyncExecutor
Core: 4 threads
Max: 16 threads
Queue: 200 tasks
Prefix: referral-async-

FHIR syncs and audit writes use this named executor. All @Async methods specify @Async("referralAsyncExecutor") — never the default SimpleAsyncTaskExecutor.

Full docker-compose example

services:
postgres:
image: postgres:15-alpine
environment:
POSTGRES_USER: ajfhir
POSTGRES_PASSWORD: ${DB_PASS}
volumes:
- ./docker/postgres-init.sh:/docker-entrypoint-initdb.d/init.sh
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ajfhir"]

hapi-fhir:
image: hapiproject/hapi:v7.4.0
ports: ["8080:8080"]
environment:
spring.datasource.url: jdbc:postgresql://postgres:5432/ajfhir_hapi
spring.datasource.username: ajfhir
spring.datasource.password: ${DB_PASS}
depends_on: [postgres]

auth-server:
image: ajfhir/smart-auth-server:latest
ports: ["9000:9000"]
environment:
DB_URL: jdbc:postgresql://postgres:5432/ajfhir_auth
DB_USER: ajfhir
DB_PASS: ${DB_PASS}
depends_on: [postgres]

consent-manager:
image: ajfhir/consent-manager:1.1.0
ports: ["8082:8082"]
environment:
DB_URL: jdbc:postgresql://postgres:5432/ajfhir_consent
DB_USER: ajfhir
DB_PASS: ${DB_PASS}
FHIR_BASE_URL: http://hapi-fhir:8080/fhir
FHIR_SERVICE_TOKEN: ${FHIR_SERVICE_TOKEN}
RSA_PUBLIC_KEY_JWK: ${RSA_PUBLIC_KEY_JWK}
JWT_EXPECTED_ISSUER: http://auth-server:9000
JWT_EXPECTED_AUDIENCE: http://hapi-fhir:8080/fhir
depends_on: [postgres, hapi-fhir, auth-server]

referral:
image: ajfhir/referral:1.0.0
ports: ["8083:8083"]
environment:
DB_URL: jdbc:postgresql://postgres:5432/ajfhir_referral
DB_USER: ajfhir
DB_PASS: ${DB_PASS}
FHIR_BASE_URL: http://hapi-fhir:8080/fhir
FHIR_SERVICE_TOKEN: ${FHIR_SERVICE_TOKEN}
CONSENT_MANAGER_URL: http://consent-manager:8082
CONSENT_SERVICE_TOKEN: ${CONSENT_SERVICE_TOKEN}
JWT_EXPECTED_ISSUER: http://auth-server:9000
JWT_EXPECTED_AUDIENCE: http://hapi-fhir:8080/fhir
depends_on: [postgres, hapi-fhir, consent-manager]

The postgres-init.sh script creates all four databases on first boot:

psql -U ajfhir -c "CREATE DATABASE ajfhir_hapi;"
psql -U ajfhir -c "CREATE DATABASE ajfhir_auth;"
psql -U ajfhir -c "CREATE DATABASE ajfhir_consent;"
psql -U ajfhir -c "CREATE DATABASE ajfhir_referral;"

API Reference · Home