Posts Tagged ‘design patterns’

OpenMRS Module Development Learnings – 102

Update November 2018: This blog post has been superseded by the OpenMRS SDK (https://wiki.openmrs.org/display/docs/OpenMRS+SDK)
My team mates and I are completing a number of OpenMRS workshops focused on improving our module development capability. This blog post captures the unwritten lessons that we have picked up as a way of giving back our lessons to help others in the community (and will be moved to the OpenMRS Wiki once the lessons have been internalized and consolidated, as that is its natural home).
The approach is based on the following OpenMRS community articles:
  1. Creating Modules – https://wiki.openmrs.org/display/docs/Creating+Modules
  2. Creating your First Module – https://wiki.openmrs.org/display/docs/Creating+Your+First+Module
As you develop the module it is important to keep testing and verifying whatever you do especially when the module involves user interface components, extending the OpenMRS UI. The process we ended up using was as follows:
  1. Setup a module using the module creation command line utility
  2. Downloaded Spring Loaded from its maven repository http://mvnrepository.com/artifact/org.springframework/springloaded
  3. Downloaded and setup OpenMRS standalone from http://openmrs.org/download/ picking a version greater than 1.11.x which supports debugging options
  4. Once the standalone version is installed, open the openmrs-standalone-runtime.properties and add the following variables to the vm_arguments: (should all be one line – separated here for clarity)
    • -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000
    • -Dmodule.development.directory={absolute path to root folder of the module}
    • -javaagent:{absolute path to spring loaded jar}
    • -noverify -Dspringloaded=inclusions=org.openmrs.module.modulepackage..* (note the two trailing dots before the *)
  5. Setup newly the module into an IDE (tested with IntelliJ & Eclipse)
  6. Installed a FileSync utility, RemoteSynchronizer for IntelliJ & FileSync (http://andrei.gmxhome.de/filesync/) for Eclipse
  7. Setup sync for the omod webapp folder into the standalone webapp folder located at WEB-INF/view/module/{modulename}
Our development workflow is smoothened out since any changes to Java classes & JSPs are automatically applied & reflected in the standalone app.
Additional Tips and Tricks
  1. Tomcat – Change the following init params in web.xml:
    • modificationTestInterval from 4 to 0, so that JSPs are automatically recompiled
    • development is true (this is the default)
  2. Intellij – the Java classes are not automatically recompiled on saving changes so there is need to run mvn package -DskipTests
  3. Follow the OpenMRS conventions as much as possible by cloning openmrs-core to see how the design of the interfaces, service layers is done. This will help get access to lots of the magic that happens behind the scenes.
  4. Java 8 will give you trouble, stick to 1. 7 as we did not try 1.6 anywhere.

 

Doctrine2 – Day 1 – Commentary from the Trenches

The new year is here so it is time to get cracking on infrastructure for the year’s development projects. There are a number of things we have been putting off, but now that a number of our client hosts support PHP 5.3, it is the right time to move up the stack for our ORM from Doctrine 1.2 to Doctrine 2 (which feels more like Hibernate) than anything else.

Well step 1 was downloading it, I went straight to Github (https://github.com/doctrine) , got the Doctrine-ORM unpacked it dropped it into the library/Doctrine and was chugging away when I got errors. Seems like some classes were missing …

Tip #1: Download the ORM or DBAL packages from the main project website and you will get all required classes

Anyway classes in tow, I started cutting away at the Doctrine 1 classes to remove all that is not supported it is alot. Doctrine 1 was an Active Record implementation (http://en.wikipedia.org/wiki/Active_record) which meant that you had to extend a base class Doctrine_Record, while Doctrine 2 is a data mapper (http://martinfowler.com/eaaCatalog/dataMapper.html), you write POPOs (Plain Old PHP Objects) for which you provide the mapping metadata so the database access is handled by a service layer.

We chose to use PHP Annotations over YAML and XML so that we do not introduce any dependencies and maintain the mapping metadata within the model classes.

Next step was integration with Zend Framework, so I followed the instructions at the Mayflower Blog (http://blog.mayflower.de/archives/799-06.12.-Doctrine-2-Zend-Framework-Integration.html)  with the following tweaks:

  1. Application.ini – instead of using doctrine.connectionParameters maintained the resources.db.params configuration which we use for storing sessions in the database using Zend_Session
  2. Bootstrap – load the resources.db settings and change configurations user to username and adapter to driver which Doctrine2 expects.
  3. Change production caching to ArrayCache since the shared hosts do not usually support APC, this will change on a project to project basis.

At least now the pages load now into the model configurations. We use two base classes BaseRecord was the one which extends Doctrine_Record in 1.2, and BaseEntity which provides commonly used properties id (autoincrement), datecreated, created by, lastupdate date and last updated by columns which are common to all tables.

First step was to add the mapping annotations, the column definitions are similar to Doctrine 1 with sensible defaults, which helps. However the associations were a mean piece of code, since the Doctrine 2 conventions are a total mismatch to normal database terminologies which I was used to. Opened a github issue too at https://github.com/doctrine/orm-documentation/issues/80 (my first Github and Open Source issue)

Anyway what is interesting in the association mapping is that the mapping columns are defined in the annotation and private variables are not defined for the mapping columns (at least I do not see that in the examples) may come back to bite me later when I start saving the entities, but that is for another time

So anyway classes setup, now the next problem I ran into. In Doctrine 1, the Doctrine_Record provided two methods:

  1. Merge – which merges data into the object
  2. SynchronizeWithArray – same as merge, but had an added function, if you have relations defined and do not pass information in them, then the relations are removed, which was excellent for cases where you need to remove relations in a hurry

Where does this leave me now, action items are:

  1. Setup automated binding of an array of data to the object, and how to deal with relations …
  2. Update the application code to enable an object to load its details from the database … seems crude I will look at what others do
  3. Add Validators since Doctrine2 provides none. Now I need to poke into how I can use Zend_Validators without too much overhead and new changes for my team …

Anha one last one, I wanted to have a PDF of the documentation, since I wanted to use it on my PC faster than opening pages, but none was available. I pinged Jonathan Wage (http://www.jwage.com/) and he pointed me to Read the Docs ( http://readthedocs.org/) which generates documentation for projects from Github etc, so you should check it out. Anyway I searched for Doctrine ORM documentation, downloaded a PDF and now I am in business.

All in a day’s work, and I hope to keep plodding and poking into it as promised.

My take on Day 1, the models feel light weight and more like POJOs, well I think PHP is becoming more and more enterprise ready as it supports core patterns of Enterprise Architecture a Martin Fowler religion that I subscribe to …

Till next time