Implementing communication client step by step
Since module version:
1.2.0
If one needs to implement a new communication client like FHIR or REST this tutorial will show you how it can be achieved.
Note: Currently, we only support HTTP based communication clients.
In order to create a new communication client you will have to follow these 9 steps:
STEP 1. Add dependency to FHIR module:
Add this line to your properties in pom.xml:
<fhirVersion>1.X.Y</fhirVersion>
Note: Specify version you wish to have dependency on by setting 'X' and 'Y' values. Minimum version is 1.14.0.
Add this block to your dependencies in your API and OMOD pom.xml files:
<dependency>
<groupId>org.openmrs.module</groupId>
<artifactId>fhir-api</artifactId>
<scope>provided</scope>
<version>${fhirVersion}</version>
</dependency>
STEP 2. Implement org.openmrs.module.fhir.api.helper.ClientHelper interface:
org.openmrs.module.fhir.api.helper.ClientHelper interface
/**
* <h1>ClientHelper</h1>
* <p>Adapts specific Client to be used by pull & push business logic.</p>
*
* @see <a href="https://issues.openmrs.org/browse/SYNCT-274">SYNCT-274</a>
* @since 1.14.0
*/
public interface ClientHelper {
/**
* <p>Implements creation of retrieve request appropriate for specific Client.</p>
*
* @param url represents URL of resource to be retrieved
* @return returns new RequestEntity with 'retrieve' request
* @throws URISyntaxException
*/
RequestEntity retrieveRequest(String url) throws URISyntaxException;
/**
* <p>Implements creation of create request appropriate for specific Client.</p>
*
* @param url represents URL of resource category, where an object will be created
* @param object represents an object that will be sent
* @return returns new RequestEntity with 'create' request
* @throws URISyntaxException
*/
RequestEntity createRequest(String url, Object object) throws URISyntaxException;
/**
* <p>Implements creation of delete request appropriate for specific Client.</p>
*
* @param url represents URL of resource category, from where an object will be deleted
* @param uuid represents UUID of the object, that will be deleted
* @return returns new RequestEntity with 'delete' request
* @throws URISyntaxException
*/
RequestEntity deleteRequest(String url, String uuid) throws URISyntaxException;
/**
* <p>Implements creation of update request appropriate for specific Client.</p>
*
* @param url represents URL of resource, that will be updated
* @param object represents an updated object
* @return returns new RequestEntity with 'update' request
* @throws URISyntaxException
*/
RequestEntity updateRequest(String url, Object object) throws URISyntaxException;
/**
* <p>Returns Class object corresponding to category name.</p>
*
* @param category represents name of category
* @return returns Class object
*/
Class resolveClassByCategory(String category);
/**
* <p>Returns a list of HTTP interceptors used in communication between nodes.</p>
*
* @param username represents username of a user
* @param password represents password of a user
* @return return a list of custom interceptors
*/
List<ClientHttpRequestInterceptor> getCustomInterceptors(String username, String password);
/**
* <p>Returns a list of custom converters, that will be used to convert messages between formats.</p>
*
* @return returns a list of custom converters
*/
List<HttpMessageConverter<?>> getCustomMessageConverter();
/**
* <p>Compares two objects of the same category.</p>
*
* @param category represents category of two compared objects
* @param from represents incoming object
* @param dest represents destination object
* @return returns true if objects are equal, false otherwise
*/
boolean compareResourceObjects(String category, Object from, Object dest);
/**
* <p>Converts a String of formatted data to an object of a specified class.</p>
*
* @param formattedData represents data as a String
* @param clazz represents desired class of returned object
* @return returns an object of specified class
*/
Object convertToObject(String formattedData, Class<?> clazz);
/**
* <p>Converts an object to a String of formatted data.</p>
*
* @param object represents an object that will be converted to a String of formatted data
* @return returns String of formatted data
*/
String convertToFormattedData(Object object);
/**
* <p>Converts an object to OpenMRS object of specified category.</p>
*
* @param object represents an object that will be converted to OpenMRS object
* @param category represents category of OpenMRS object as a String
* @return returns OpenMRS object of specified category
* @throws NotSupportedException
*/
Object convertToOpenMrsObject(Object object, String category) throws NotSupportedException;
}
for example:
TestClientHelper class
Note: We will be using TestClientHelper example until the end of this tutorial.
STEP 3. Modify Sync2 module. Add a new constant to org.openmrs.module.sync2.SyncConstants:
As a name take the first part of your ClientHelper interface implementation class name, in our case it will be:
org.openmrs.module.sync2.SyncConstants class
STEP 4. In Sync2 module add a new case to org.openmrs.module.sync2.client.ClientHelperFactory switch:
org.openmrs.module.sync2.client.ClientHelperFactory class
Remember: You have to import TEST_CLIENT constant first.
STEP 5. In Sync2 module, in org.openmrs.module.sync2.api.utils.SyncUtils class, implement your own method for extracting UUID from your resource link:
Note: Name of this method follows this pattern: extractUUIDFrom<name of your client>Resource.
STEP 6. In Sync2 module add a new case to org.openmrs.module.sync2.api.utils.extractUUIDFromResourceLinks switch:
org.openmrs.module.sync2.api.utils.extractUUIDFromResourceLinks method
Note: As an argument of your extract method put "resourceLinks.get(client)".
Remember: You have to import TEST_CLIENT constant first.
STEP 7. When running your OpenMRS instance, go to Atomfeed > Load Configuration page
Add your API endpoints to linkTemplates object in JSON file, for example:
Atomfeed configuration
Note: Key (in our case "test") must match TEST_CLIENT constant that was set in STEP 2.
STEP 8. Set your communication client as preferred client for pulling resources.
From Home page go to System Administration > Advanced Administration > Maintenence > Advanced Settings.
Find sync2.resource.preferred.client property and set its value to the value of TEST_CLIENT constant, for example:
STEP 9. That's the end. Once you have finished this tutorial, you should have a working communication client.