Warning: Please note that not all developer documentation has been updated to reflect the GlassFish to WildFly transition that is part of PerformanceBridge v3.9.0, so please refer to the upgrade guide or reach out to us via Slack for more information if necessary.

As discussed in tutorial part 11, all apps must pass our validation checklist and fulfill the packaging specification in order to be distributed. The checklist below will be returned when an app is submitted and does not pass validation, with feedback on the items that need improvement (like the tutorial example).

Deploying applications requires the following:

Validation Checklist

✔ = Passes Validation, ✘ = Fails Validation

# Validation Goal Validation Results Feedback
1 Any user that can log in to the system (regardless of clinical role) receives a clear message regarding their authorization to use the page. If they are authorized it just works, if they are not in the proper clinical roles then they are told as much. ✔ / ✘
2 All PHI is protected through basic authentication (using the SSO through the SDK) at a minimum. ✔ / ✘
3 All PHI views are sent to the HIPAA audit logs via the SDK methods. ✔ / ✘
4 No PHI is sent to other systems or is accessible via other systems without proper authorization/security. ✔ / ✘
5 There are no queries that take an excessive amount of time to return or put an unacceptable load on the system. If there are unconstrained queries (no limits, no where, etc.), there needs to be a well-reasoned argument for why this behavior should be accepted. ✔ / ✘
6 Libraries and dependencies are up-to-date and supported (e.g. harbinger-rails-extenions, and harbinger-sdk). ✔ / ✘
7 The application handles poor data quality (there will inevitably be poor data quality in any production environment). The application must handle null values, and visualization must not break when there are missing data points, i.e., the data queries are filtering appropriately. ✔ / ✘
8 The application communicates errors to the user if they occur (no infinity spinner for AJAX) ✔ / ✘
9 The application works in a relative root environment. ✔ / ✘
10 The application is submitted compliant to the packaging specifications. ✔ / ✘
11 Values that are not platform-managed cannot be hard-coded and must be configurable via an administrative interface in the application. By way of example, a platform-managed value set would be clinical_roles, a non-managed value set would be modalities. The full list of platform-managed values is enumerated in the Service Tools application under the Reference heading of the Data Browser tab. ✔ / ✘
12 If user access is restricted by more than just authentication, authorization must be configurable using clinical_roles, similar to #11. ✔ / ✘
13 Interfaces to other APIs or external systems must not have credentials embedded in the application, similar to #11. By way of example, if an app displays location data using the Google Maps API, the API key must be a configuration variable not hardcoded into the application. ✔ / ✘
14 If the application has a database schema for storing app-specific information, all tables must have a primary key. Any tables queried must have columns appearing in a where clause indexed. Additionally, timestamp data must use the column type timestamp with time zone and foreign key reference columns must use the bigint type. Table and other object names must be prefixed with the application name or a similar abbreviation. ✔ / ✘

Precompiled Assets

Applications deployed on the AI platform require precompiled assets. To learn how to precompile assets in Rails, please see the developer tutorial part 11

Database Scripts

All of these scripts can be found in both the starter and tutorial applications. They are included here for reference: For more information on application data models, see developer tutorial part 8

The following files are required within the db_scripts folder:

install.sh, create.sql, and create-glassfish-jdbc.sh are standardized and are included for reference:


echo 'Creating schema, user, tables, etc.'
psql -e -f create.sql -U postgres harbinger
export PGPASSWORD=2893ourj8923urjl
psql -e -f schema.sql -U railsdevelopertutorial harbinger
psql -e -f data.sql -U railsdevelopertutorial harbinger


create user railsdevelopertutorial password '2893ourj8923urjl';
create schema AUTHORIZATION railsdevelopertutorial;
revoke all on all tables in schema public from railsdevelopertutorial;
grant usage on schema public to railsdevelopertutorial;
grant select on all tables in schema public to railsdevelopertutorial;
alter user railsdevelopertutorial set search_path to railsdevelopertutorial,public;

create-glassfish-jdbc.sh - Create JDBC



cd /servers/glassfish/glassfish3/glassfish/bin
./asadmin login

if [ $? != 0 ]; then
 echo "Must login to continue"

./asadmin create-jdbc-connection-pool \
--datasourceclassname=org.postgresql.ds.PGConnectionPoolDataSource \
--restype=javax.sql.ConnectionPoolDataSource \
--property user=${DB_USER}:password=${DB_PASSWORD}:databaseName=${DB}:serverName=${DB_HOST} \

./asadmin create-jdbc-resource \
--connectionpoolid ${JDBC_POOL} \


A changelog in Markdown-format should be provided in the package. Each release should be under a heading and include the following details:


An installation guide in Markdown-format should be provided. It should cover any required database installation tasks, cron jobs, or other configuration/initialization required.

WAR File

Applications on the AI Platform are deployed through a WAR file. See Generating the WAR file for directions.


Applications need to be submitted with the WAR file, db_scripts/ directory, and CHANGELOG.md in a single ZIP archive. Below is an example script named package-application.sh (at the root of the Rails application) to automatically build a compliant ZIP archive.

This script presumes the following requirements are filled:


APPNAME=`cat config/application.name`
VERSION=`git describe --always`

if [ ! -e $WARFILE ]
  echo "Packager: $WARFILE not present."
  read -p "Would you like to build now? (yN)  "
  [[ $REPLY = [yY] ]] && ./warblizer.sh || echo "Packager: $WARFILE will not built"
if [ ! -e $WARFILE ]
  echo "Packager: $WARFILE not present, exiting"
  exit 2

if [ -e $PACKAGEDIR ]
  echo "Packager: Please remove or rename $PACKAGEDIR"
  exit 2

mkdir -v $PACKAGEDIR
cp -Rv db_scripts $PACKAGEDIR
echo "Packager: Created $PACKAGEDIR.zip"