Monday, June 26, 2023

GSoC 2023 at OpenMRS | Coding Period Week 04

You are welcome to this week's blog. This marks week number 4 of this year's GSoC coding period. I am excited to share what i have been able to achieve throughout this entire week. 

This week i have laboured to look into XML PATCHing and how to implement that in the OpenMRS Fhir2 Module. I started off by creating a utils class in the Util directory within the api directory. I will break down the contents of the class below, please follow along;-

First of all, it contains a static method applyXmlPatch that handles XML patch operations for resources in the context of the FHIR (Fast Healthcare Interoperability Resources) standard.

public static <T extends IBaseResource> T applyXmlPatch(FhirContext theCtx, T theResourceToUpdate, String thePatchBody) {

The applyXmlPatch method is declared as public static, which means it can be accessed without creating an instance of the XmlPatchUtils class. It takes three parameters: 

  • theCtx: An instance of FhirContext representing the FHIR context. 
  • theResourceToUpdate: An object of type T that extends IBaseResource, which represents the resource to be updated.
  • thePatchBody: A String containing the XML patch to be applied to the resource.
@SuppressWarnings("unchecked")
Class<T> clazz = (Class<T>) theResourceToUpdate.getClass();

The above line retrieves the class of the theResourceToUpdate object and casts it to Class<T>. It is used later for parsing the patched resource.

String inputResource = theCtx.newXmlParser().encodeResourceToString(theResourceToUpdate);

This line encodes the theResourceToUpdate object into an XML string using the newXmlParser() method of the theCtx object.

ByteArrayOutputStream result = new ByteArrayOutputStream();
try {
    Patcher.patch(new ByteArrayInputStream(inputResource.getBytes(Constants.CHARSET_UTF8)),
        new ByteArrayInputStream(thePatchBody.getBytes(Constants.CHARSET_UTF8)), result);
}
catch (IOException e) {
    throw new InvalidRequestException(e);
}


 The above block of code performs the XML patching operation using the Patcher.patch method. It takes the encoded input resource as a ByteArrayInputStream, the patch body as another ByteArrayInputStream, and writes the patched result to the result ByteArrayOutputStream.

return theCtx.newXmlParser().parseResource(clazz, toUtf8String(result.toByteArray()));

Finally, this line parses the patched resource from the result byte array using the newXmlParser() method of the theCtx object. It specifies the resource class (clazz) and uses the toUtf8String method to convert the byte array to a UTF-8 encoded string.

Overall, this code provides a utility method for applying XML patches to FHIR resources using the FHIR context and XML parsing capabilities provided by the FhirContext class.

To achieve the patching, we have utilized a library developed by dnaut and can be found at https://github.com/dnault/xml-patch.

I added the dependency to the root pom.xml file in the OpenMRS Module Fhir2 as shown below:-

            <dependency>
                <groupId>com.github.dnault</groupId>
                <artifactId>xml-patch</artifactId>
                <version>0.3.1</version>
            </dependency>

This and more can be accessed from the pull request at https://github.com/openmrs/openmrs-module-fhir2/pull/493.

Thanks for taking time to read through.

Monday, June 19, 2023

GSoC 2023 at OpenMRS | Coding Period Week 03

 

Week three(03) of my GSoC journey was a move into the right direction since it involved assessment of my work so far on my part so as to forge a way forward to meeting all the project objectives. Welcome to the past week's blog post and i hope you enjoy the read or better yet pick something useful from it.

Like the forecast was from last week, this week was more into code reviews and finishing up on some of the resources. I began the week by adding Encounter resource to the resources that need to support json merge patch and json patch operations. 

However the patching was not happening for the Encounter resource and the error below was being returned. Actually this blocker consumed a big chunk of my time this week.

Expected: response with HTTP status indicating request was handled successfully
     but: response with status code <500> with message "Failed to call access method: org.hibernate.HibernateException: A collection with cascade=\"all-delete-orphan\" was no longer referenced by the owning entity instance: org.openmrs.Encounter.encounterProviders"

The issue here was that somehow we deleted an encounter but not the encounterproviders attached to the encounter. This was brought about by how the translation of the Fhir Encounter resource to the OpenMRS Encounter data model was done. On further investigation and consultation with my mentor, we came with a fix for that as can be seen at https://github.com/openmrs/openmrs-module-fhir2/pull/489.

The rest of the week i embarked on making changes as was advised by my mentor especially on the integrations. I  had to migrate them the Integration tests 2.2 directory to the integration tests directory. The former is based of openmrs v2.2 whereas the latter is based off openmrs v2.0.5 so since most resources were supported by openmrs v2.0.5, it was fine to have all our integration tests in that folder save for a few which are not supported upto until version 2.2.

During our weekly meetings with my mentor, part of agenda was the discussion on the need to discuss the projected length of the project for administrative purpose. I wont dive into the reasons here, i am just highlighting it among the developments from last week.

Part of my projections last week was to be able to start on XML Patching but most of the week was taken up in fixing the Encounter resource and making changes as advised on our weekly call.

Appreciation to my mentor Ian for the time he offers to have me unblocked or learn something new. 

Thanks for the taking your time to read through.

Onto next week enthusiastically 😎

Sunday, June 11, 2023

GSoC 2023 at OpenMRS | Coding Period Week 02

Comes another opportunity for me to update my blog with the experience i have had in the past week as i was working on my GSoC project. Here's the Coding Period Week 01 blog in case you missed it. I will breakdown my writing today into the various tickets/issues i encountered throughout this week. I was lucky to have some of work merged this week and it felt awesome 😍.

toOpenmrsType translators should set uuid to id part of id, not full: This ticket was created to fix the bug that was on a couple of the resources. This would cause an error where the uuid provided would exceed the maximum length which is 38. For example when i tried doing a patch operation on the patient resource, the error i got was failed to validate with reason: uuid: This value exceeds the maximum length of 38 permitted for this field. This was fixed and merged into master to cater for all other resources it could be affecting.

Add support for Json Patch operations - Patient Resource: This was meant to introduce the json patches to work along with the json merge patches as i explained in the previous blog. This work was also merged into master and it was able to unblock all the other tickets that would wish to implement any of the two patch formats. The rest of  the implementation can be at this commit.

Add Support for Json Merge Patch - Service Request Resource: This was meant to introduce json merge patch operations to the Service Request resource. However, this resource was not fully translated into the OpenMRS data model. Hence after spending hours on it, my mentor advised that i created a ticket for it but that could be out of scope for this project. So for future work on the module i ticketed the required changes at https://issues.openmrs.org/browse/FM2-591. This therefore means that the Service Request resource could also be out of scope for this project unless towards the end i get sometime at hand to dive into fully translating the resource.

Add support for Json Merge Patch operations - Medication: This was meant to introduce json merge patch operations to the Medication Resource. The pull request has been sent in and it is await review and hopefully merging into master. While working on this, i realized that the OpenMRS fhirIG index page didn't cater for the Medication resource so that it is easier to locate on the IG so i pushed a followup commit to ensure it does that and it is awaiting review and merging.

This was pretty much it from this past week and i am hoping this week will be more of review of the many pull requests i have created and having them merged. I also intend to work on the integration tests to test out the json patch functionality on the resources.

Thanks for taking your time to through, cheers 🍸🍷



Monday, June 5, 2023

GSoC 2023 at OpenMRS | Coding Period Week 01

 


Greetings all, coming to the end of the first week of the 2023 Google Summer of Code Coding period  which officially began on 29th, May 2023. Here's my project OpenMRS talk post https://talk.openmrs.org/t/gsoc-2023-fhir-add-support-for-fhir-patch-operations-project-updates/39555?u=mherman22.

Having held a couple of meetings with my mentors and being guided on how to go about the whole period, i was advised to first of all choose five(5) resource providers and implement JSON_MERGE_PATCH patch operations, after that is done i can then implement XML_PATCH for those same resource providers. I would then go on to the other formats like FHIR_PATCH_JSON and FHIR_PATCH_XML.

I set out to implement JSON_MERGE_PATCH operations on on R4 Resource providers that included the following Patient Resource, Condition Resource, Location Resource, Person Resource and Allergy Intolerance Resource. To ensure that the implementation i am adding to the OpenMRS-Module-Fhir2, i have to include integration tests.

Everything went on as planned as i was implementing the JSON MERGE PATCH operations for resources like condition, location but things got a little complicated when i had to make patches for resources like patient, person. This was because these resources had some complicated JSON documents that included Arrays, Lists hence not being able to do operations like replace on them hence a JSON MERGE PATCH not being feasible. This is something that i initially missed when i was reading through the JSON MERGE PATCH RFC documentation.

The quote below is from the RFC

Also, it is not possible to patch part of a target that is not an object,such as to replace just some of the values in an array

On consultation with my mentor, he pointed me to the hapi/fhir interceptor that was added to the openmrs fhir module that simply intercepted the patch operations and converted the JSON_MERGE_PATCH operations into JSON_PATCH operations. This was done because of the fact that the PatchTypeEnum enum class from hapi fhir does not really provide an implementation for JSON_MERGE_PATCH operation. So all that this means is Json merge patch and Json patch were both coming across as the same type since we needed to use one of the values in PatchTypeEnum (which doesn’t support Merge Patch), so we hack around this by temporarily making it appear that a merge patch request is actually a JSON patch request. Here's the implementation of this https://github.com/openmrs/openmrs-module-fhir2/blob/master/omod/src/main/java/org/openmrs/module/fhir2/web/util/SupportMergePatchInterceptor.java.

The task at hand to find a way of separating the two operations(JSON PATCH vs JSON MERGE PATCH). I created the ticket https://issues.openmrs.org/browse/FM2-579 to track these changes. I did the following, i created an if-else statement under JSON_PATCH because both merge patches and normal patches will come in under that. What i did is to get the RequestDetails object (add it as a parameter to the patch method on the provider and then pass it to the service method call and check the Content-Type. If it’s application/merge-patch+json, then it’s a merge patch, otherwise, treat it as a JSON patch. Checkout the pull request at https://github.com/openmrs/openmrs-module-fhir2/pull/483

With the pull request above, we can now implement both JSON PATCH and JSON MERGE PATCH operations on the OpenMRS-Module-Fhir2. With the second coding week imminent, i hope to finalize with json patches and json merge patch operations on the remaining resources.

 I am loving the journey and the lessons 

Below are the pull requests from week 01:-