Convert our own data to FHIR data Format

Hello,
I hope everyone is well and doing well.
We are implementing Milestone-2.
And after we get a callback from URL https://dev.ndhm.gov.in/gateway/v0.5/health-information/hip/request, we are getting keyMaterial, dataPushUrl, nonce.
We are responding above API using https://dev.ndhm.gov.in/gateway/v0.5/health-information/hip/on-request this API.
Now,

  1. we have to send our own prescribed treatment/record/any data, to data PUSH URL, is this correct?
  2. How should we convert our own data to FHIR JSON Format?
    We have above 2 doubts, it will be really helpful if anyone will help us to clear above doubts.
    @dheerajp, @sukreet, @kiranma, @angshuonline
    Thank you in advance.
1 Like

Hi Shubham,

Please see if you can join the FHIR India Meetup on Saturday.
The first session in the meetup will give a walk through on how to create FHIR object from your own data / model and create, read, and validate the FHIR JSON structures for NDHM Profiles.

For details on registration refer the post: Join session on working with NDHM FHIR profiles

Hello mam,

I hope you are well.
As you said, we have attended FHIR Meetup on Saturday. It was helpful to know things in a better way.
But we are still facing an issue with FHIR data conversion/validation.
As @Pranouti mam explained, we are trying the same.
Library issue we are facing now while validating data for FHIR format…
Below is the issue.
"Exception in thread "main" java.lang.NoSuchMethodError: org.apache.commons.lang3.StringUtils.countMatches(Ljava/lang/CharSequence;C)I"
We are stuck at this point and until this issue will get resolved, we can’t move forward.
It will be really helpful if you could help us in solving this issue asap.

Hi Shubham,

The issue is not related to sample codes nor related to the profiles.
Looking at error, I think you have missed to include the dependencies or there might be some version conflict. It seems the issue is with Apache commons lang jar. Please check for the dependencies.

Regards,
Manisha

Hello mam,

Thank you for quick reply.
Yes its the issue of dependencies only. But not sure about which dependencies will require.

Can you please tell us which version is compatible for commons-lang jar as there is no information about this in the read me text file

On saturday meetup, @Pranouti mam have already created sample project where 1 file was present, pom.xml, and we are not getting what are the contents of this file and what exact dependencies will require.
It will be really helpful if you could help us in this dependencies issue. Or it will be better ift you could hep us to know the contents of pom.xml file.

Thank you again.

Dear Shubham,

I have uploaded png of pom.xml for your reference. Also, you can check this link: [https://reflectoring.io/nosuchmethod/](http://Steps to Fix NoSuchMethodErrors and NoSuchMethodExceptions)

Hope this helps.

Regards,
Sayali

Hello mam,

Thank you.
Please refer image attached. We have changes line no 300 and added .json file there with path, but its giving error on line no 304.
Are we doing correct or we missing something?

Hi Shubham,

If you want to parse profiles in .json files then you need to create json parser in FHIR context, like,

IParser parserJson =ctx.newJsonParser();

// Read all Profile Structure Definitions in JSON.

String[] fileList = new File("F:\\NDHMProfiles\\").list(new WildcardFileFilter("*.json"));
for(String file:fileList)
{
	//Parse All Profiles and add to prepopulated support
	sd = parserJson.parseResource(StructureDefinition.class, new FileReader("F:\\NDHMProfiles\\"+file));
	prePopulatedSupport.addStructureDefinition(sd);
}

Hope this helps.

Regards,
Pranouti

1 Like

Hello @Pranouti mam,

That issue gets resolved now.
Now we are getting issue of Null pointer, I have attached screenshots below, please check once.

As you can see in 1st image, where we have marked by orange color, we are getting error there and 2nd image is of validate method we have implemented.
What we are missing here?

Hi shubbham,

Can you please provide entire Stacktrace of exception.

Hello mam,

Here is stacktrace of exception,
Exception in thread "main" java.lang.NullPointerException at org.hl7.fhir.validation.instance.InstanceValidator.checkReference(InstanceValidator.java:2216) at org.hl7.fhir.validation.instance.InstanceValidator.checkChild(InstanceValidator.java:4155) at org.hl7.fhir.validation.instance.InstanceValidator.validateElement(InstanceValidator.java:4012) at org.hl7.fhir.validation.instance.InstanceValidator.checkChild(InstanceValidator.java:4186) at org.hl7.fhir.validation.instance.InstanceValidator.validateElement(InstanceValidator.java:4012) at org.hl7.fhir.validation.instance.InstanceValidator.startInner(InstanceValidator.java:3472) at org.hl7.fhir.validation.instance.InstanceValidator.start(InstanceValidator.java:3396) at org.hl7.fhir.validation.instance.InstanceValidator.validateResource(InstanceValidator.java:4727) at org.hl7.fhir.validation.instance.InstanceValidator.validateContains(InstanceValidator.java:3875) at org.hl7.fhir.validation.instance.InstanceValidator.checkChild(InstanceValidator.java:4169) at org.hl7.fhir.validation.instance.InstanceValidator.validateElement(InstanceValidator.java:4012) at org.hl7.fhir.validation.instance.InstanceValidator.checkChild(InstanceValidator.java:4186) at org.hl7.fhir.validation.instance.InstanceValidator.validateElement(InstanceValidator.java:4012) at org.hl7.fhir.validation.instance.InstanceValidator.startInner(InstanceValidator.java:3472) at org.hl7.fhir.validation.instance.InstanceValidator.start(InstanceValidator.java:3384) at org.hl7.fhir.validation.instance.InstanceValidator.validateResource(InstanceValidator.java:4727) at org.hl7.fhir.validation.instance.InstanceValidator.validate(InstanceValidator.java:712) at org.hl7.fhir.validation.instance.InstanceValidator.validate(InstanceValidator.java:563) at org.hl7.fhir.common.hapi.validation.validator.ValidatorWrapper.validate(ValidatorWrapper.java:142) at org.hl7.fhir.common.hapi.validation.validator.FhirInstanceValidator.validate(FhirInstanceValidator.java:301) at org.hl7.fhir.common.hapi.validation.validator.BaseValidatorBridge.doValidate(BaseValidatorBridge.java:22) at org.hl7.fhir.common.hapi.validation.validator.BaseValidatorBridge.validateResource(BaseValidatorBridge.java:45) at org.hl7.fhir.common.hapi.validation.validator.FhirInstanceValidator.validateResource(FhirInstanceValidator.java:30) at ca.uhn.fhir.validation.FhirValidator.validateWithResult(FhirValidator.java:221) at ca.uhn.fhir.validation.FhirValidator.validateWithResult(FhirValidator.java:188) at com.dpdocter.security.PrescriptionSample.validate(PrescriptionSample.java:330) at com.dpdocter.security.PrescriptionSample.main(PrescriptionSample.java:74)

Hello @Pranouti mam,

Good Morning,

I am looking for your help on this.

HI shubham,

It is difficult to find the exact issue with the stacktrace only that you provided. Is it possible for you to provide the populated resource code which you are trying to validate with the profiles? so that I can reproduce the exception at my side and resolve the issue. Also you can post the Changes you made in Usage Sample.

Hello @Pranouti mam,
below is our file of prescription sample for which we are facing null pointer issue in validate function .

package com.dpdocter.security;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
import java.util.Scanner;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.filefilter.WildcardFileFilter;
import org.apache.log4j.Logger;
import org.hl7.fhir.common.hapi.validation.support.CommonCodeSystemsTerminologyService;
import org.hl7.fhir.common.hapi.validation.support.InMemoryTerminologyServerValidationSupport;
import org.hl7.fhir.common.hapi.validation.support.PrePopulatedValidationSupport;
import org.hl7.fhir.common.hapi.validation.support.SnapshotGeneratingValidationSupport;
import org.hl7.fhir.common.hapi.validation.support.ValidationSupportChain;
import org.hl7.fhir.common.hapi.validation.validator.FhirInstanceValidator;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.model.Bundle;
import org.hl7.fhir.r4.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.r4.model.Bundle.BundleType;
import org.hl7.fhir.r4.model.CodeableConcept;
import org.hl7.fhir.r4.model.Coding;
import org.hl7.fhir.r4.model.Composition;
import org.hl7.fhir.r4.model.Composition.CompositionStatus;
import org.hl7.fhir.r4.model.Composition.SectionComponent;
import org.hl7.fhir.r4.model.DateTimeType;
import org.hl7.fhir.r4.model.Identifier;
import org.hl7.fhir.r4.model.InstantType;
import org.hl7.fhir.r4.model.Meta;
import org.hl7.fhir.r4.model.Narrative;
import org.hl7.fhir.r4.model.Narrative.NarrativeStatus;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.hl7.fhir.r4.model.Reference;
import org.hl7.fhir.r4.model.StructureDefinition;

import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.dpdocter.collections.PatientCollection;
import com.dpdocter.collections.PrescriptionCollection;
import com.dpdocter.exceptions.BusinessException;
import com.dpdocter.exceptions.ServiceError;
import com.dpdocter.response.JasperReportResponse;
import com.dpdocter.services.impl.JasperReportServiceImpl;
import com.jaspersoft.mongodb.connection.MongoDbConnection;

import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.support.DefaultProfileValidationSupport;
import ca.uhn.fhir.parser.DataFormatException;
import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.validation.FhirValidator;
import ca.uhn.fhir.validation.SingleValidationMessage;
import ca.uhn.fhir.validation.ValidationResult;
import common.util.web.DPDoctorUtils;
import net.sf.jasperreports.engine.JREmptyDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.design.JasperDesign;

/**

  • The PrescriptionSample class populates, validates, parse and serializes Clinical Artifact - Prescription
    */
    public class PrescriptionSample {

    private static Logger logger = Logger.getLogger(PrescriptionSample.class.getName());

    @Value(value = “${bucket.name}”)
    private String bucketName;

    @Value(value = “${mail.aws.key.id}”)
    private String AWS_KEY;

    @Value(value = “${mail.aws.secret.key}”)
    private String AWS_SECRET_KEY;

    // The FHIR context is the central starting point for the use of the HAPI FHIR API
    // It should be created once, and then used as a factory for various other types of objects (parsers, clients, etc.)
    static FhirContext ctx = FhirContext.forR4();

    static FhirInstanceValidator instanceValidator;
    static FhirValidator validator;

    public static String prescriptionConvert(PrescriptionCollection prescriptionCollection,PatientCollection patientCollection) throws DataFormatException, IOException
    {

     String serializeBundle=null;
     try {
     //Initialize validation support and loads all required profiles
     init();
    
     // Populate the resource
     Bundle prescriptionBundle = populatePrescriptionBundle(prescriptionCollection,patientCollection);
    
     // Validate it. Validate method return result of validation in boolean
     // If validation result is true then parse, serialize operations are performed
     if(validate(prescriptionBundle))	
     {
     	System.out.println("Validated populated Prescripton bundle successfully");
    
     	// Instantiate a new parser
     	IParser parser= ctx.newJsonParser(); 
    
     	// Enter file path (Eg: C://generatedexamples//bundle-prescriptionrecord.json)
     	// Depending on file type xml/json instantiate the parser
    

// File file;
// Scanner scanner = new Scanner(System.in);
// System.out.println("\nEnter file path to write bundle");
// String filePath = scanner.nextLine();
// if(FilenameUtils.getExtension(filePath).equals(“json”))
// {
// parser = ctx.newJsonParser();
// }
// else if(FilenameUtils.getExtension(filePath).equals(“xml”))
// {
// parser = ctx.newXmlParser();
// }
// else
// {
// System.out.println(“Invalid file extention!”);
// scanner.close();
// return null;
// }

		// Indent the output
		parser.setPrettyPrint(true);

		// Serialize populated bundle
		serializeBundle = parser.encodeResourceToString(prescriptionBundle);
		System.out.println("out"+serializeBundle);
		// Write serialized bundle in xml/json file

// file = new File(filePath);
// file.createNewFile();
// FileWriter writer = new FileWriter(file);
// writer.write(serializeBundle);
// writer.flush();
// writer.close();
// scanner.close();

		// Parse the xml/json file
		//IBaseResource resource = parser.parseResource(new FileReader(new File(filePath)));
		IBaseResource resource = parser.parseResource(serializeBundle);
			

		// Validate Parsed file
		if(validate(resource)){
			System.out.println("Validated parsed file successfully");
		}
		else{
			throw new BusinessException(ServiceError.Unknown, "Failed to validate parsed file");
		}
	}
	else
	{
		throw new BusinessException(ServiceError.Unknown, "Failed to validate populate Prescription bundle : ");
		}
	}
	catch (BusinessException e) {
		e.printStackTrace();
		logger.error("Error : " + e.getMessage());
		throw new BusinessException(ServiceError.Unknown, "Error : " + e.getMessage());
	}
	return serializeBundle;
}


	




// Populate Composition for Prescription
static Composition populatePrescriptionCompositionResource()
{
	Composition composition = new Composition();	

	// Set logical id of this artifact
	composition.setId("Composition-01");

	// Set metadata about the resource - Version Id, Lastupdated Date, Profile
	Meta meta = composition.getMeta();
	meta.setVersionId("1");
	meta.setLastUpdatedElement(new InstantType("2020-07-09T15:32:26.605+05:30"));
	meta.addProfile("https://nrces.in/ndhm/fhir/r4/StructureDefinition/PrescriptionRecord");

	// Set language of the resource content
	composition.setLanguage("en-IN");

	// Plain text representation of the concept
	Narrative text= composition.getText();
	text.setStatus((NarrativeStatus.GENERATED));
	text.setDivAsString("<div xmlns=\"http://www.w3.org/1999/xhtml\">Prescription report</div>");

	// Set version-independent identifier for the Composition
	Identifier identifier = composition.getIdentifier();
	identifier.setSystem("https://ndhm.in/phr");
	identifier.setValue("645bb0c3-ff7e-4123-bef5-3852a4784813");

	// Status can be preliminary | final | amended | entered-in-error
	composition.setStatus(CompositionStatus.FINAL);

	// Kind of composition ("Prescription record ")
	composition.setType(new CodeableConcept(new Coding("http://snomed.info/sct", "440545006", "Prescription record")));

	// Set subject - Who and/or what the composition/Prescription record is about
	composition.setSubject(new Reference().setReference("Patient/Patient-01"));

	// Set Timestamp
	composition.setDateElement(new DateTimeType("2017-05-27T11:46:09+05:30"));

	// Set author - Who and/or what authored the composition/Presciption record
	composition.addAuthor(new Reference().setReference("Practitioner/Practitioner-01"));

	// Set a Human Readable name/title
	composition.setTitle("Prescription record");

	// Composition is broken into sections / Prescription record contains single section to define the relevant medication requests
	// Entry is a reference to data that supports this section
	Reference reference1 = new Reference();
	reference1.setReference("MedicationRequest/MedicationRequest-01");
	reference1.setType("MedicationRequest");

	Reference reference2 = new Reference();
	reference2.setReference("MedicationRequest/MedicationRequest-02");
	reference2.setType("MedicationRequest");

	Reference reference3 = new Reference();
	reference3.setReference("Binary/Binary-01");
	reference3.setType("Binary");

	SectionComponent section = new SectionComponent();
	section.setTitle("Prescription record");
	section.setCode(new CodeableConcept(new Coding("http://snomed.info/sct", "440545006", "Prescription record"))).
	addEntry(reference1).
	addEntry(reference2).
	addEntry(reference3);
	composition.addSection(section);	

	return composition;
}

// Populate Prescription Bundle
public static Bundle populatePrescriptionBundle(PrescriptionCollection prescriptionCollection, PatientCollection patientCollection)
{
	Bundle prescriptionBundle = new Bundle();

	// Set logical id of this artifact
	prescriptionBundle.setId("prescription-bundle-01");

	// Set metadata about the resource
	Meta meta = prescriptionBundle.getMeta();
	meta.setVersionId("1");
	meta.setLastUpdatedElement(new InstantType("2020-07-09T15:32:26.605+05:30"));
	meta.addProfile("https://nrces.in/ndhm/fhir/r4/StructureDefinition/DocumentBundle");

	// Set Confidentiality as defined by affinity domain
	meta.addSecurity(new Coding("http://terminology.hl7.org/CodeSystem/v3-Confidentiality", "V", "very restricted"));

	// Set version-independent identifier for the Bundle
	Identifier identifier = prescriptionBundle.getIdentifier();
	identifier.setValue("bc3c6c57-2053-4d0e-ac40-139ccccff645");
	identifier.setSystem("http://hip.in");

	// Set Bundle Type 
	prescriptionBundle.setType(BundleType.DOCUMENT);

	// Set Timestamp 
	prescriptionBundle.setTimestampElement(new InstantType("2020-07-09T15:32:26.605+05:30"));

	// Add resources entries for bundle with Full URL
	List<BundleEntryComponent> listBundleEntries = prescriptionBundle.getEntry();

	BundleEntryComponent bundleEntry1 = new BundleEntryComponent();
	bundleEntry1.setFullUrl("Composition/Composition-01");
	bundleEntry1.setResource(populatePrescriptionCompositionResource());

	BundleEntryComponent bundleEntry2 = new BundleEntryComponent();
	bundleEntry2.setFullUrl("Patient/Patient-01");
	bundleEntry2.setResource(ResourcePopulator.populatePatientResource(patientCollection));

	BundleEntryComponent bundleEntry3 = new BundleEntryComponent();
	bundleEntry3.setFullUrl("Practitioner/Practitioner-01");
	bundleEntry3.setResource(ResourcePopulator.populatePractitionerResource());

	BundleEntryComponent bundleEntry4 = new BundleEntryComponent();
	bundleEntry4.setFullUrl("MedicationRequest/MedicationRequest-01");
	bundleEntry4.setResource(ResourcePopulator.populateMedicationRequestResource());

	BundleEntryComponent bundleEntry5 = new BundleEntryComponent();
	bundleEntry5.setFullUrl("MedicationRequest/MedicationRequest-02");
	bundleEntry5.setResource(ResourcePopulator.populateSecondMedicationRequestResource());

	BundleEntryComponent bundleEntry6 = new BundleEntryComponent();
	bundleEntry6.setFullUrl("Condition/Condition-01");
	bundleEntry6.setResource(ResourcePopulator.populateConditionResource());

	BundleEntryComponent bundleEntry7 = new BundleEntryComponent();
	bundleEntry7.setFullUrl("Binary/Binary-01");
	bundleEntry7.setResource(ResourcePopulator.populateBinaryResource());

	listBundleEntries.add(bundleEntry1);
	listBundleEntries.add(bundleEntry2);
	listBundleEntries.add(bundleEntry3);
	listBundleEntries.add(bundleEntry4);
	listBundleEntries.add(bundleEntry5);
	listBundleEntries.add(bundleEntry6);
	listBundleEntries.add(bundleEntry7);

	return prescriptionBundle;
}

/**
 * This method initiates loading of FHIR default profiles and NDHM profiles for validation 
 */
static void init() throws DataFormatException, FileNotFoundException
{

	// Create xml parser object for reading profiles
	IParser parser = ctx.newJsonParser();

	// Create a chain that will hold our modules
	ValidationSupportChain supportChain = new ValidationSupportChain();
	
	// Add Default Profile Support
	// DefaultProfileValidationSupport supplies base FHIR definitions. This is generally required
	// even if you are using custom profiles, since those profiles will derive from the base
	// definitions.
	DefaultProfileValidationSupport defaultSupport = new DefaultProfileValidationSupport(ctx);
	
	// Create a PrePopulatedValidationSupport which can be used to load custom definitions.
	// In this example we're loading all the custom Profile Structure Definitions, in other scenario we might
	// load many StructureDefinitions, ValueSets, CodeSystems, etc.
	PrePopulatedValidationSupport prePopulatedSupport = new PrePopulatedValidationSupport(ctx);
	StructureDefinition sd ;
	
	/** LOADING PROFILES **/
	// Read all Profile Structure Definitions 
	String[] fileList = new File("/home/ubuntu/Ndhm Sample/").list(new WildcardFileFilter("*.json"));
	for(String file:fileList)
	{
		//Parse All Profiles and add to prepopulated support
		sd = parser.parseResource(StructureDefinition.class, new FileReader("/home/ubuntu/Ndhm Sample/"+file));
		prePopulatedSupport.addStructureDefinition(sd);
	}

	//Add Snapshot Generation Support
	SnapshotGeneratingValidationSupport snapshotGenerator = new SnapshotGeneratingValidationSupport(ctx);

	//Add prepopulated support consisting all structure definitions and Terminology support
	supportChain.addValidationSupport(defaultSupport);
	supportChain.addValidationSupport(prePopulatedSupport);
	supportChain.addValidationSupport(snapshotGenerator);
	supportChain.addValidationSupport(new InMemoryTerminologyServerValidationSupport(ctx));
	supportChain.addValidationSupport(new CommonCodeSystemsTerminologyService(ctx));

	// Create a validator using the FhirInstanceValidator module and register.
	instanceValidator = new FhirInstanceValidator(supportChain);
	validator = ctx.newValidator().registerValidatorModule(instanceValidator);

}

/**
 * This method validates the FHIR resources 
 */
static boolean validate(IBaseResource resource)
{
	// Validate
	ValidationResult result = validator.validateWithResult(resource);

	// The result object now contains the validation results
	for (SingleValidationMessage next : result.getMessages()) {
		System.out.println(next.getSeverity().name() + " : " + next.getLocationString() + " " + next.getMessage());
	}

	return result.isSuccessful();
}

}

Hello @Pranouti mam,

We are waiting for your reply on this. Could you please help us?

Hello @Pranouti mam, @neha.parnami mam, @Manisha mam, @Gayatrij mam,
Can you help us in this?

@Shubham,

A null pointer exception, comes when you have not set some field which is expected with value by the method / API. I suggest you please recheck your source code. Meanwhile our team will try to see where you are getting this exception.

Hello @Manisha mam,
we have already checked for variable which is throwing null pointer ,but didin’t find any,and also in validate function the arguement type is IBaseResource but it is calling with arguement type bundle in void main() function after returning prescription bundle,so is this can be the issue?

Dear Shubha,

To help you resolve your NullPointer exception can you please join meeting to discuss the issue. The link of meeting is mailed to you on your e-mail id.

Hello mam,

Yes joining in couple of minutes.