Imagine a world where content & functionality can easily be distributed, versioned, and added to existing OpenMRS systems, whether to support a single distribution or to share functionality across multiple different implementations or distributions.
OpenMRS started with a modular architecture and OpenMRS modules:
- Write Java code following OpenMRS module conventions
- “Zip” it into a Java Archive (.jar) file
- Change the extension from
.omod(for OpenMRS module)
These can be hot-loaded into a running system to add or change any system behavior.
OpenMRS modules allow implementations to take a base system and adapt it to meet their needs. But we often need to do more than introduce Java code; we need to introduce or share content or, in the case of OpenMRS 3.0, frontend (non-Java) code. There have been several workarounds and new approaches over the years:
- Modules created to import & export metadata (e.g., metadata sharing, iniz)
- Modules that deliver embedded metadata (e.g., PIH content modules, refapp demo data)
- Combine code and content within a pre-defined folder structure
- Zip it up using Maven (or OpenMRS tools)
- Distribute as Maven artifact
Use these to add new capabilities to existing system, define the basis for a distribution/deployment, or share capabilities with others.
While an OpenMRS module is Java code, an OpenMRS Package can contain any/all of:
- ESMs (frontend modules)
- Metadata (concepts, forms, reports, analytics transforms/rules)
- Configuration settings
- Other packages
These assets are arranged into a conventional folder structure (like the 3.x folder structure) and zipped up into an archive that can be used by the SDK and other tooling to deploy or share the content & functionality.
Why use Maven? Maven already provides the mechanism to package artifacts, manage dependencies, etc. We don’t need to be re-inventing or coming up with OpenMRS-specific approaches when widely-adapted established tooling can meet our needs.
Do we need a manifest file? Information about the package (owner, version, etc.) would typically be included in a manifest file. Since we are using Maven to manage and distribute artifacts, we should try to leverage these capabilities within Maven (e.g., the POM file) before creating OpenMRS-specific (bespoke) approaches.
Can packages be installed into a running system (like modules)? Currently, ESMs (frontend modules) are compiled into a unified frontend using Webpack in a compile step that happens before the system is run and we don’t have a mechanism to introduce new frontend modules on the fly to a running system. This means OpenMRS packages (at least any new frontend features) will need to be introduced in a compilation step prior to running a system. We hope we can overcome this and create a path for introducing new frontend modules during runtime in the future in a way that doesn’t compromise performance or security.
What’s the difference between a OpenMRS package and an OpenMRS distribution? An OpenMRS package bundles content & behavior that can be used to build a system or added to an existing system; while a package might declare compatibility with certain versions of the platform, it can work within any compatible platform). A distribution includes the entire stack (including the specific version of platform & framework).
Moving the conversations forward…
- Reaching consensus on packaging conventions
- Adapting the SDK and other tooling to follow and promote those conventions
- We’ve already done some work to build upon the conventions of iniz and arranged the 3.x refapp folder structure to build OpenMRS 3.0
- Migrating add-ons to adopt packaging conventions