Wiki Spaces


Get Help from Others

Q&A: Ask OpenMRS
Discussion: OpenMRS Talk
Real-Time: IRC Chat | Slack


Page tree
Skip to end of metadata
Go to start of metadata

What this module does

This module creates easy handle points for other modules to hook onto. When an event occurs in openmrs it will notify all registered/subscribed listeners.


View Source:
Checkout Source:

Technical Documentation

Possible Actions

An enum on Event.Action contains the possible actions of CREATED, UPDATED, RETIRED, UNRETIRED, VOIDED, UNVOIDED, PURGED

Registering module domain objects for which to fire events

The module's domain objects must be subclasses of OpenmrsObject.
If you wish for retired/unretired or voided/unvoided events to be fired, they should implement Retireable or Voidable respectively.

To subscribe to an event

In your module activator or anywhere else in your module code:

Event.subscribe(Class, String, EventListener); // The String argument can be any of the values in the Event.Action Enum
Event.setSubscription(SubscribableEventListener); // spring callable, see below

or in your Spring moduleApplicationContext:

<bean class="org.openmrs.eventbus.Event">
   <property name="subscription"><bean class="org.your.module.package.SubscribableEventListenerImpl"></bean></property>

A SubscribableEventListener specifies the list of Classes and list of Actions that it supports.

Getting notified of an event.

The module uses apache's ActiveMQ messaging server, your EventListener class should extend EventListener and its onMessage(Message message) will be called

Unsubscribing from an event

Event.unsubscribe(Class, Action, EventListener);
Event.unsetSubscription(SubscribableEventListener); // just because its cute

Using external ActiveMQ instance

By default, event module uses embedded ActiveMQ instance.
If you would like to use standalone ActiveMQ instance, simply set activeMQ.externalUrl Global property with a value of your desired ActiveMQ instance and restart module.
Example ip address:

Example Client code

  • The Atom Feed Module takes advantage of this module.
  • The below class should be registered to the Event class with Event.subscribe(____, new CountEventListener());
// A simple event listener that just keeps a count of all created, updated and purged items
public class CountEventListener implements EventListener {

	private int createdCount = 0;

	private int updatedCount = 0;

	private int purgedCount = 0;

	public int getCreatedCount() {
		return createdCount;

	public void getUpdatedCount() {
		return updatedCount;

	public int getPurgedCount() {
		return purgedCount;

	public void onMessage(Message message) {
		try {
			MapMessage mapMessage = (MapMessage) message;
			if (Action.CREATED.toString().equals(mapMessage.getString("action")))
			else if (Action.UPDATED.toString().equals(mapMessage.getString("action")))
			else if (Action.PURGED.toString().equals(mapMessage.getString("action")))

                        //..... Keep counts for more event actions
		catch (JMSException e) {
			System.out.println("Ooops! some error occurred");


Release Notes


  • Fixes the issue of OpenMRS hanging on startup due to incorrect activemq-data location (EVNT-31)

2.2 (broken for bean subscription, please use 2.2.1)


  • Changed module so that it works via Hibernate Interceptors instead of AOP (EVNT-22)


  • Handle saving of subclasses (EVNT-23)
  • Added person to list of supported classes (EVNT-24)


  • Handle events on Orders (EVNT-21)


  • To be written after release


  1. At a glance, I'm not sure we want to be exposing these as static methods (Event.subscribe); for style shouldn't they be in a service or a bean or something?

    (I'm sure the 99.99% use case is to have a singleton Event object, so the static method will work fine.)

    1. I intentionally didn't put it into a service to make it easier to call. And making it a bean doesn't make it any more settable by sprint.