SlideShare ist ein Scribd-Unternehmen logo
1 von 50
Downloaden Sie, um offline zu lesen
JEE-Microservices mit Quarkus - eine Einführung
25.11.2019
Dirk Weil, GEDOPLAN GmbH
Dirk Weil
GEDOPLAN GmbH, Bielefeld
GEDOPLAN IT Consulting
Consulting, coaching, concepts, reviews, development
GEDOPLAN IT Training & partner
Java, JEE, tools trainings
Berlin, Frankfurt, Bielefeld, Köln, on-site
JEE since 1998
Speaker and author
JEE-Microservices mit Quarkus - eine Einführung 2gedoplan.de
Java EE  Jakarta EE
2017:
Projekt EE4J (Eclipse Enterprise for Java)
Produktname Jakarta EE
Oracle behält Namens- und Urheberrechte
Java EE
Paketnamen javax.*
Jakarta EE 8
codegleich zu Java EE 8
Release 10.09.2019
JEE-Microservices mit Quarkus - eine Einführung 3
JEE
gedoplan.de
MicroProfile
microprofile.io
„Next step of Java EE / Jakarta EE evolution“
„… optimize Enterprise Java for a microservices architecture …“
JEE-Microservices mit Quarkus - eine Einführung 4gedoplan.de
Config
1.3
Fault Tolerance
2.0
Health
2.0
JWT Authentication
1.1
Metrics
2.0.0
OpenAPI
1.1
OpenTracing
1.3
Rest Client
1.3
CDI
2.0
JAX-RS
2.1
JSON-B
1.0
JSON-P
1.1
MicroProfile Runtimes: Klassische Application Server
5
Anwendungsklassen
Konfigurationsfiles
(Deployment Descriptors,
Properties, …)
JEE Server
CDI Runtime
JPA Runtime
REST Runtime
Technische Konfiguration *
JRE
build deploy
run
* DB-Verbindungen,
Messaging
Security
…
Thin WAR
klein
groß
gedoplan.deJEE-Microservices mit Quarkus - eine Einführung
MicroProfile Runtimes: „Micro“ Frameworks
6
Anwendungsklassen
Konfigurationsfiles *
CDI Runtime
JPA Runtime
REST Runtime
JRE
build
run
* Anwendungsparameter,
DB-Verbindungen,
Messaging
Security
…
Fat JAR
JAR + Dependencies
groß
gedoplan.deJEE-Microservices mit Quarkus - eine Einführung
Workshop-Projekt
Source
github.com/GEDOPLAN/quarkus-workshop
Branches:
master
Demos, Skripte, Kopiervorlagen, …
jvmcon2019
basiert auf master
wird während des Workshops sukzessive aufgebaut
Tooling
JDK 8+ (z. B. adoptopenjdk.net)
Maven 3 (maven.apache.org/download.cgi)
Git Client (git-scm.com/downloads)
curl (curl.haxx.se/download.html)
JEE-Microservices mit Quarkus - eine Einführung 7gedoplan.de
Quarkus
Red Hats Antwort auf Spring Boot
Designierter Nachfolger von Thorntail (aka WildFly Swarm)
Optimiert für kurze Startzeiten
Hotspot und GraalVM
https://quarkus.io/
JEE-Microservices mit Quarkus - eine Einführung 8gedoplan.de
Quarkus
Core
+ Extensions
(= Maven Dependencies)
Project Bootstrap mit
Maven Plugin
(oder Gradle)
 quarkus.io/guides/maven-tooling.html
JEE-Microservices mit Quarkus - eine Einführung 9gedoplan.de
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
mvn io.quarkus:quarkus-maven-plugin:1.0.0.CR1:create 
-DprojectGroupId=… 
-DprojectArtifactId=… 
-B
Quarkus
Maven-Plugin für Build
Thin jar target/quarkus-getting-started-runner.jar
Dependencies in target/lib/
Anwendungsstart
java –jar target/quarkus-getting-started-runner.jar
JEE-Microservices mit Quarkus - eine Einführung 10gedoplan.de
<plugins>
<plugin>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<version>${quarkus.version}</version>
<executions>
<execution>
<goals><goal>build</goal></goals>
</execution>
Quarkus
Development mode
Hot reload
bei REST/Web-Request
falls Quellcodeänderung
JEE-Microservices mit Quarkus - eine Einführung 11gedoplan.de
$ mvn quarkus:dev
Listening for transport dt_socket at address: 5005
17:54:50,319 INFO [io.qua.dep.QuarkusAugmentor] (main) Beginning quarkus au
17:54:50,949 INFO [io.qua.resteasy] (build-1) Resteasy running without serv
17:54:50,949 INFO [io.qua.resteasy] (build-1) - Add quarkus-undertow to run
17:54:50,980 INFO [io.qua.dep.QuarkusAugmentor] (main) Quarkus augmentation
17:54:52,452 INFO [io.quarkus] (main) Quarkus 0.26.1 started in 2.320s. Lis
17:54:52,452 INFO [io.quarkus] (main) Profile dev activated. Live Coding ac
17:54:52,454 INFO [io.quarkus] (main) Installed features: [cdi, resteasy]
Quarkus
Configuration
application.properties
Properties quarkus.… für Quarkus
quarkus.io/guides/config
quarkus.io/guides/all-config
Weitere Properties für Anwendung (MicroProfile Config)
Configuration Profiles %prod, %dev, %test
JEE-Microservices mit Quarkus - eine Einführung 12gedoplan.de
# Ports
quarkus.http.port=8080
# Logging
quarkus.log.console.format=%d{HH:mm:ss,SSS} %-6p [%c{1.}] (%t) %s%e%n
quarkus.log.console.color=false
quarkus.log.level=INFO
quarkus.log.category."some.logger.name".level=WARN
%dev.quarkus.log.category."some.logger.name".level=FINE
Demo: getting-started
Bootstrap
Start
JEE-Microservices mit Quarkus - eine Einführung 13gedoplan.de
mvn io.quarkus:quarkus-maven-plugin:1.0.0.CR1:create 
-DprojectGroupId=jvmcon 
-DprojectArtifactId=getting-started 
-DclassName="jvmcon.GreetingResource" 
-B
getting-started-bootstrap.sh
cd getting-started
mvn compile quarkus:dev
Kleiner Ausflug: JAX-RS
Klasse mit @Path definiert Rest Endpoints
Methoden mit @GET, @PUT, @POST, @DELETE
@Path kann auf Methoden ergänzend genutzt werden
Pfade dürfen Templates enthalten
@Produces und @Consumes bestimmen (De-)Serialisierung
Parameter können aus URL übernommen werden
siehe Klasse GreetingResource (nach Bootstrap ergänzt)
Beispiel-Aufrufe mittels curl
siehe getting-started-curl.txt
JEE-Microservices mit Quarkus - eine Einführung 14gedoplan.de
Übungs-Domäne
Skipass-Verwaltung und Nutzung
1. Schritt: skipass-manager
mit POST-Endpoint zur Erzeugung von Skipässen
JEE-Microservices mit Quarkus - eine Einführung 15gedoplan.de
skipass-manager
• POST /skipass?validTo=2019-12-14T18:00
Erzeugen eines Skipasses (id = UUID)
• GET /skipass/2a910ff2-b92a-477f-861d-36fdf2c3c249/validTo
Abfrage der Gültigkeit (Ende-Timestamp oder Ungültig-Wert)
• PUT /skipass/2a910ff2-b92a-477f-861d-36fdf2c3c249/blocked
Sperren oder Freigeben eines Skipasses
• …
DB
skipass-gate
• GET /gate/2a910ff2-b92a-477f-861d-36fdf2c3c249
Einlass-Prüfung (GREEN/RED)
Übungs-Domäne
1. Schritt: skipass-manager
mit POST-Endpoint zur Erzeugung von Skipässen
(Project Bootstrap, JAX-RS)
JEE-Microservices mit Quarkus - eine Einführung 16gedoplan.de
skipass-manager
• POST /skipass?validTo=2019-12-14T18:00
Erzeugen eines Skipasses (id = UUID)
• GET /skipass/2a910ff2-b92a-477f-861d-36fdf2c3c249/validTo
Abfrage der Gültigkeit (Ende-Timestamp oder Ungültig-Wert)
• PUT /skipass/2a910ff2-b92a-477f-861d-36fdf2c3c249/blocked
Sperren oder Freigeben eines Skipasses
• …
DB skipass-gate
• GET /gate/2a910ff2-b92a-477f-861d-36fdf2c3c249
Einlass-Prüfung (GREEN/RED)
Übung 1: Bootstrap skipass-manager
1. Erzeugen Sie das Quarkus-Projekt skipass-manager
2. Ergänzen Sie die Entity SkiPass
• Kopiervorlage: skipass.txt
• Paket, Getter, Setter, toString nach Gusto
JEE-Microservices mit Quarkus - eine Einführung 17gedoplan.de
mvn io.quarkus:quarkus-maven-plugin:1.0.0.CR1:create 
-DprojectGroupId=jvmcon 
-DprojectArtifactId=skipass-manager 
-B
public class SkiPass {
private String id;
private LocalDateTime validFrom;
private LocalDateTime validTo;
private boolean blocked;
Übung 1: Bootstrap skipass-manager
3. Ergänzen Sie die Rest-Resource SkiPassResource
• @Path("skipass")
• Methode für Skipass-Anlage
• @POST
• @Produces(MediaType.TEXT_PLAIN)
• Parameter
• @QueryParam("validTo") LocalDateTime validTo
• @QueryParam("validFrom") LocalDateTime validFrom
• neues SkiPass-Objekt instanziieren und seine Id als Returnwert liefern
4. Anwendung starten
5. Rest-Call ausprobieren
JEE-Microservices mit Quarkus - eine Einführung 18gedoplan.de
curl -X POST -i http://localhost:8080/skipass?validTo=2019-12-24T23:59
mvn compile quarkus:dev
Übungs-Domäne
2. Schritt: Skipässe persistent ablegen
(JPA, CDI, JSON-B)
Validierungslogik
JEE-Microservices mit Quarkus - eine Einführung 19gedoplan.de
skipass-manager
• POST /skipass?validTo=2019-12-14T18:00
Erzeugen eines Skipasses (id = UUID)
• GET /skipass/2a910ff2-b92a-477f-861d-36fdf2c3c249/validTo
Abfrage der Gültigkeit (Ende-Timestamp oder Ungültig-Wert)
• PUT /skipass/2a910ff2-b92a-477f-861d-36fdf2c3c249/blocked
Sperren oder Freigeben eines Skipasses
• …
DB skipass-gate
• GET /gate/2a910ff2-b92a-477f-861d-36fdf2c3c249
Einlass-Prüfung (GREEN/RED)
Kleiner Ausflug: CDI
Anwendungen / Geschäftslogik besteht aus vielen Services
die einander benutzen / referenzieren
deren Daten unterschiedlich lang benötigt werden
(gesamte Laufzeit, einzelner Request, …)
JEE-Microservices mit Quarkus - eine Einführung 20gedoplan.de
Application
Use Case
Domain Data
Service
Domain Data
Service
Data Repository
Data Repository Data Repository
Page / View Endpoint
TX
JPA
Mail
JMS
Kleiner Ausflug: CDI
Definition von Beans (=Services)
und Zuordnung zu Scopes (=Lebensdauer)
Verknüpfung untereinander
mittels Injektion
Descriptor META-INF/beans.xml
für Quarkus optional
Inhalt wird von Quarkus (derzeit?) nicht genutzt
JEE-Microservices mit Quarkus - eine Einführung 21gedoplan.de
@ApplicationScoped
public class PersonRepository {
@ApplicationScoped
@Path("person")
public class PersonResource {
@Inject
PersonRepository personRepository;
Kleiner Ausflug: CDI
Interceptors z. B. für Transaktionssteuerung
Weitere Features (hier nicht benötigt):
Qualifier
Alternatives
Producer
Events
JEE-Microservices mit Quarkus - eine Einführung 22gedoplan.de
@ApplicationScoped
@Transactional(rollbackOn = Exception.class)
public class PersonRepository {
@Inject
EntityManager entityManager;
public void persist(Person entity) {
this.entityManager.persist(entity);
Kleiner Ausflug: JPA
Aufgabenstellung:
Speichern und Laden von
Java-Objekten
Mapping OO  RDBMS
Entities (=persistente Objekte)
sind POJOs
nicht final
No-args constructor
@Entity
@Id
Diskussion über Ids, Generatoren, equals, hashCode siehe
javaeeblog.wordpress.com/2017/11/15/
identity-and-equality-of-jpa-entities/
JEE-Microservices mit Quarkus - eine Einführung 23gedoplan.de
@Entity
public class Person {
@Id
@GeneratedValue(strategy = …)
private Integer id;
private String name;
private String firstname;
protected Person() {
}
Kleiner Ausflug: JPA
EntityManager = API für CRUD, Queries, …
JEE-Microservices mit Quarkus - eine Einführung 24gedoplan.de
public class PersonRepository {
@Inject
EntityManager entityManager;
public Person findById(Integer id) {
return this.entityManager.find(Person.class, id);
}
public List<Person> findAll() {
return this.entityManager
.createQuery("select x from Person x", Person.class)
.getResultList();
}
public void persist(Person entity) {
this.entityManager.persist(entity);
JPA in Quarkus
Extensions für Hibernate und DB-Treiber
Konfiguration der Datasource(s)
META-INF/persistence.xml optional
JEE-Microservices mit Quarkus - eine Einführung 25gedoplan.de
mvn quarkus:add-extensions –Dextensions=quarkus-hibernate-orm,quarkus-jdbc-h2
# Datasource
quarkus.datasource.url=jdbc:h2:mem:test;…
quarkus.datasource.driver=org.h2.Driver
quarkus.datasource.username=showcase
quarkus.datasource.password=showcase
quarkus.hibernate-orm.database.generation=update
quarkus.datasource.hugo.url=jdbc:…
application.properties
Kleiner Ausflug: JSON-B
(De-)Serialisierung POJO  JSON
Automatische Nutzung in JAX-RS
Mediatype application/json
Quarkus-Extension quarkus-resteasy-jsonb
(statt quarkus-resteasy)
JEE-Microservices mit Quarkus - eine Einführung 26gedoplan.de
Person person = new Person("Wacker", "Willi");
Jsonb jsonb = JsonbBuilder.create();
String personJson = jsonb.toJson(person);
Übung 2a: Persistenz in skipass-manager
1. Ergänzen Sie die für JPA nötigen Extensions
2. Konfigurieren Sie die Datasource
3. Machen Sie die Entity SkiPass JPA-fähig
• @Entity, @Id
• No-args constructor
JEE-Microservices mit Quarkus - eine Einführung 27gedoplan.de
mvn quarkus:add-extensions 
–Dextensions=quarkus-hibernate-orm,quarkus-jdbc-h2
# Datasource
quarkus.datasource.url=jdbc:h2:~/h2/jvmcon;AUTO_SERVER=TRUE
quarkus.datasource.driver=org.h2.Driver
quarkus.datasource.username=jvmcon
quarkus.datasource.password=jvmcon
quarkus.hibernate-orm.database.generation=update
Übung 2a: Persistenz in skipass-manager
4. Ergänzen Sie die Klasse SkiPassRepository für CRUD-Operationen
• vgl. PersonRepository aus rest-cdi-jpa
• persist, findAll und findById reichen
5. Nutzen Sie SkiPassRepository in SkiPassResource
• Injizieren Sie eine SkiPassRepository-Instanz
• Ergänzen Sie die POST-Methode um die Speicherung des Skipasses
6. Prüfen Sie, ob mittels POST erzeugte Skipässe in der DB gespeichert
werden
• Das Treiber-Jar der H2-DB enthält einen einfachen Client
• liegt im lokalen Maven-Repository
(~/.m2/repository/com/h2database/h2/1.4.197/h2-1.4.197.jar)
• Start per java -jar h2-1.4.197.jar
JEE-Microservices mit Quarkus - eine Einführung 28gedoplan.de
Übung 2a: Persistenz in skipass-manager
7. Tauschen Sie die Quarkus-Extension für Rest gegen die mit
JSON-B-Unterstützung aus
• quarkus-resteasy-jsonb
8. Ergänzen Sie SkiPassResource um GET-Methoden für alle
Skipässe bzw. für einen Skipass in JSON
• GET /skipass
• GET /skipass/{id}
9. Fragen Sie zum Test bspw. per curl Skipässe ab
• curl http://localhost:8080/skipass
• curl http://localhost:8080/skipass/2a910ff2-b92a-477f-861d-36fdf2c3c249
JEE-Microservices mit Quarkus - eine Einführung 29gedoplan.de
Übung 2b: Logik für Skipass-Validierung
1. Ergänzen Sie den Rest-Service um eine PUT-Methode
zum Setzen des blocked-Attributs eines Skipasses
• PUT /skipass/{id}/blocked
• Konsumiert boolean als JSON
• Skipass zur angegebenen Id suchen und blocked setzen
• @Transactional
2. Ergänzen Sie eine weitere Methode zur Abfrage des
Gültigkeitsendes eines Skipasses
• GET /skipass/{id}/validTo
• Liefert LocalDateTime-Objekt als JSON
• falls Skipass gültig (*), sein validTo
(* vorhanden, nicht blockiert, jetzt gültig)
• andernfalls LocalDateTime.MIN
JEE-Microservices mit Quarkus - eine Einführung 30gedoplan.de
Übungs-Domäne
3. Schritt: Service skipass-gate
mit Aufruf von skipass-manager
(Rest Client)
JEE-Microservices mit Quarkus - eine Einführung 31gedoplan.de
skipass-manager
• POST /skipass?validTo=2019-12-14T18:00
Erzeugen eines Skipasses (id = UUID)
• GET /skipass/2a910ff2-b92a-477f-861d-36fdf2c3c249/validTo
Abfrage der Gültigkeit (Ende-Timestamp oder Ungültig-Wert)
• PUT /skipass/2a910ff2-b92a-477f-861d-36fdf2c3c249/blocked
Sperren oder Freigeben eines Skipasses
• …
DB skipass-gate
• GET /gate/2a910ff2-b92a-477f-861d-36fdf2c3c249
Einlass-Prüfung (GREEN/RED)
Kleiner Ausflug: MicroProfile Rest Client
Rest Client
Injizierbare REST clients
aus Interface generiert
konfigurierbare URL
JEE-Microservices mit Quarkus - eine Einführung 32gedoplan.de
@Path("v2")
@RegisterRestClient
public interface CountryApi {
@GET
@Path("all")
@Produces("application/json")
Collection<Country> getAll();
de.gedoplan.showcase.….CountryApi/mp-rest/url=http://restcountries.eu/rest
META-INF/microprofile-config.properties
@Path("country")
@ApplicationScoped
public class CountryResource {
@Inject
@RestClient
CountryApi countryClient;
@GET
@Path("count")
@Produces(MediaType.APPLICATION_JSON)
public int getCount() {
return countryClient.getAll().size();
MP Rest Client in Quarkus
Extension
Konfiguration von externer URL und Scope auch in
application.properties möglich
JEE-Microservices mit Quarkus - eine Einführung 33gedoplan.de
mvn quarkus:add-extensions –Dextensions=quarkus-rest-client
# Rest Client
fully.qual.rest.Intf/mp-rest/url=http://…
fully.qual.rest.Intf/mp-rest/scope=javax.enterprise.context.ApplicationScoped
application.properties
Übung 3: skipass-gate
1. Erzeugen Sie das Quarkus-Projekt skipass-gate
2. Ergänzen Sie ein Rest Client Interface SkiPassManager
• beschreibt Ihren Rest Service in skipass-manager
(Methode für GET /skipass/{id}/validTo reicht)
• @RegisterRestClient
JEE-Microservices mit Quarkus - eine Einführung 34gedoplan.de
mvn io.quarkus:quarkus-maven-plugin:1.0.0.CR1:create 
-DprojectGroupId=jvmcon 
-DprojectArtifactId=skipass-gate 
-Dextensions=quarkus-resteasy-jsonb,quarkus-rest-client
-B
Übung 3: skipass-gate
3. Ergänzen Sie in skipass-gate den Service GateService
• zunächst nur als Wrapper um SkiPassManager
(Kopiervorlage: gateservice.txt)
JEE-Microservices mit Quarkus - eine Einführung 35gedoplan.de
@ApplicationScoped
public class GateService {
@Inject
@RestClient
SkiPassManager skiPassManager;
public boolean isValid(String skiPassId) {
LocalDateTime validTo = fetch(skiPassId);
return validTo != null && validTo.isAfter(LocalDateTime.now());
}
private LocalDateTime fetch(String skiPassId) {
return this.skiPassManager.getValidTo(skiPassId);
}
Übung 3: skipass-gate
4. Ergänzen Sie in skipass-gate einen Rest Endpoint
• @Path("gate")
• GateService-Objekt injizieren
• GET-Methode für Tor-Öffnung
• GET /gate/{id}
• nutzt GateService zur Prüfung
• liefert "GREEN" oder "RED" in text/plain
5. Konfigurieren Sie andere Ports
• HTTP-Port mit Config Property:
quarkus.http.port=8180
• Debug-Port mittels Startparameter: -Ddebug=5105
6. Prüfen Sie die Funktion mit curl
JEE-Microservices mit Quarkus - eine Einführung 36gedoplan.de
Übungs-Domäne
4. Schritt: Fault Tolerance in skipass-gate
JEE-Microservices mit Quarkus - eine Einführung 37gedoplan.de
skipass-manager
• POST /skipass?validTo=2019-12-14T18:00
Erzeugen eines Skipasses (id = UUID)
• GET /skipass/2a910ff2-b92a-477f-861d-36fdf2c3c249/validTo
Abfrage der Gültigkeit (Ende-Timestamp oder Ungültig-Wert)
• PUT /skipass/2a910ff2-b92a-477f-861d-36fdf2c3c249/blocked
Sperren oder Freigeben eines Skipasses
• …
DB skipass-gate
• GET /gate/2a910ff2-b92a-477f-861d-36fdf2c3c249
Einlass-Prüfung (GREEN/RED)
Kleiner Ausflug: MicroProfile Fault Tolerance
Interceptors für Resilience
@Retry wiederholt Aufruf bei Fehler (=Exception)
@Timeout bricht langsame Aufrufe ab
@Fallback liefert Ersatzwert
JEE-Microservices mit Quarkus - eine Einführung 38gedoplan.de
@Retry(maxRetries = 4)
public int doSomethingWithRetry() {
@Timeout(1000)
public int doSomethingWithTimeout() {
private int return42() {
return 42;
}
@Fallback(fallbackMethod = "return42")
public int doSomethingWithFallback() {
MicroProfile Fault Tolerance
Interceptors für Resilience
@CircuitBreaker unterdrückt Aufrufe bei hoher Fehlerrate
Quarkus-Extension: quarkus-smallrye-fault-tolerance
JEE-Microservices mit Quarkus - eine Einführung 39gedoplan.de
@CircuitBreaker(failureRatio = 0.25, requestVolumeThreshold = 10)
public int doSomethingWithCircuitBreaker() {
closed open
half-open
zu viele
Fehler
ok
Delay
Fehler
Übung 4: Fault Tolerance in skipass-gate
1. Machen Sie GateService.isValid in skipass-gate
fault-tolerant
• skipass-manager nicht erreichbar  Gate öffnen
• Fallback-Methode, die immer true liefert
• @Fallback auf isValid
2. Prüfen Sie die Funktion von skipass-gate bei nicht laufendem
skipass-manager
JEE-Microservices mit Quarkus - eine Einführung 40gedoplan.de
Übungs-Domäne
5. Schritt: Caching der Skipass-daten in skipass-gate
Invalidierung des Caches per Message
JEE-Microservices mit Quarkus - eine Einführung 41gedoplan.de
skipass-manager
• POST /skipass?validTo=2019-12-14T18:00
Erzeugen eines Skipasses (id = UUID)
• GET /skipass/2a910ff2-b92a-477f-861d-36fdf2c3c249/validTo
Abfrage der Gültigkeit (Ende-Timestamp oder Ungültig-Wert)
• PUT /skipass/2a910ff2-b92a-477f-861d-36fdf2c3c249/blocked
Sperren oder Freigeben eines Skipasses
• …
DB skipass-gate
• GET /gate/2a910ff2-b92a-477f-861d-36fdf2c3c249
Einlass-Prüfung (GREEN/RED)
Übung 5a: Cache in skipass-gate
1. Simulieren Sie eine langsame Ausführung von skipass-gate
• In skipass-manager,
Methode für GET /skipass/{id}/validTo:
Thread.sleep(3000)
2. Verifizieren Sie, dass skipass-gate nun recht zäh arbeitet
3. Cachen Sie die Skipass-Gültigkeit in skipass-gate,
GateService
• nutzen Sie ein ConcurrentMap<String,
LocalDateTime> zum cachen der Gültigkeit der Skipässe
(Kopiervorlage: gateservice-chached.txt)
JEE-Microservices mit Quarkus - eine Einführung 42gedoplan.de
Übung 5a: Cache in skipass-gate
4. Verifizieren Sie, dass skipass-gate
• nun nur einmal pro Id langsam arbeitet,
• danach aber auch bei nachträglicher Blockierung eines
Skipasses weiter mit veralteten Daten arbeitet
Abhilfe: Invalidieren (Entfernen) der gecachten Einträge in skipass-
gate nach jeder Änderung in skipass-manager
JEE-Microservices mit Quarkus - eine Einführung 43gedoplan.de
skipass-manager
• PUT /skipass/2a910ff2-b92a-477f-861d-36fdf2c3c249/blocked
Sperren oder Freigeben eines Skipasses
skipass-gate
2a910ff2-b92a-477f-861d-36fdf2c3c249
Kleiner Ausflug: (Reactive) Messaging
@Incoming = Meldungsempfänger
Analog: @Outgoing für Meldungsproduzenten
im Workshop ungenutzt
@Channel(…) Emitter
= Brücke imperativ  reaktiv
JEE-Microservices mit Quarkus - eine Einführung 44gedoplan.de
@Incoming("channel-one")
public void onReceive(String someReceivedString) {
@Inject
@Channel("channel-two")
Emitter<String> emitter;
…
this.emitter.send(someString);
Reactive Message in Quarkus mit AMQP
Extension
Konfiguration
JEE-Microservices mit Quarkus - eine Einführung 45gedoplan.de
mvn quarkus:add-extensions –Dextensions=quarkus-smallrye-reactive-messaging-amqp
# Messaging
amqp-username=quarkus
amqp-password=quarkus
mp.messaging.incoming.channel-one.connector=smallrye-amqp
mp.messaging.incoming.channel-one.address=topic-one-on-amqp-server
mp.messaging.incoming.channel-one.durable=false
mp.messaging.incoming.channel-one.broadcast=true
mp.messaging.outgoing.channel-two.connector=smallrye-amqp
mp.messaging.outgoing.channel-two.address=topic-two-on-amqp-server
mp.messaging.outgoing.channel-two.durable=false
mp.messaging.outgoing.channel-two.broadcast=true
application.properties
Übung 5b: Cache in skipass-gate
1. Installieren, konfigurieren und starten Sie ActiveMQ Artemis
• Demo-Projekt active-mq-artemis
• mvn lädt Artemis herunter
und konfiguriert Broker in target/demoserver
• Start: target/demoserver/bin/artemis run
2. Ergänzen Sie die AMQP-Konfiguration in skipass-manager
(Kopiervorlage: skipass-manager-amqp.txt)
JEE-Microservices mit Quarkus - eine Einführung 46gedoplan.de
# Messaging
amqp-username=quarkus
amqp-password=quarkus
mp.messaging.outgoing.skipassInvalidation.connector=smallrye-amqp
mp.messaging.outgoing.skipassInvalidation.address=skipassInvalidation
mp.messaging.outgoing.skipassInvalidation.durable=false
mp.messaging.outgoing.skipassInvalidation.broadcast=true
Übung 5b: Cache in skipass-gate
3. Senden Sie die Ids von veränderten Skipässen als Message
• In SkiPassResource in skipass-manager:
• Emitter<String> injizieren für Channel
skipassInvalidation
• In Methode für PUT /skipass/{id}/blocked am Ende
Id des geänderten Skipasses versenden
4. Ergänzen Sie die AMQP-Konfiguration in skipass-gate
(Kopiervorlage: skipass-gate-amqp.txt)
JEE-Microservices mit Quarkus - eine Einführung 47gedoplan.de
amqp-username=quarkus
amqp-password=quarkus
mp.messaging.incoming.skipassInvalidation.connector=smallrye-amqp
mp.messaging.incoming.skipassInvalidation.address=skipassInvalidation
mp.messaging.incoming.skipassInvalidation.durable=false
mp.messaging.incoming.skipassInvalidation.broadcast=true
Übung 5b: Cache in skipass-gate
5. Ergänzen Sie im GateService von skipass-gate eine
Methode,
• die eingehende Ids von veränderten Skipässen annimmt
• und diese aus dem Cache entfernt
6. Verifizieren Sie dass skipass-gate nun auch nach
(Ent-)Sperren von Skipässen richtig arbeitet
JEE-Microservices mit Quarkus - eine Einführung 48gedoplan.de
@Incoming("skipassInvalidation")
public void invalidate(String skiPassId) {
this.cache.remove(skiPassId);
}
Weitere Quarkus-Features
Tests mit @QuarkustTest
OpenAPI
MongoDB, Neo4j, …
Kafka, JMS, Camel
OpenID Connect
Health, Metrics
Spring Integration
Scheduling
Mail
Native Mode
JEE-Microservices mit Quarkus - eine Einführung 49gedoplan.de
More
Wir bilden Sie aus!
www.gedoplan-it-training.de
Trainings in Berlin, Frankfurt, Köln, Bielefeld, inhouse
neu: JEE Microservice Foundation
neu: Java DevOps: Development und
Delivery mit Docker und Kubernetes
Wir unterstützen Sie in Ihren Projekten
www.gedoplan-it-consulting.de
Reviews, Coaching, …
javaeeblog.wordpress.com
 dirk.weil@gedoplan.de
@dirkweil
50gedoplan.deJEE-Microservices mit Quarkus - eine Einführung

Weitere ähnliche Inhalte

Ähnlich wie JEE-Microservices mit Quarkus – eine Einführung

Cloud-native and Enterprise Java? Hold my beer!
Cloud-native and Enterprise Java? Hold my beer!Cloud-native and Enterprise Java? Hold my beer!
Cloud-native and Enterprise Java? Hold my beer!OPEN KNOWLEDGE GmbH
 
Schnell, schneller, Quarkus!!
Schnell, schneller, Quarkus!!Schnell, schneller, Quarkus!!
Schnell, schneller, Quarkus!!gedoplan
 
Ready for the Future: Jakarta EE in Zeiten von Cloud Native & Co
Ready for the Future: Jakarta EE in Zeiten von Cloud Native & CoReady for the Future: Jakarta EE in Zeiten von Cloud Native & Co
Ready for the Future: Jakarta EE in Zeiten von Cloud Native & CoOPEN KNOWLEDGE GmbH
 
Java EE Microservices ohne Server
Java EE Microservices ohne ServerJava EE Microservices ohne Server
Java EE Microservices ohne Servergedoplan
 
Microservices mit Rust
Microservices mit RustMicroservices mit Rust
Microservices mit RustJens Siebert
 
Feige sein! Testen im Java-EE-Umfeld
Feige sein! Testen im Java-EE-UmfeldFeige sein! Testen im Java-EE-Umfeld
Feige sein! Testen im Java-EE-Umfeldgedoplan
 
Gradle - Beginner's Workshop (german)
Gradle - Beginner's Workshop (german)Gradle - Beginner's Workshop (german)
Gradle - Beginner's Workshop (german)Joachim Baumann
 
Docker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-PatternsDocker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-PatternsJosef Adersberger
 
Docker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-PatternsDocker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-PatternsQAware GmbH
 
Mögen die Tests mit dir sein
Mögen die Tests mit dir seinMögen die Tests mit dir sein
Mögen die Tests mit dir seincodepitbull
 
Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...
Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...
Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...GFU Cyrus AG
 
Automatisiertes disaster recovery testing mit der oracle cloud
Automatisiertes disaster recovery testing mit der oracle cloudAutomatisiertes disaster recovery testing mit der oracle cloud
Automatisiertes disaster recovery testing mit der oracle cloudTrivadis
 
DB-Schema-Evolution mit LiquiBase
DB-Schema-Evolution mit LiquiBaseDB-Schema-Evolution mit LiquiBase
DB-Schema-Evolution mit LiquiBasegedoplan
 
Logical Data Warehouse - SQL mit Oracle DB und Hadoop
Logical Data Warehouse - SQL mit Oracle DB und HadoopLogical Data Warehouse - SQL mit Oracle DB und Hadoop
Logical Data Warehouse - SQL mit Oracle DB und HadoopOPITZ CONSULTING Deutschland
 
Deployment mit Ansible auf JBoss Servern
Deployment mit Ansible auf JBoss ServernDeployment mit Ansible auf JBoss Servern
Deployment mit Ansible auf JBoss ServernHarald Schmaldienst
 
JSUG - OSGi by Michael Greifeneder
JSUG - OSGi by Michael GreifenederJSUG - OSGi by Michael Greifeneder
JSUG - OSGi by Michael GreifenederChristoph Pickl
 
Einführung in RequireJS
Einführung in RequireJSEinführung in RequireJS
Einführung in RequireJSandreaswo
 
Vagrant, Puppet, Docker für Entwickler und Architekten
Vagrant, Puppet, Docker für Entwickler und ArchitektenVagrant, Puppet, Docker für Entwickler und Architekten
Vagrant, Puppet, Docker für Entwickler und ArchitektenOPITZ CONSULTING Deutschland
 
Slides__Splunk_UserGroup_20220407.pdf
Slides__Splunk_UserGroup_20220407.pdfSlides__Splunk_UserGroup_20220407.pdf
Slides__Splunk_UserGroup_20220407.pdfAlexanderStz1
 

Ähnlich wie JEE-Microservices mit Quarkus – eine Einführung (20)

Cloud-native and Enterprise Java? Hold my beer!
Cloud-native and Enterprise Java? Hold my beer!Cloud-native and Enterprise Java? Hold my beer!
Cloud-native and Enterprise Java? Hold my beer!
 
Schnell, schneller, Quarkus!!
Schnell, schneller, Quarkus!!Schnell, schneller, Quarkus!!
Schnell, schneller, Quarkus!!
 
Ready for the Future: Jakarta EE in Zeiten von Cloud Native & Co
Ready for the Future: Jakarta EE in Zeiten von Cloud Native & CoReady for the Future: Jakarta EE in Zeiten von Cloud Native & Co
Ready for the Future: Jakarta EE in Zeiten von Cloud Native & Co
 
Java EE Microservices ohne Server
Java EE Microservices ohne ServerJava EE Microservices ohne Server
Java EE Microservices ohne Server
 
Testing tools
Testing toolsTesting tools
Testing tools
 
Microservices mit Rust
Microservices mit RustMicroservices mit Rust
Microservices mit Rust
 
Feige sein! Testen im Java-EE-Umfeld
Feige sein! Testen im Java-EE-UmfeldFeige sein! Testen im Java-EE-Umfeld
Feige sein! Testen im Java-EE-Umfeld
 
Gradle - Beginner's Workshop (german)
Gradle - Beginner's Workshop (german)Gradle - Beginner's Workshop (german)
Gradle - Beginner's Workshop (german)
 
Docker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-PatternsDocker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-Patterns
 
Docker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-PatternsDocker und Kubernetes Patterns & Anti-Patterns
Docker und Kubernetes Patterns & Anti-Patterns
 
Mögen die Tests mit dir sein
Mögen die Tests mit dir seinMögen die Tests mit dir sein
Mögen die Tests mit dir sein
 
Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...
Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...
Java Code Quality: Gute Software braucht guten Code - Regeln für verständlich...
 
Automatisiertes disaster recovery testing mit der oracle cloud
Automatisiertes disaster recovery testing mit der oracle cloudAutomatisiertes disaster recovery testing mit der oracle cloud
Automatisiertes disaster recovery testing mit der oracle cloud
 
DB-Schema-Evolution mit LiquiBase
DB-Schema-Evolution mit LiquiBaseDB-Schema-Evolution mit LiquiBase
DB-Schema-Evolution mit LiquiBase
 
Logical Data Warehouse - SQL mit Oracle DB und Hadoop
Logical Data Warehouse - SQL mit Oracle DB und HadoopLogical Data Warehouse - SQL mit Oracle DB und Hadoop
Logical Data Warehouse - SQL mit Oracle DB und Hadoop
 
Deployment mit Ansible auf JBoss Servern
Deployment mit Ansible auf JBoss ServernDeployment mit Ansible auf JBoss Servern
Deployment mit Ansible auf JBoss Servern
 
JSUG - OSGi by Michael Greifeneder
JSUG - OSGi by Michael GreifenederJSUG - OSGi by Michael Greifeneder
JSUG - OSGi by Michael Greifeneder
 
Einführung in RequireJS
Einführung in RequireJSEinführung in RequireJS
Einführung in RequireJS
 
Vagrant, Puppet, Docker für Entwickler und Architekten
Vagrant, Puppet, Docker für Entwickler und ArchitektenVagrant, Puppet, Docker für Entwickler und Architekten
Vagrant, Puppet, Docker für Entwickler und Architekten
 
Slides__Splunk_UserGroup_20220407.pdf
Slides__Splunk_UserGroup_20220407.pdfSlides__Splunk_UserGroup_20220407.pdf
Slides__Splunk_UserGroup_20220407.pdf
 

JEE-Microservices mit Quarkus – eine Einführung

  • 1. JEE-Microservices mit Quarkus - eine Einführung 25.11.2019 Dirk Weil, GEDOPLAN GmbH
  • 2. Dirk Weil GEDOPLAN GmbH, Bielefeld GEDOPLAN IT Consulting Consulting, coaching, concepts, reviews, development GEDOPLAN IT Training & partner Java, JEE, tools trainings Berlin, Frankfurt, Bielefeld, Köln, on-site JEE since 1998 Speaker and author JEE-Microservices mit Quarkus - eine Einführung 2gedoplan.de
  • 3. Java EE  Jakarta EE 2017: Projekt EE4J (Eclipse Enterprise for Java) Produktname Jakarta EE Oracle behält Namens- und Urheberrechte Java EE Paketnamen javax.* Jakarta EE 8 codegleich zu Java EE 8 Release 10.09.2019 JEE-Microservices mit Quarkus - eine Einführung 3 JEE gedoplan.de
  • 4. MicroProfile microprofile.io „Next step of Java EE / Jakarta EE evolution“ „… optimize Enterprise Java for a microservices architecture …“ JEE-Microservices mit Quarkus - eine Einführung 4gedoplan.de Config 1.3 Fault Tolerance 2.0 Health 2.0 JWT Authentication 1.1 Metrics 2.0.0 OpenAPI 1.1 OpenTracing 1.3 Rest Client 1.3 CDI 2.0 JAX-RS 2.1 JSON-B 1.0 JSON-P 1.1
  • 5. MicroProfile Runtimes: Klassische Application Server 5 Anwendungsklassen Konfigurationsfiles (Deployment Descriptors, Properties, …) JEE Server CDI Runtime JPA Runtime REST Runtime Technische Konfiguration * JRE build deploy run * DB-Verbindungen, Messaging Security … Thin WAR klein groß gedoplan.deJEE-Microservices mit Quarkus - eine Einführung
  • 6. MicroProfile Runtimes: „Micro“ Frameworks 6 Anwendungsklassen Konfigurationsfiles * CDI Runtime JPA Runtime REST Runtime JRE build run * Anwendungsparameter, DB-Verbindungen, Messaging Security … Fat JAR JAR + Dependencies groß gedoplan.deJEE-Microservices mit Quarkus - eine Einführung
  • 7. Workshop-Projekt Source github.com/GEDOPLAN/quarkus-workshop Branches: master Demos, Skripte, Kopiervorlagen, … jvmcon2019 basiert auf master wird während des Workshops sukzessive aufgebaut Tooling JDK 8+ (z. B. adoptopenjdk.net) Maven 3 (maven.apache.org/download.cgi) Git Client (git-scm.com/downloads) curl (curl.haxx.se/download.html) JEE-Microservices mit Quarkus - eine Einführung 7gedoplan.de
  • 8. Quarkus Red Hats Antwort auf Spring Boot Designierter Nachfolger von Thorntail (aka WildFly Swarm) Optimiert für kurze Startzeiten Hotspot und GraalVM https://quarkus.io/ JEE-Microservices mit Quarkus - eine Einführung 8gedoplan.de
  • 9. Quarkus Core + Extensions (= Maven Dependencies) Project Bootstrap mit Maven Plugin (oder Gradle)  quarkus.io/guides/maven-tooling.html JEE-Microservices mit Quarkus - eine Einführung 9gedoplan.de <dependencies> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-resteasy</artifactId> </dependency> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-junit5</artifactId> <scope>test</scope> </dependency> mvn io.quarkus:quarkus-maven-plugin:1.0.0.CR1:create -DprojectGroupId=… -DprojectArtifactId=… -B
  • 10. Quarkus Maven-Plugin für Build Thin jar target/quarkus-getting-started-runner.jar Dependencies in target/lib/ Anwendungsstart java –jar target/quarkus-getting-started-runner.jar JEE-Microservices mit Quarkus - eine Einführung 10gedoplan.de <plugins> <plugin> <groupId>io.quarkus</groupId> <artifactId>quarkus-maven-plugin</artifactId> <version>${quarkus.version}</version> <executions> <execution> <goals><goal>build</goal></goals> </execution>
  • 11. Quarkus Development mode Hot reload bei REST/Web-Request falls Quellcodeänderung JEE-Microservices mit Quarkus - eine Einführung 11gedoplan.de $ mvn quarkus:dev Listening for transport dt_socket at address: 5005 17:54:50,319 INFO [io.qua.dep.QuarkusAugmentor] (main) Beginning quarkus au 17:54:50,949 INFO [io.qua.resteasy] (build-1) Resteasy running without serv 17:54:50,949 INFO [io.qua.resteasy] (build-1) - Add quarkus-undertow to run 17:54:50,980 INFO [io.qua.dep.QuarkusAugmentor] (main) Quarkus augmentation 17:54:52,452 INFO [io.quarkus] (main) Quarkus 0.26.1 started in 2.320s. Lis 17:54:52,452 INFO [io.quarkus] (main) Profile dev activated. Live Coding ac 17:54:52,454 INFO [io.quarkus] (main) Installed features: [cdi, resteasy]
  • 12. Quarkus Configuration application.properties Properties quarkus.… für Quarkus quarkus.io/guides/config quarkus.io/guides/all-config Weitere Properties für Anwendung (MicroProfile Config) Configuration Profiles %prod, %dev, %test JEE-Microservices mit Quarkus - eine Einführung 12gedoplan.de # Ports quarkus.http.port=8080 # Logging quarkus.log.console.format=%d{HH:mm:ss,SSS} %-6p [%c{1.}] (%t) %s%e%n quarkus.log.console.color=false quarkus.log.level=INFO quarkus.log.category."some.logger.name".level=WARN %dev.quarkus.log.category."some.logger.name".level=FINE
  • 13. Demo: getting-started Bootstrap Start JEE-Microservices mit Quarkus - eine Einführung 13gedoplan.de mvn io.quarkus:quarkus-maven-plugin:1.0.0.CR1:create -DprojectGroupId=jvmcon -DprojectArtifactId=getting-started -DclassName="jvmcon.GreetingResource" -B getting-started-bootstrap.sh cd getting-started mvn compile quarkus:dev
  • 14. Kleiner Ausflug: JAX-RS Klasse mit @Path definiert Rest Endpoints Methoden mit @GET, @PUT, @POST, @DELETE @Path kann auf Methoden ergänzend genutzt werden Pfade dürfen Templates enthalten @Produces und @Consumes bestimmen (De-)Serialisierung Parameter können aus URL übernommen werden siehe Klasse GreetingResource (nach Bootstrap ergänzt) Beispiel-Aufrufe mittels curl siehe getting-started-curl.txt JEE-Microservices mit Quarkus - eine Einführung 14gedoplan.de
  • 15. Übungs-Domäne Skipass-Verwaltung und Nutzung 1. Schritt: skipass-manager mit POST-Endpoint zur Erzeugung von Skipässen JEE-Microservices mit Quarkus - eine Einführung 15gedoplan.de skipass-manager • POST /skipass?validTo=2019-12-14T18:00 Erzeugen eines Skipasses (id = UUID) • GET /skipass/2a910ff2-b92a-477f-861d-36fdf2c3c249/validTo Abfrage der Gültigkeit (Ende-Timestamp oder Ungültig-Wert) • PUT /skipass/2a910ff2-b92a-477f-861d-36fdf2c3c249/blocked Sperren oder Freigeben eines Skipasses • … DB skipass-gate • GET /gate/2a910ff2-b92a-477f-861d-36fdf2c3c249 Einlass-Prüfung (GREEN/RED)
  • 16. Übungs-Domäne 1. Schritt: skipass-manager mit POST-Endpoint zur Erzeugung von Skipässen (Project Bootstrap, JAX-RS) JEE-Microservices mit Quarkus - eine Einführung 16gedoplan.de skipass-manager • POST /skipass?validTo=2019-12-14T18:00 Erzeugen eines Skipasses (id = UUID) • GET /skipass/2a910ff2-b92a-477f-861d-36fdf2c3c249/validTo Abfrage der Gültigkeit (Ende-Timestamp oder Ungültig-Wert) • PUT /skipass/2a910ff2-b92a-477f-861d-36fdf2c3c249/blocked Sperren oder Freigeben eines Skipasses • … DB skipass-gate • GET /gate/2a910ff2-b92a-477f-861d-36fdf2c3c249 Einlass-Prüfung (GREEN/RED)
  • 17. Übung 1: Bootstrap skipass-manager 1. Erzeugen Sie das Quarkus-Projekt skipass-manager 2. Ergänzen Sie die Entity SkiPass • Kopiervorlage: skipass.txt • Paket, Getter, Setter, toString nach Gusto JEE-Microservices mit Quarkus - eine Einführung 17gedoplan.de mvn io.quarkus:quarkus-maven-plugin:1.0.0.CR1:create -DprojectGroupId=jvmcon -DprojectArtifactId=skipass-manager -B public class SkiPass { private String id; private LocalDateTime validFrom; private LocalDateTime validTo; private boolean blocked;
  • 18. Übung 1: Bootstrap skipass-manager 3. Ergänzen Sie die Rest-Resource SkiPassResource • @Path("skipass") • Methode für Skipass-Anlage • @POST • @Produces(MediaType.TEXT_PLAIN) • Parameter • @QueryParam("validTo") LocalDateTime validTo • @QueryParam("validFrom") LocalDateTime validFrom • neues SkiPass-Objekt instanziieren und seine Id als Returnwert liefern 4. Anwendung starten 5. Rest-Call ausprobieren JEE-Microservices mit Quarkus - eine Einführung 18gedoplan.de curl -X POST -i http://localhost:8080/skipass?validTo=2019-12-24T23:59 mvn compile quarkus:dev
  • 19. Übungs-Domäne 2. Schritt: Skipässe persistent ablegen (JPA, CDI, JSON-B) Validierungslogik JEE-Microservices mit Quarkus - eine Einführung 19gedoplan.de skipass-manager • POST /skipass?validTo=2019-12-14T18:00 Erzeugen eines Skipasses (id = UUID) • GET /skipass/2a910ff2-b92a-477f-861d-36fdf2c3c249/validTo Abfrage der Gültigkeit (Ende-Timestamp oder Ungültig-Wert) • PUT /skipass/2a910ff2-b92a-477f-861d-36fdf2c3c249/blocked Sperren oder Freigeben eines Skipasses • … DB skipass-gate • GET /gate/2a910ff2-b92a-477f-861d-36fdf2c3c249 Einlass-Prüfung (GREEN/RED)
  • 20. Kleiner Ausflug: CDI Anwendungen / Geschäftslogik besteht aus vielen Services die einander benutzen / referenzieren deren Daten unterschiedlich lang benötigt werden (gesamte Laufzeit, einzelner Request, …) JEE-Microservices mit Quarkus - eine Einführung 20gedoplan.de Application Use Case Domain Data Service Domain Data Service Data Repository Data Repository Data Repository Page / View Endpoint TX JPA Mail JMS
  • 21. Kleiner Ausflug: CDI Definition von Beans (=Services) und Zuordnung zu Scopes (=Lebensdauer) Verknüpfung untereinander mittels Injektion Descriptor META-INF/beans.xml für Quarkus optional Inhalt wird von Quarkus (derzeit?) nicht genutzt JEE-Microservices mit Quarkus - eine Einführung 21gedoplan.de @ApplicationScoped public class PersonRepository { @ApplicationScoped @Path("person") public class PersonResource { @Inject PersonRepository personRepository;
  • 22. Kleiner Ausflug: CDI Interceptors z. B. für Transaktionssteuerung Weitere Features (hier nicht benötigt): Qualifier Alternatives Producer Events JEE-Microservices mit Quarkus - eine Einführung 22gedoplan.de @ApplicationScoped @Transactional(rollbackOn = Exception.class) public class PersonRepository { @Inject EntityManager entityManager; public void persist(Person entity) { this.entityManager.persist(entity);
  • 23. Kleiner Ausflug: JPA Aufgabenstellung: Speichern und Laden von Java-Objekten Mapping OO  RDBMS Entities (=persistente Objekte) sind POJOs nicht final No-args constructor @Entity @Id Diskussion über Ids, Generatoren, equals, hashCode siehe javaeeblog.wordpress.com/2017/11/15/ identity-and-equality-of-jpa-entities/ JEE-Microservices mit Quarkus - eine Einführung 23gedoplan.de @Entity public class Person { @Id @GeneratedValue(strategy = …) private Integer id; private String name; private String firstname; protected Person() { }
  • 24. Kleiner Ausflug: JPA EntityManager = API für CRUD, Queries, … JEE-Microservices mit Quarkus - eine Einführung 24gedoplan.de public class PersonRepository { @Inject EntityManager entityManager; public Person findById(Integer id) { return this.entityManager.find(Person.class, id); } public List<Person> findAll() { return this.entityManager .createQuery("select x from Person x", Person.class) .getResultList(); } public void persist(Person entity) { this.entityManager.persist(entity);
  • 25. JPA in Quarkus Extensions für Hibernate und DB-Treiber Konfiguration der Datasource(s) META-INF/persistence.xml optional JEE-Microservices mit Quarkus - eine Einführung 25gedoplan.de mvn quarkus:add-extensions –Dextensions=quarkus-hibernate-orm,quarkus-jdbc-h2 # Datasource quarkus.datasource.url=jdbc:h2:mem:test;… quarkus.datasource.driver=org.h2.Driver quarkus.datasource.username=showcase quarkus.datasource.password=showcase quarkus.hibernate-orm.database.generation=update quarkus.datasource.hugo.url=jdbc:… application.properties
  • 26. Kleiner Ausflug: JSON-B (De-)Serialisierung POJO  JSON Automatische Nutzung in JAX-RS Mediatype application/json Quarkus-Extension quarkus-resteasy-jsonb (statt quarkus-resteasy) JEE-Microservices mit Quarkus - eine Einführung 26gedoplan.de Person person = new Person("Wacker", "Willi"); Jsonb jsonb = JsonbBuilder.create(); String personJson = jsonb.toJson(person);
  • 27. Übung 2a: Persistenz in skipass-manager 1. Ergänzen Sie die für JPA nötigen Extensions 2. Konfigurieren Sie die Datasource 3. Machen Sie die Entity SkiPass JPA-fähig • @Entity, @Id • No-args constructor JEE-Microservices mit Quarkus - eine Einführung 27gedoplan.de mvn quarkus:add-extensions –Dextensions=quarkus-hibernate-orm,quarkus-jdbc-h2 # Datasource quarkus.datasource.url=jdbc:h2:~/h2/jvmcon;AUTO_SERVER=TRUE quarkus.datasource.driver=org.h2.Driver quarkus.datasource.username=jvmcon quarkus.datasource.password=jvmcon quarkus.hibernate-orm.database.generation=update
  • 28. Übung 2a: Persistenz in skipass-manager 4. Ergänzen Sie die Klasse SkiPassRepository für CRUD-Operationen • vgl. PersonRepository aus rest-cdi-jpa • persist, findAll und findById reichen 5. Nutzen Sie SkiPassRepository in SkiPassResource • Injizieren Sie eine SkiPassRepository-Instanz • Ergänzen Sie die POST-Methode um die Speicherung des Skipasses 6. Prüfen Sie, ob mittels POST erzeugte Skipässe in der DB gespeichert werden • Das Treiber-Jar der H2-DB enthält einen einfachen Client • liegt im lokalen Maven-Repository (~/.m2/repository/com/h2database/h2/1.4.197/h2-1.4.197.jar) • Start per java -jar h2-1.4.197.jar JEE-Microservices mit Quarkus - eine Einführung 28gedoplan.de
  • 29. Übung 2a: Persistenz in skipass-manager 7. Tauschen Sie die Quarkus-Extension für Rest gegen die mit JSON-B-Unterstützung aus • quarkus-resteasy-jsonb 8. Ergänzen Sie SkiPassResource um GET-Methoden für alle Skipässe bzw. für einen Skipass in JSON • GET /skipass • GET /skipass/{id} 9. Fragen Sie zum Test bspw. per curl Skipässe ab • curl http://localhost:8080/skipass • curl http://localhost:8080/skipass/2a910ff2-b92a-477f-861d-36fdf2c3c249 JEE-Microservices mit Quarkus - eine Einführung 29gedoplan.de
  • 30. Übung 2b: Logik für Skipass-Validierung 1. Ergänzen Sie den Rest-Service um eine PUT-Methode zum Setzen des blocked-Attributs eines Skipasses • PUT /skipass/{id}/blocked • Konsumiert boolean als JSON • Skipass zur angegebenen Id suchen und blocked setzen • @Transactional 2. Ergänzen Sie eine weitere Methode zur Abfrage des Gültigkeitsendes eines Skipasses • GET /skipass/{id}/validTo • Liefert LocalDateTime-Objekt als JSON • falls Skipass gültig (*), sein validTo (* vorhanden, nicht blockiert, jetzt gültig) • andernfalls LocalDateTime.MIN JEE-Microservices mit Quarkus - eine Einführung 30gedoplan.de
  • 31. Übungs-Domäne 3. Schritt: Service skipass-gate mit Aufruf von skipass-manager (Rest Client) JEE-Microservices mit Quarkus - eine Einführung 31gedoplan.de skipass-manager • POST /skipass?validTo=2019-12-14T18:00 Erzeugen eines Skipasses (id = UUID) • GET /skipass/2a910ff2-b92a-477f-861d-36fdf2c3c249/validTo Abfrage der Gültigkeit (Ende-Timestamp oder Ungültig-Wert) • PUT /skipass/2a910ff2-b92a-477f-861d-36fdf2c3c249/blocked Sperren oder Freigeben eines Skipasses • … DB skipass-gate • GET /gate/2a910ff2-b92a-477f-861d-36fdf2c3c249 Einlass-Prüfung (GREEN/RED)
  • 32. Kleiner Ausflug: MicroProfile Rest Client Rest Client Injizierbare REST clients aus Interface generiert konfigurierbare URL JEE-Microservices mit Quarkus - eine Einführung 32gedoplan.de @Path("v2") @RegisterRestClient public interface CountryApi { @GET @Path("all") @Produces("application/json") Collection<Country> getAll(); de.gedoplan.showcase.….CountryApi/mp-rest/url=http://restcountries.eu/rest META-INF/microprofile-config.properties @Path("country") @ApplicationScoped public class CountryResource { @Inject @RestClient CountryApi countryClient; @GET @Path("count") @Produces(MediaType.APPLICATION_JSON) public int getCount() { return countryClient.getAll().size();
  • 33. MP Rest Client in Quarkus Extension Konfiguration von externer URL und Scope auch in application.properties möglich JEE-Microservices mit Quarkus - eine Einführung 33gedoplan.de mvn quarkus:add-extensions –Dextensions=quarkus-rest-client # Rest Client fully.qual.rest.Intf/mp-rest/url=http://… fully.qual.rest.Intf/mp-rest/scope=javax.enterprise.context.ApplicationScoped application.properties
  • 34. Übung 3: skipass-gate 1. Erzeugen Sie das Quarkus-Projekt skipass-gate 2. Ergänzen Sie ein Rest Client Interface SkiPassManager • beschreibt Ihren Rest Service in skipass-manager (Methode für GET /skipass/{id}/validTo reicht) • @RegisterRestClient JEE-Microservices mit Quarkus - eine Einführung 34gedoplan.de mvn io.quarkus:quarkus-maven-plugin:1.0.0.CR1:create -DprojectGroupId=jvmcon -DprojectArtifactId=skipass-gate -Dextensions=quarkus-resteasy-jsonb,quarkus-rest-client -B
  • 35. Übung 3: skipass-gate 3. Ergänzen Sie in skipass-gate den Service GateService • zunächst nur als Wrapper um SkiPassManager (Kopiervorlage: gateservice.txt) JEE-Microservices mit Quarkus - eine Einführung 35gedoplan.de @ApplicationScoped public class GateService { @Inject @RestClient SkiPassManager skiPassManager; public boolean isValid(String skiPassId) { LocalDateTime validTo = fetch(skiPassId); return validTo != null && validTo.isAfter(LocalDateTime.now()); } private LocalDateTime fetch(String skiPassId) { return this.skiPassManager.getValidTo(skiPassId); }
  • 36. Übung 3: skipass-gate 4. Ergänzen Sie in skipass-gate einen Rest Endpoint • @Path("gate") • GateService-Objekt injizieren • GET-Methode für Tor-Öffnung • GET /gate/{id} • nutzt GateService zur Prüfung • liefert "GREEN" oder "RED" in text/plain 5. Konfigurieren Sie andere Ports • HTTP-Port mit Config Property: quarkus.http.port=8180 • Debug-Port mittels Startparameter: -Ddebug=5105 6. Prüfen Sie die Funktion mit curl JEE-Microservices mit Quarkus - eine Einführung 36gedoplan.de
  • 37. Übungs-Domäne 4. Schritt: Fault Tolerance in skipass-gate JEE-Microservices mit Quarkus - eine Einführung 37gedoplan.de skipass-manager • POST /skipass?validTo=2019-12-14T18:00 Erzeugen eines Skipasses (id = UUID) • GET /skipass/2a910ff2-b92a-477f-861d-36fdf2c3c249/validTo Abfrage der Gültigkeit (Ende-Timestamp oder Ungültig-Wert) • PUT /skipass/2a910ff2-b92a-477f-861d-36fdf2c3c249/blocked Sperren oder Freigeben eines Skipasses • … DB skipass-gate • GET /gate/2a910ff2-b92a-477f-861d-36fdf2c3c249 Einlass-Prüfung (GREEN/RED)
  • 38. Kleiner Ausflug: MicroProfile Fault Tolerance Interceptors für Resilience @Retry wiederholt Aufruf bei Fehler (=Exception) @Timeout bricht langsame Aufrufe ab @Fallback liefert Ersatzwert JEE-Microservices mit Quarkus - eine Einführung 38gedoplan.de @Retry(maxRetries = 4) public int doSomethingWithRetry() { @Timeout(1000) public int doSomethingWithTimeout() { private int return42() { return 42; } @Fallback(fallbackMethod = "return42") public int doSomethingWithFallback() {
  • 39. MicroProfile Fault Tolerance Interceptors für Resilience @CircuitBreaker unterdrückt Aufrufe bei hoher Fehlerrate Quarkus-Extension: quarkus-smallrye-fault-tolerance JEE-Microservices mit Quarkus - eine Einführung 39gedoplan.de @CircuitBreaker(failureRatio = 0.25, requestVolumeThreshold = 10) public int doSomethingWithCircuitBreaker() { closed open half-open zu viele Fehler ok Delay Fehler
  • 40. Übung 4: Fault Tolerance in skipass-gate 1. Machen Sie GateService.isValid in skipass-gate fault-tolerant • skipass-manager nicht erreichbar  Gate öffnen • Fallback-Methode, die immer true liefert • @Fallback auf isValid 2. Prüfen Sie die Funktion von skipass-gate bei nicht laufendem skipass-manager JEE-Microservices mit Quarkus - eine Einführung 40gedoplan.de
  • 41. Übungs-Domäne 5. Schritt: Caching der Skipass-daten in skipass-gate Invalidierung des Caches per Message JEE-Microservices mit Quarkus - eine Einführung 41gedoplan.de skipass-manager • POST /skipass?validTo=2019-12-14T18:00 Erzeugen eines Skipasses (id = UUID) • GET /skipass/2a910ff2-b92a-477f-861d-36fdf2c3c249/validTo Abfrage der Gültigkeit (Ende-Timestamp oder Ungültig-Wert) • PUT /skipass/2a910ff2-b92a-477f-861d-36fdf2c3c249/blocked Sperren oder Freigeben eines Skipasses • … DB skipass-gate • GET /gate/2a910ff2-b92a-477f-861d-36fdf2c3c249 Einlass-Prüfung (GREEN/RED)
  • 42. Übung 5a: Cache in skipass-gate 1. Simulieren Sie eine langsame Ausführung von skipass-gate • In skipass-manager, Methode für GET /skipass/{id}/validTo: Thread.sleep(3000) 2. Verifizieren Sie, dass skipass-gate nun recht zäh arbeitet 3. Cachen Sie die Skipass-Gültigkeit in skipass-gate, GateService • nutzen Sie ein ConcurrentMap<String, LocalDateTime> zum cachen der Gültigkeit der Skipässe (Kopiervorlage: gateservice-chached.txt) JEE-Microservices mit Quarkus - eine Einführung 42gedoplan.de
  • 43. Übung 5a: Cache in skipass-gate 4. Verifizieren Sie, dass skipass-gate • nun nur einmal pro Id langsam arbeitet, • danach aber auch bei nachträglicher Blockierung eines Skipasses weiter mit veralteten Daten arbeitet Abhilfe: Invalidieren (Entfernen) der gecachten Einträge in skipass- gate nach jeder Änderung in skipass-manager JEE-Microservices mit Quarkus - eine Einführung 43gedoplan.de skipass-manager • PUT /skipass/2a910ff2-b92a-477f-861d-36fdf2c3c249/blocked Sperren oder Freigeben eines Skipasses skipass-gate 2a910ff2-b92a-477f-861d-36fdf2c3c249
  • 44. Kleiner Ausflug: (Reactive) Messaging @Incoming = Meldungsempfänger Analog: @Outgoing für Meldungsproduzenten im Workshop ungenutzt @Channel(…) Emitter = Brücke imperativ  reaktiv JEE-Microservices mit Quarkus - eine Einführung 44gedoplan.de @Incoming("channel-one") public void onReceive(String someReceivedString) { @Inject @Channel("channel-two") Emitter<String> emitter; … this.emitter.send(someString);
  • 45. Reactive Message in Quarkus mit AMQP Extension Konfiguration JEE-Microservices mit Quarkus - eine Einführung 45gedoplan.de mvn quarkus:add-extensions –Dextensions=quarkus-smallrye-reactive-messaging-amqp # Messaging amqp-username=quarkus amqp-password=quarkus mp.messaging.incoming.channel-one.connector=smallrye-amqp mp.messaging.incoming.channel-one.address=topic-one-on-amqp-server mp.messaging.incoming.channel-one.durable=false mp.messaging.incoming.channel-one.broadcast=true mp.messaging.outgoing.channel-two.connector=smallrye-amqp mp.messaging.outgoing.channel-two.address=topic-two-on-amqp-server mp.messaging.outgoing.channel-two.durable=false mp.messaging.outgoing.channel-two.broadcast=true application.properties
  • 46. Übung 5b: Cache in skipass-gate 1. Installieren, konfigurieren und starten Sie ActiveMQ Artemis • Demo-Projekt active-mq-artemis • mvn lädt Artemis herunter und konfiguriert Broker in target/demoserver • Start: target/demoserver/bin/artemis run 2. Ergänzen Sie die AMQP-Konfiguration in skipass-manager (Kopiervorlage: skipass-manager-amqp.txt) JEE-Microservices mit Quarkus - eine Einführung 46gedoplan.de # Messaging amqp-username=quarkus amqp-password=quarkus mp.messaging.outgoing.skipassInvalidation.connector=smallrye-amqp mp.messaging.outgoing.skipassInvalidation.address=skipassInvalidation mp.messaging.outgoing.skipassInvalidation.durable=false mp.messaging.outgoing.skipassInvalidation.broadcast=true
  • 47. Übung 5b: Cache in skipass-gate 3. Senden Sie die Ids von veränderten Skipässen als Message • In SkiPassResource in skipass-manager: • Emitter<String> injizieren für Channel skipassInvalidation • In Methode für PUT /skipass/{id}/blocked am Ende Id des geänderten Skipasses versenden 4. Ergänzen Sie die AMQP-Konfiguration in skipass-gate (Kopiervorlage: skipass-gate-amqp.txt) JEE-Microservices mit Quarkus - eine Einführung 47gedoplan.de amqp-username=quarkus amqp-password=quarkus mp.messaging.incoming.skipassInvalidation.connector=smallrye-amqp mp.messaging.incoming.skipassInvalidation.address=skipassInvalidation mp.messaging.incoming.skipassInvalidation.durable=false mp.messaging.incoming.skipassInvalidation.broadcast=true
  • 48. Übung 5b: Cache in skipass-gate 5. Ergänzen Sie im GateService von skipass-gate eine Methode, • die eingehende Ids von veränderten Skipässen annimmt • und diese aus dem Cache entfernt 6. Verifizieren Sie dass skipass-gate nun auch nach (Ent-)Sperren von Skipässen richtig arbeitet JEE-Microservices mit Quarkus - eine Einführung 48gedoplan.de @Incoming("skipassInvalidation") public void invalidate(String skiPassId) { this.cache.remove(skiPassId); }
  • 49. Weitere Quarkus-Features Tests mit @QuarkustTest OpenAPI MongoDB, Neo4j, … Kafka, JMS, Camel OpenID Connect Health, Metrics Spring Integration Scheduling Mail Native Mode JEE-Microservices mit Quarkus - eine Einführung 49gedoplan.de
  • 50. More Wir bilden Sie aus! www.gedoplan-it-training.de Trainings in Berlin, Frankfurt, Köln, Bielefeld, inhouse neu: JEE Microservice Foundation neu: Java DevOps: Development und Delivery mit Docker und Kubernetes Wir unterstützen Sie in Ihren Projekten www.gedoplan-it-consulting.de Reviews, Coaching, … javaeeblog.wordpress.com  dirk.weil@gedoplan.de @dirkweil 50gedoplan.deJEE-Microservices mit Quarkus - eine Einführung