November Tech Report

rnjn
Bahmni Blog
Published in
7 min readJan 15, 2016

Standalone components

Early in 2016 we will release Bahmni components which will run as standalone services, as against web-apps on a tomcat server. This means that each component may be started, stopped and reasoned with separately. Each service can be started using standard centos6 service inits — service start <component>, service stop <component>, service restart <component>. Each service will run on its own port.

We have designed the components to be installed in locations according to the Linux Filesystem Hierarchy Standard. Roughly, this means all our configs go to /etc, all our binaries go to /opt/<component>, logs go to /var/log/<component> and pids can be found at /var/run/<component>

All our component service will be run by/under a non-admin (no sudo), no-login (no ssh or login) user — bahmni. This means that only the bahmni user will have relevant permissions to access files needed for running a component.

Bahmni component packaging

Late this October we started working on upgrading our packaging of Bahmni artifacts — our components — openmrs, lab, erp and connects. We decided to version, transport and install our components using standard yum packaging (RPMs) — using Netflix’s Nebula gradle plugin The code is here. We should be able to leverage the following benefits of using RPMS -

  1. Versioning — all client machines will be able to use the standard Yum package versioning (see list of installs, upgrade or install to a version, search for Bahmni packages)
  2. Release components only, when needed.
  3. Standard packing and distribution (we are already leveraging a fast third party rpm host — bintray)

All our builds result in RPMs and our CI server uploads them to our packages repo We have added a release pipeline that will be manually triggered to “release” a new version to https://bahmni-repo.twhosted.com/packages/bahmni-release/ and also to Bintray for bahmni We expect our production installations to look at the Bintray repository, interested developers can look at the former for develop builds.

There have been requests from the community to target debian packages that work on Ubuntu linux machines, and on that front, we are looking forward to stabilise our rpm packaging first, and then help the community in building the corresponding debian packages.

Provisioning Bahmni using Ansible

We started work on ansible scripts to provision bahmni installation in November. The code is here. We chose ansible because -

  1. Ansible scripts are standard yaml files and file organization is quite easy to reason with. We found that the learning curve is not as steep as for puppet.
  2. No agent required for multi machine setup
  3. Default order of execution is how it is written — top-to-bottom (as against our earlier puppet setup where ordering of resources run is not how it is written)
  4. Ansible is basically a thin-wrapper for executing commands over SSH, hence is easier to debug.

Added to the above, not carrying to legacy from previous puppet scripts has helped a lot in cleaning up and redesigning the installation, and maintaining design consistency in component installation.

The ansible scripts themselves will be released (per version) as an RPM package. A user who wants to install bahmni with default configuration and all components will find it easy to run a script and setup a Centos 6 VM/machine — execute one shell command (since it takes a bit of time, we advice a pot of tea and a bag of chips to go by).

For custom installation, we plan to advice our users to edit a configuration file(s) to specify which components to not install, and in case of multi-machine setup, where to install what. We expect an advanced user to be able to modify standard ansible inventory and variables files (located conveniently at /opt/bahmni-installer/bahmni-playbooks) for multi-machine installation.

Bahmni Offline

We started our work on the Bahmni Offline android app and Chrome app late October and carried out some spikes during November. We have made quite a bunch of decisions -

  1. We are building a hybrid android app — using ionic to help us with development tooling. The android app will host a webview that will present the bahmni angularjs application on the device.
  2. Building a version agnostic android application — the first time setup of the app will require pointing to a bahmni server, and the app will download the user interface and required metadata from this server.
  3. Using service-worker to build an offline first application, which will serve locally cached files, allowing us to build the apps that do not require rewriting our existing web app. To enable service-worker on our target android devices that run an older version of android, we are going to use the crosswalk plugin which will enable the android app to embed the latest chrome versions necessary to run service worker.
  4. We are targetting low resource android tabs, and one of the constraints is device space. Since we assume that each device may hold upto 5000 patients, we had to identify options to store data that may run above the gigabyte mark. We have chosen to go with sqlite DB located on the sdcard of the device on android and standard indexeddb for Chrome app. For Chrome app, we have encountered chrome tab crash when the database size of indexededdb goes above 2GB.
  5. To keep us close to web standards, we will continue work on 2 fronts — sqlite (due to android constraints) and indexeddb which has replaced WebSQL as the browser based database of choice for the community. We will write interfaces for both of the above which will strictly follow the same data access calls — the only change on the front-end (android app or Chrome app) may be that they will be installed with the appropriate interface. We are spiking lovefield for SQL like interface to indexeddb.
  6. Service-worker needs an SSL certificate to work, so while we work with self-signed certs on our development boxes, we are spiking the recent release of LetsEncrypt to help us get free valid SSL certificates.
  7. We have finalized a simple approach very similar to atom feeds to help synchronize data from the bahmni server to the device, the paging of items to be sync’ed will be done by server time to make it easier to develop. Since network is expected to be flaky and low (2G), we have chosen to have the device downloads resources (e.g. patients) in units (one GET patient at a time) and not in bulk.
  8. We have been discussing about preventing data theft from android devices, and on that end we are working on a couple of areas — data on the android device will be encrypted, and a bahmni administrator should be able to remote clean the database, when it comes online again. Ideas are welcome in this area.

As of today, we have a working android app that lets a user search patients offline. Code for the offline app can be found here The changes made to the bahmni web app have been merged to master (on the 8th of December).

Performance

NewRelic reports — we have been spiking on and getting value from newrelic performance monitoring in our QA environments. We are using the free version that has limits on data storage and security of data in transport. We have identified that we need to mimic natural user behaviour on our servers while the monitoring is on, and to that effect we are going to setup our servers with monitoring and run a bug-bash once per release to benchmark that release. With every release, we plan to compare benchmarks to prior releases to identify performance issues. We plan to run the bug bash on a production like environment. More from Sushma on this, soon.

Newrelic reports for bahmni can be seen here (login and password shared earlier on slack).

We are planning to purchase a NewRelic license for JSS, which will enable us to identify production issues. Paid licenses are required to secure and anonymise parameters and other data sent to NewRelic.

Fixed a performance issue on Clinical dashboard that loaded all the visits for all the patients. We did not catch this in our environments since loading all the visits didn’t take a lot of time (as much as it did at Possible).

Security

A focus area for the coming months would be make sure we follow strict security guidelines in order to make it hard for malicious parties to access patient data. For a start, we have identified configuration files that contain passwords — app, db etc. — these are now going to be ansible template files and our next steps would be to allow users to configure the installation process with passwords that they create.

All our components will run under a no-login non-root user, and all the configuration files will be accessible to this user (and root).

The previously unsecured Bahmni Reports application has now been made accessible to OpenMRS users who have a certain role.

We have been discussing about preventing data theft from android devices, and on that end we are working on a couple of areas — data on the android device will be encrypted, and a bahmni administrator should be able to remote clean the database, when it comes online again. [Copied from offline block]

Build

Started running integration tests on Bahmni reports

Packaging rpm and manual release process is part of the build pipeline.

As a pocess change, we actively look for developers in the team to volunteer chaperoning the builds for a day (or week), this happens during signups.

--

--