chap 5: Umsetzung — 11 Abschnitte + module-components/zip-stream/race-condition diagrams

This commit is contained in:
2026-08-25 20:33:15 +02:00
parent ce6b01626c
commit f857a244dd
17 changed files with 437 additions and 110 deletions
+29 -2
View File
@@ -1,5 +1,32 @@
\section{Anbindung des S3-Speichers}
\label{sec:s3-client}
% TODO: AWS SDK für .NET, IAmazonS3, keyed services in Program.cs, S3Settings (DEV/TEST/PROD Buckets)
% Abbildung~\ref{fig:s3-settings-registration}, \ref{fig:s3-documents-client}
\subsection{Zugriff über das AWS SDK}
Der Zugriff auf den Speicher erfolgt über das AWS SDK für .NET. Obwohl der Speicher nicht bei Amazon betrieben wird, ist dies der naheliegende Weg: StorageGRID implementiert die S3-Schnittstelle, und das SDK lässt sich über die Angabe einer abweichenden Dienstadresse auf einen beliebigen kompatiblen Endpunkt richten. Eine eigene Implementierung der Protokolldetails — insbesondere der Signaturberechnung — wäre aufwendig und fehleranfällig gewesen.
Der \texttt{S3DocumentsClient} kapselt die verwendeten Operationen. Er ist bewusst schmal gehalten und bietet nur die tatsächlich benötigten Zugriffe an: das Auflisten von Objekten unterhalb eines Präfixes, das Abrufen der Metadaten eines einzelnen Objekts, das Erzeugen zeitlich begrenzter Zugriffs-URLs, das Lesen eines Objektinhalts sowie — für die Ordnerverwaltung — das Anlegen, Kopieren und Löschen von Objekten.
Diese Kapselung erfüllt zwei Zwecke. Zum einen hält sie die SDK-spezifischen Anfrage- und Antworttypen aus der fachlichen Schicht heraus. Zum anderen ist sie die Voraussetzung dafür, den Speicherzugriff in Tests durch ein Mock zu ersetzen (siehe Abschnitt~\ref{sec:unit-tests}).
\subsection{Konfiguration mehrerer Speicher}
Eine Besonderheit ergab sich daraus, dass Houston bereits vor diesem Projekt einen S3-Speicher verwendete — für die Anbindung des Dokumentationssystems. Mit dem Dokumentenbereich kam ein zweiter, davon unabhängiger Speicher hinzu, mit eigenem Bucket und eigenen Zugangsdaten.
In der ersten Fassung wurden die Einstellungen des neuen Speichers als eigenständiger Satz von Konfigurationswerten geführt. Im Review wurde angeregt, stattdessen eine gemeinsame Struktur für S3-Einstellungen zu verwenden und die beiden Verwendungen über benannte Registrierungen im Dienstcontainer auseinanderzuhalten \autocite{dotnet-keyed-di}.
Der Vorteil dieser Lösung liegt in der Erweiterbarkeit: Ein dritter Speicher erfordert lediglich einen weiteren Konfigurationsabschnitt und eine weitere Registrierung, nicht aber eine erneute Verdopplung der Einstellungsklassen. Zudem ist an der Registrierung unmittelbar ablesbar, welcher Programmteil auf welchen Speicher zugreift — bei zwei gleichartig benannten Konfigurationssätzen wäre diese Zuordnung nur aus dem Kontext erkennbar gewesen.
\subsection{Umgebungen und Zugangsdaten}
Für die drei Umgebungen existiert je ein eigener Bucket. Die Trennung erfolgt damit nicht über Präfixe innerhalb eines gemeinsamen Buckets, sondern über getrennte Buckets mit getrennten Zugangsdaten. Ein fehlerhaft konfigurierter Entwicklungsstand kann dadurch nicht auf Produktivdaten zugreifen.
Die Zugangsdaten selbst liegen nicht im Quelltext, sondern werden über die Konfigurationsmechanismen der Anwendung bereitgestellt; hinterlegt sind sie im unternehmensweiten Passwortmanager. Für die lokale Entwicklung wurden die Entwicklungseinstellungen um die entsprechenden Werte ergänzt.
\subsection{Auflisten von Objekten}
Die zentrale Leseoperation ist das Auflisten von Objekten unterhalb eines Präfixes. Sie wird mit dem Kundenpräfix aufgerufen und liefert sämtliche Objekte des jeweiligen Kunden — über alle Typordner hinweg, da die Anzeige eine flache Liste ist.
Zwei Eigenschaften dieser Operation prägten die Umsetzung. Erstens liefert sie Ergebnisse blockweise: Überschreitet die Trefferzahl eine bestimmte Größe, wird ein Fortsetzungsmerkmal zurückgegeben, mit dem der nächste Block abgerufen werden kann \autocite{aws-listobjectsv2}. Diese Eigenschaft wurde für die Paginierung genutzt (siehe Abschnitt~\ref{sec:filter-pagination}). Zweitens liefert sie zwar Schlüssel, Größe und Änderungszeitpunkt, aber keine benutzerdefinierten Metadaten. Genau diese Einschränkung ist die Ursache des in Abschnitt~\ref{sec:lookup-research} beschriebenen Lookup-Problems.
Beim Auflisten werden zwei Arten von Einträgen herausgefiltert. Zum einen die Platzhalterobjekte, die die Typordner repräsentieren — sie sind technisch Objekte, fachlich aber keine Dokumente. Zum anderen der Marker des Kundenordners selbst. Beide erkennt der Dienst daran, dass ihr Schlüssel auf das Trennzeichen endet.