Sam’s Petrol is not Sam’s Petrol!

Generating ADX output with OpenMRS DHIS2 Reporting Module

Jayasanka Weerasinghe
3 min readAug 3, 2020

This is the 9th week of my GSoC project. The big focus for this week was generating the XML payload which is ready to be sent to DHIS2.

First, I had to create a new service method to execute the mapped openMRS report and map the result with the dataset. Fortunately, the OpenMRS Reporting Module had enough facilities to achieve it.

DHIS2 accepts the data in a special XML format named ADX. ADX stands for Aggregate Data Exchange. It is an international standard for aggregate health data exchange that is relatively simple, and extensible making it easy to implement in a range of different systems. ADX is developed and maintained by the Quality Research and Public Health committee of the IHE (Integrating the Healthcare Enterprise).

Could you remember the Covid-19 update example I discussed in my previous blog post?

According to the example, this is how it looks like after converting to ADX.

Note that “MALE”, “FEMALE”, “DE_covid_19_patients”, etc. are DHIS2 code values which we entered when we created data elements, categories, and category options.

It was a bit challenging when converting data to this format. I had to go through some docs to find a way to add dynamic attributes. In each ‘dataValue’ element, we have to define the category — categoryOption pairs using their code. ‘GENDER’ is the code of ‘gender’ category and ‘FEMALE’ is the code of category option ‘female’. We have free will to decide code names when we create using the DHIS2 dashboard. As always I used JAXB to convert it to XML. JAXB is a tool that provides the ability to convert objects into XML and XML into objects. When it comes to dynamic attributes; we can simply use @XmlAnyAttribute with QName, String map.

When I’m converting it to XML I get a random error. It says,

“java.lang.ClassCastException: javax.xml.namespace.QName cannot be cast to javax.xml.namespace.QName”

I was like, What?? It’s weird… I have never seen this type of error. It’s something like this,

I couldn’t find an answer from anywhere over the internet. I had done so many experiments throughout the day and finally, I found the answer! Another module of OpenMRS loads the same class with the same package name which is inbuilt in a third-party dependency. It’s happening at runtime. Whenever I create a new QName object it creates from that replica class that is loaded with a different loader. It’s something like another company buys petrol from the original company and repack and resell it using the labels, names, colors as same as in the original brand. It looks the same, but it’s not.

Meanwhile, I joined the newly initiated OpenMRS team “OpenMRS analytics squad”. We had our first call on Friday. I’m so grateful to be a part of that team.

I learned a lot this week; Java stream API, class loaders, JAXB marshaling, ADX, and a lot more. Next week I’m planning to complete the flow end to end. Thanks, Google and OpenMRS for this wonderful opportunity!

Let’s get connected

Follow/connect with me anytime.

Github: https://github.com/jayasanka-sack
Linkedin: https://www.linkedin.com/in/jayasanka-sack
Facebook: https://www.facebook.com/jayasanka.sack

--

--

Jayasanka Weerasinghe

A professional key presser who turns characters into interesting web things 🙂