\documentclass{uebung}

\author{Linus Nagel}
\chapter{3}

\begin{document}

\maketitle

\begin{exercises}
    \item \textbf{Worum handelt es sich bei JMS?}

    JMS (Jakarta Messaging Service) ist ein Jakarta‑EE‑Standard für die asynchrone Nachrichtenübermittlung. Er ermöglicht die lose, sprachunabhängige Kopplung von Komponenten, indem Sender und Empfänger nur über einen Nachrichtendienst (Message Broker) kommunizieren. Der Sender gibt eine Nachricht ab und arbeitet sofort weiter; der Empfänger verarbeitet sie unabhängig. JMS garantiert dabei eine zuverlässige Zustellung und unterstützt transaktionale Abläufe.

    \item \textbf{Erläutern Sie das Point-to-point-Modell.}

    Im Point‑to‑Point‑Modell werden Nachrichten in eine \emph{Queue} (Warteschlange) eingestellt. Beliebig viele Empfänger können sich bei derselben Queue registrieren, aber der JMS‑Server liefert jede Nachricht immer nur an genau einen Empfänger aus. Nach der Auslieferung wird die Nachricht aus der Queue entfernt. Ist zum Zeitpunkt des Sendens kein Empfänger aktiv, bleibt die Nachricht in der Queue gespeichert, bis ein Empfänger sie abholt.

    \item \textbf{Erläutern Sie das Publish-subscribe-Modell.}

    Beim Publish‑Subscribe‑Modell werden Nachrichten an ein \emph{Topic} gesendet. Alle Empfänger, die gerade für dieses Topic registriert sind, erhalten eine Kopie der Nachricht – ähnlich wie Zuschauer eines Fernsehprogramms. Empfänger, die zum Sendezeitpunkt nicht lauschen, bekommen die Nachricht nicht mit, es sei denn, sie haben eine \emph{dauerhafte Subscription} (Durable Subscription). In diesem Fall bewahrt der Server die Nachrichten auf und stellt sie bei der nächsten Verbindung zu.

    \item \textbf{Beschreiben Sie die einzelnen Schritte um eine Nachricht über JMS zu senden.}
    \begin{enumerate}
        \item \texttt{Properties} für den JNDI-Zugriff setzen und einen \texttt{InitialContext} erzeugen.
        \item \texttt{ConnectionFactory} aus dem JNDI holen (\texttt{context.lookup}).
        \item Mit der Factory eine \texttt{Connection} zum Nachrichtenserver erstellen \break (\texttt{factory.createConnection(user, pwd)}).
        \item Über die Connection eine \texttt{Session} anlegen \break (\texttt{con.createSession(false, AUTO\_ACKNOWLEDGE)}).
        \item Die Connection mit \texttt{con.start()} aktivieren.
        \item Das Ziel (\texttt{Destination}) – eine Queue oder ein Topic – per JNDI-Lookup ermitteln.
        \item Mit der Session einen \texttt{MessageProducer} für das Ziel erzeugen \break (\texttt{session.createProducer(ziel)}).
        \item Eine konkrete Nachricht erstellen (z.\,B. \texttt{TextMessage}) und mit Inhalt füllen.
        \item Nachricht über den Producer versenden (\texttt{producer.send(message)}).
        \item Connection schließen (\texttt{con.close()}).
    \end{enumerate}

    \item \textbf{In welcher Datei kann eine Queue oder ein Topic konfiguriert werden? In welchem Abschnitt wird die Konfiguration vorgenommen?}

    Die Konfiguration erfolgt in der Datei \texttt{standalone-full.xml} im Verzeichnis \path{<Wildfly>/standalone/configuration}. Queues und Topics werden im Subsystem \texttt{messaging-activemq} innerhalb des Elements \texttt{<subsystem xmlns="urn:jboss:domain:messaging-activemq:...">} definiert. Queues mit dem Tag \texttt{<jms-queue ...>}, Topics mit \texttt{<jms-topic ...>}.

    \item \textbf{Welche unterschiedlichen Schritte sind im Vergleich zum Senden erforderlich, wenn Sie als Client eine Nachricht lesen möchten?}

    Statt eines \texttt{MessageProducer} wird ein \texttt{MessageConsumer} benötigt. Der Empfang erfolgt mit der blockierenden Methode \texttt{consumer.receive()}, die ein \texttt{jakarta.jms.Message}-Objekt zurückgibt. Dieses wird auf den konkreten Nachrichtentyp (z.\,B. \texttt{TextMessage}) gecastet und der Inhalt mit der entsprechenden \texttt{get...()}‑Methode ausgelesen. Außerdem entfällt das Erstellen einer Nachricht und das Senden.

    \item \textbf{Wie kann bei einer Nachricht ein Wert angegeben werden, nach dem beim Empfang gefiltert werden kann?}

    Auf der gesendeten Nachricht werden vor dem Versand Properties gesetzt, z.\,B. mit \break \texttt{message.setStringProperty("Typ", "Typ1")}. Es stehen für alle primitiven Typen (außer \texttt{char}) entsprechende Setter zur Verfügung.

    \item \textbf{Wie kann beim Empfang einer Nachricht ein Filterwert angegeben werden?}

Beim Erstellen des \texttt{MessageConsumer} wird der Methode \texttt{session}\allowbreak\texttt{.createConsumer(destination, messageSelector)} ein Selektor-String nach der Syntax \texttt{key = 'value'} übergeben. Beispiel: \texttt{session}\allowbreak\texttt{.createConsumer(queue, "Typ = 'Typ1'")}. Dadurch empfängt der Consumer nur Nachrichten, deren Property \texttt{Typ} den Wert \texttt{'Typ1'} besitzt.

    \item \textbf{Wie kann sich ein Empfänger dauerhaft für den Empfang von Topics registrieren?}

Der Empfänger setzt zunächst mit \texttt{connection.setClientID("eindeutigerName")} eine eindeutige Client-ID. Anschließend wird anstelle eines normalen \texttt{MessageConsumer} ein \texttt{Topic}\allowbreak\texttt{Subscriber} über \texttt{session.createDurableSubscriber((Topic) topic, "{}eindeutigerName")} erzeugt. Der Server merkt sich diese dauerhafte Subscription und liefert alle Nachrichten aus, die während der Abwesenheit des Clients eingegangen sind, sobald der Client sich erneut verbindet.

    \item \textbf{Worum handelt es sich bei einer MDB?}

    Eine Message Driven Bean (MDB) ist ein von Jakarta EE bereitgestellter Bean-Typ, der ausschließlich dazu dient, asynchron eingehende Nachrichten aus einer Queue oder einem Topic zu verarbeiten. Sie wird vom Container in einem Pool verwaltet, benötigt keine Client-Interfaces und implementiert das Interface \texttt{jakarta.jms.MessageListener} mit der Methode \texttt{onMessage(Message)}.

    \item \textbf{Wie wird eine MDB erstellt? Gehen Sie insbesondere auf die zu verwendenden Annotationen ein.}

    Eine MDB wird als POJO erstellt und mit \texttt{@MessageDriven} annotiert. Die Klasse implementiert \texttt{jakarta.jms.MessageListener} und überschreibt \texttt{onMessage(Message)}. Die Zuweisung zu einer Queue bzw. einem Topic erfolgt über das \texttt{activationConfig}-Attribut der Annotation, das ein Array von \texttt{@ActivationConfigProperty}-Annotationen enthält. Wichtige Properties sind:
    \begin{itemize}
        \item \texttt{destinationType} – \texttt{jakarta.jms.Queue} oder \texttt{jakarta.jms.Topic}
        \item \texttt{destination} – JNDI-Name der Queue / des Topics
        \item \texttt{acknowledgeMode} – \texttt{AUTO\_ACKNOWLEDGE} oder \texttt{DUPS\_OK\_ACKNOWLEDGE}
        \item \texttt{messageSelector} – optionaler Filterausdruck
        \item \texttt{subscriptionDurability} – \texttt{durable} oder \texttt{nonDurable} (nur bei Topics)
    \end{itemize}
    Zusätzlich können per \texttt{@Resource} oder \texttt{@EJB} weitere Ressourcen injiziert werden.

    \item \textbf{Welchen Vorteil bieten MDBs gegenüber dem Vorgehen des Empfangs bei einem Stand-Alone-Client?}

    MDBs werden vollständig vom Container verwaltet. Der Container übernimmt das Verbindungsmanagement, die Lebenszyklus‑Steuerung, das Pooling sowie die Transaktionssteuerung. Der Entwickler muss sich nicht um das manuelle Erzeugen von Connections, Sessions oder Consumern kümmern und profitiert von automatischer Skalierung und robustem Fehlerverhalten. Stand‑Alone‑Clients erfordern hingegen expliziten Code für Verbindungsaufbau, Empfangsschleifen und Fehlerbehandlung.

    \item \textbf{JMS-Projekt: MDB und Client}

    \noindent\textbf{Message Driven Bean:}
    \inputminted[breaklines]{java}{../../server/src/main/java/org/example/demo/uebung3/aufgabe13/ReceiveQueueMessageAndSendAsMail.java}

    \noindent\textbf{Client:}
    \inputminted[breaklines]{java}{../../client/src/main/java/org/example/demo/uebung3/aufgabe13/Client.java}

\end{exercises}

\end{document}
