
Introduktion
Formål
Dette dokument beskriver hvordan man kommer i gang med at tilpasse eller videreudvikle EMR - EHMI MeddelelsesRegistrering.
Læsevejledning
Læser forventes at have kendskab til Java softwareudvikling med anvendelse af Maven, konfiguration af WildFly og brug af docker-compose.
Komponentens struktur
Selve komponenten er delt op i følgende moduler:
- msh_common: Fælles kode, bl.a. til status- og alarm-endpoints og oprettelse af http-klienter.
- msh_integration_tests: Integrationstests mod en kørende service. Lige pt. understøttes kun localhost, da der afventes installation på NSPs testmiljøer.
- msh_services: Selve service-koden, inklusiv baggrundsjobs, DAO'er, EHMI-besked-generering og Domibus-service (klienten til Domibus ligger under "msh_integrations").
- msh_adapter: Web-modul der udstiller snitflader til at starte baggrundsjobs, aflæsning af status'er og alarm'er samt indlæsning af konfiguration.
- msh_integrations: Integrationer til DROS, Domibus og EDS-service.
- msh_schema: Domibus- og EHMI-skemaer til generering af Java-kode.
Komponenten indeholder følgende integrationer, som alle ligger under "msh_integrations":
- Domibus-integration, baseret på WSDL-fil fra "msh_schema" og jakarta.xml.ws.
- EDS-integration som er FHIR-baseret.
- DROS-integration baseret på IHE-frameworket og Apache CXF.
Beskeder, kvitteringer og standarder
Dette afsnit giver et overblik over beskeder EMR henter og sender, hvordan de er pakket ind, og hvilke standarder der er i spil.
Hvad laver komponenten?
EMR fungerer som en bro mellem tre eksterne systemer:
- Domibus: Access Punkt hvor der hentes indgående EHMI-forretningsbeskeder. Hertil sendes også kvitteringer retur.
- DROS: Dokumentregister. Indgående dokumenter uploades hertil via IHE ITI-41.
- EDS: Forsendelsesstatus/audit. Der sendes track-and-trace-hændelser hertil som FHIR
AuditEvent.
Flowet er kø-baseret: Jobs kører i faste trin, og beskeder flyttes mellem interne DB-køer (ehmi_message_queue for forretningsbeskeder og kvitteringer, eds_message_queue for forsendelsesstatus). Der er ingen intern scheduler. Hvert job trigges udefra via en HTTP-servlet.
Beskeder ind og ud
Ind (hentes)
| Besked | Kilde | Hvordan |
|---|
| EHMI-forretningsbesked | Domibus | Fetch-jobbet henter ventende beskeder (listPendingMessages + retrieveMessage), parser dem og gemmer dem i køen som type EHMI. |
Ud (sendes)
| Besked | Modtager | Hvornår |
|---|
| Dokument-upload (ITI-41) | DROS | Save-jobbet uploader den indgående forretningsbesked til dokumentregisteret. |
Kvittering (ReceiptAcknowledgement / ReceiptException) | Domibus (retur til oprindelig afsender) | Save-jobbet opretter kvitteringen og lægger den i køen som type RECEIPT. Send-jobbet sender den. |
Forsendelsesstatus (FHIR AuditEvent) | EDS | Alle tre jobs skriver track-and-trace-hændelser til EDS-køen. Et separat EDS-job sender dem. |
Bemærk: der er to forskellige ting, der begge kan kaldes "kvittering":
- En kvittering til modparten (ReceiptAcknowledgement/ReceiptException). En EHMI-besked, der sendes tilbage gennem Domibus til den oprindelige afsender.
- En forsendelsesstatus til EDS. En intern statusmelding (FHIR AuditEvent) om, at en besked er hentet, gemt eller sendt.
Kvitteringer til modparten
En kvittering er selv en EHMI StandardBusinessDocument (se indpakning nedenfor). Der findes to slags:
- ReceiptAcknowledgement. En positiv kvittering, når en indgående besked er behandlet og uploadet til DROS.
- ReceiptException. En fejlkvittering, når beskeden ikke kunne valideres eller uploades.
Kvitteringen korrelerer til den oprindelige besked, og retningen vendes: Afsender og modtager byttes om, så kvitteringen går tilbage til den, der sendte den oprindelige besked. Korrelationen bæres flere steder:
- I SBDH via Scope-elementer: Kvitteringen får sit eget MESSAGEIDENTIFIER, mens den oprindelige beskeds id bevares i ORIGINALMESSAGEIDENTIFIER.
- I selve kvitterings-payloaden via felter som OriginalMessageIdentifier, OriginalDocumentIdentifier og CollaborationIdentifier.
Sådan er en besked pakket ind
En besked består af tre indpakningslag: Ydre, indre og payload. De to sidste lag er begge base64-encoded.
TODO: Tegning af indpakning.
Konkret betyder det:
- Forretnings-payloaden base64-kodes ind i SBDH'ens BinaryContent.
- Hele SBDH-dokumentet serialiseres til XML og base64-kodes ind i ebMS-payloaden (PartInfo/value).
- Det hele lægges i en ebMS3 UserMessage og sendes som AS4 gennem Domibus.
Ved modtagelse foldes lagene ud i omvendt rækkefølge.
Centrale begreber
Begreberne stammer fra to forskellige lag: ebMS3 (den ydre AS4-konvolut) og SBDH (den indre EHMI-besked).
ebMS3-laget (AS4-konvolutten)
- CollaborationInfo: Beskriver hvilken forretningsproces beskeden hører til.
- PartyId: Identificerer AP (afsender/modtager på AS4-niveau).
- MessageProperties: Nøgle/værdi-metadata på hele beskeden, fx originalSender og finalRecipient.
SBDH-laget (EHMI-beskeden)
- StandardBusinessDocument (SBD): Det yderste EHMI-element eren StandardBusinessDocumentHeader + et BinaryContent (den base64-kodede forretnings-payload).
- StandardBusinessDocumentHeader (SBDH): Routing- og metadata-header: Sender, Receiver, DocumentIdentification og BusinessScope.
- BusinessScope: Hvert Scope har en Type (fx SENDERID, RECEIVERID, MESSAGEIDENTIFIER, ORIGINALMESSAGEIDENTIFIER, XDS-METADATA, StatisticalInformation) og et InstanceIdentifier. Det er her fx XDS-metadata til DROS og korrelationen mellem besked og kvittering ligger.
- Partner-identifikation (ehmiPartner): SBDH's egen afsender/modtager: en Identifier med Authority (typisk GLN-baseret). Dette er ikke det samme som PartyId i Domibus-beskederne.
Standarder og namespaces
Skemaerne ligger i msh_schema/src/main/resources/.
Relevante specifikationer:
Hvor i koden
Vigtige klasser i koden hvor de enkelte dele af besked-flowet håndteres:
- Parsing/marshalling af SBD: ehmi/EhmiMessageParser.java, ehmi/SbdUtil.java.
- Bygning af kvitteringer og response-SBD: ehmi/EhmiMessageFactory.java.
- Validering: validation/EhmiDocumentValidator.java.
- Domibus (submit/retrieve, ebMS-konvolut): domibus/DomibusService.java, integrations/domibus/DomibusWsPluginClient.java, profil i domibus/DomibusMessageProfile.java.
- Jobs: job/fetchjob/, job/savejob/, job/sendjob/, job/edsjob/. Wiring i msh_adapter/.../setup/JobsConfig.java.
- Genererede JAXB-klasser: pakkerne dk.nsp.msh.ehmisbdh (EHMI/SBDH) og org.oasis_open.docs.ebxml_msg... (ebMS3), genereret fra skemaerne i msh_schema.
Opsætning af udviklingsmiljø
Projektet ligger som nspop git-repository på følgende adresse:
Som en del af projektet, leveres der også en konfiguration af Domibus, som skal anvendes af NSP. Den findes også i git:
EMR er udviklet i java 21 og kan bygges med.
Som en del af bygget afvikles der unit tests.
Afvikling
Maven bygger war-filerne, som kan deployes med docker compose. Dette gøres lokalt med kommandoen:
docker-compose -f compose/development/docker-compose.yaml up --build |
Herefter vil EMR services være tilgængelig under http://localhost:8092/msh-adapter/.
Det er muligt at sætte en remote debugger op på port 5056.
Integrationstests
Integrationstesten kan afvikles op imod et kørende system på localhost med følgende kommando:
mvn verify -pl msh_integration_tests -Pintegration-test |
Pt. er det et udestående omkring at definerer profiler, så testen kan køre mod udviklingsmiljøerne på test1 og test2, da disse i skrivende stund endnu ikke er deployed.
Projektstruktur
For nærmeste beskrivelse af projektets struktur og opbygning, se Design- og Arkitekturbeskrivelsen.
Database
Databasemodellen styres ved hjælp af liquibase. Det betyder, at når der skal laves ændringer til databasen, så må man ikke rette i de eksisterende skemafiler. I stedet skal der laves nye filer, der beskriver ændringerne.