Skip to content

nightingaleproject/VRDR_javalib

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

VRDR_javalib

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

Standards

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

Info

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

Versions

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.

VRDR IG Messaging IG FHIR Version VRDR VRDR.Messaging
STU2.2-preview1 v0.9.1 R4 V4.0.4 nuget github nuget github
STU2.1 CI build version v0.9.1 R4 V1.4.3 nuget github nuget github
STU2.1 Published v0.9.1 R4 V1.4.3 nuget github nuget github
STU2 Published v0.9.1 R4 V1.4.3 nuget github nuget github
STU2 v1.3 v0.9 R4 V1.4.3 nuget github nuget github
STU2.1 v0.9.1 R4 V1.4.2 nuget github nuget github
STU2.1 v1.4.1 R4 V1.4.1 nuget github nuget github
STU2 v1.4.0 R4 V1.4.0 nuget github nuget github
STU2 v.1.3.5 R4 V1.3.5 nuget github nuget github
STU1.3 v1.3.4 R4 V1.3.4 nuget github nuget github
STU1.3 2nd try v1.3.3 R4 V1.3.3 nuget github nuget github
STU1.3 v1.3.2 R4 V1.3.2 nuget github nuget github
STU1.3 v1.3.1 R4 V1.3.1 nuget github nuget github
STU1.3%60 v1.3 R4 V1.3 nuget github nuget github
STU1.2 v1.2.3 R4 V1.2.3 nuget github nuget github
STU1.2 v1.2.2 R4 V1.2.2 nuget github nuget github
STU1.2 v1.2.1 R4 V1.2.1 nuget github nuget github
STU1.2 v1.2.0 R4 V1.2.0 nuget github nuget github
Updated test cases and added HelperFunctions v1.0.1 R4 V1.0.1 nuget github nuget github
VRDR-STU1 Compatible v1.0.0 R4 V1.0.0 nuget github nuget github
R4 v0.1.0 STU Ballot #1 REVISED [BETA] N/A V0.1.0 Revised Beta/td> nuget github nuget github
R4 v0.1.0 STU Ballot #1 N/A V0.1.0 nuget github nuget github

Build

Build the library using maven:

  • mvn clean install

Optionally, build the command line tool using maven command:

  • mvn clean package appassembler:assemble

Running

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.

Coding Examples

Creating death record

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 for death record

// 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 acknowledgenent for submission message

// 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 coding message

// 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 coding response

// 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();

Create status message

VRDRFhirContext ctx = new VRDRFhirContext();
DeathRecordSubmissionMessage submission = BaseMessage.parseJsonFile(DeathRecordSubmissionMessage.class, ctx, "src/test/resources/json/DeathRecordSubmissionMessage.json");
StatusMessage status = new StatusMessage(submission, "manualCauseOfDeathCoding");

Batch processing production or submission

// 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);

Batch processing consumption or reception

// parse the stringified bundle of bundles by invoking static function parseBundleOfBundles
List<BaseMessage> listOfMessages = BaseMessage.parseBundleOfBundles(ctx, bundleString);

Publishing a Version

To create a new release of the VRDR Java Library:

  1. Incorporate the changes into the CHANGELOG.md file, providing a summary account of the modifications made in this release.
  2. Modify the pom.xml file by updating the release version, specifically adjusting the version element.
  3. Generate a pull request to merge the aforementioned modifications into the master branch.
  4. Publish a new GitHub release by following these steps:
    1. Go to the Releases page
    2. Select "Draft a new release"
    3. Create a new release version on the tag and release (e.g., v1.4.0-STU2.1)
    4. Copy the information from the CHANGELOG.md file relevant to this version and paste it into the release description
    5. Ensure that the "pre-release" button remains unchecked, even for preview releases, as pre-releases will not be displayed on the main GitHub page
  5. 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.