- Introduction
- Contract testing with Pact
- Benchmarking with Hyperfoil
- Running the Application
- Running Locally via Docker Compose
- Deploying to Kubernetes
This is the Location gRPC microservice. It is a classical gRPC microservice, written in Kotlin, and exposing CRUD operations on Locations. Location information is stored in a MariaDB database. This service is implemented using gRPC with blocking endpoints and Quarkus Hibernate ORM with Panache's repository pattern.
Additionally, this application favors constructor injection of beans over field injection (i.e. @Inject
annotation).
Since this is a gRPC service, the protobuf definition can be found here.
Pact is a code-first tool for testing HTTP and message integrations using contract tests
. Contract tests assert that inter-application messages conform to a shared understanding that is documented in a contract. Without contract testing, the only way to ensure that applications will work correctly together is by using expensive and brittle integration tests.
Eric Deandrea and Holly Cummins recently spoke about contract testing with Pact and used the Quarkus Superheroes for their demos. Watch the replay and view the slides if you'd like to learn more about contract testing.
The grpc-locations
application is a Pact Provider, and as such, should run provider verification tests against contracts produced by consumers.
Note
The grpc-locations
service uses gRPC/protobuf and not REST, therefore the consumer contract tests between rest-fights
and grpc-locations
use the Pact protobuf plugin. There is no installation necessary. When the tests execute the plugin will be automatically installed.
As this README states, contracts generally should be hosted in a Pact Broker and then automatically discovered in the provider verification tests.
One of the main goals of the Superheroes application is to be super simple and just "work" by anyone who may clone this repo. That being said, we can't make any assumptions about where a Pact broker may be or any of the credentials required to access it.
Therefore, the Pact contract is committed into this application's source tree inside the src/test/resources/pacts
directory. In a realistic
scenario, if a broker wasn't used, the consumer's CI/CD would commit the contracts into this repository's source control.
The Pact tests use the Quarkus Pact extension. This extension is recommended to give the best user experience and ensure compatibility.
Hyperfoil doesn't yet support gRPC. This issue is currently tracking it.
The application runs on port 8089
(defined by quarkus.http.port
in application.yml
).
From the quarkus-super-heroes/grpc-locations
directory, simply run ./mvnw quarkus:dev
to run Quarkus Dev Mode, or running quarkus dev
using the Quarkus CLI. The application will be exposed at http://localhost:8089 and the Quarkus Dev UI will be exposed at http://localhost:8089/q/dev.
NOTE: Running the application outside of Quarkus dev mode requires standing up a MariaDB instance and binding it to the app. By default, the application is configured with the following:
Description | Environment Variable | Java Property | Value |
---|---|---|---|
Database URL | QUARKUS_DATASOURCE_JDBC_URL |
quarkus.datasource.jdbc.url |
jdbc:mariadb://locations-db:3306/locations_database |
Database username | QUARKUS_DATASOURCE_USERNAME |
quarkus.datasource.username |
locations |
Database password | QUARKUS_DATASOURCE_PASSWORD |
quarkus.datasource.password |
locations |
Pre-built images for this application can be found at quay.io/quarkus-super-heroes/grpc-locations
.
Pick one of the versions of the application from the table below and execute the appropriate docker compose command from the quarkus-super-heroes/grpc-locations
directory.
Note
You may see errors as the applications start up. This may happen if an application completes startup before one if its required services (i.e. database, kafka, etc). This is fine. Once everything completes startup things will work fine.
Description | Image Tag | Docker Compose Run Command |
---|---|---|
JVM Java 21 | java21-latest |
docker compose -f deploy/docker-compose/java21.yml up --remove-orphans |
Native | native-latest |
docker compose -f deploy/docker-compose/native.yml up --remove-orphans |
These Docker Compose files are meant for standing up this application and the required database only. If you want to stand up the entire system, follow these instructions.
Once started the application will be exposed at http://localhost:8089
.
The application can be deployed to Kubernetes using pre-built images or by deploying directly via the Quarkus Kubernetes Extension. Each of these is discussed below.
Pre-built images for this application can be found at quay.io/quarkus-super-heroes/grpc-locations
.
Deployment descriptors for these images are provided in the deploy/k8s
directory. There are versions for OpenShift, Minikube, Kubernetes, and Knative.
Note
The Knative variant can be used on any Knative installation that runs on top of Kubernetes or OpenShift. For OpenShift, you need OpenShift Serverless installed from the OpenShift operator catalog. Using Knative has the benefit that services are scaled down to zero replicas when they are not used.
Pick one of the versions of the application from the table below and deploy the appropriate descriptor from the deploy/k8s
directory.
Description | Image Tag | OpenShift Descriptor | Minikube Descriptor | Kubernetes Descriptor | Knative Descriptor |
---|---|---|---|---|---|
JVM Java 21 | java21-latest |
java21-openshift.yml |
java21-minikube.yml |
java21-kubernetes.yml |
java21-knative.yml |
Native | native-latest |
native-openshift.yml |
native-minikube.yml |
native-kubernetes.yml |
native-knative.yml |
The application is exposed outside of the cluster on port 80
.
These are only the descriptors for this application and the required database only. If you want to deploy the entire system, follow these instructions.
Following the deployment section of the Quarkus Kubernetes Extension Guide (or the deployment section of the Quarkus OpenShift Extension Guide if deploying to OpenShift), you can run one of the following commands to deploy the application and any of its dependencies (see Kubernetes (and variants) resource generation of the automation strategy document) to your preferred Kubernetes distribution.
Note
For non-OpenShift or minikube Kubernetes variants, you will most likely need to push the image to a container registry by adding the -Dquarkus.container-image.push=true
flag, as well as setting the quarkus.container-image.registry
, quarkus.container-image.group
, and/or the quarkus.container-image.name
properties to different values.
Target Platform | Java Version | Command |
---|---|---|
Kubernetes | 21 | ./mvnw clean package -Dquarkus.profile=kubernetes -Dquarkus.kubernetes.deploy=true -DskipTests |
OpenShift | 21 | ./mvnw clean package -Dquarkus.profile=openshift -Dquarkus.container-image.registry=image-registry.openshift-image-registry.svc:5000 -Dquarkus.container-image.group=$(oc project -q) -Dquarkus.kubernetes.deploy=true -DskipTests |
Minikube | 21 | ./mvnw clean package -Dquarkus.profile=minikube -Dquarkus.kubernetes.deploy=true -DskipTests |
Knative | 21 | ./mvnw clean package -Dquarkus.profile=knative -Dquarkus.kubernetes.deploy=true -DskipTests |
Knative (on OpenShift) | 21 | ./mvnw clean package -Dquarkus.profile=knative-openshift -Dquarkus.container-image.registry=image-registry.openshift-image-registry.svc:5000 -Dquarkus.container-image.group=$(oc project -q) -Dquarkus.kubernetes.deploy=true -DskipTests |
You may need to adjust other configuration options as well (see Quarkus Kubernetes Extension configuration options and Quarkus OpenShift Extension configuration options).
Tip
The do_build
function in the generate-k8s-resources.sh
script uses these extensions to generate the manifests in the deploy/k8s
directory.