Merge remote-tracking branch 'origin/main'

This commit is contained in:
Piet Ostendorp
2025-12-21 13:36:27 +01:00
7 changed files with 367 additions and 4 deletions

View File

@@ -0,0 +1,41 @@
@startuml Architektur
component "<<Angular>>\nFrontend" as frontend {
[<<npm>>\nFrontend-Model] as fm
}
frontend ..> REST : uses
component "<<Quarkus>>\nBackend" as backend {
[<<Maven>>\nBackend-Model] as bm
}
REST -right- backend
component "<<Quarkus>>\nPersistence" as persistence {
[<<Maven>>\nPersistence-Model] as pm
}
component "<<Kafka>>\nMessaging" as messaging {
[<<Topic>>\nCommand-Replies] as resp
[<<Topic>>\nCommand] as cmd
}
backend <-down- resp : "consumed by"
backend -down-> cmd : produces
persistence -up-> resp : produces
persistence <-up- cmd : "consumed by"
[<<PostgreSQL>>\nDatenbank] as db
[<<MongoDB>>\nDatenbank Statistiken] as dbs
persistence -left-> db : queries
persistence -right-> dbs : queries
[<<Telosys>>\nModel] as model
model -> fm : generates
model -> bm : generates
model -> pm : generates
@enduml

View File

@@ -0,0 +1,69 @@
@startuml "Generierte Klassen"
class Film {
id: int
..
title: string
description: string
duration: int
image: string
rating: short
..
category: Filmkategorie
}
abstract class Command {}
class CommandGetFilm {
id: int
}
CommandGetFilm -up-|> Command
class CommandCreateFilm {
}
CommandCreateFilm -up-|> Command
CommandCreateFilm -down-> "1" Film : create
class CommandUpdateFilm {
}
CommandUpdateFilm -up-|> Command
CommandUpdateFilm -down-> "1" Film : update
class CommandDeleteFilm {
}
CommandDeleteFilm -up-|> Command
CommandDeleteFilm -down-> "1" Film : delete
class CommandGetFilmResponse {
}
CommandGetFilmResponse -up-|> Command
CommandGetFilmResponse -up-> "1" Film : film
class CommandCreateFilmResponse {
}
CommandCreateFilmResponse -up-|> Command
CommandCreateFilmResponse -up-> "1" Film : created
class CommandDeleteFilmResponse {
}
CommandDeleteFilmResponse -up-|> Command
CommandDeleteFilmResponse -up-> "1" Film : deleted
class CommandUpdateFilmResponse {
}
CommandUpdateFilmResponse -up-|> Command
CommandUpdateFilmResponse -up-> "1" Film : updated
class CommandListFilm {
filters: List<String>
}
CommandListFilm -up-|> Command
class CommandListFilmResponse {
}
CommandListFilmResponse -up-|> Command
CommandListFilmResponse -up-> "0..*" Film : list
'Todo: Methoden + Processor + einiges mehr evtl.?
@enduml

View File

@@ -0,0 +1,37 @@
@startuml "Generated Processor"
interface CommandCreateFilmProcessor {
processCommandCreateFilm(cmd: CommandCreateFilm): Command
}
interface CommandGetFilmProcessor {
processCommandGetFilm(cmd: CommandGetFilm): Command
}
interface CommandUpdateFilmProcessor {
processCommandUpdateFilm(cmd: CommandUpdateFilm): Command
}
interface CommandDeleteFilmProcessor {
processCommandDeleteFilm(cmd: CommandDeleteFilm): Command
}
interface CommandListFilmProcessor {
processCommandListFilm(cmd: CommandListFilm): Command
}
class FilmProcessor {
processCommandCreateFilm(cmd: CommandCreateFilm): Command
processCommandGetFilm(cmd: CommandGetFilm): Command
processCommandUpdateFilm(cmd: CommandUpdateFilm): Command
processCommandDeleteFilm(cmd: CommandDeleteFilm): Command
processCommandListFilm(cmd: CommandListFilm): Command
}
FilmProcessor -right-|> CommandListFilmProcessor
FilmProcessor -up-|> CommandDeleteFilmProcessor
FilmProcessor -up-|> CommandUpdateFilmProcessor
FilmProcessor -up-|> CommandGetFilmProcessor
FilmProcessor -left-|> CommandCreateFilmProcessor
@enduml

View File

@@ -0,0 +1,74 @@
@startuml Messaging Sequenzdiagramm Links
group "Backend: Request produzieren und warten"
Endpoint -> RequestReply: request(cmdW)
RequestReply -> AtomicReference : <<create>>
RequestReply <-- AtomicReference : responseRef
RequestReply -> RequestReply : responses.put(\nrequestId,\nresponseRef)
RequestReply -> Kafka: produce(cmdW)
RequestReply <-- Kafka : Ack
RequestReply -> AtomicReference : wait()
end
note over Kafka : asynchron
group "Persistence: Request konsumieren und enqueuen"
Quarkus -> Kafka: poll()
Quarkus <-- Kafka: cmdW
Quarkus -> CommandObserver: process(cmdW)
CommandObserver -> Transaction: get(txId)
CommandObserver <-- Transaction: tx
CommandObserver -> Transaction: queue(tx, cmdW)
CommandObserver <-- Transaction
Quarkus <-- CommandObserver
Kafka <-- Quarkus : Ack
end
note over Transaction : asynchron
... Persistence: Request verarbeiten und Response produzieren\n(siehe weiteres Sequenzdiagramm) ...
note over Kafka : asynchron
group "Backend: Response konsumieren und benachrichtigen"
RequestReply -> Kafka : poll()
RequestReply <-- Kafka : respW
RequestReply -> RequestReply : responses.get(requestId)
RequestReply -> AtomicReference : set(respW)
RequestReply <-- AtomicReference
RequestReply -> AtomicReference : notifyAll()
RequestReply <-- AtomicReference
end
note over RequestReply : asynchron
group "Backend: Response zu Request zurückgeben" [synchron nach 1. Block, siehe oben]
RequestReply <-- AtomicReference : wegen wait (siehe oben)
RequestReply -> AtomicReference : get()
RequestReply <-- AtomicReference : respW
Endpoint <-- RequestReply : respW
end
@enduml

View File

@@ -0,0 +1,38 @@
@startuml Messaging Sequenzdiagramm Rechts
participant Kafka
group "Persistence: Request verarbeiten und Response produzieren"
Transaction -> CommandWrapper : process(cmdW)
CommandWrapper -> Command : <<reflection>>\ndeserialize(cmdW)
CommandWrapper <-- Command : cmd
CommandWrapper -> Command : process(cmd)
Command -> CDI : select(Class)
Command <-- CDI : Processor
Command -> Processor : process(cmd)
note over Processor : Verarbeitung\ndes Commands
Command <-- Processor : resp
CommandWrapper <-- Command : resp
Transaction <-- CommandWrapper : resp
Transaction -> CommandResponse : serialize(resp).copyIds(cmdW)
Transaction <-- CommandResponse : respW
Transaction -> Interceptor : intercept(respW)
note over Interceptor : (asynchron;\nDetails nicht\ndargestellt)
Transaction <-- Interceptor
Transaction -> Transaction : commit()
Transaction -> Kafka : produce(respW)
Transaction <-- Kafka : Ack
end
@enduml

View File

@@ -0,0 +1,104 @@
@startuml Messaging Sequenzdiagramm
group "Backend: Request produzieren und warten"
Endpoint -> RequestReply: request(cmdW)
RequestReply -> AtomicReference : <<create>>
RequestReply <-- AtomicReference : responseRef
RequestReply -> RequestReply : responses.put(\nrequestId,\nresponseRef)
RequestReply -> Kafka: produce(cmdW)
RequestReply <-- Kafka : Ack
RequestReply -> AtomicReference : wait()
end
note over Kafka : asynchron
group "Persistence: Request konsumieren und enqueuen"
Quarkus -> Kafka: poll()
Quarkus <-- Kafka: cmdW
Quarkus -> CommandObserver: process(cmdW)
CommandObserver -> Transaction: get(txId)
CommandObserver <-- Transaction: tx
CommandObserver -> Transaction: queue(tx, cmdW)
CommandObserver <-- Transaction
Quarkus <-- CommandObserver
Kafka <-- Quarkus : Ack
end
note over Transaction : asynchron
group "Persistence: Request verarbeiten und Response produzieren"
Transaction -> CommandWrapper : process(cmdW)
CommandWrapper -> Command : <<reflection>>\ndeserialize(cmdW)
CommandWrapper <-- Command : cmd
CommandWrapper -> Command : process(cmd)
Command -> CDI : select(Class)
Command <-- CDI : Processor
Command -> Processor : process(cmd)
note over Processor : Verarbeitung\ndes Commands
Command <-- Processor : resp
CommandWrapper <-- Command : resp
Transaction <-- CommandWrapper : resp
Transaction -> CommandResponse : serialize(resp).copyIds(cmdW)
Transaction <-- CommandResponse : respW
Transaction -> Interceptor : intercept(respW)
note over Interceptor : (asynchron;\nDetails nicht\ndargestellt)
Transaction <-- Interceptor
Transaction -> Transaction : commit()
Transaction -> Kafka : produce(respW)
Transaction <-- Kafka : Ack
end
note over Kafka : asynchron
group "Backend: Response konsumieren und benachrichtigen"
RequestReply -> Kafka : poll()
RequestReply <-- Kafka : respW
RequestReply -> RequestReply : responses.get(requestId)
RequestReply -> AtomicReference : set(respW)
RequestReply <-- AtomicReference
RequestReply -> AtomicReference : notifyAll()
RequestReply <-- AtomicReference
end
note over RequestReply : asynchron
group "Backend: Response zu Request zurückgeben" [synchron nach 1. Block, siehe oben]
RequestReply <-- AtomicReference : wegen wait (siehe oben)
RequestReply -> AtomicReference : get()
RequestReply <-- AtomicReference : respW
Endpoint <-- RequestReply : respW
end
@enduml

View File

@@ -27,12 +27,12 @@ Ein Mitarbeiter kann beim Einlass das Ticket eines Kunden kontrollieren. Dazu is
### 🟥 Kinostatistik anzeigen
Der Kinoinhaber kann sich Statistiken (gesamt, pro Vorstellung oder pro Film) zu seinem Kinobetrieb anzeigen lassen. \
Der Kinoinhaber kann sich Statistiken (~~gesamt,~~ pro Vorstellung oder pro Film) zu seinem Kinobetrieb anzeigen lassen. \
Dazu gehören unter anderem:
* Besucheranzahl
* Einnahmen
* Anzahl reservierter/gebuchter Sitzplätze
* Beliebteste Filme basierend auf Besucheranzahlen
* ~~Beliebteste Filme basierend auf gebuchten Sitzplätzen~~
<br/>