An open API service indexing awesome lists of open source software.

https://github.com/consol/jugm-quarkus

Sample code for JUG Munich quarkus talk on 2020-05-27
https://github.com/consol/jugm-quarkus

Last synced: 12 months ago
JSON representation

Sample code for JUG Munich quarkus talk on 2020-05-27

Awesome Lists containing this project

README

          

# Demo Code for the [JUG Munich][jugm] Talk "GraalVM und Quarkus: von heiligen Relikten und subatomaren Partikeln" held on 2020-05-27

The code serves as a basis to play around with different features and as code sample for
bootstrapping own projects.

## Prerequisites

The dependent systems (DBMS-system, OAuth2-provider, Jaeger) are started through docker, thus a
working docker installation is needed.

In order to build and execute the application, ja JDK >= 11 must be installed. Furthermore, for
native compilation, [GraalVM][GraalVM] and the [native image feature][GraalVMNative]. Compilation
has been tested with GraalVM version 20.0.0 and version 20.1.0.

## The environment

The environment consists of:

- A dbms service: This is a postgres docker container with two databases:
- one for the keycloak (name: `keycloak`, username `keycloak`, password `keycloak`)
- one for the application (name: `app_user`, username `app_user`, password `app_user`)
The database is accessible through local port 15432.
- An OAuth2 service: This is a keycloak docker container. The container is configured to load a
suiting realm (located in `localdeployment/keycloak/app.json`) and connect to the DBMS service to
persist its data. When started (takes about 30 seconds), it is accessible through
[`http://localhost:8090`][LocalKeycloak].
- username: `keycloak`
- password: `keycloak`
- A tracing service: This is an all-in-one Jaeger container. It exposes port `14268` for trace
collecting and port `16686` for the Web-UI. When started, the Web-UI is accessible at
[`http://localhost:16686`][LocalJaeger].

## Deploying dependencies in docker

To deploy the dependent services, execute

localdeployment/deploy.[cmd|sh]

If you with to also initialize the database for the application with a schema, execute

localdeployment/migrate-database-and-deploy.[cmd|sh]

## Building and starting the application

The application uses maven wrappers, so no further installation is required to build it. Execute

./mvnw clean package

to build the application. This will generate a file `target/jugm-quarkus-0.0.1-SNAPSHOT-runner.jar`,
which can be executed directly to start the application:

cd target
java -jar jugm-quarkus-0.0.1-SNAPSHOT-runner.jar

The application is then accessible through [`http://localhost:8080`][LocalApp]

## What it does

The app provides two general domains by exposing a REST API:

- creating, querying and deleting users: This is done through the endpoint `/users`. We give some
example commands to interact with the REST API.
- `POST`ing a new user:
``` bash
curl --location --request POST 'localhost:8080/users' \
--header 'Content-Type: application/json' \
--data-raw '{
"name": "John Doe",
"email": "john@doe.com"
}'
```
- `GET`ting a single user by name:
``` bash
curl --location --request GET 'http://localhost:8080/users/John%20Doe'
```
- `GET`ting all users: In order to get all users, we first need to obtain a token from the
keycloak server:
``` bash
export TOKEN=$(curl --location --request POST 'http://localhost:8090/auth/realms/app/protocol/openid-connect/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=app-client' \
--data-urlencode 'client_secret=31a859f6-95f5-4f32-8403-0b2a3f36969e' \
--data-urlencode 'grant_type=password' \
--data-urlencode 'username=adminUser' \
--data-urlencode 'password=adminUser' \
| jq '.access_token') \
&& TOKEN=$(sed -e 's/^"//' -e 's/"$//' <<<"$TOKEN")
```
With the token obtained, we can now make a request with this token to obtain a list of all
users:
``` bash
curl --request GET 'http://localhost:8080/users' --header "Authorization: Bearer $TOKEN"
```
- `DELETE`ing a user:
``` bash
curl --location --request DELETE 'http://localhost:8080/users/john Doe'
```
- Querying an (external) REST-Service: The endpoint `fruits/{name}` will query the external REST
service [`http://www.fruityvice.com/`][FruityVice] for fruit information.
```
curl --location --request GET 'http://localhost:8080/fruits/apple'
```

Aside from this, the application provides the following technical endpoints:

- [`/health`][LocalHealth]: showing the overall health status of the application.
- [`/health/ready`][LocalReady], [`health/live`][LocalLive]: showing readiness and liveness of the
application.
- [`/metrics`][LocalMetrics]: showing all metrics of the application.
- [`/metrics/application`][LocalMetricsApp]: showing all application-specific metrics.
- `/metrics/application/{name}` (e.g.
[`/metrics/application/de.consol.dus.boundary.endpoints.UserResource.allUsersTimer`][LocalMetricTimer]):
showing only the metrics to the specified name.

## Tracing with Jaeger

After making some request against the application, we can trace the requests by accessing the
[Jaeger Web-UI][LocalJaeger].

## Cleanup

When we are done playing around with the application, we can shut down all started docker
containers by executing

target/destroy.[cmd|sh]

## Native compilation

The native compilation can also be done through maven by executing

./mvnw -Pnative clean package

---
Attention:

Native compilation is extremely memory-intensive. The process can use well beyond 10 GB of RAM. If
the OS starts swapping, the compilation may result in a system freeze.

---

This will generate an executable `target/jugm-quarkus-0.0.1-SNAPSHOT-runner`. Starting this
executable will result in the same behaviour as starting the jar-file.

[jugm]: https://www.jugm.de/
[GraalVM]: https://www.graalvm.org/
[GraalVMNative]: https://www.graalvm.org/docs/reference-manual/native-image/
[LocalKeycloak]: http://localhost:8090
[LocalJaeger]: http://localhost:16686
[LocalApp]: http://localhost:8080
[FruityVice]: http://www.fruityvice.com/
[LocalHealth]: http://localhost:8080/health
[LocalReady]: http://localhost:8080/health/ready
[LocalLive]: http://localhost:8080/health/live
[LocalMetrics]: http://localhost:8080/metrics
[LocalMetricsApp]: http://localhost:8080/metrics/application
[LocalMetricTimer]: http://localhost:8080/metrics/application/de.consol.dus.boundary.endpoints.UserResource.allUsersTimer