= Lecture Notes  4ahif - NVS 21/22
Thomas W. Stütz
1.0.0, {docdate}: Quarkus, Android Jetpack Compose
ifndef::imagesdir[:imagesdir: images]
//:toc-placement!:  // prevents the generation of the doc at this position, so it can be printed afterwards
:sourcedir: ../src/main/java
:icons: font
:sectnums:    // Nummerierung der Überschriften / section numbering
:toc: left


//Need this blank line after ifdef, don't know why...
ifdef::backend-html5[]

// https://fontawesome.com/v4.7.0/icons/
icon:file-text-o[link=https://raw.githubusercontent.com/2122-4ahif-nvs/2122-4ahif-nvs-lecture-notes/main/asciidocs/{docname}.adoc] ‏ ‏ ‎
icon:github-square[link=https://github.com/2122-4ahif-nvs/2122-4ahif-nvs-lecture-notes] ‏ ‏ ‎
icon:home[link=https://htl-leonding.github.io/]
endif::backend-html5[]

// print the toc here (not at the default position)
//toc::[]

== 2021-09-28

* Quarkus Grundlagen (Foliensätze)

== 2021-09-30 - entfallen


== 2021-10-05 - entfallen wegen AHS-Vortrag

== 2021-10-07, Do.

image::request-response.png[]

* REST-Clients

* Testen in Quarkus (@QuarkusTest)

== 2021-10-12, Di.

image:v-modell.png[]

[plantuml,vehicle-cld-1,png]
----
@startuml
left to right direction
class Customer {
}

class Vehicle {
}

Customer "*" -- "*" Vehicle : > entleiht
(Customer, Vehicle) .. Rental

@enduml
----

[plantuml,vehicle-cld-2,png]
----
@startuml
left to right direction
class Customer {
}

class Vehicle {
}

class Rental {
  Vehicle: vehicle
  Customer: customer
  LocalDate: dateFrom
  LocalDate: dateTo
}

Rental "*" --> "1" Vehicle : < wird entliehen
Customer "1" <-- "*" Rental : > leiht

@enduml
----

=== Einteilung Mikroprojekte

* Abazović Edina
* Ablinger Raphael
* Aichinger Niklas
* Baumgartner Lukas
* Bogdan Sebastijan
* Handel Christoph
* Hartl Anna
* Hautzmayer Sheila
* Hirsch Nico
* Keintzel Florian
* Kerschbaum Philipp
* König Julia
* Melcher Tamara
* Neudorfer Niklas
* Pavelescu Darius-Cristian
* Pelzeder Joachim
* Plakolb Marcel
* Rathberger Jakob
* Remplbauer Markus
* Sugic Oliver
* Tran Michael
* Tunc Johannes


== 2021-10-14

=== REST Context
=== REST WebApplication Exception
=== JSON-B, JSON-P

*  https://javaee.github.io/jsonb-spec/users-guide.html


=== REST Parameter

* QueryParam
* PathParam
* FormParam

== 2021-10-18 (Einschub)

image::jsonb-formparam.png[]

image::hash.png[]

image::mapping.png[]

image::cors.png[]

=== Rest-Endpoints erstellt

* FormParam
* POST mit Location-Rückgabe

=== Mit JPA begonnen

== 2021-11-04

image::ide-database-overview.png[]

=== 3 Strategien zur Erstellung der Schlüsselwerte
** Table
** IDENTITY
** Sequence

=== Transactions

=== Verwendung von Test zum Ausprobieren von DB-Zugriffen

Begriffe:

* ORM
* JDBC
* JAX-RS
** resteasy
* JPA
** Hibernate


== 2021-11-08

=== Mögliche Fragen:

* Welche Möglichkeiten gibt es, ein Quarkus Projekt zu erstellen?
** Assistent auf quarkus.io
** Assistent in IDE (zB IntelliJ)
** Aufruf mit mvn

* Strategien zum Erzeugen von Primärschlüsselwerten?
** TABLE
** SEQUENCE
** IDENTITY

* Wie kann man eine Testklasse für eine beliebige Klasse erstellen?
** Cursor auf Klassenbezeichnung
** Rechte Maustaste
** Create Test

* Was bewirkt die Annotation `@QuarkusTest`?

=== Repositories für JPA

https://docs.microsoft.com/en-us/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/infrastructure-persistence-layer-design[The Repository pattern, window="_blank"]

image::microsoft-repository-pattern.png[]

=== Startup

* Die Methode init() wird sofort nach Start der Applikation ausgeführt (vglbar mit  main()-Methode)
* Die init()-Methode kann beliebig benannt werden

[source,java]
----
package at.htl.carrental.control;

import at.htl.carrental.entity.Person;
import io.quarkus.runtime.StartupEvent;

import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.event.Observes;
import javax.inject.Inject;

@ApplicationScoped
public class InitBean {

    @Inject
    PersonRepository personRepository;

    void init(@Observes StartupEvent event) {
        Person p = new Person("Susi");
        personRepository.save(p);
    }

}
----



=== Automatisches Befüllen der Tabelle mit IMPORT.sql

* in Ordner `src/main/resources/` eine Datei `import.sql` erstellen: `src/main/resources/import.sql`
* INSERTs einfügen
* beim nächsten Start der App werden die INSERTs ausgeführt
* https://quarkus.io/guides/hibernate-orm

=== NamedQueries

* 2 Varianten
** JP-QL
** Criteria API (verwenden wir NICHT)

.JP-QL (Java Persistence Query Language)
[source,java]
----
@Entity
@NamedQueries({
        @NamedQuery(
                name = "Person.findAll",
                query = "select p from Person p"
        )
})
public class Person {
    //...
}
----

* JP-QL ist vergleichbar mit SQL
* jedoch werden i.N. keine SPalten angegeben, da nur ganze Objekte zurückgegeben werden.
* die Rückgabe von Spalten ist sehr wohl möglich
* Joins und Aggregationen sind ebenfalls möglich
* https://www.objectdb.com/java/jpa/query/jpql/structure


== 2021-11-09

=== Ausführen einer NamedQuery

[source, java,highlight=3-4]
----
@Test
void getAllPersons() {
    TypedQuery<Person> query = em
            .createNamedQuery("Person.findAll",Person.class);
    List<Person> persons = query.getResultList();
    assertThat(persons.size()).isEqualTo(8);
    logger.info(persons);
}
----

=== Ausführen einer Query

[source,java,highlight=3-4]
----
@Test
void getAllPersonsWithQuery() {
    TypedQuery<Person> query = em
            .createQuery("select p from Person p",Person.class);
    List<Person> persons = query.getResultList();
    assertThat(persons.size()).isEqualTo(8);
    logger.info(persons);
}
----

=== Ausführen einer NativeQuery

* Es gibt auch hier
** NativeQuery
** NativeNamedQuery

[source,java]
----
@Test
void getAllPersonsWithNativeQuery() {
    Query query = em
            .createNativeQuery("select p.id, p.name from person p");
    List<Object[]> persons = query.getResultList();
    for (Object[] elem : persons) {
        System.out.println(elem[0] + " " + elem[1]);
    }
    assertThat(persons.size()).isEqualTo(9);
}
----

* https://thorben-janssen.com/jpa-native-queries/

=== Mikroprojekte-Themen






|===
|Name |Thema

|Abazović Edina
|Stadtrundfahrten

|Ablinger Raphael
|Linienbusunternehmen inkl. Fahrplan

|Aichinger Niklas
|Supermarkkt

|Baumgartner Lukas
|Teehändler

|Bogdan Sebastijan
|Friedhofsverwaltung

|Handel Christoph
|Schuhplattln

|Hartl Anna
|Gärtnerei

|Hautzmayer Sheila
|Tanzverein

|Hirsch Nico
|Rezeptseite

|Keintzel Florian
|Hotel

|Kerschbaum Philipp
|Fussballverein

|König Julia
|Tennisverein

|Melcher Tamara
|Kletterverein mit Kletterrouten

|Neudorfer Niklas
|Gebäudeverwaltung (wo sind welche Geräte installiert zB Chromecasts)

|Pavelescu Darius-Cristian
|Musikdatenbank

|Pelzeder Joachim
|Personaleinteilung in Produktonsbetrieb mit Schichten (es wird durchgehend produziert)

|Plakolb Marcel
|Luftfahrtlinie (Wo fliegen die Flugzeuge, Linien)

|Rathberger Jakob
|Doodle

|Remplbauer Markus
|Modellagentur

|Sugic Oliver
|Schwimmverein

|Tran Michael
|Restaurant (Tischreservierung)

|Tunc Johannes
|Reisebüro
|===


=== Übung

* Erstellen eines Datenmodell in plantuml (3-5 Entitäten)
* Publishen zu gh-pages
* Zusätzlich eine kurze Erklärung für die Anwendung
* Termin: 11.11.2021
* Ordner im Root-Folder: asciidocs, backend, frontend
* Erstellen eines Quarkus-Projekts mit einer Tabelle, persisitert in eine postgre-db und einem Endpoint


=== Erstellen einer aggregierten Abfrage

==== Schritt 1: Sql-Query

[source,sql]
----
  select substr(name,1,1), count(*)
    from person
group by substr(name,1,1)
order by 1;
----

==== Schritt 2: Übertragen nach Java

[source,java]
----
@Test
void countLetters() {

    Query query = em.createQuery("select substring(p.name,1,1), count(p) from Person p group by substring(p.name,1,1)");
    List<Object[]> list = query.getResultList();

    for (Object[] elem : list) {
        logger.info(elem[0] + " - " + elem[1]);
    }

    assertThat(list.size()).isEqualTo(8);
}
----

=== Beziehungen zwischen Entitäten - Vererbung


* http://edufs.edu.htl-leonding.ac.at/~t.stuetz/download/nvs/presentations.2021/06_JPA.pdf[Skriptum JPA ab Seite 44, window="_blank"]


image::assoziative-Beziehung.png[]

== 2021-11-16

=== NamedQueries mit Parameter

=== Aggregated Queries

.NamedQuery in Entity
[source,java]
----
package at.htl.carrental.entity;

import javax.persistence.*;

@Entity
@NamedQueries({
        @NamedQuery(
                name = "Person.countByInital",
                query = "select substring(p.name,1, 1), count(p) from Person p group by substring(p.name,1, 1)"
        )
})
public class Person {

    // ...
}
----

.Use NamedQuery in Repository
[source,java]
----
@ApplicationScoped
public class PersonRepository {

    @Inject
    EntityManager em;

    // ...

    public Map<Character, Integer> countByInitial() {
        Map<Character, Integer> result = new HashMap<>();
        Query query = em
                .createNamedQuery("Person.countByInital");
        List<Object[]> initials = query.getResultList();
        for (Object[] initial : initials) {
            result.put(
                    initial[0].toString().charAt(0),
                    Integer.parseInt(initial[1].toString())
            );
        }
        return result;
    }
}
----

.Test repository method
[source,java]
----
@QuarkusTest
class PersonTest {

    // ...

    @Test
    void countLetters() {

        Query query = em.createQuery("select substring(p.name,1,1), count(p) from Person p group by substring(p.name,1,1)");
        List<Object[]> list = query.getResultList();

        for (Object[] elem : list) {
            logger.info(elem[0] + " - " + elem[1]);
        }

        assertThat(list.size()).isEqualTo(8);
    }
}
----

== 2021-11-29 Vorbereitung für Test-W

* Cascadierende Assoziationen

== 2021-12-07 Panache

https://quarkus.io/guides/hibernate-orm-panache[Simplified Hibernate ORM with Panache]

== 2021-12-13 Panache - Persistence Context

image::persistence-context.png[]


* Befindet sich ein Java-Objekt im Persistence Context, so hat es den Status "Managed"
** Ein Objekt kann den Zustand "managed" durch den Aufruf von persist() erhalten
** aber auch durch ein Holen des Objekts (Methode find()) aus der DB
** wichtig ist dabei, dass eine Transaktion aktiv ist
*** Entweder Verwendung einer UserTransaction (mit tx.begin() und tx.commit())
*** oder Verwendung von @Transactional
* Im Persistence Context kann man automatisch DB-Aktionen an abhängige Objekte weitergeben (zB cascading persist, ...)

== 2021-12-14

=== Datenzugriffs-Pattern

==== Repository-Pattern
==== Active-Record-Pattern


=== Queries in Panache

== 2021-12-21

=== Validation

https://quarkus.io/guides/validation

=== Qute

https://quarkus.io/guides/qute

=== Übung: Validierung und Qute im Microproject

* Einbinden von Validation und Qute ins Mikroprojekt
* zb Bei Validation:
** nicht alle (Entity-)Klassen müssen validiert werden.
** es sind allerdings die Konzepte aus dem Tutorial zu verwenden, zB
*** vorgefertigte Validatoren
*** Erstellung eines eigenen Validators
* Es ist ein asciidoc-File zu erstellen (im Ordner asciidocs), in dem die Arbeiten dokumentiert werden.
** vergleichbar mit den Lecture (pro Datum ein Kapitel) ist auch in diesen adoc-File für jede Technologie (Übung) eine kurze Doku zu erstellen (Cheat Sheet)
*** Warum benötige ich das? (Einsatzzweck)
*** Ev. die Alternativen anführen
*** Möglichkeiten der Anwendung (Code im Microproject kurz erklärt)
** diese Asciidocs sollen automatisch als gh-pages dargestellt werden
*** https://github.com/htl-leonding-college/asciidoctor-docker-template/releases/tag/v1.1.4
*** https://github.com/htl-leonding-college/asciidoctor-convert-template


image::tafelbild01-vmodell.jpeg[]
image::tafelbild03-testen.jpeg[]
image::tafelbild02-vmodell-scrum.jpeg[]
image::tafelbild04-ucd.jpeg[]



== 2021-12-23

=== Übung: gRPC - Termin: 5. Jänner 2022

* Recherche: Was ist gRPC? (Einsatzzweck, welches Problem wird gelöst, Konzept)
* Mutiny: https://quarkus.io/guides/getting-started-reactive
* Verwendung in Quarkus -> Tutorials auf quarkus.io
+
image::grpc-tutorials.png[]

* Einbauen ins Mikroprojekt und dokumentieren

== Qute

image::qute.png[]

* Beispiel
** In der Klasse StudentResource sind die Qute-Template typisiert deklariert.
** Wird im Browser die jeweilige Route des Qute-Templates aufgerufen, liefert der Server die das gerenderte Template als html aus
** Der User kann nun zB ein Formular ausfüllen.
** Nach dem Klicken auf den Submit Button, werden die Inhalte der Formularfelder an den im Form-Attribut "action" angegeben REST-Endpoint übermittelt.
** Dieser REST-Endpoint gibt nun die neue Route jener Seite, die als nächstes angezeigt wird, an den Browser zurück


== 2022-01-11

=== Quarkus Security

==== Hausübung
* Using Security with .properties File: https://quarkus.io/guides/security-properties
* Using Security wit JDBC: 
https://quarkus.io/guides/security-jdbc

==== Besprochen

Wir haben über Security mithilfe von Keycloak gesprochen: https://www.keycloak.org/downloads

* Kleine mini quarkus Anwendung die geschützt werden (z.B.: nur rest teil)

* User haben Rollen --> Rollen geben einen User gewisse Rechte, die er machen darf.

== 2022-01-17

* assert: stelle sicher, Zusicherung

image:projektarchitektur.jpeg[]

.Bottom-Up (Basis-Ansatz)
Einzelne Programmbestandteile werden definiert, eventuell sogar direkt geschrieben.
Aus diesen Teilen werden dann größere Elemente des Programms zusammengesetzt, bis das vollständige System erstellt ist.

.Top-Down (Vogelperspektive, Überbau-Ansatz)
Grundlegender Architekturüberblick (Zuerst Landkarte => z.B.: Wo muss Technologie hin?)

.REST-Service
Daten zwischen Komponenten austauschen mit z.B.: Delete, Patch, Put, Get, Post

.Metadata
Daten über Daten. Z.B.: Datentyp, Autowert, ...

.Daten
Daten sind rohe, unorganisierte, zusammenhangslose Fakten.

.Informationen
* Informationen entstehen aus Daten
* Daten werden verwendet zur Problemlösung, dann werden diese Daten zu Informationen
* Wenn man Daten verarbeitet, organisiert, strukturiert oder in bestimmten Kontext stellt

.Data Mining
Mit mathematischen Methoden Zusammenhänge zwischen Daten ermitteln.
Z.B.: Wenn man Bier kauft, kaufen viel auch Chips =>
daher sind meistens Bier und Chips in unmittelbarer Nähe von einander

.Testen
Nicht zu viele Tests, aber auch nicht zu wenige Tests.

* assertj
* myBatis
* jdbc



== 2022-02-03

=== Rest-Client

image::rest-client.png[]


=== Übung Mikroprojekt

* Einen Zugriff auf einen REST-Service implementieren

** https://httpbin.org/
** https://http.cat/
** https://www.boredapi.com/
** https://quotes.rest/


== 2022-02-08

=== Unit--Testing

==== Test Struktur

===== Arrange-Act-Assert

* AAA-Pattern

===== Given-When-Then

== 2022-02-15

=== Kotlin - Grundlagen

* http://edufs.edu.htl-leonding.ac.at/~t.stuetz/download/android/01-kotlin-grundlagen/01_Introduction.pdf[01_Introduction.pdf^]

* http://edufs.edu.htl-leonding.ac.at/~t.stuetz/download/android/01-kotlin-grundlagen/02_Functional_Programming.pdf[02_Functional_Programming.pdf^]

////
* http://edufs.edu.htl-leonding.ac.at/~t.stuetz/download/android/01-kotlin-grundlagen/03_Object_Orientation.pdf[03_Object_Orientation.pdf^]

* http://edufs.edu.htl-leonding.ac.at/~t.stuetz/download/android/01-kotlin-grundlagen/04_Android.pdf[Android^]
////


== 2022-02-17 (Do.) SYP-Ersatzstunde

=== Einrichten der oravm


== 2022-02-08 - Foliensätze Kotlin



== 2022-03-10 Erstes Android Project

=== CoolDroid (siehe labs folder)

* ist noch ohne jetpack compose mit xml-files


== 2022-03-29









































