Organization: whocoronavirus.org
All production servers - such as who-mh-prod
- are part of the WHO Google Cloud
organization and not the developer organization.
Domain: hack.whocoronavirus.org
Domain: covid19app.who.int
Domain: staging.whocoronavirus.org
Domain: none yet.
The v2 backend is based on Firebase.
We use many of Firebase's services, including Firestore, Cloud Functions, and Hosting, to serve the backend.
There are two standard Firebase configuration files checked in to the repo:
- A firebase.json configuration file that lists our project configuration.
- firebase.json - project configuration file
.firebaserc
- project aliases
We use Firestore in Native mode. It has the following top-level collections:
Collection | Document contents |
---|---|
Client | Client settings |
Where possible, we access the database directly (using Firestore's own APIs) rather than write our own APIs. Firebase's Security Rules determine the permitted access. Our security rules are defined in app/server/firestore.rules
.
Static content is hosted by Firebase Hosting. Everything in the app/server/public
folder is hosted. Most notable is the content
folder; the contents of that folder are automatically produced at deploy-time.
Static content will be available via a URL like https://OUR-PROJECT-ID.web.app
as well as any of our custom domains that we attach to the project (e.g. example.whocoronavirus.org
).
Dynamic content, HTTPS-based APIs, and any other server-side code are hosted on Cloud Functions. There are two kinds of Cloud Functions:
- HTTPS functions are reachable via a URL like
https://europe-west6-OUR-PROJECT-ID.cloudfunctions.net/getCaseStats
. - Firestore-triggered functions respond to events in the database, they can't be called directly.
Our Cloud Functions code is in app/server/functions/src
.
Using a custom domain to invoke HTTPS functions isn't possible for us yet, since we run outside of us-central1
, where Firebase Hosting Rewrites aren't supported yet. However, the hostname of our API should be a detail that's invisible to our users and therefore unimportant.
To test your Firebase code (security rules, Cloud Functions) in a local environment, we use Firebase's Emulator Suite.
To manually experiment with the emulator suite, run the following from the functions
directory:
npm run serve
To experiment with the HTTPS endpoints you can use the Postman collection of requests in app/server/WHO.postman_collection.json
.
Our unit tests (app/server/functions/**_spec.ts
) should be the main source of truth however; they use the emulators under the hood.
To run our unit tests, run the following from the server
directory:
npm run test
When setting up a new project, follow the instructions in terraform/README.md to...
- Obtain Terraform credentials.
- Create the project resources you'll be working with.
Make sure to also take the steps listed in Manual Setup that create the Firebase resources.
To update the whole project to the latest version, from the app/server
folder, run:
firebase deploy --project=YOUR-PROJECT-ID
If you only want to update static assets, run:
firebase deploy --project=YOUR-PROJECT-ID --only hosting
You should always specify a --project=YOUR-PROJECT-ID
. If you'd like you can
use one a project alias instead of a project ID.
Currently, the v2 backend isn't ready for use by the client.
# App Engine
curl -i \
-H 'Content-Type: application/json' \
-H 'Who-Client-ID: 00000000-0000-0000-0000-000000000000' \
-H 'Who-Platform: WEB' \
-X POST \
-d '{token: 'test', isoCountryCode: CH}' \
'https://staging.whocoronavirus.org/WhoService/putClientSettings'
Served from Google Cloud Storage:
curl https://staging.whocoronavirus.org/content/bundles/protect_yourself.en_US.yaml
curl https://covid19app.who.int/content/bundles/protect_yourself.en_US.yaml
Note: The deployment scripts run the build automatically.
All commands run from the server folder:
cd server
gradle build
./bin/run-dev-server.sh
Then open http://localhost:8080/.
Either login with the service account or your personal account:
# personal account
gcloud auth
Service Account:
# service account
gcloud auth activate-service-account --key-file xxxx.json
Deployment is organized by ProjectId.
./bin/deploy-server.sh who-mh-staging
Then open https://staging.whocoronavirus.org/app for a redirect to the app store.
Deployed automatically on push to master by .github/workflows/static-content.yaml (NOTE: old staging server). Or pushed manually with (new staging server):
./tools/build-and-push-static-serving.sh who-mh-staging
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
Note: We run on Java 12 but target Java 8.
brew tap adoptopenjdk/openjdk
brew cask install adoptopenjdk12
brew install gradle
Follow the directions here.
gcloud auth login
And, if you want to be able to manipulate Firebase:
gcloud auth application-default login
gcloud components install beta app-engine-java && gcloud components update
Follow the directions here
brew cask install intellij-idea-ce
Open the project in IntelliJ:
open -a /Applications/IntelliJ\ IDEA\ CE.app/ .
Install the Firebase Command-Line Interface by following the instructions here.