Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • jordine/se3sose2022vorlesung
  • jr125/se3sose2022vorlesung
  • lb189/se3sose2022vorlesung
  • mb345/se3sose2022vorlesung
4 results
Show changes
Showing
with 1289 additions and 0 deletions
package de.hdm.jordine.vorlesung.concurrency.solutions;
import java.util.concurrent.atomic.AtomicInteger;
public class LostUpdateAtomic {
private AtomicInteger counter = new AtomicInteger(0);
public void increment(){
counter.incrementAndGet();
}
public static void main(String[] args) throws InterruptedException {
LostUpdateAtomic lu = new LostUpdateAtomic();
Thread t0 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10000; i++) {
lu.increment();
}
}
});
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10000; i++) {
lu.increment();
}
}
});
t0.start();
t1.start();
t0.join();
t1.join();
System.out.println("Counter value: " + lu.counter.get());
}
}
package de.hdm.jordine.vorlesung.concurrency.solutions;
public class LostUpdateSynchronized {
private int counter = 0;
public synchronized void increment(){
counter++;
}
public static void main(String[] args) throws InterruptedException {
LostUpdateSynchronized lu = new LostUpdateSynchronized();
Thread t0 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10000; i++) {
lu.increment();
}
}
});
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10000; i++) {
lu.increment();
}
}
});
long start = System.currentTimeMillis();
t0.start();
t1.start();
t0.join(); // required for synchronisation with main thread
t1.join(); // required for synchronisation with main thread
long end = System.currentTimeMillis();
System.out.println("Counter value: " + lu.counter);
System.out.println(end - start);
}
}
# Übungen Software-Entwicklung 3: Parallele Programmierung
## Ausgangslage
In der Vorlesungen haben wir besprochen, wie Sie Teile Ihrer Anwendung parallelisieren können. Bei der Umsetzung müssen jedoch einige Dinge beachtet werden, insbesondere wenn auf _shared state_, sprich Variablen und Objekte, die von mehreren Threads gleichzeitig verarbeitet werden, zugegriffen wird.
## Aufgabe
* Überlegen Sie sich, welche Teile Ihrer Anwendung parallelisierbar sind. Kann dadurch Wartezeit verhindert oder währenddessen andere Aufgaben abgearbeitet werden? Gibt es Hintergrundaufgaben?
* Identifizieren Sie _shared state_ und überlegen sich wie Sie diesen schützen können. Dokumentieren Sie dies.
* Nutzen Sie geeignete Mittel, damit es weder zu Konsistenzproblemen (z.B. _lost update_) noch zu Programmflussproblemen (z.B. _dead lock_) kommt.
* Setzen Sie mindestens einen Anwendungsfall für parallele Programmierung inkl. Schutmaßnahmen in Ihrem Projekt vollständig um.
## Tipps
* Nutzen Sie `log`-Ausgaben um das Verhalten Ihrer Threads zur Laufzeit nachvollziehen zu können.
* `ParallelStream`s können in Java eine Möglichkeit sein, große Datenmengen effektiv zu verarbeiten.
## Ziele
* Ihr Projekt besitzt nebenläufige Programmanteile, die gegen die besprochenen Concurrency-Probleme geschützt sind.
\ No newline at end of file
# Übungen Software-Entwicklung 3: Container, CI/CD
## Ausgangslage
In der Vorlesung wurde die Container-Technologie (Docker) als auch die Prinzipien von Continuous Integration/Continuous Deployment vorgestellt. Mit Hilfe con GitLab sollen Sie nun diese Prinzipien in Ihrem Projekt anwenden. Voraussetzung dafür ist, dass sie Ihr Projekt mit Hilfe eines Buildmangementtools (z.B. `maven`) per Kommandozeile bauen, testen und paketieren können.
## Aufgabe
* Erstellen Sie eine passende `.gitlab-ci.yml`, sodass sie die Build-Lifecycle Phasen `compile`, `test` und `package` in GitLab ausführen können.
* Überlegen Sie sich welche Phasen des Build-Lifecycle immer ausgeführt werden müssen und welche nur bei bestimmten Ereignissen (z.B. neuer `Tag` erstellt).
## Tipps
* Nutzen Sie als Start die `.gitlab-ci.yml` aus dem [Vorlesungsprojekt](https://gitlab.mi.hdm-stuttgart.de/jordine/se3sose2022projekt)
* Weitere Informationen gibt es in der [GitLab Ci Dokumentation](https://docs.gitlab.com/ee/ci/) bzw. in der [Keyword Reference](https://docs.gitlab.com/ee/ci/yaml/)
* Ggf. kann es sinnvoll sein, Ihre Anwendung oder Teile davon (z.B. Datenbank, Webserver) in einem Container zu kapseln, sodass eine gleichbleibende Ausführungsumgebung sichergestellt ist.
## Ziele
* Ihr Projekt wird über einen CI/CD-Mechanismus regelmäßig gebaut und getestet.
\ No newline at end of file
# MVP-Vorstellung
Folgende Dinge sollen zur MVP-Präsentation vorgestellt werden:
* Kurze Vorstellung des Projektziels
* Was sind Ihre Kernanforderungen?
* Wie haben Sie Ihre Anforderungen priorisiert?
* Vorstellung der Codebase
* Wie haben Sie den Code organisiert? Was sind Ihre Module?
* Was sind die dahinterliegenden architektonischen Prinzipien?
* Wie ist Ihr Entwicklungsprozess mit `git`?
* Welche Clean Code Prinzipien setzen Sie ein?
* Kurze Präsentation des Stands
## Ablauf
* Alle Gruppen müssen präsentieren
* Dauer der Vorstellung: ca. 15 Minuten
* Danach: Kurze Fragerunde
* Übungen entfallen am Tag der Vorstellung
\ No newline at end of file
# Übungen Software-Entwicklung 3: Build Management & Testing
## Ausgangslage
Die in der Vorlesung vorgestellten Konzepte des Build Managements und des Testings sollen nun in Ihrem Projekt angewandt werden. Sofern Sie Java einsetzen, verwenden Sie `Maven` für das Build Management und `JUnit` für das Testing.
## Aufgabe
* Erstellen Sie eine passende `pom.xml`, sodass sie die Build-Lifecycle Phasen `compile`, `test` und `package` nutzen können.
* Überlegen Sie sich welche Testarten für Sie relevant sein könnten.
* Erstellen Sie Unit-Tests nach dem `F.I.R.S.T`-Prinzip. Achten Sie auch darauf, dass Sie den "Happy Path", Randbedingungen sowie Fehlerfälle testen.
* Erstellen Sie Integrationstests für Ihre Komponenten.
## Tipps
* `IntelliJ` kann Sie bei der Testerstellung unterstützen. Dafür müssen Sie in einer `.java`-Datei `command` + `n`/`Strg` + `n` ➡️ `Test...` wählen.
* Nutzen Sie bei Bedarf (z.B. Simulation eines komplexen Objekts) das Mock-Framework [Mockito](https://site.mockito.org)
* Versuchen Sie eine Funktionalität/Anforderung nach den Test-driven Design Prinzipen zu entwickeln.
## Ziele
* Das Projekt besitzt eine valide Maven-Konfiguration, mit der per `mvn`-Aufruf das Projekt automatisch getestet und gebaut wird.
* Ihre `Model` und `Controller`-Klassen werden wie oben beschrieben getestet.
* Zusätzlich werden die Schnittstellen Ihre Komponenten nach diesen Regeln getestet.
\ No newline at end of file
# Übungen Software-Entwicklung 3: Schnittstellen
## Ausgangslage
Nachdem wir besprochen haben, wie Sie Ihre Programmdaten persistent speichern können, können Sie nun Ihrem Projekt Schnittstellen hinzufügen, sodass Sie Daten nach "außen" zur Verfügung stellen bzw. von dort empfangen können.
## Aufgabe
* Entscheiden Sie sich, welche Schnittstellenart (synchron/asynchron) für Ihr Projekt am besten geeignet ist.
* Erstellen Sie eine Komponente, die für die Außenschnittstelle Ihrer Anwendung zuständig ist.
* Welche Daten werden bereitgestellt?
* Welche Daten können modifiziert werden?
* Welche Daten können gesendet werden?
* Erstellen Sie die geeigneten `CRUD`-Operationen für Ihre Schnittstelle.
* Sofern Sie sich für eine REST-Schnittstelle entscheiden: Denken Sie an die korrekte Wahl der [HTTP-Verben](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods) und [HTTP-Status-Codes](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status).
## Tipps
* Für REST-APIs: Die Verwendung eines REST-Clients (z.B. Browser-Extensions, [Postman](https://www.postman.com), [Swagger Editor](https://editor.swagger.io), [IntelliJ](https://www.jetbrains.com/help/idea/http-client-in-product-code-editor.html#converting-curl-requests)) macht das Testen der Schnittstelle einfacher.
## Ziele
* Ihr Projekt verfügt über eine gekapselte Schnittstellenschicht, mit der von außen auf Ihr Programm zugegriffen werden kann.
\ No newline at end of file
# Übungen Software-Entwicklung 3: Software-Architektur
## Ausgangslage
Nachdem Sie letzte Woche sich überlegt haben, welches Thema Sie bearbeiten wollen, sollen Sie nun in erste Umsetzungen starten.
## Aufgabe
* Überlegen Sie sich welche Teilkomponenten für Ihre Projektaufgabe notwendig sind.
* Identifzieren Sie zusammengehörige Komponenten und bündeln diese. Erstellen Sie für z.B. ein Klassendiagramm.
* Definieren Sie, wie die Kommunikation zwischen diesen Komponenten stattfinden soll. Achten Sie auf Austauschbarkeit und Erweiterbarkeit.
* Denken Sie darüber nach, welche Teile Ihres Projekts besonders verlässlich bzgl. der Schnittstelle sind.
* Unterteilen Sie Ihr Projekt in `packages`. Nutzen Sie zur Zugriffssteuerung die verschiedenen Sichtbarkeiten für Klassen.
* Nutzen Sie `Interfaces` und `Factories` zur Kapselung und Modularisierung.
## Tipps
* Beginnen Sie mit der einfachsten Umsetzung Ihrer Kernanforderungen. Fangen Sie erst im Anschluss mit der Strukturierung/Modularisierung Ihres Projekts an
* Schauen Sie in das [Vorlesungsprojekt](https://gitlab.mi.hdm-stuttgart.de/jordine/se3sose2022projekt). Hier finden Sie eine Möglichkeit wie Sie ihr Projekt untergliedern und modularisieren können.
* **Wichtig für später**: Erstellen Sie Ihr Java-Projekt mit Maven.
* Stellen Sie sich vor, dass Ihre Module als einzelne Artefakte deploybar sein sollen.
* Wenn Sie möchten, schauen Sie sich Informationen zu Java Modules an und überlegen sich, ob sie diese für Ihr Projekt einsetzen wollen.
## Ziele
* Grundstruktur Ihres Projekts steht.
* Aufteilung in modulare Einheiten.
* Nutzen von Interfaces statt konkreter Implementierung.
* Nutzung von Factories.
File added
# Übungen Software-Entwicklung 3: `git`, Dokumentation, Clean Code
## Ausgangslage
In der Vorlesung haben Sie weitergehende Konzepte zu `git`, Dokumentation und Clean Code kennengelernt. Diese sollen nun auf Ihr Projekt angewandt werden.
## Aufgabe
* Überlegen Sie sich im Team, wie Sie mit `git` umgehen möchten.
* Wie sieht Ihr Workflow aus?
* Wie möchten Sie mit Branches umgehen?
* Wann werden Tags erstellt? Wie ist Ihre Versionsschematik?
* Erstellen Sie in Ihrem Repository ein Changelog, in dem Ihre Änderungen festhalten und pflegen.
* Erstellen Sie eine Readme, die beschreibt, wie Ihr Projekt gestartet wird.
* Legen Sie Ihre Projektdokumentation in einem Wiki ab.
* Prüfen Sie Ihren vorhandenen Code auf die `SOLID`-Prinzipien und passen diesen ggf. entsprechend an.
* Sind Benennungen so gewählt, dass diese keine weitere Erklärung benötigen?
* Sind Ihre Klassen immer gleichartig strukturiert?
## Tipps
* Nutzen Sie `git` auf der Commandline. Das hilft, die Konzepte zu verinnerlichen.
* Scheuen Sie sich nicht vor `merge`-Konflikten! Nach ein paar Mal, ist es nicht mehr so schlimm 😊
* Nutzen Sie `merge`-Requests, um sich gegenseitig zu reviewen.
* Schauen Sie in das [Vorlesungsprojekt](https://gitlab.mi.hdm-stuttgart.de/jordine/se3sose2022projekt). Hier finden Sie eine Möglichkeit wie Sie Beispiele wie die `SOLID`-Prinzipien umgesetzt werden können.
## Ziele
* Sie können mit `git` umgehen und haben eine Vorgehensweise für branches definiert.
* Changelogs dokumentieren wesentliche Änderungen Ihres Projekts.
* Eine Readme beschreibt wie Ihr Projekt gestartet werden kann.
* Ihre Dokumentation liegt in einem Wiki ab.
* Die `SOLID`-Prinzipen werden in Ihrem Projekt angewandt.
\ No newline at end of file
# Übungen Software-Entwicklung 3: SQL, NoSQL
## Ausgangslage
Die in der Vorlesung vorgestellten Persistenz-Möglichkeiten SQL bzw. NoSQL sollen nun in Ihr Projekt integriert werden.
## Aufgabe
* Entscheiden Sie sich, welches Datenbankprinzip besser für Ihren Anwendungsfall geeignet ist.
* Erstellen Sie eine Komponente, die für die Persistenz Ihrer Daten zuständig ist.
* Erstellen Sie die geeigneten `CRUD`-Operationen.
## Tipps
* Nutzen Sie einen Docker-Container um das Datenbanksystem einheitlich in Ihrem Team zugreifbar zu machen.
* IntelliJ kann Sie bei der Datenbankentwicklung unterstützen: [Übersichtsvideo für SQL-DBMS](https://www.youtube.com/watch?v=BOoJQhDVcWg)
## Ziele
* Ihr Projekt verfügt über eine gekapselte Persistenzschicht, die die notwendigen Daten speichern, lesen, ändern und löschen kann.
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<title>git, Dokumentation, Clean Code</title>
<meta charset="utf-8">
<link href="css/hdm.css" rel="stylesheet"></link>
<style>
/* yanone-kaffeesatz-regular - latin */
@font-face {
font-family: 'Yanone Kaffeesatz';
font-style: normal;
font-weight: 400;
src: url('fonts/yanone-kaffeesatz-v22-latin-regular.eot'); /* IE9 Compat Modes */
src: local(''),
url('fonts/yanone-kaffeesatz-v22-latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('fonts/yanone-kaffeesatz-v22-latin-regular.woff2') format('woff2'), /* Super Modern Browsers */
url('fonts/yanone-kaffeesatz-v22-latin-regular.woff') format('woff'), /* Modern Browsers */
url('fonts/yanone-kaffeesatz-v22-latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */
url('fonts/yanone-kaffeesatz-v22-latin-regular.svg#YanoneKaffeesatz') format('svg'); /* Legacy iOS */
}
/* noto-serif-regular - latin */
@font-face {
font-family: 'Noto Serif';
font-style: normal;
font-weight: 400;
src: url('fonts/noto-serif-v20-latin-regular.eot'); /* IE9 Compat Modes */
src: local(''),
url('fonts/noto-serif-v20-latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('fonts/noto-serif-v20-latin-regular.woff2') format('woff2'), /* Super Modern Browsers */
url('fonts/noto-serif-v20-latin-regular.woff') format('woff'), /* Modern Browsers */
url('fonts/noto-serif-v20-latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */
url('fonts/noto-serif-v20-latin-regular.svg#NotoSerif') format('svg'); /* Legacy iOS */
}
/* ubuntu-mono-regular - latin */
@font-face {
font-family: 'Ubuntu Mono';
font-style: normal;
font-weight: 400;
src: url('fonts/ubuntu-mono-v14-latin-regular.eot'); /* IE9 Compat Modes */
src: local(''),
url('fonts/ubuntu-mono-v14-latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('fonts/ubuntu-mono-v14-latin-regular.woff2') format('woff2'), /* Super Modern Browsers */
url('fonts/ubuntu-mono-v14-latin-regular.woff') format('woff'), /* Modern Browsers */
url('fonts/ubuntu-mono-v14-latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */
url('fonts/ubuntu-mono-v14-latin-regular.svg#UbuntuMono') format('svg'); /* Legacy iOS */
}
/* ubuntu-mono-italic - latin */
@font-face {
font-family: 'Ubuntu Mono';
font-style: italic;
font-weight: 400;
src: url('fonts/ubuntu-mono-v14-latin-italic.eot'); /* IE9 Compat Modes */
src: local(''),
url('fonts/ubuntu-mono-v14-latin-italic.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('fonts/ubuntu-mono-v14-latin-italic.woff2') format('woff2'), /* Super Modern Browsers */
url('fonts/ubuntu-mono-v14-latin-italic.woff') format('woff'), /* Modern Browsers */
url('fonts/ubuntu-mono-v14-latin-italic.ttf') format('truetype'), /* Safari, Android, iOS */
url('fonts/ubuntu-mono-v14-latin-italic.svg#UbuntuMono') format('svg'); /* Legacy iOS */
}
/* ubuntu-mono-700 - latin */
@font-face {
font-family: 'Ubuntu Mono';
font-style: normal;
font-weight: 700;
src: url('fonts/ubuntu-mono-v14-latin-700.eot'); /* IE9 Compat Modes */
src: local(''),
url('fonts/ubuntu-mono-v14-latin-700.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('fonts/ubuntu-mono-v14-latin-700.woff2') format('woff2'), /* Super Modern Browsers */
url('fonts/ubuntu-mono-v14-latin-700.woff') format('woff'), /* Modern Browsers */
url('fonts/ubuntu-mono-v14-latin-700.ttf') format('truetype'), /* Safari, Android, iOS */
url('fonts/ubuntu-mono-v14-latin-700.svg#UbuntuMono') format('svg'); /* Legacy iOS */
}
body { font-family: 'Noto Serif'; }
h1, h2, h3 {
font-family: 'Yanone Kaffeesatz';
font-weight: normal;
}
.remark-code, .remark-inline-code { font-family: 'Ubuntu Mono'; }
</style>
</head>
<body>
<textarea id="source">
class: center, middle, first
# Software-Entwicklung 3
## git, Dokumentation, Clean Code
---
# Agenda
1. Recap
2. Arbeit mit git
3. Dokumentation
4. Clean Code
---
# Recap: Was haben wir letzte Woche besprochen?
* Softwarearchitektur
* Basisprinzipien der Softwarearchitektur
* Praktisches Beispiel
> Blick ins [Repository](https://gitlab.mi.hdm-stuttgart.de/jordine/se3sose2022projekt)
---
# Arbeit mit VCS
VCS = **V**ersion **C**ontrol **S**ystem
Ablage von Dateien/Ordnern, die nicht aus anderen versionierten Dateien abgeleitet werden können. Beispielsweise sollten `.class`-Dateien nicht in einem VCS verwaltet werden.
Heute Fokus auf Teamarbeit mit `git`
---
# `git` Basisbefehle
* `git pull REMOTE TARGET-BRANCH`: Updates aus Remote-Repo laden und in TARGET-BRANCH mergen
* `git status`: Status des Repo. Zeigt z.B., ob Dateien noch nicht commited wurden
* `git log`: Zeigt die History des aktuellen Branches an
Erklärungen zu sämtlichen Befehlen: [git Cheat Sheet](https://training.github.com/downloads/de/github-git-cheat-sheet/)
---
# `git graph`
Anzeige der commits und branches als Graph.
**git CLI**
```bash
git log --all --decorate --oneline --graph
# Beenden mit ":q"
```
**GitLab**
_Repo-Seite_ ➡️ **Repository** ➡️ **Graph**
Beispiel: https://gitlab.mi.hdm-stuttgart.de/jordine/se3sose2022projekt/-/network/main
---
# Erstellen eines Branches und Merge
```bash
git branch my-new-branch
git checkout my-new-branch # Abkürzung: git checkout -b my-new-branch
# Änderungen machen
git add --all
git commit -m "update README.md"
git checkout main
git merge my-new-branch
```
---
# Merge conflicts beheben
Entstehen, wenn in beiden Branches (source und target) in der gleichen Zeile Änderungen vorgenommen wurden.
```bash
git checkout <TARGET BRANCH>
git merge <SOURCE BRANCH>
# Konflikt mit Editor beheben. Entscheiden, welche Änderung "korrekt" ist.
git add <AFFECTED FILES>
git commit -m "merged TARGET BRANCH"
# Ergänzung: Merge abbrechen
git merge --abort
```
---
# git flow
* Besteht aus
* mehreren Feature Branches, d.h. parallele Entwicklungsstränge
* langlebige Branches
* Integrationstests auf `develop`
* Releases auf `main`, inkl. Tags
* Merge auf `main` wird oft nur von bestimmten Personen durchgeführt
* Geeignet z.B. für feste Releasezyklen
* git flow Cheatsheet: http://danielkummer.github.io/git-flow-cheatsheet/
<img src="img/git-doku-cleancode/git-flow.png" alt="git flow" width="60%"/>
---
# Trunk-basierte Entwicklung mit git
* Geeignet, **häufige** und **kleine Änderungen** in einem Hauptbranch (_Trunk_, oft `main`) einfließen sollen.
* Alle haben Zugriff auf alle Branches, auch `main`
* Grundannahme: Trunk-Branch ist immer stabil und bereit für Deployment.
* Kleine Branches. Dadurch weniger Konflikte beim merge.
<img src="img/git-doku-cleancode/git-tdd.png" alt="Trunk based development" width="90%"/>
---
# `merge` requests in GitLab
* Kann Bestandteil eines Reviewprozesses sein
> [Demo im Repo](https://gitlab.mi.hdm-stuttgart.de/jordine/se3sose2022projekt)
---
# `cherry pick`
* Kopieren einzelner Änderungen/Commits von einem Branch in einen anderen.
* Sinnvoll, wenn an zwei Branches gearbeitet wird und eine Änderung vor dem `merge` benötigt wird. Beispiel: Hotfix.
## Schritte
1. Commit ID herausfinden, die kopiert werden soll: `git log`
2. Wechseln in den Branch, in dem der Commit kopiert werden soll: `git checkout BRANCHNAME`
3. Kopieren des Commits in den aktuellen Branch (mit neuem Commit): `git cherry-pick COMMIT-ID [COMMIT-ID COMMIT-ID]`
4. _Kopieren des Commits in den aktuellen Branch (ohne neuem Commit): `git cherry-pick COMMIT-ID [COMMIT-ID COMMIT-ID] -n`_
---
# git Tricks
* `.gitignore`: Datei, in der angegeben werden kann, welche Dateien/Ordner nicht versioniert werden sollen
> [Sammlung mit `.gitignore`-Konfigurationen](https://github.com/github/gitignore)
---
# Tagging und Semantic Versioning
* [Semantic Versioning](https://semver.org): Dreiteilige Versionsnummern. Z.B. `v2.3.1`.
* Muster `v{Major}.{Minor}.{Patch}`
* `Major`: (API-)Änderungen, die nicht mehr kompatibel zu Vorgängerversionen sind.
* `Minor`: (API-)Änderungen, die kompatibel zu Vorgängerversionen sind.
* `Patch`: Bug-Behebungen, keine API-Änderungen.
## Tagging mit git
* Tag = Versionsnummer, die auf einen commit zeigt
```bash
git tag -a TAGNAME COMMIT-ID
```
* Alternativ mit GitLab
---
# Changelogs
* Dokumentieren, was eine spezifische Version auszeichnet.
* Was ist neu?
* Was wurde geändert?
* Welche Funktionen werden in Zukunft entfernt?
* Welche Funktionen wurden entfernt?
* Welche Bugs wurden behoben?
* Welche Security-Probleme wurden behoben?
* Weitere Infos: [Keep a changelog](https://keepachangelog.com/de/1.0.0/)
---
# Tricks in GitLab
`git commit -m "Arbeit an Issue #2"`
Verknüpft Commits mit Issues. Sinnvoll für Nachvollziehbarkeit.
---
class: center, middle
# Dokumentation & Issue Management
---
# Dokumentationsformen
* Doku am Code (`javadoc`), sofern notwendig
* Doku im Repository
* Readme, z.B. mit Anleitung wie das Programm gestartet werden kann
* Changelog
* Technische Dokumentation
* Diagramme mit `mermaid` möglich: https://mermaid-js.github.io/mermaid/#/
* Enduser Doku
> Schulungen mitdenken!
---
# Nutzen eines Wikis
> [Demo im Repo](https://gitlab.mi.hdm-stuttgart.de/jordine/se3sose2022projekt)
# Nutzen von Milestones
> [Demo im Repo](https://gitlab.mi.hdm-stuttgart.de/jordine/se3sose2022projekt)
---
class: center, middle
# Clean code
---
# Warum ist clean code wichtig?
* Ursprung: Buch "Clean Code", Robert C. Martin, Sammlung von Prinzipien um clean code zu erreichen
* Ziele:
* Code leichter verständlich machen
* Wartbarkeit des Codes erhöhen
* Einheitlichkeit schaffen
* Projektorganisation
* (Selbst-)Organisation
---
# SOLID Prinzipien
_Teilweise Wiederholung_
* **S**ingle Responsibilty Principle:
* Jede Klasse sollte nur eine Aufgabe bearbeiten, Speichern in Model-Klasse auslagern
* **O**pen Closed Princple:
* Offen für Erweiterung, geschlossen für Veränderung
* Info-Methode für Audio/Videos auslagern
* **L**iskov'sches Substiotions Prinzip:
* Unterklassen erweitern Oberklassen
* Unterklassen dürfen Verhalten der Oberklassen nicht einschränken
* **I**nterface Segregation Principle:
* Große Schnittstellen in kleinere, modularere Schnittstellen aufteilen
* **D**ependency Inversion Principle:
* Interfaces statt konkreter Implementierung
* Gruppierende Methoden
> Demo
---
# Umgang mit Benennungen
* Es soll kein Kommentar für Variablenbenennungen notwendig sein
* Variablendefinition an dem Ort, wo sie definiert werden
* Nicht zu viele Kommentare, Code sollte ohne verständlich sein
---
# Eindeutigkeit
* Gleichartige Struktur: Z.B. Wie sind Klassen strutkturiert
* Wo befinden sich `imports`, Konstruktoren, Methoden etc.?
* Unterstützung durch IDE, i.S.v. Templates
* Kann automatisiert über statische Codeanalyse/Lint (z.B. [SonarCube](https://docs.sonarqube.org/latest/)) geprüft werden
* Jede Methode sollte nur eine Sache tun, ggf. aufteilen in mehrere Methoden
---
# Zusammenfassung der Clean Code Regeln
> [Tutorials zu Clean Code, TU Dortmund](https://sopra.cs.tu-dortmund.de/wiki/_media/infos/tutorials/cleancode/cleancode_paper.pdf)
> [Clean Code Tugenden, clean-code-developer.de](https://clean-code-developer.de/die-tugenden/)
**Nicht immer sind alle Clean Code praktikabel!**
---
# Refactoring des Demoprojekts
</textarea>
<script src="js/remark.min.js">
</script>
<script>
var slideshow = remark.create();
</script>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<title>Parallele Programmierung</title>
<meta charset="utf-8">
<link href="css/hdm.css" rel="stylesheet"></link>
<style>
/* yanone-kaffeesatz-regular - latin */
@font-face {
font-family: 'Yanone Kaffeesatz';
font-style: normal;
font-weight: 400;
src: url('fonts/yanone-kaffeesatz-v22-latin-regular.eot'); /* IE9 Compat Modes */
src: local(''),
url('fonts/yanone-kaffeesatz-v22-latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('fonts/yanone-kaffeesatz-v22-latin-regular.woff2') format('woff2'), /* Super Modern Browsers */
url('fonts/yanone-kaffeesatz-v22-latin-regular.woff') format('woff'), /* Modern Browsers */
url('fonts/yanone-kaffeesatz-v22-latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */
url('fonts/yanone-kaffeesatz-v22-latin-regular.svg#YanoneKaffeesatz') format('svg'); /* Legacy iOS */
}
/* noto-serif-regular - latin */
@font-face {
font-family: 'Noto Serif';
font-style: normal;
font-weight: 400;
src: url('fonts/noto-serif-v20-latin-regular.eot'); /* IE9 Compat Modes */
src: local(''),
url('fonts/noto-serif-v20-latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('fonts/noto-serif-v20-latin-regular.woff2') format('woff2'), /* Super Modern Browsers */
url('fonts/noto-serif-v20-latin-regular.woff') format('woff'), /* Modern Browsers */
url('fonts/noto-serif-v20-latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */
url('fonts/noto-serif-v20-latin-regular.svg#NotoSerif') format('svg'); /* Legacy iOS */
}
/* ubuntu-mono-regular - latin */
@font-face {
font-family: 'Ubuntu Mono';
font-style: normal;
font-weight: 400;
src: url('fonts/ubuntu-mono-v14-latin-regular.eot'); /* IE9 Compat Modes */
src: local(''),
url('fonts/ubuntu-mono-v14-latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('fonts/ubuntu-mono-v14-latin-regular.woff2') format('woff2'), /* Super Modern Browsers */
url('fonts/ubuntu-mono-v14-latin-regular.woff') format('woff'), /* Modern Browsers */
url('fonts/ubuntu-mono-v14-latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */
url('fonts/ubuntu-mono-v14-latin-regular.svg#UbuntuMono') format('svg'); /* Legacy iOS */
}
/* ubuntu-mono-italic - latin */
@font-face {
font-family: 'Ubuntu Mono';
font-style: italic;
font-weight: 400;
src: url('fonts/ubuntu-mono-v14-latin-italic.eot'); /* IE9 Compat Modes */
src: local(''),
url('fonts/ubuntu-mono-v14-latin-italic.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('fonts/ubuntu-mono-v14-latin-italic.woff2') format('woff2'), /* Super Modern Browsers */
url('fonts/ubuntu-mono-v14-latin-italic.woff') format('woff'), /* Modern Browsers */
url('fonts/ubuntu-mono-v14-latin-italic.ttf') format('truetype'), /* Safari, Android, iOS */
url('fonts/ubuntu-mono-v14-latin-italic.svg#UbuntuMono') format('svg'); /* Legacy iOS */
}
/* ubuntu-mono-700 - latin */
@font-face {
font-family: 'Ubuntu Mono';
font-style: normal;
font-weight: 700;
src: url('fonts/ubuntu-mono-v14-latin-700.eot'); /* IE9 Compat Modes */
src: local(''),
url('fonts/ubuntu-mono-v14-latin-700.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('fonts/ubuntu-mono-v14-latin-700.woff2') format('woff2'), /* Super Modern Browsers */
url('fonts/ubuntu-mono-v14-latin-700.woff') format('woff'), /* Modern Browsers */
url('fonts/ubuntu-mono-v14-latin-700.ttf') format('truetype'), /* Safari, Android, iOS */
url('fonts/ubuntu-mono-v14-latin-700.svg#UbuntuMono') format('svg'); /* Legacy iOS */
}
body { font-family: 'Noto Serif'; }
h1, h2, h3 {
font-family: 'Yanone Kaffeesatz';
font-weight: normal;
}
.remark-code, .remark-inline-code { font-family: 'Ubuntu Mono'; }
</style>
</head>
<body>
<textarea id="source">
class: center, middle, first
# Software-Entwicklung 3
## Parallele Programmierung
---
# Agenda
1. Recap
2. Parallele Programmierung
---
# Recap: Was haben wir in der letzten Vorlesung besprochen?
* Client-/Server-Kommunikation
* Synchrone & asynchrone Schnittstellen
* REST-APIs
> Blick ins [Repository](https://gitlab.mi.hdm-stuttgart.de/jordine/se3sose2022projekt)
---
class: center, middle
# Warum und wofür wird parallele Programmierung benötigt?
---
# Prozesse <-> Threads
## Prozess
* Eigener Speicherbereich
* Schwergewichtig
* Wird vom Betriebssystem verwaltet
## Thread
* "Leichtgewichtiger Prozess"
* Programmteil, der parallel ausgeführt werden kann
* Wird aus einem Prozess heraus gestartet
* Kann auf Speicherbereich anderer Threads zugreifen
---
# Amdahls Law
> Anwendungen lassen sich **nicht** unendlich durch Parallelisierung beschleunigen
**Ursachen**:
* Programmanteile, die synchron ablaufen müssen
* Verwaltungsaufwand (-> Overhead) steigt mit steigender Anzahl CPUs/Prozesse/Threads
<img src="img/concurrency/Amdahl.png" alt="Amdahl's Law" width="30%">
_Quelle: Frank Klemm, 2017, [Wikipedia](https://commons.wikimedia.org/wiki/File:Amdahl.png), [Creative Commons Share Alike](https://creativecommons.org/licenses/by-sa/4.0/deed.en)_
---
# Schritte der parallelen Programmierung
1. Identifikation des parallellaufenden Anteils
2. Herauslösen und auslagern des parallellaufenden Anteils
3. Starten des parallelen Anteils
4. Ggf. zusammenführen mit anderen Programmteilen
---
# Schritte der parallelen Programmierung mit Java-`Threads` (I)
* Identifikation des parallellaufenden Anteils
* Herauslösen und auslagern des parallellaufenden Anteils in einen `Thread`
```java
class MyThread extends Thread {...}
class MyRunnable implements Runnable {...}
```
* Implementieren der `run()`-Methode
```java
public void run(){
// do stuff
}
```
---
# Schritte der parallelen Programmierung mit Java-`Threads` (II)
* Starten des parallelen Anteils -> `Thread` & `start()`
```java
MyThread t0 = new MyThread();
t0.start();
Thread t1 = new Thread(new MyRunnable());
t1.start();
```
* Ggf. zusammenführen mit anderen Programmteilen
```java
t0.join();
t1.join();
```
---
# `volatile`
```java
private volatile int value = 10;
```
* Garantiert dass alle Threads Änderungen an einer Variable umgehend mitbekommen
* Variable wird **nicht** von Threads gecacht
---
# Thread-relevante Methoden (I)
## `join()`
```java
Thread t0 = new Thread();
...
t0.join(); // warten bis t0 fertig ist
```
---
# Thread-relevante Methoden (II)
```java
public class BlockingQueue<T> {
private Queue<T> queue = new LinkedList<T>();
private int capacity;
public BlockingQueue(int capacity) {
this.capacity = capacity;
}
public synchronized void put(T element) throws InterruptedException {
while(queue.size() == capacity) {
wait();
}
queue.add(element);
notify(); // notifyAll() for multiple producer/consumer threads
}
public synchronized T take() throws InterruptedException {
while(queue.isEmpty()) {
wait();
}
T item = queue.remove();
notify(); // notifyAll() for multiple producer/consumer threads
return item;
}
}
```
_Quelle: https://stackoverflow.com/a/2537117_
---
# `ExecutorService`
```java
ExecutorService executor = Executors.newFixedThreadPool(10);
Runnable runnableTask = () -> {
try {
TimeUnit.MILLISECONDS.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
};
Callable<String> callableTask = () -> {
TimeUnit.MILLISECONDS.sleep(300);
return "Task's execution";
};
executorService.execute(runnableTask);
Future<String> future = executorService.submit(callableTask);
List<Callable<String>> callableTasks = new ArrayList<>();
callableTasks.add(callableTask);
callableTasks.add(callableTask);
callableTasks.add(callableTask);
List<Future<String>> futures = executorService.invokeAll(callableTasks);
String result = executorService.invokeAny(callableTasks);
```
_Quelle: https://www.baeldung.com/java-executor-service-tutorial_
---
# Probleme bei paralleler Programmierung
> **Shared state!**
### Konsistenzprobleme
### Programmflussprobleme
---
# Konsistenzprobleme
> Ungeschützer Zugriff aufgeteilte Ressourcen
* "Lost update"
* "Race condition"
* "Dirty read"
> Blick ins [Vorlesungs-Repository](https://gitlab.mi.hdm-stuttgart.de/jordine/se3sose2022vorlesung)
---
# Programmflussprobleme
> Gegenseitige Blockade parallellaufender Programmteile
## Dead lock
* Überkreuzzugriff auf Locks
> Blick ins [Vorlesungs-Repository](https://gitlab.mi.hdm-stuttgart.de/jordine/se3sose2022vorlesung)
---
# Möglichkeiten, Concurrency-Probleme in Java zu beheben
* Locks/Monitor-Objekte/`synchronized`
* `Atmoic`-Klassen
* `Concurrent`-Collections
* Funktionale Programmierung -> Java Streams
> Blick ins [Vorlesungs-Repository](https://gitlab.mi.hdm-stuttgart.de/jordine/se3sose2022vorlesung)
---
# Skalierung
## Vertikale Skalierung
> Erhöhung der Hardwareressourcen einer Maschine
## Horizontale Skalierung
> Erhöhen der Maschinenanzahl
</textarea>
<script src="js/remark.min.js">
</script>
<script>
var slideshow = remark.create();
</script>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<title>Container, CI/CD</title>
<meta charset="utf-8">
<link href="css/hdm.css" rel="stylesheet"></link>
<style>
/* yanone-kaffeesatz-regular - latin */
@font-face {
font-family: 'Yanone Kaffeesatz';
font-style: normal;
font-weight: 400;
src: url('fonts/yanone-kaffeesatz-v22-latin-regular.eot'); /* IE9 Compat Modes */
src: local(''),
url('fonts/yanone-kaffeesatz-v22-latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('fonts/yanone-kaffeesatz-v22-latin-regular.woff2') format('woff2'), /* Super Modern Browsers */
url('fonts/yanone-kaffeesatz-v22-latin-regular.woff') format('woff'), /* Modern Browsers */
url('fonts/yanone-kaffeesatz-v22-latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */
url('fonts/yanone-kaffeesatz-v22-latin-regular.svg#YanoneKaffeesatz') format('svg'); /* Legacy iOS */
}
/* noto-serif-regular - latin */
@font-face {
font-family: 'Noto Serif';
font-style: normal;
font-weight: 400;
src: url('fonts/noto-serif-v20-latin-regular.eot'); /* IE9 Compat Modes */
src: local(''),
url('fonts/noto-serif-v20-latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('fonts/noto-serif-v20-latin-regular.woff2') format('woff2'), /* Super Modern Browsers */
url('fonts/noto-serif-v20-latin-regular.woff') format('woff'), /* Modern Browsers */
url('fonts/noto-serif-v20-latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */
url('fonts/noto-serif-v20-latin-regular.svg#NotoSerif') format('svg'); /* Legacy iOS */
}
/* ubuntu-mono-regular - latin */
@font-face {
font-family: 'Ubuntu Mono';
font-style: normal;
font-weight: 400;
src: url('fonts/ubuntu-mono-v14-latin-regular.eot'); /* IE9 Compat Modes */
src: local(''),
url('fonts/ubuntu-mono-v14-latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('fonts/ubuntu-mono-v14-latin-regular.woff2') format('woff2'), /* Super Modern Browsers */
url('fonts/ubuntu-mono-v14-latin-regular.woff') format('woff'), /* Modern Browsers */
url('fonts/ubuntu-mono-v14-latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */
url('fonts/ubuntu-mono-v14-latin-regular.svg#UbuntuMono') format('svg'); /* Legacy iOS */
}
/* ubuntu-mono-italic - latin */
@font-face {
font-family: 'Ubuntu Mono';
font-style: italic;
font-weight: 400;
src: url('fonts/ubuntu-mono-v14-latin-italic.eot'); /* IE9 Compat Modes */
src: local(''),
url('fonts/ubuntu-mono-v14-latin-italic.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('fonts/ubuntu-mono-v14-latin-italic.woff2') format('woff2'), /* Super Modern Browsers */
url('fonts/ubuntu-mono-v14-latin-italic.woff') format('woff'), /* Modern Browsers */
url('fonts/ubuntu-mono-v14-latin-italic.ttf') format('truetype'), /* Safari, Android, iOS */
url('fonts/ubuntu-mono-v14-latin-italic.svg#UbuntuMono') format('svg'); /* Legacy iOS */
}
/* ubuntu-mono-700 - latin */
@font-face {
font-family: 'Ubuntu Mono';
font-style: normal;
font-weight: 700;
src: url('fonts/ubuntu-mono-v14-latin-700.eot'); /* IE9 Compat Modes */
src: local(''),
url('fonts/ubuntu-mono-v14-latin-700.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('fonts/ubuntu-mono-v14-latin-700.woff2') format('woff2'), /* Super Modern Browsers */
url('fonts/ubuntu-mono-v14-latin-700.woff') format('woff'), /* Modern Browsers */
url('fonts/ubuntu-mono-v14-latin-700.ttf') format('truetype'), /* Safari, Android, iOS */
url('fonts/ubuntu-mono-v14-latin-700.svg#UbuntuMono') format('svg'); /* Legacy iOS */
}
body { font-family: 'Noto Serif'; }
h1, h2, h3 {
font-family: 'Yanone Kaffeesatz';
font-weight: normal;
}
.remark-code, .remark-inline-code { font-family: 'Ubuntu Mono'; }
</style>
</head>
<body>
<textarea id="source">
class: center, middle, first
# Software-Entwicklung 3
## Container, CI/CD
---
# Agenda
1. Recap
2. Container
3. CI/CD
---
# Recap: Was haben wir in der letzten Vorlesung besprochen?
* Build Management mit Maven
* Testing mit JUnit
> Blick ins [Repository](https://gitlab.mi.hdm-stuttgart.de/jordine/se3sose2022projekt)
---
class: center, middle
# Was muss getan werden um eine (Server-)Anwendung zu starten? Was sind die Probleme?
???
* Umgebung einrichten
* Unterschiedliche Versionen (Libraries, OS)
* Kompatibilitätsprobleme
---
# Möglichkeiten zur Problemlösung
* ...
* Virtuelle Maschinen
* Containerisierte Anwendungen
> Kapselung der Anwendung mit zugehöriger Umgebung
---
# Virtuelle Maschinen
_Schematische Darstellung_
<img src="img/container-ci_cd/vm.png" alt="VM Aufbau" width="100%">
---
# Container
_Schematische Darstellung_
<img src="img/container-ci_cd/container.png" alt="Container Aufbau" width="100%">
---
# Docker
* Umsetzung für Container
* Erste Version 2013
* Container sind OCI (Open Container Initiative) kompatibel
* Enthält Versionsverwaltung für Images
* Sammlung von Images auf https://hub.docker.com
* Alternative `podman`
* Teilweise lizenzpflichtig (Docker Desktop)
* `root`-Problematik
---
# Begriffe
**Image**: Containerabbild, das sämtliche Applikationen und Konfigurationen enthält. Kann auf bestehenden Images aufbauen.
**Container**: Instanziierung eines Images. Aus einem Image können beliebig viele Container gestartet werden.
**Dockerfile**: Beschreibt die Konfiguration eines Images.
**docker-compose.yml**: Konfigurationsdatei zur Ausführung ein oder mehrere Container.
---
# Grundprinzipien
* Jeder Container sollte nur einen Zweck erfüllen
* In Containern werden keine persistenten Daten gespeichert
* Sollen Daten persistiert werden, können z.B. `Volumes` oder `bind mounts` genutzt werden
* (weitere Prinzipen können folgen, abhängig von der Systemarchitektur)
---
# Beispiele
* Bauen eines Containers
* Starten eines Containers
* Containerzugriff
* Einbinden von Dateien des Hostsystems
* Zusammenfassendes Beispiel mit `docker compose`
## Dokumentationen/Links
* [Docker Installation](https://docs.docker.com/compose/install/)
* [Dockerfile](https://docs.docker.com/engine/reference/builder/)
* [Docker Compose - Getting started](https://docs.docker.com/compose/gettingstarted/)
* [Nginx Docker Doku](https://hub.docker.com/_/nginx)
---
# Bauen eines Containers
## `Dockerfile`
```
FROM nginx
COPY html-dir /usr/share/nginx/html
```
## Bauen
```bash
docker build -t se3-nginx:0.0.1 .
```
---
# Starten eines Container
```bash
# Starten
docker run --rm -d se3-nginx:0.0.1
# Prüfen, ob der Container läuft
docker ps
# Logs überprüfen (Containername entweder beim Start vergeben
# oder per docker ps)
docker logs <CONTAINER NAME>
# Container beenden
docker stop <CONTAINER NAME>
```
---
# Containerzugriff
```bash
docker run --rm -d - p 8080:80 se3-nginx:0.0.1
```
## Öffnen der Website
> http://localhost:8080
## Alternative Variante (ohne Dockerfile)
```bash
docker run --rm -d -p 8081:80 -v $(pwd)/html-dir:/usr/share/nginx/html:ro nginx
```
---
# `docker-compose`
```yaml
version: '2'
services:
web:
image: nginx
volumes:
- "./html-dir:/usr/share/nginx/html:ro"
ports:
- "8082:80"
```
## Start
`docker-compose.yml` muss sich im aktuellen Verzeichnis befinden
```bash
# Mit M1 Chip "docker compose", sonst "docker-compose"
docker compose up -d
```
---
class: center, middle
# CI/CD
## Continuous Integration & Continuous Deployment
---
# Was ist Continuous Integration?
_nach ["What is Continuous Integration?", AWS, 2022](https://aws.amazon.com/devops/continuous-integration/?nc1=h_ls)_
* DevOps-Verfahren
* Zentrales Repository
* Automatisiertes testen und bauen der Anwendung
* Früher:
* Isolierte Arbeit an einzelnen Aufgaben
* Code wurde spät zusammengeführt (=Integration)
* Ziele:
* Bugs früher erkennen
* Kürzere Veröffentlichungszeiten
* Steigerung der Produktivität -> Warum?
---
# Mögliche Continuous Integration Vorgehensweise
_angepasst nach ["Continuous Integration", Martin Fowler, 2006](https://www.martinfowler.com/articles/continuousIntegration.html)_
* Code muss zentral in einem Repository abliegen. Definition eines Integrationsbranches.
* Automatisieren des Build-Prozesses
* Automatisieren des Test-Prozesses
* Regelmäßiger `merge` auf den Integrationsbranch
* Jeder `commit` auf den Integrationsbranch baut die Anwendung
* Schlägt ein Build fehl, soll dieser so schnell wie möglich repariert werden
* Build-Zeiten so schnell halten (nicht immer möglich)
* Testen in einem Klon der Produktionsumgebung
* Einfaches Bereitstellen der aktuellsten (kompilierten) Version
---
# Was ist Continuous Deployment?
_nach ["What is Continuous Deployment?", AWS, 2022](https://aws.amazon.com/devops/continuous-delivery/)_
* Automatisches Veröffentlichen der Software auf einer Testumgebung
* Unterschied zu Continuous Deployment
* Continuous Deployment: Automatische Veröffentlichung auf Produktionsumgebung
* Continuous Delivery: Manuelle Veröffentlichung inkl. Freigabe auf Produktionsumgebung
---
# Was ist Continuous Deployment?
_nach ["What is Continuous Deployment?", AWS, 2022](https://aws.amazon.com/devops/continuous-delivery/)_
<img src="img/container-ci_cd/ci_cd.png" alt="Ablauf CI/CD" width="100%">
---
# CI/CD mit GitLab
* Repository wird für CI/CD genutzt
* (Shared) Runner führen Aktionen in definierten Phasen(=Stages & Jobs) aus
* Eine Stage kann ein oder mehrere Jobs enthalten
* Ein Job kann auf einem Container-Image basieren
* Innerhalb des Image können Skripte ausgeführt werden
* Eine Pipeline besteht aus einer oder mehreren Stages
---
# Beispiel CI/CD mit GitLab
* Beschreibung in `.gitlab-ci.yml`
* Voraussetzungen:
* CI/CD-Funktionen wurden für das Repo aktiviert: Settings ➡️ General ➡️ Visibility, project features, permissions ➡️ CI/CD (aktivieren)
* Runner wurden zugewiesen: Settings ➡️ CI/CD ➡️ Runners ➡️ Enable shared runners for this project
> Blick ins [Projekt](https://gitlab.mi.hdm-stuttgart.de/jordine/se3sose2022projekt)
</textarea>
<script src="js/remark.min.js">
</script>
<script>
var slideshow = remark.create();
</script>
</body>
</html>
\ No newline at end of file
File deleted
website/img/concurrency/Amdahl.png

29.8 KiB

website/img/container-ci_cd/ci_cd.png

253 KiB

website/img/container-ci_cd/container.png

113 KiB

website/img/container-ci_cd/vm.png

156 KiB

website/img/git-doku-cleancode/git-flow.png

116 KiB