Metadata Sharing Project
This page refers to a ?Summer Of Code 2010 project. Please see the ?Metadata Sharing Module documentation page for the outcome.
Deliverables, in approximate order
Manually select metadata to export
Export a package of metadata as a file
Import a packaged file, thus creating/editing metadata locally
Publish a packaged file, along with extra version info
Subscribe to a published URL, thus importing a package
Check for updates on subscribed URLs, and download them
Timeline
Timeline includes only the three first deliverables that are initially planned to be implemented within the GSoC project.
Sourcecode
Sourcecode is available in the OpenMRS repository:
http://svn.openmrs.org/openmrs-modules/metadatasharing/
Class Diagram
Select Metadata to export
Need a way to find and list all OpenmrsMetadata
Initially we can hardcode known classes with their getter methods.
For release, we need this to be dynamic, so that metadata provided by modules is included too.
Maybe scan the classpath for classes that implement the interface
Maybe introspect all OpenmrsServices, looking for getAll() and get*ByUuid(String) methods
Need a special-case to handle 'Concept' which does not implement OpenmrsMetadata, but is the most valuable type of metadata to share.
Identify dependencies between object
Fail on circular dependencies
Export a Metadata Package
XML? JSON?
if there's no specific reason for JSON I'd prefer we stick to XML -Rafal
sounds fair -Darius
Serialization
org.openmrs.User: drop any of these properties
primitives: easy
lists, sets, maps: easy
anything that extends OpenmrsMetadata: replace with class & uuid
anything else (i.e. complex objects that are not OpenmrsMetadata): recursively serialize
All serialized in one file? Or a zip of individual files for each metadata item? Order matters.
Why order matters anyway? -Rafal
Because of dependencies between metadata. If you are exporting a form, and that form contains a concept, you need to import the concept before the form. -Darius
Import a Metadata Package
Go through package one item at a time.
If there's already an existing local entity with the same uuid, ask the user if they want to overwrite. (If not, cancel the whole thing.)
Once all is confirmed, create/save all items
Keep imported packages around to help with reverting local modifications later
(This may belong under Subscribing, but it might be possible to implement it when importing.)
Identify local modifications
Version 1: fail on this case
Version 2: allow overwriting local changes
Version 3: allow merge, ignore, etc
Publish a Metadata Package
Publish a package with
Name
Version/revision (auto incrementing integer, nothing fancy like "4.0.2")
Publishing authority (e.g. "WHO")
What URL to check for updates
This will create a file (which should be persisted on the server) and can be downloaded, or fetched via a web service
Subscribe to a Metadata Package
Two ways:
upload a file
enter a URL
Some sort of download / check / apply / error workflow and status
Once a package is applied, record what version/revision of it we're at.
Check for updates
Check all update urls to see which subscribed packages have new versions available. (Checking versions should use very little bandwidth.)
Download the new version, apply it, and record new version/revision we're at.
Also allow this to be done by uploading a file (e.g. distributing updates via USB stick)
(Way) Future Work
A package should be able to be a link to other packages, e.g. a 'Rwanda Locations' package could actually just be symlinks to 'Rwanda District Hospitals' and 'Rwanda Health Centers'
Allow replacement, e.g. I am downloading a metadata package that contains a concept for Weight, but I want to use my own (compatible) weight concept, not the downloaded one.
One solution for this would be to use a uuid-->uuid mapping table. If a user chooses an existing concept, you map the uuids so that any future import can continue without a problem