Java library implementation of the FHIR VRDR and FHIR VRDR Messaging standards. This repository includes Java code for:
- Producing and consuming the Vital Records Death Reporting (VRDR) Health Level 7 (HL7) Fast Healthcare Interoperability Resources (FHIR) standard. Click here to view the FHIR Implementation Guide STU2.1.
- Producing and consuming FHIR messages for the exchange of VRDR documents.
- Example VRDR FHIR documents and messages in JSON and XML formats
- Numerous test cases illustrating proper usage of the library
This java library implements the FHIR VRDR and VRDR Messaging standards http://hl7.org/fhir/us/vrdr/
, explained in the implementation guides below:
- VRDR IG:
http://build.fhir.org/ig/HL7/vrdr/branches/master/index.html
- VRDR Messaging IG:
http://build.fhir.org/ig/nightingaleproject/vital_records_fhir_messaging_ig/branches/main/index.html
This project uses the hapi-fhir java libraries extensively to create its representation.
It is recommended to have a strong understanding of the resource extension section of the hapi-fhir library before diving into the code. Info can be found here. https://hapifhir.io/hapi-fhir/docs/model/custom_structures.html
This project is made up of several major components:
edu.gatech.VRDR.model
Contains all the custom resources needed for the VRDR IG.edu.gatech.VRDR.model.util
Contains utility methods like custom codes and static definitions for data structure resources.edu.gatech.VRDR.messaging
Contains all the custom resources needed for the VRDR Messaging IG.edu.gatech.VRDR.messaging.util
Contains utility methods like custom codes and static definitions for messaging resources.
You can refer to the src/test
directory for an in-depth unit test example on how to construct a full EDRS record, and serialize it to JSON
Interactions with NCHS are governed by the CI build version of the VRDR and Vital Records Messaging IGs, and should use the latest, supported releases of the VRDR .NET software and Canary.
Build the library using maven:
mvn clean install
Optionally, build the command line tool using maven command:
mvn clean package appassembler:assemble
For the library, simply place the compiled target jar in your classpath and import the VRDR classes to use the library.
Optionally, use the command line tool to generate example records for Canary testing:
-
sh target/appassembler/bin/app create submission canary-submission-test.json
-
sh target/appassembler/bin/app create update canary-update-test.json
-
sh target/appassembler/bin/app create void canary-void-test.json
You can also output XML instead of JSON by passing the --xml
option.
VRDRFhirContext ctx = new VRDRFhirContext();
// creating death record from xml data file
DeathCertificateDocument deathRecordFromXML = BaseMessage.parseXMLFile(DeathCertificateDocument.class, ctx, "path-to-xml-data-file/DeathRecord.xml");
// creating death record from json data file
DeathCertificateDocument deathRecordFromJson = BaseMessage.parseJsonFile(DeathCertificateDocument.class, ctx, "path-to-json-data-file/DeathRecord.json");
// creating death record with no identifiers from json data file
DeathCertificateDocument deathRecordNoIdentifiers = BaseMessage.parseJsonFile(DeathCertificateDocument.class, ctx, "path-to-json-data-file/DeathRecordNoIdentifiers.json");
// adding fullUrl to death record's component and resource
Generic: deathCertificateDocument.addEntry(new BundleEntryComponent().setResource(resource).setFullUrl(uuidPrefix+resource.getId()));
Example: deathCertificateDocument.addEntry(new BundleEntryComponent().setResource(deathCertificate).setFullUrl(uuidPrefix + deathCertificate.getId()));
// Create submission message from Bundle
DeathRecordSubmissionMessage submission = new DeathRecordSubmissionMessage();
submission.setDeathRecord(new DeathCertificateDocument());
submission.setCertNo(42);
submission.setStateAuxiliaryId("identifier");
final String submissionBundleStr = submission.toJson(ctx);
DeathRecordSubmissionMessage parsed = BaseMessage.parseJson(DeathRecordSubmissionMessage.class, ctx, submissionBundleStr);
// Create submission message from death record with no identifiers in json data file
VRDRFhirContext ctx = new VRDRFhirContext();
DeathCertificateDocument deathRecordNoIdentifiers = BaseMessage.parseJsonFile(DeathCertificateDocument.class, ctx, "path-to-json-data-file/DeathRecordNoIdentifiers.json");
DeathRecordSubmissionMessage submission = DeathRecordSubmissionMessage.fromDeathRecord(deathRecordNoIdentifiers);
// Create submission message from death record in xml data file
VRDRFhirContext ctx = new VRDRFhirContext();
DeathCertificateDocument deathRecordFromXML = BaseMessage.parseXMLFile(DeathCertificateDocument.class, ctx, "path-to-xml-data-file/DeathRecord.xml");
DeathRecordSubmissionMessage submission = DeathRecordSubmissionMessage.fromDeathRecord(deathRecordFromXML);
// Create submission message from death record in json data file
VRDRFhirContext ctx = new VRDRFhirContext();
DeathCertificateDocument deathRecordFromJson = BaseMessage.parseJsonFile(DeathCertificateDocument.class, ctx, "path-to-json-data-file/DeathRecord.json");
DeathRecordSubmissionMessage submission = DeathRecordSubmissionMessage.fromDeathRecord(deathRecordFromJson);
// Create submission message in json data file
VRDRFhirContext ctx = new VRDRFhirContext();
DeathRecordSubmissionMessage submission = BaseMessage.parseJsonFile(DeathRecordSubmissionMessage.class, ctx, "path-to-json-data-file/Submission.json");
// Create submission message from empty submission in json data file
VRDRFhirContext ctx = new VRDRFhirContext();
DeathRecordSubmissionMessage submission = BaseMessage.parseJsonFile(DeathRecordSubmissionMessage.class, ctx, "path-to-json-data-file/EmptySubmission.json");
// Create submission message from wrong structure in json data file
VRDRFhirContext ctx = new VRDRFhirContext();
AcknowledgementMessage acknowledgementMessage = BaseMessage.parseJsonFile(AcknowledgementMessage.class, ctx, "path-to-json-data-file/DeathRecordSubmissionMessage.json");
// Create general Ack
VRDRFhirContext ctx = new VRDRFhirContext();
DeathRecordSubmissionMessage submission = BaseMessage.parseJsonFile(DeathRecordSubmissionMessage.class, ctx, "path-to-json-data-file/DeathRecordSubmissionMessage.json");
AcknowledgementMessage ack = new AcknowledgementMessage(submission);
// Create Ack for message with no identifiers
DeathRecordSubmissionMessage submission = new DeathRecordSubmissionMessage();
AcknowledgementMessage ack = new AcknowledgementMessage(submission);
// Create Ack from json data file
VRDRFhirContext ctx = new VRDRFhirContext();
AcknowledgementMessage ack = BaseMessage.parseJsonFile(AcknowledgementMessage.class, ctx, "path-to-json-data-file/AcknowledgementMessage.json");
// Create Ack from XML data file
VRDRFhirContext ctx = new VRDRFhirContext();
AcknowledgementMessage ack = BaseMessage.parseXMLFile(AcknowledgementMessage.class, ctx, "path-to-xml-data-file/AcknowledgementMessage.xml");
// Create Ack from Bundle
VRDRFhirContext ctx = new VRDRFhirContext();
AcknowledgementMessage ackBundle = BaseMessage.parseJsonFile(AcknowledgementMessage.class, ctx, "path-to-json-data-file/AcknowledgementMessage.json");
String bundleString = ackBundle.toJson(ctx, false);
AcknowledgementMessage ack = BaseMessage.parseJson(AcknowledgementMessage.class, ctx, bundleString);
// Create cause of death coding message
VRDRFhirContext ctx = new VRDRFhirContext();
DeathRecordSubmissionMessage submission = BaseMessage.parseJsonFile(DeathRecordSubmissionMessage.class, ctx, "path-to-json-data-file/DeathRecordSubmissionMessage.json");
CauseOfDeathCodingMessage coding = new CauseOfDeathCodingMessage(submission);
// Create cause of death coding message with no identifiers
CauseOfDeathCodingMessage coding = new CauseOfDeathCodingMessage((DeathRecordSubmissionMessage)null);
// Create cause of death coding message with no message
DeathRecordSubmissionMessage submission = new DeathRecordSubmissionMessage();
CauseOfDeathCodingMessage coding = new CauseOfDeathCodingMessage(submission);
// Create Ack for status message
VRDRFhirContext ctx = new VRDRFhirContext();
StatusMessage statusMessage = BaseMessage.parseJsonFile(StatusMessage.class, ctx, "src/test/resources/json/StatusMessage.json");
AcknowledgementMessage ack = new AcknowledgementMessage(statusMessage);
// Create cause of death coding response from json data file
VRDRFhirContext ctx = new VRDRFhirContext();
CauseOfDeathCodingMessage message = BaseMessage.parseJsonFile(CauseOfDeathCodingMessage.class, ctx, "path-to-json-data-file/CauseOfDeathCodingMessage.json");
CauseOfDeathCodedContentBundle bundle = message.getCauseOfDeathCodedContentBundle();
// By getting list of RecordAxisCauseOfDeath from bundle
List<RecordAxisCauseOfDeath> recordAxis = bundle.getRecordAxisCauseOfDeath();
// By getting list of EntityAxisCauseOfDeath from bundle
List<EntityAxisCauseOfDeath> entityAxis = bundle.getEntityAxisCauseOfDeath();
// By getting CodingStatusValues from bundle
CodingStatusValues codingStatusValues = bundle.getCodingStatusValues();
VRDRFhirContext ctx = new VRDRFhirContext();
DeathRecordSubmissionMessage submission = BaseMessage.parseJsonFile(DeathRecordSubmissionMessage.class, ctx, "src/test/resources/json/DeathRecordSubmissionMessage.json");
StatusMessage status = new StatusMessage(submission, "manualCauseOfDeathCoding");
// create the outer bundle
BaseMessage responseBundle = BaseMessage.parseJsonFile(AcknowledgementMessage.class, ctx, "src/test/resources/json/AcknowledgementMessage.json");
// add different types of messages or inner bundles to the outer bundle
responseBundle.addEntry(new Bundle.BundleEntryComponent().setResource(BaseMessage.parseJsonFile(DeathRecordSubmissionMessage.class, ctx, "src/test/resources/json/DeathRecordSubmissionMessage.json")));
// convert the loaded outer bundle, or bundle of bundles, to String
String bundleString = responseBundle.toJson(ctx);
// parse the stringified bundle of bundles by invoking static function parseBundleOfBundles
List<BaseMessage> listOfMessages = BaseMessage.parseBundleOfBundles(ctx, bundleString);
To create a new release of the VRDR Java Library:
- Incorporate the changes into the
CHANGELOG.md
file, providing a summary account of the modifications made in this release. - Modify the
pom.xml
file by updating the release version, specifically adjusting the version element. - Generate a pull request to merge the aforementioned modifications into the master branch.
- Publish a new GitHub release by following these steps:
- Go to the Releases page
- Select "Draft a new release"
- Create a new release version on the tag and release (e.g., v1.4.0-STU2.1)
- Copy the information from the CHANGELOG.md file relevant to this version and paste it into the release description
- Ensure that the "pre-release" button remains unchecked, even for preview releases, as pre-releases will not be displayed on the main GitHub page
- Review the recently created package and update the package description as necessary.
Following each release, the compiled package is published on GitHub Packages, accessible through https://github.com/orgs/nightingaleproject/packages and the repository landing page.