Skip to content

Latest commit

 

History

History
158 lines (113 loc) · 6.73 KB

development.md

File metadata and controls

158 lines (113 loc) · 6.73 KB

Development Guide

This document describes how to develop and add features to the Bank of Anthos application in your local environment.

Prerequisites

  1. A Google Cloud project, connected to your billing account.
  2. A GKE cluster in your project.

Installing required tools

You can use MacOS or Linux as your dev environment - all these languages and tools support both. Additionally, you can use Cloud Shell which comes with most required tools built-in.

  1. Docker Engine or Docker Desktop
  2. kubectl (can be installed separately or via gcloud)
  3. skaffold 2.9+ (latest version recommended)
  4. OpenJDK 21+ (newer versions not tested)
  5. Maven 3.9+ (newer versions not tested)
  6. Python 3.12+
  7. piptools

Installing JDK 21 and Maven 3.9

If your package manager doesn't allow you to install JDK 17 or Maven 3.8 (for example, if you're on an older version of Ubuntu), you can follow the following instructions.

Find the latest release of JDK 21 and extract it to the /opt directory:

wget https://download.java.net/java/GA/jdk21.0.1/415e3f918a1f4062a0074a2794853d0d/12/GPL/openjdk-21.0.1_linux-x64_bin.tar.gz
tar xvf openjdk-21.0.1_linux-x64_bin.tar.gz
sudo mv jdk-21.*/ /opt/jdk21

Find the latest release of Maven 3.9 and extract it to the /opt directory:

wget https://dlcdn.apache.org/maven/maven-3/3.9.5/binaries/apache-maven-3.9.5-bin.tar.gz
sudo tar xf apache-maven-*.tar.gz -C /opt

Create a profile containing the paths of the newly extracted JDK and Maven directories:

sudo tee /etc/profile.d/java.sh <<EOF
export JAVA_HOME=/opt/jdk21
export M2_HOME=/opt/apache-maven-3.9.5
export MAVEN_HOME=/opt/apache-maven-3.9.5
export PATH=\$JAVA_HOME/bin:\$M2_HOME/bin:\$PATH
EOF
sudo chmod +x /etc/profile.d/java.sh

Verify that the versions are correct:

source /etc/profile.d/java.sh
java -version
mvn -version

Adding external packages

Python

If you're adding a new feature that requires a new external Python package in one or more services (frontend, contacts, userservice), you must regenerate the requirements.txt file using piptools. This is what the Python images will use to install external packages inside the containers.

To add a package:

  1. Add the package name to requirements.in within the src/<service> directory:

  2. From inside that directory, run:

python3 -m pip install pip-tools
python3 -m piptools compile --output-file=requirements.txt requirements.in
  1. Re-run skaffold dev or skaffold run to trigger a Docker build using the updated requirements.txt.

Java

If you're adding a new feature to one or more of the Java services (ledgerwriter, transactionhistory, balancereader) and require a new third-party package, do the following:

  1. Add the package to the pom.xml file in the src/<service> directory, under <dependencies>. You can find specific package info in Maven Central (example). Example:
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
        </dependency>
  1. Re-run skaffold dev or skaffold run to trigger a Jib container build using Maven and the updated pom file.

Generating your own JWT public key

The extras directory provides the RSA key/pair secret used for demos. To create your own:

openssl genrsa -out jwtRS256.key 4096
openssl rsa -in jwtRS256.key -outform PEM -pubout -out jwtRS256.key.pub
kubectl create secret generic jwt-key --from-file=./jwtRS256.key --from-file=./jwtRS256.key.pub

Testing your changes locally

We recommend you test and build directly on Kubernetes, from your local environment. This is because there are seven services and for the app to fully function, all the services need to be running. All the services have dependencies, environment variables, and secrets and that are built into the Kubernetes environment / manifests, so testing directly on Kubernetes is the fastest way to see your code changes in action.

You can use the skaffold tool to build and deploy your code to the GKE cluster in your project.

Start by exporting your project ID:

export PROJECT_ID="your project id"

Option 1 - Build and deploy continuously

The skaffold dev command watches your local code, and continuously builds and deploys container images to your GKE cluster anytime you save a file. Skaffold uses Docker Desktop to build the Python images, then Jib (installed via Maven) to build the Java images.

skaffold dev --profile development --default-repo=gcr.io/${PROJECT_ID}/bank-of-anthos

Note that you can skip tests by running skaffold with --skip-tests=true, if needed.

Option 2 - Build and deploy once

The skaffold run command build and deploys the services to your GKE cluster one time, then exits.

skaffold run --profile development --default-repo=gcr.io/${PROJECT_ID}/bank-of-anthos

Running services selectively

Skaffold reads the skaffold.yaml file to understand the project setup. Here, it's split into modules that can be iterated on individually:

  • the frontend module for the single frontend service.
  • the accounts module for the two account services.
  • the ledger module for the three ledger services.
  • the loadgenerator module for the single load generator service.

For example, to work with only the frontend module, run:

skaffold dev --profile development --default-repo=gcr.io/${PROJECT_ID}/bank-of-anthos --module frontend

Cleaning up your deployment

To clean up your deployment, you can run skaffold delete:

skaffold delete --profile development

Continuous integration

When you're ready to create a Pull Request for your branch, you will notice that the Github Actions CI workflows run on your branch. This includes both code and deploy tests into a separate GKE cluster owned by the maintainers. The GitHub Actions CI workflows are described here.