Background

OpenMRS has always had a web application component however, the web application focused primarily on basic administrative features and lacked most content, leaving it up to modules and administrators to provide EMR functionality and content.  OpenMRS 2.x is our new major release line with a new vision: to provide a starter set of content along with basic EMR workflows (e.g., registration, basic reports, etc.). OpenMRS 2.x is built on top of a mix of pre-existing OpenMRS modules, and new ones, and the distribution includes the legacy OpenMRS user interface, alongside a new user interface, written from scratch and aimed at point-of-care use. Thus existing modules and forms can still be accessible in OpenMRS 2.x, until they can be rewritten in the new user interface.

We also support two new application development paradigms, that are both more agile and fun than classic OpenMRS webapp development: (1) the OpenMRS UI Framework, which lets you write hot-recompilable Java controllers, and Groovy views, and (2) HTML + JavaScript + REST web service apps, which can be written with non-Java toolsets.

Motivation to build the reference application was due to the work done for the Mirebalais project and we continued with that momentum to develop and release OpenMRS 2.0. It is still early in the maturity of the OpenMRS 2.x line, and you'll surely find occasional Mirebalais references, and hacky ways that code is split across projects.

Developing for OpenMRS 2.x is different from developing for the 1.x application in several ways:

  • Development is expected to be done via modules
  • We are using the a custom UI framework which involves usage of of spring controllers but used a little differently and groovy server pages(GSPs) as the view technology, for more about the framework and using it see UI Framework, this is intended to make development easier, faster and more fun.
    • as mentioned above, we support controller-free HTML + JS + REST approaches as well
  • Development is strongly CI driven, if any anything gets broken on our bamboo server, fixing the build becomes the top priority.
  • We use Compass and Sass to build our CSS
  • We are using several useful Javascript libraries in the UI

The basis of OpenMRS 2.x (and the reason we're able to let new UI Framework-based modules and new HTML+JS+REST-based modules live alongside the classic UI) is the App Framework, which introduces the concept of Apps and Extensions, allowing us to build smaller independent pieces of functionality, and loosely couple them.

IDE

You should use an IDE to do OpenMRS EMR development. There are core OpenMRS developers who use both IntelliJ and Eclipse.

Please do not commit any IDE-specific files to the source code repository. If you are creating a new OpenMRS 2.x module, or you are the first to work on a module with your particular IDE, please modify the .gitignore file as appropriate (e.g. ignore *.iml and *.idea)

IntelliJ

We suggest that you create an "OpenMRS Reference Application" Project and you import OpenMRS core, as well as any OpenMRS modules you will be working on (including new ones you create) as IntelliJ "Modules" in that Project.

We suggest using git at the command line to clone modules from github and then using "Import Modules" to add them into your IntelliJ project.

Eclipse

We suggest that you clone OpenMRS core and modules with git at the command line and import them into Eclipse with the m2e plugin. If you do not know how to work with Eclipse see Getting Started as a Developer for specific instructions.

Contributing code to the core and modules

If you expect to contribute any bug fixes to OpenMRS core and the modules, follow the fork + pull-request git workflow at Using Git

Check out OpenMRS Core

OpenMRS 2.x is generally released on top of the latest stable release of the OpenMRS Platform at the time of its release (e.g. OpenMRS 2.1 was distributed with OpenMRS Platform 1.10.0, and OpenMRS 2.2 is distributed with OpenMRS Platform 1.11.2), but individual modules that make up the OpenMRS 2.x application generally are designed to require lower versions of openmrs-core (and an inspired implementation can mix and match them on top of a potentially-lower version of the OpenMRS Platform).

When working on OpenMRS 2.x you generallyshouldmake bugfixes to openmrs-core for any issues you discover, but you should implement any new features in modules (since new features since are not typically backported to the already-released lines).

You need to check out openmrs-core so that you can run OpenMRS under jetty. This is documented elsewhere on the wiki. We recommend that you make your own fork of the main repository, so that you can submit bugfixes as pull requests.

After cloning the git repository check out the branch that the current OpenMRS 2.x build is based on (e.g. at time of writing this is the 1.11.x branch, => "git checkout -b 1.11.x origin/1.11.x"). To verify this is still the right branch to check out, look at https://github.com/openmrs/openmrs-distro-referenceapplication/blob/master/pom.xml, look at the value of the openMRSVersion property, and get the release branch associated with that property value (e.g. <openMRSVersion>1.11.3</openMRSVersion> => branch 1.11.x).

Database

In order to be able to run openmrs-core you need to install a SQL database, most commonly MySQL.

Run Configuration

To run OpenMRS, use the "mvn jetty:run" goal in the webapp module of openmrs-core.

In eclipse you can set this up as a Run Configuration like:

  • Base directory:

     ${workspace_loc:/openmrs-webapp} 
  • Goals: jetty:run

Set the following VM options to use our preferred webapp name, give OpenMRS sufficient memory, and enable rapid UI development (replacing with correct pointers to the source code you have checked out):

-Dwebapp.name=openmrs
-Xms512m -Xmx1024m -XX:PermSize=256m -XX:MaxPermSize=512m
-DuiFramework.development.referenceapplication=/Users/djazayeri/code/openmrs/openmrs-module-referenceapplication

(See the Development Mode section of Using the UI Framework in Your Module for an explanation of the uiFramework.development setting.)

First-time setup wizard: No demo data

When you go through the OpenMRS first-time setup wizard the first time you run the OpenMRS webapp, make sure you choose not to install demo data.

Building and running the reference application

Most development work on OpenMRS 2.x can be done without needing to check out all the code for all modules in the distribution. You should be able to implement new features by working on the specific module that includes the app in question, or by creating a module with new functionality. To run the reference application, you need compiled versions of all modules in the distribution.

Building the latest distribution

After checking out OpenMRS core, you should check out the OpenMRS Reference Application distribution at https://github.com/openmrs/openmrs-distro-referenceapplication. Running "mvn clean install" in this project will assemble the modules that make up the latest version of OpenMRS 2.x.

You probably want to create a script to run this maven goal, and then copy the assembled modules into your OpenMRS modules folder. For example you might put the following in the root of the openmrs-distro-referenceapplication folder.

#!/bin/bash

mvn clean package -DskipTests
if [ -d ~/.OpenMRS/modules ];
then
    rm ~/.OpenMRS/modules/*
else
    mkdir -p ~/.OpenMRS/modules
fi
cp package/target/distro/*.omod ~/.OpenMRS/modules
echo Done copying omods to module repo

Running the above script from the root of the distro project and then re-running openmrs-core's jetty:run target will run the latest version of OpenMRS 2.x.

Running OpenMRS 2.x in a production-like environment.

The target environment for CI, and other servers is Tomcat7 running on Ubuntu 12.04.  If you'd like create a virtual machine in your environment for testing, see the wiki page: Developer How-To Launch a Local Instance of the Reference Application.

Typically our CI setup will constantly be building the latest versions of the above modules. The only way to be sure you have the equivalent build yourself is to update and build all of these modules regularly.

Writing your own module on top of OpenMRS 2.x

You may write new OpenMRS 2.x functionality by creating your own module, without needing to make any modifications to the existing codebase.

  1. Create the module project following steps described at /wiki/spaces/docs/pages/25481039.
    1. If you intend for your module to be shared with the broader community, you should require the lowest feasible supported version of openmrs-core given the functionality you need to create. If you are building a module just for your implementation, your module should require the version of openmrs-core being used at the implementation.
    2. Make your module depend on something like the following set of modules: (check the latest version in the properties here)
      1. appui 1.2.2
      2. uicommons 1.3
      3. emrapi 1.4
  2. If you intend to host the module project on github, you will need to create a repo for it on github as described at Creating a github repo.
  3. To set up the module to use the UI framework see Using the UI Framework in Your Module. In your omod sub project you might need to also include dependencies for uicommons, appui, and appframework modules.
  4. To share your code on github, from the command line, go to the module project directory and run the git commands below:

    git init
    git remote add origin https://github.com/openmrs/openmrs-module-moduleId.git
    git pull --rebase origin master
    git push origin master

     

     

    Remember to exclude any IDE specific files

     

     

  5. Define an App to appear on the OpenMRS 2.x home page. You should read App Framework Step by Step Tutorial, and get more details at App Framework Developer Documentation.

     

    It is a json descriptor file that you have to add to omod/resources/apps directory in your module, as shown in the example below:

    Example - An App with an extension adding a link to the homepage
    [
        {
            "id": "mymoduleid.myAppId",
            "description": "Text description of my app, not shown to regular user",
            "extensions": [
                {
                    "id": "mymoduleid.myExtId",
                    "extensionPointId": "org.openmrs.referenceapplication.homepageLink",
                    "type": "link",
                    "label": "My App Label",
                    "url": "moduleid/someurl.page",
                    "icon": "icon-user",
                    "requiredPrivilege": "App: mymoduleid.myAppPrivilege"
                }
            ]
        }
    ]

Explanation:

The file name MUST end with '_app.json' to be able to be picked up by the framework.


Meaning of the properties: (*=required)

id*: The application wide unique extension id, it is recommended that it starts with the module namespace e.g org.openmrs.module.moduleId.myExtId

extensionPointId*: The id of the extension point to attach to

type*: Currently supported values are 'link' and 'script', link implies that the value of the url property is an actual URL where for script the value is a javascript function to be executed when the user clicks the app's icon

label: A message code for the short text to display below the icon

url*: A URL to navigate to or javascript function to call when the user clicks the app, the type property above will determine if is a script Vs a URL

icon: The icon to use for the app

order: Determines the order in which the app appears, apps with lower order numbers get to be displayed first while those with higher ones come last on the home page

require: A piece of javascript code to be evaluated, if it resolves to true, the app gets displayed otherwise it is not 

requiredPrivilege:  The privilege the logged in user must have to be able to view the app

 

Developing CSS

We use Compass and Sass to build CSS in the core OpenMRS 2.x modules, and we highly recommend you do also.

See an example of how this is set up by looking at an existing OpenMRS 2.x module, for example the reportingui module. (See everything that mentions ruby, sass, or compass in pom.xml and omod/pom.xml.) 

  • Every time you do a maven build (in the process-resources phase), the contents of omod/src/main/compass/sass will be compiled into omod/src/main/resources/styles (so they can be picked up by the UI Framework)
  • If you are doing active CSS development, and want these files compiled every time you change them, do this from the omod folder:

    mvn process-resources -Pwatch-sass

Developing the core of the OpenMRS 2.x

If you are a core developer, you will most likely need to clone the following modules:

  • EMR API
  • UI Commons
  • App UI
  • Core Apps
  • Reference Application

All modules can be built by running mvn clean install. If some module is not building for you, please check its status in our CI. If it is green, then it means that it is only your local problem and you need to resolve it yourself. If you need assistance, please contact us.

Continuous Integration

We are using Bamboo, running at https://ci.openmrs.org. Automated tests are run against http://devtest01.openmrs.org:8080/openmrs and you may do manual testing against http://devtest02.openmrs.org:8080/openmrs. The scripts that deploy to these servers are run after every commit, we encourage devs to look at the CI server a couple of minutes after they commit their code to ensure no plans are broken as a result of their commit. (Failures are emailed to the dev-refapp@openmrs.org mailing list and reported by OpenMRSBot on our IRC channel.) After completing significant functionality, you should manually verify that it works there. Note that deployment to devtest02 only happens if the ui tests are run successfully against devtest01.