Routine Report Service Component Diagram

The following component diagram lays out the high-level components and how they interact within the Routine Report Service.  As it's name implies the functionality of this Service is to provide the capability to store report definitions and retrieve generated Reporting and Analytics.

As we can see from the diagram this Service owns the Routine Report definitions, interacts with the Reference Data service to add/remove rights based on those report definitions, and finally retrieve filled in Routine Reports on-demand.


Service owns compiled storage and management, centralizing this in the system while allowing the non-compiled definition to be owned by other ServicesReport SQL will have to have a direct connection to each Service's private database - this means that Reports will likely break often as this internal database(s) change.
Service encapsulates and centralizes the Jasper engineService's will need to store their data all in one database - i.e. if a Service wanted to use it's own PostgreSQL instance, or a separate database, this Report service couldn't handle the multiple connections or types of databases
Report right management (the when and what to add to Reference Data Rights) is centralized here


  • Currently data-pumps, event-based or otherwise, are considered out of scope.  Data pumps could help reduce the cons of this approach listed above regarding report fragility as well as Service databases needing to be co-located in the same PostgreSQL cluster.  The most basic data pump may look like:
  • Jaspersoft Server, which could help us with report filters, scheduling, etc is considered out-of-scope.  We should re-visit this when we'd like these additional features / desire to have a less hack-y filtering solution.

Neither of these two options block the other - they're orthogonal and could be pulled in at any future point.

Alternative - Data wrapper

It's worth noting that an alternative was considered which extended work that had been done in the Requisition Service.  This approach is mainly the same, however instead of the Service having access to the report content database(s), this service expected the report content to be given to it through the RESTful interface.  This has approach has two critical flaws:

  • the report content needs to come from somewhere that's external to the Jasper report definition.  In practice this would mean that if a new report was defined, that a Java programmer would have to write code in the Requisition service (as an example) that was just for providing the data in a neat form to the Report service, along with the Report definition itself.  This is inflexible and works against some of the advantages of encapsulating Reports in a separate service.
  • The Report service would ideally come with a UI module which allowed reports to be administered as well as run.  The UI module that would allow running a report would be problematic:  the user would click a link to run a report, which ideally would just link to this Report service to run the report, however before the report would be run, some sort of call to another Service would likely need to be done to gather the data first (as noted in previous bullet point).  A clean workaround to this didn't seem likely.
  • Preparing the report content would likely involve numerous API calls between services.  For example a Requisition Report would need to pull in facility names and the like from Reference Data.  While this API access is clean (as in the databases are separate), for reports which involve aggregation it's predicted to be unacceptable slow.

For these reasons, this approach of passing the report content data to the Service, was deemed undesirable.

Next Steps

OpenLMIS: the global initiative for powerful LMIS software