bookmarkit - Quarkus coding dojo
You can use the docker-compose.yml
file located on the root of this repository to launch all dependencies.
So going inside the root directory and launching the following command will get you up and running :)
docker-compose up
There is a Postman collection that can help to test your application during you developement, it is located here.
Step 1 - Quarkus basics
Goal: implements a bookmark service that pass the test from fr.loicmathieu.bookmarkit.BookmarkResourceTest
.
Steps:
- Open
bookmark-service
inside your favorite IDE - Implements the
fr.loicmathieu.bookmarkit.BookmarkResource
service, it's a classical CRUD service to allow to create/read/update/delete a bookmark. You must implement the service as a JAX-RS resource (WRITING JSON REST SERVICES). You must use Hibernate ORM with Panache to access the database (SIMPLIFIED HIBERNATE ORM WITH PANACHE). - Run the service with
mvn compile quarkus:dev
it has live reload ! - Test that everything works with
mvn test -Dtest=BookmarkResourceTest
.
NOTE: Hibernate is configured to drop and recreate the schema each time you restart your application. You can change this behavior inside your application.properties
.
Step 2 - Observability: OpenAPI, OpenMetrics and Health
Goal: implements Observability principles: metrology, health and discoverability
Steps:
- Add OpenAPI annotations to document your API, it will be available at http://localhost:8080/openapi and there is an embedded swagger UI at http://localhost:8080/swagger-ui
- Use
@Operation
to document each operation.
- Use
- Add OpenMetrics annotations to create metrics for each method of your endpoints, you should provide counted and timed metrics via
@Counted
and@Timed
, be careful that the name of the metric must be unique. You can access your metrics at http://localhost:8080/metrics. - See that an health check is available at http://localhost:8080/health.
- Create a custom check
@Readiness
public class AppHealthCheck implements HealthCheck {
@Override
public HealthCheckResponse call() {
return HealthCheckResponse.builder().name("bookmark").withData("is", "always").up().build();
}
}
- Test that everything works with
mvn test -Dtest=BookmarkObservabilityTest
.
NOTE: OpenAPI and OpenMetrics works as soon as you integrate the extension inside your application as it provides default documentation and metrics. Health provides basic liveness and readiness checks, you can add your own if needed.
Step 3 - Configuration
Goal: understand how we can configure the application: Application Configuration.
Steps:
- Add a configuration property inside you
application.properties
file:greeting=World
- Modify
BookmarkResource
to read this configuration property and log it at startup:- Use
@ConfigProperty
to inject the property inside agreeting
variable. - Create a
@PostConstruct
method that log it viaLOGGER.infof("Hello %s", greeting)
using Jboss logging.
- Use
- Test using
mvn quarkus:dev
you should seeHello World
in the console. - Add a new line to
application.properties
file:%dev.greeting=Dev
this is an override of the same property for the dev profile. - Test using
mvn quarkus:dev
you should seeHello Dev
in the console.
NOTE: you must call the endpoint to initialize it so the method annotated by @PostConstruct
runs.
Step 4 - Run you app inside a container
Goal: understand how to build your application, package it in a container, configure it and run it.
Steps:
- Package your application with
mvn package -DskipTests
- Run your application with
java -jar target/bookmark-service-1.0-SNAPSHOT-runner.jar
- Limit it's Heap memory with
java -Xmx32m -jar target/bookmark-service-1.0-SNAPSHOT-runner.jar
(you can go lower but your apps will be slower) - Override it's configuration from the command line with
java -Dgreeting=JAR -jar target/bookmark-service-1.0-SNAPSHOT-runner.jar
- Build a docker image with
docker build -f src/main/docker/Dockerfile.jvm -t bookmarkit .
- Run it with
docker run -ti -p 8080:8080 -e "QUARKUS_DATASOURCE_URL=jdbc:postgresql://{your_ip}:5432/mydatabase" bookmarkit
(replace {your_ip} by your ip).
Step 5 - Send a message via AMQP for each created bookmark
Goal: implements asynchronous messaging via AMQP
Steps:
- Uncomment the commented dependency
quarkus-smallrye-reactive-messaging-amqp
inside the pom.xml file. - Configure AMQP inside your
application.properties
amqp-username=quarkus
amqp-password=quarkus
- Configure MicroProfile messaging inside your
application.properties
mp.messaging.outgoing.bookmarks.connector=smallrye-amqp
mp.messaging.outgoing.bookmarks.address=bookmarks
mp.messaging.outgoing.bookmarks.durable=true
- Inject an
Emitter
inside yourBookmarkResource
:@Inject @Stream("bookmarks") Emitter<Bookmark> emitter;
- Use this emitter to send the bookmark inside the
create()
method. - Launch the consumer from bookmark-message-consumer via
mvn compile quarkus:dev
in an other console - Create some bookmarks, you should see a line in the console of bookmark-message-consumer for each creation
Step 6 - Call an external service reliability
Goal: learn how to call an external REST service via MicroProfile RestClient and use the fault-tolerance capabilities to make it reliable
Steps:
- Uncomment the commented dependencies
quarkus-rest-client
andquarkus-smallrye-fault-tolerance
inside the pom.xml file. - Create an interface annotated with Jax-rs annotations to call the webservice TODO
- Inject it inside the
BookmarkResource
with the@RestClient
annotation - Use it to make a call to the ws each time a bookmark is created
- Test it multiple times, you should see that it crash half of the time
- Add fault-tolerance
@Retry
annotation to retry the call - Test it again multiple times, it should work now :)