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

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.