Middleware/Sync Module

The middleware for Intelehealth is developed using Java. The below libraries are used,

  • Maven – This is a build tool which can be used to import the correct version of jar files, compile and deploy the war.The config file for this is POM.xml which is present in the EMR-Middleware folder

  • Jersey - Jersey RESTful Web Services framework is open source, production quality, framework for developing RESTful Web Services in Java that provides support for JAX-RS APIs.

  • SL4J – This library is used for logging

  • Mybatis – This is a persistence framework. It automates the mapping between sql and objects.

  • Gson – This library is used to convert an object to a json string and vice-versa

  • Retrofit - It makes it relatively easy to retrieve and upload JSON (or other structured data) via a REST based webservice.

Purpose of middleware

The purpose of the middleware is to pull and push data from and to the OpenMRS platform to avoid multiple requests from the client to the OpenMRS platform server. It consists of 2 API’s - the Pull Data API and Push Data API. For both API’s basic authorization credentials also should be passed.

Pull Data API

This is a GET request , the url is given as below

http://host:port/EMR-Middleware/webapi/pull/pulldata/{locationuuid}/{lastpulltime}

locationuuid and the lastpulltime is the input paramters this API expects.This API will pull the following parameters based on the location and last created or modified time:

Patientlist,patientAttributeTypeListMater,patientAttributesList,VisitList,encounterList,obslist,locationlist,providerlist,providerAttributeTypeList,providerAttributeList,visitAttributeTypeList, and VisitAttributeList

Push Data API

This is a post request.The url is given below

http://host:port/EMR-Middleware/webapi/push/pushdata

This expects the application/json structure as the input.The sample is given below.

 

{ "persons": [ { "uuid": "8ee4484b-8718-45c8-8e41-8b9d3ce28e4f", "gender": "M", "names": [ { "givenName": "KennethIDGEN", "middleName": "", "familyName": "George" } ], "birthdate": "1955-02-06", "attributes": [ { "attributeType": "14d4f066-15f5-102d-96e4-000c29c2a5d7", "value": "" }, { "attributeType": "5a889d96-0c84-4a04-88dc-59a6e37db2d3", "value": "OBC" }, { "attributeType": "f4af0ef3-579c-448a-8157-750283409122", "value": "APL" }, { "attributeType": "1c718819-345c-4368-aad6-d69b4c267db7", "value": "Primary" }, { "attributeType": "1b2f34f7-2bf8-4ef7-9736-f5b858afc160", "value": "" }, { "attributeType": "ecdaadb6-14a0-4ed9-b5b7-cfed87b44b87", "value": "" } ], "addresses": [ { "address1": "", "address2": "", "cityVillage": "Bengalurur", "stateProvince": "Karantaka", "country": "India", "postalCode": "560043" } ] } ], "patients": [ { "person": "8ee4484b-8718-45c8-8e41-8b9d3ce28e4f", "identifiers": [ { "identifierType": "05a29f94-c0ed-11e2-94be-8c13b969e334", "location": "b56d5d16-bf89-4ac0-918d-e830fbfba290", "preferred": true } ] } ], "visits": [ { "uuid": "ef4fd44b-42cb-437d-9464-6d9109c2f281", "startDatetime": "2019-02-06T12:44:34.662+0530", "visitType": "a86ac96e-2e07-47a7-8e72-8216a1a75bfd", "patient": "8ee4484b-8718-45c8-8e41-8b9d3ce28e4f", "location": "b56d5d16-bf89-4ac0-918d-e830fbfba290" } ], "encounters": [ { "uuid": "0eae3430-c7c6-40d5-a2c4-d128480a91b8", "encounterDatetime": "2019-02-06T12:44:34.662+0530", "patient": "ffc30b9b-0de9-4c10-95e5-227043c8b45b", "encounterType": "67a71486-1a54-468f-ac3e-7091a9a79584", "visit": "5b72525f-f553-4557-b7b1-06801ab2aad9", "obs": [ { "concept": "5089AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", "value": 4 }, { "concept": "5090AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", "value": 25 }, { "concept": "5085AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", "value": 80 }, { "concept": "5086AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", "value": 110 } ], "encounterProviders": [ { "encounterRole": "73bbb069-9781-4afc-a9d1-54b6b2270e04", "provider": "163b48e5-26fb-40c1-8d94-a6c873dd2869" } ], "location": "b56d5d16-bf89-4ac0-918d-e830fbfba290" }, { "uuid":"c3a5747f-607d-4115-a59e-c2280a0b56d5", "encounterDatetime": "2019-02-06T12:44:34.662+0530", "patient": "ffc30b9b-0de9-4c10-95e5-227043c8b45b", "encounterType": "8d5b27bc-c2cc-11de-8d13-0010c6dffd0f", "visit": "5b72525f-f553-4557-b7b1-06801ab2aad9", "obs": [ { "concept": "62bff84b-795a-45ad-aae1-80e7f5163a82", "value": "• Pregnancy status - Not pregnant.<br/>• Alcohol use - Yes - Number of drinks consumed in one go - 3-4.<br/>" }, { "concept": "d63ae965-47fb-40e8-8f08-1f46a8a60b2b", "value": "•Diabetes : Mother.<br/>" }, { "concept": "3edb0e09-9135-481e-b8f0-07a26fa9a5ce", "value": "►<b>Fever</b>: <br/>• Duration - since 5 Hours.<br/> " }, { "concept": "e1761e85-9b50-48ae-8c4d-e6b7eeeba084", "value": "<b>General exams: </b><br/>• Eyes: Jaundice-no jaundice seen. <br/>• Eyes: Pallor-normal pallor. <br/>• Arm-Pinch skin - appears slow on pinch test. <br/>• Nail abnormality-clubbing. <br/>• Nail anemia-Nails are not pale. <br/>• Ankle-pedal oedema in left foot. <br/><b>Any Location: </b><br/>• Skin Rash:-no rash. <br/>• Ulcer:-no ulcer. <br/><b>Mouth: </b><br/>• back of throat normal. <br/><b>Abdomen: </b><br/>• tenderness seen - location - Middle(C)." } ], "encounterProviders": [ { "encounterRole": "73bbb069-9781-4afc-a9d1-54b6b2270e04", "provider": "163b48e5-26fb-40c1-8d94-a6c873dd2869" } ], "location": "b56d5d16-bf89-4ac0-918d-e830fbfba290" } ] }

This data is pushed to the middleware and in turn calls the relevant OpenMRS API’s to add/edit patient, visits, encounters and observations. If each of the object succeeds or fails it returns the uuid and whether that object has synced or not. This sync value will be updated in the android db , so that if an object has not syncd succeessfully it will resend that object in the next try.

General flow architecture

 

  1. Rest Controllers – This can be seen in the com.emrmiddleware.rest package.This is the entry point for the API calls.

  2. Action – This is seen in the com.emrmiddleware.action package.For any computation or API calls to the openmrs platform this is used.

  3. DAO - This is the Data Access object seen in the package com.emrmiddleware.dao.These classes are used to directly query the database.

  4. DMO - This is the Data Mapper object.This maps a query directly to an object.This is seen in the com.emrmiddleware.dmo package.

Images are not uploaded or downloaded through the middleware, it makes direct use of the OpenMRS API’s from the android device. Each image may be a few mb’s , so there would be no advantage in sending a bulk of images especially in areas with poor connectivity to the middleware through one API call.