2. 2024-10-01
-
Hanan: IoT/HA - Alarmierung für ältere PErsonen
-
Zangenfeind: Koordination für Müllsammeln
-
Projektarten
-
Stakeholder
-
Projektantrag
2.1. Test Driven development
2.1.1. Continous Testing
-
Grundprinzipien
-
Der Source-Code wird nur geändert, wenn ein Test fehlschlägt
-
Zuerst werden die Tests geschrieben, dann die Methoden implementiert.
-
Unit-Tests so einfach wie möglich.
-
Die Umsetzung in den Methoden ist so einfach wie möglich zu gestalten. MNur der Test soll grün werden. Auch wenn man weiß, dass man später noch refactoren muss.
-
-
Continous Testing
-
Nach Speichern des Codes, werden automatisch Tests durchgeführt
-
-
Stack
package at.htl;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.*;
class MyStackTest {
@Test
void givenNewStack_ThenTheStackIsEmpty() {
var myStack = new MyStack();
//assertThat(myStack.isEmpty()).isTrue();
assertTrue(myStack.isEmpty()); (1)
}
@Test
void givenNewStack_whenPushingOneElement_thenStackIsNotEmpty() {
var myStack = new MyStack(); // <.> // String-Stack
myStack.push("hallo");
assertFalse(myStack.isEmpty());
}
@Test
void givenNewStack_whenPushingOneElementAndPoppingOneElement_thenStackIsEmpty() {
var myStack = new MyStack(); (2)
}
}
3. 2024-10-08
4. 2024-10-21
5. 2024-10-22
5.1. Docker
-
Virtualisierung bezeichnet in der Informatik die Nachbildung eines Hard- oder Software-Objekts durch ein ähnliches Objekt vom selben Typ mit Hilfe einer Abstraktionsschicht. Dadurch lassen sich virtuelle (d. h. nicht-physische) Geräte oder Dienste wie emulierte Hardware, Betriebssysteme, Datenspeicher oder Netzwerkressourcen erzeugen. Dies erlaubt es etwa, Computer-Ressourcen (insbesondere im Server-Bereich) transparent zusammenzufassen oder aufzuteilen, oder ein Betriebssystem innerhalb eines anderen auszuführen. Dadurch können u. a. mehrere Betriebssysteme auf einem physischen Server oder „Host“ ausgeführt werden.[wikipedia]

8. Git branching strategy
8.1. Was ist ein git branch?
-
Ein Git-Branch ist eine unabhängige Version eines Repositories, die es ermöglicht, an neuen Features oder Fixes zu arbeiten, ohne den Hauptcode (meistens im
master
- odermain
-Branch) zu stören. Nach Abschluss der Arbeiten kann der Branch zurück in den Hauptbranch gemergt werden, um die Änderungen zu integrieren.
-
Der main-Branch ist immer lauffähig
-
Die Entwicklung der Features findet auf feature Branches statt.

BEACHTE
|
-
Beurteilungkriterien:
-
Anzahl der Commits (Insights)
-
Anzahl der feature-Branches
-
Qualität der Commit-Messages
-
Issue-Nummer
-
Existenz eines Tasks (Issue) zu jedem Commit
-
-
10. 2024-11-19 [Hanan]

10.4. Was ist Docker?
-
Eine Technologie , um eine Application und alle ihre Abhängigkeiten in einen einzelnen , leicht zu transportierenden Container zu packen.
-
Wird eine Applikation in einem Docker-Container gepackt, so ist sichergestellt , dass die Laufzeitumgebung unverändert bleibt, auch wenn der Container auf einem anderen Hostsystem läuft.
10.5. Wie funktioniert Docker?

-
Dockerfile: Dies ist eine Textdatei, die Anweisungen enthält , um ein Docker-Image zu erstellen.(Kochrezept zum Erstellen des Images).
-
docker build:
-
Mit diesem Befehl wird aus dem Dockerfile ein Docker-Image erstellt. Dieses Image hat alle notwendigen Datien und Abhängigkeiten , um eine Anwendung auszuführen.
-
docker build
-
Docker Registry: Bibliothek oder Lager , wo Docker-Images gespeichert und verwaltet werden.
-
docker pull: Man holt sich mit diesem Befehl ein Docker-Image aus der Docker-Registry.(herunterladen oder pullen)
docker pull
-
docker run: Mit docker run wird aus dem Docker Image ein Docker Container gestartet. Ein Docker Container ist die laufende Instanz eines Docker Images.
docker run
10.6. Leichtgewichtige Virtualisierung VS Schwergewichtige Virtualisierung
Leichtgewichtige Virtualisierung |
Schwergewichtige Virtualisierung |
Die beiden OS sind nicht unabhängig und müssen den selben Kernel benutzen. z.b Linux/Linux, verlangt aber weniger Ressourcenutzung. Beispiele: Docker,Podman |
Die beiden OS sind völlig unabhängig und können verschieden sein. Beispiele: Virtual Box, vmWare |

10.7. Docker Registries
-
ist ein Remote-Repository zum Abspeichern von Docker Images
-
kann privat und öffentlich(public) sein
10.8. Docker Image
-
Ein Docker Image enthält alle notwendigen Dateien, Einstellungen und Abhängigkeiten , um eine Anwendung auszuführen.
10.9. Docker Container
-
Ein Docker Container ist die laufende Instanz von einem Docker Image und wird mit docker run erstellt
10.10. Docker-Wiederholung
10.10.3. Volume
-
Bits and Bytes, die man schreiben und lessen kann (→ File)
-
2 Arten von Volumes:
-
bind mount
-
volume
-
10.10.4. BuildContext
-
Der Docker Build Context ist der Satz von Dateien, die Docker benötigt, um ein Docker-Image zu erstellen. Wenn Sie den Befehl docker build ausführen, übergeben Sie Docker einen Pfad zu einem Verzeichnis als Build Context. Docker sendet dann den Inhalt dieses Verzeichnisses (rekursiv) an den Docker-Daemon.
-
Der Build Context enthält typischerweise die Dockerfile und alle Dateien, die in der Dockerfile referenziert werden, wie z.B. Quellcode, Konfigurationsdateien und Abhängigkeiten.
Beispiel:docker build -t my-image:latest .
-
In diesem Beispiel ist das aktuelle Verzeichnis (.) der Build Context. Docker wird alle Dateien und Unterverzeichnisse im aktuellen Verzeichnis an den Docker-Daemon senden, um das Image zu erstellen.
12. 2024-12-17 [Hanan]
12.1. Beziehungen - Assoziation
-
Die Assoziation zwischen einem Akteur und einem Anwendungsfall wird durch eine einfache Linie dargestellt. Diese Linie symbolisiert die Interaktion, jedoch keine Datenflussrichtung.
-
Beispiel:
-
Ein Benutzer interagiert mit einem System, z. B. ein Kunde führt eine Bestellung durch.
-
12.2. Use case
-
Ein Beispiel für einen Use Case:
-
Ein Kunde kauft ein Auto.
-
-
Grund:
-
Der Kunde benötigt ein Transportmittel, um Güter von A nach B zu befördern.
-
12.3. includes vs extends
-
extends
-
Wird verwendet, wenn ein Anwendungsfall optional erweitert werden kann. Beispiel: 'Registrierung abschließen' kann optional 'Gutschein anwenden' erweitern.
-
-
include
-
Wird verwendet, wenn ein Anwendungsfall zwingend einen anderen Anwendungsfall beinhaltet, um korrekt zu funktionieren. Beispiel: 'Zahlung verarbeiten' beinhaltet zwingend 'Rechnungsdetails prüfen'.
-
12.4. Zustandsmaschine
-
Eine Zustandsmaschine zeigt die verschiedenen Zustände eines Objekts und die möglichen Übergänge zwischen diesen Zuständen.
-
Ein Fußballspiel kann mehrere Zustände haben
-
In Vorbereitung - Startzustand, z.B. Mannschaften werden aufgestellt.
-
Ablauf - Das Spiel wird gespielt.
-
Abbruch - Das Spiel wird vorzeitig beendet.
-
Pause - Halbzeitpause
-
Abschluss - Endzustand, z.B.Spielende
-
14. 2025-02-04
14.1. Entwurfsentscheidungen
14.1.1. Schritt 1: Erarbeiten des Zielsystems
-
Was ist mir wichtig?
-
Bsp: Auswahl einer Datenbank für Ermittlung eines Produkts zu einem gewissen EAN-Code
-
kostenfrei
-
Zugriff über API möglich
-
keine Zugriffsbeschränkungen (möglichst viele Anfragen pro Tag)
-
möglichst viele Produkte sollen enthalten sein
-
ev. Eintragen eigener (neuer) Produkte
-
16. 2025-02-25 Docker
16.1. nginx mit Docker
-
Aufgabenstellung: ein nginx-Image mittels Docker starten.
-
Wenn http://localhost:8080 dann "Hallo <Vorname> <Nachname>"
-
docker image ls docker pull nginx # mit Bind Mount docker run --name nginx \ --rm \ -v $PWD/www-data:/usr/share/nginx/html \ -p 8080:80 \ -d nginx:1.27-alpine docker container stop nginx && docker container rm nginx # Mit Docker Volume docker run --name nginx \ --rm \ -v www-data:/usr/share/nginx/html \ -p 8080:80 \ -d nginx:1.27-alpine docker exec -it nginx /bin/ash docker cp www-data/index.html nginx:/usr/share/nginx/html
Nur der root user darf Ports unter 1000 verwenden, daher verwenden wir 8080 |
17. 2025-03-04 Dockerfile
public class Main {
public static void main(String[] args) {
System.out.println("Hello Chris!");
}
}
FROM eclipse-temurin:21
COPY Main.java /usr/local/src/
WORKDIR /usr/local/src/
RUN javac Main.java
CMD ["java","Main"]
docker build --tag hello-chris . # Bauen des Images anhand des Dockerfiles docker run hello-chris # Starten des Container mir dem gebauten Image
17.1. Vereinbarung
-
Programmieren einer User Story
-
Erstellen eines Docker Container
-
Erstellen eines Verezichnisses
compose
im project-root -
Erstellen eines Dockerfiles für ein beliebiges maven-PRojekt mit Textausgabe
-
Verwenden des maven-Images
-
mvn package
-
Java-Programm - gibt das Datum und die Uhrzeit auf der Console aus und gibt an ob das aktuelle Jahr ein Schaltjahr ist und wann das nächste Schaltjahr ist.
-
-
19. 2025-03-11
19.2. Docker
19.2.1. Lab
-
Das Dockerimage des Nachbarn ausführen
-
Multistage-Build mit 2 Stages
-
Sämtliche Files werden in das Docker-Image kopiert, daher ist es wichtig, dass nur die notwendigen Files im Build-Context sind. |
FROM eclipse-temurin:21 AS builder
COPY Main.java /usr/local/src/
WORKDIR /usr/local/src/
RUN javac Main.java
CMD ["java","Main"]
# Build the image
FROM eclipse-temurin:21
RUN mkdir -p /opt/app
COPY --from=builder /usr/local/src/*.class /opt/app/
WORKDIR /opt/app/
CMD ["java","Main"]
docker build --tag hello-chris .
docker login ghcr.io docker build --tag ghcr.io/htl-leonding/hello-world-chris:latest . docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE ghcr.io/htl-leonding/hello-world-chris latest bf8419a868f2 14 seconds ago 478MB ...

docker push ghcr.io/htl-leonding/hello-world-chris:latest

docker run ghcr.io/htl-leonding/hello-world-chris:latest
Hello Chris!
20. 2025-03-18
20.1. Microservices
-
Package by Feature als Vorstufe zu microservices.
-
Microservices: Eine Applikation wird fachl,ich in mehrere kleinere (unabhängige) Services aufgeteilt. Eine Koordinationsschicht ermöglicht die Kommunikation zwischen den Services.
20.2. Verteilungsdiagramm (Deployment Diagram)
-
Stellt dar, auf welcher Hardware welche Softwarekomponenten laufen.
21. 2025-03-24
21.1. assertj-db

-
Dependency in pom.xml eintragen
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-db</artifactId>
<version>3.0.0</version>
<scope>test</scope>
</dependency>
-
jdbc-Verbindung von unserer Testklasse zur Datenbank erstellen
private final static DataSource dataSource = Database.getDataSource();
// ...
var conn = AssertDbConnectionFactory.of(dataSource).create();
-
den Inhalt der Datenbanktabelle auf der Console ausgeben
import org.assertj.db.type.Table;
import static org.assertj.db.output.Outputs.output;
//...
Table contactTable = conn.table("contact").build();
output(contactTable).toConsole();
-
einen Vergleich durchführen
assertThat(contactTable).row(0)
.value("c_name").isEqualTo("John Doe")
.value("c_email").isEqualTo("john.doe@fmail.com")
.value("c_dob").isEqualTo(LocalDate.of(1990, 6, 23))
.value("c_id").isEqualTo(1);
@Test
void t010_createGroups_Ok() {
// Arrange
groupRepository.deleteAll();
// Act
Map<Character, Group> groups = t.createGroups("ABCDEF");
// Assert
// check table
Table table = new Table(ds, "T_GROUP");
output(table).toConsole();
assertThat(table).hasNumberOfRows(6)
.column("G_GROUP")
.value().isEqualTo('A')
.value().isEqualTo('B')
.value().isEqualTo('C')
.value().isEqualTo('D')
.value().isEqualTo('E')
.value().isEqualTo('F');
// check Map
org.assertj.core.api.Assertions.assertThat(groups).hasSize(6);
org.assertj.core.api.Assertions.assertThat(groups).containsOnlyKeys('A', 'B', 'C', 'D', 'E', 'F');
org.assertj.core.api.Assertions.assertThat(groups.values())
.usingElementComparator((t1, t2) -> t1.groupLetter.compareTo(t2.groupLetter))
.contains(
new Group('A'),
new Group('B'),
new Group('C'),
new Group('D'),
new Group('E'),
new Group('F')
);
}
23. 2025-04-08
23.1. wie kann man in Projekten REST-api’s verwenden?
-
api’s können abgefragt werden mittels:
-
Browser (eher nur GET)
-
standalone-Applikationen wie Postman und Insomnia
-
(Java-)Programme mittels http-client
-
curl und httpie (cli)
-
curl "http://opengtindb.org?ean=4337256824132&cmd=query&queryid=400000000"
-
http "http://opengtindb.org?ean=4337256824132&cmd=query&queryid=400000000"
-
-
REST-assured (Test-Framework)
-
REST-client (IDEA-Plugin oder auch für VSCode)
-
Browser-Plugin für REST
-
23.2. Marshalling / Unmarshalling
Java-Objekt -→ JSON-String : Marshalling JSON-String -→ Java-Objekt : Unmarshalling
-
Library: Jackson
-
https://www.baeldung.com/jackson-deserialize-json-unknown-properties
24. Docker Context
-
In der pom.xml muss das manifest konfiguriert werden, damit die Main-Klasse gefunden wird.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>at.htl</groupId>
<artifactId>webserver</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.4.2</version>
<configuration>
<archive>
<manifest>
<mainClass>at.htl.ServerSingleThreaded</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>
-
beim Erstellen eines Docker Images ist darauf zu achten, dass der Build Context korrekt ist.
-
Sämtliche Files werden vom Build Context in die Docker Ausführungsumgebung kopiert.
-
Mit COPY werden dann die Files von dem Build Context in das Docker Image kopiert.
docker build --tag webserver --file src/main/docker/Dockerfile .
FROM maven:3.9.9-eclipse-temurin-21 AS builder ARG MAIN_CLASS=ServerSingleThreaded COPY src/main/java/at/htl/$MAIN_CLASS.java /usr/local/src/ WORKDIR /usr/local/src/ RUN javac $MAIN_CLASS.java CMD ["java", "$MAIN_CLASS"] # Build the image FROM eclipse-temurin:21 RUN mkdir -p /opt/app COPY --from=builder /usr/local/src/*.class /opt/app/at/htl/ WORKDIR /opt/app CMD ["java","at.htl.ServerSingleThreaded"]
docker run --rm -it webserver /bin/bash
docker run --rm -p 8080:8080 --name webserver webserver