Moving toward configuration file-based setup

Hi all,

I’d like to initiate a proposal for establishing a convention for how and where we enable configuration-file-based setup of OpenMRS. My starting proposal is to reserve a directory named “configuration” within the existing application data directory. Within this directory, we would namespace based on module ID, and a “core” directory for OpenMRS core configuration.

Example: I want to enable implementations installing the addresshierarchy module to be able to automatically set-up their address template, address levels, and address hierarchy entries upon startup. And I don’t want them to have to write Java code in a custom module to do it. So, I would add a feature to do this in addresshierarchy, and it could load the necessary configuration files from: {application_data_dir}/configuration/addresshierarchy/* as needed. One could easily imagine MDS supporting loading metadata packages on startup in much the same way.

More details / TLDR:

Currently there are a variety of ways that organizations are supporting the distribution of OpenMRS with a particular configuration setup (metadata, global properties, and other settings).

Historically, at least in the last few years, what we have done at PIH is to embed this configuration in code, to be executed during the started method in one or more module activators. Our method of choice has been to use metadatadeploy with the configuration compiled into our omods. This has given us a great deal of control, type safety, and the ability to know exactly what is being installed. The drawback of this approach is that it removes the configurability of the system from our implementation teams, and leads to a not-entirely-great situation where content or configuration changes (eg. adding new diagnoses or a new question to a form) require a new software release.

As I have started exploring Bahmni recently, one aspect that I have appreciated is the separation between the installed software distribution and the configuration of this distribution. By moving configuration out of the compiled code and into a separate project (eg. see this provides more of an ability to empower the implementation team to change the system configuration, create reports, and add new content, without depending on OpenMRS Java development.

However, one thing I have noticed with Bahmni (and I’d appreciate @darius / @vinay / @vsingh and others’ input on this) is that there is no established set of conventions for it to follow, and it’s taking over the application data directory in a way that feels unsustainable. For example, here is what mine looks like on a vanilla install:

drwxr-xr-x. 3 bahmni bahmni 4096 Apr 26 14:08 activemq-data -rwxr-xr-x. 1 bahmni bahmni 58 Apr 26 14:07 lrwxrwxrwx. 1 bahmni bahmni 22 Apr 26 14:08 bahmni_config -> /var/www/bahmni_config -rw-r–r--. 1 bahmni bahmni 274 Apr 26 14:07 drwxr-xr-x. 2 bahmni bahmni 4096 Apr 26 14:06 bin lrwxrwxrwx. 1 bahmni bahmni 48 Apr 26 14:08 encounterModifier -> /var/www/bahmni_config/openmrs/encounterModifier drwxr-xr-x. 2 bahmni bahmni 4096 Apr 26 14:07 etc drwxr-xr-x. 2 bahmni bahmni 4096 Apr 26 14:06 lib drwxr-xr-x. 2 bahmni bahmni 4096 Apr 26 14:07 log drwxr-xr-x. 3 bahmni bahmni 4096 Apr 26 14:07 lucene drwxr-xr-x. 2 bahmni bahmni 4096 Apr 26 14:07 modules lrwxrwxrwx. 1 bahmni bahmni 44 Apr 26 14:08 obscalculator -> /var/www/bahmni_config/openmrs/obscalculator drwxr-xr-x. 8 bahmni bahmni 4096 Apr 26 14:06 openmrs -rw-r–r--. 1 bahmni bahmni 256978 Apr 27 18:17 openmrs.log -rw-r–r--. 1 bahmni bahmni 49419046 Mar 21 17:54 openmrs.war lrwxrwxrwx. 1 bahmni bahmni 45 Apr 26 14:08 ordertemplates -> /var/www/bahmni_config/openmrs/ordertemplates lrwxrwxrwx. 1 bahmni bahmni 55 Apr 26 14:08 patientMatchingAlgorithm -> /var/www/bahmni_config/openmrs/patientMatchingAlgorithm drwxr-xr-x. 2 bahmni bahmni 4096 Apr 26 14:09 person_images drwxr-xr-x. 3 bahmni bahmni 4096 Apr 26 14:07 run

If we had a convention like I am proposing, then we might see bahmni_config,, encounterModifier, obscalculator, ordertemplates, patientMatchingAlgorithm, etc. all underneath a “configuration/bahmnicore” folder.

The fact that they also seem to be using this directory for lots of other things, including Tomcat, is also likely problematic, but that’s for another thread.

Thoughts on this idea? @burke / @darius?

Thanks, Mike

1 Like

I think i agree with having a convention but I don’t think not being able to implement things such that they can be configured outside Java code is because we have no convention. I guess my point is that currently nothing stops you from Implementing address hierarchies such that they can be configured externally in a file

@wyclif - not sure if this is an endorsement?

Correct, nothing is stopping me from doing this. But before I do it, I’d like to establish if there is a conventional way we can agree to do it, so every module owner doesn’t go their own way.

Ultimately my goal is to maintain github projects containing configuration for our distributions, and to be able to version these and install them into my application data directory. If we all use the “configuration/moduleid” approach, then I can do that. If some modules put their configuration files in other random locations, then this becomes harder.

I also want to ensure I’m not going to choose a file location that another module owner might choose and clash with. A convention establishes rules by which I can follow and feel confident in.

Finally, I don’t want implementers to have to learn the 50 different locations where they need to configure things, based on module developers whims. A convention at least encourages consistency and makes it easier to for things to work as people expect.

Thanks for the quick feedback…


I do agree that we should have a convention, what I said in my previous reply was just a by the way.

I agree having a convention is a great idea.

I like this idea.

As to what it takes to make this a reality, I would think: (a) describe this convention on a wiki page (b) PIH (or others) take the initiative to make a couple modules (e.g. addresshierarchy) follow this pattern

And I suggest helper methods or something in core that enables easy path to follow the convention

Did we settle on that approach? @pkornowski, could you please store sync2 config as agreed here?

Okay, I’ll do that. Thanks!