Verteilte Systeme WS 14/15 Übung 2

Werbung
Verteilte Systeme WS 14/15 ­ Übung 2 Für jede der unten stehenden Aufgaben ist im Maven­Template ein entsprechendes Package vorbereitet in welchem zu implementierende Interfaces/Klassen enthalten sind. Die Implementierungen werden auf Basis von JUnit­Tests überprüft und bewertet. Bitte halten Sie sich daher strikt an das vorgegebene Interface. Sollte die Implementierung nicht auf den vorgegebenen Interfaces basieren oder sollten diese verändert worden sein, wird die Lösung nicht bewertet. Die Abgabe muss in Form eines vollständigen (gezippten) Maven­Projekts erfolgen, welches die Lösungen beinhaltet. Die in den verschiedenen Aufgaben zu erstellenden Klassen (und ggf. Ressourcen) sind in die entsprechenden Packages zu verteilen (z.B. müssen sich alle für Aufgabe 2 relevanten Dateien im Package de.uniluebeck.itm.vs.exercise2.noxml.task2 befinden).
Nachrichtendarstellung Aufgabe 1: XML­basierte Serialisierung Machen Sie sich mit der “Java Architecture for XML Binding (JAXB)” vertraut. JAXB ist die Standard­Schnittstelle in Java zur Serialisierung und Deserialisierung von XML­Dokumenten. Auf Basis von Annotationen können Klassen an ein XML Schema gebunden werden. Im Verzeichnis src/main/resources/de/uniluebeck/itm/vs/exercise2/task1 des oben genannten Java­Projekts befinden sich einige XML Dokumente. Diese können Sie für eigene Tests verwenden. A) Erstellen Sie ein XML­Schema mit targetNamespace = http://itm.uniluebeck.de/vs/exercise2/task1, welches lediglich “menuRequest” und “menuResponse” als root­Elemente von XML­Dokumenten erlaubt (siehe MenuRequest.xml und MenuResponse.xml). Die anderen Beispiel­Dateien (DayOfYearElement.xml und MenuElement.xml) müssen beim Decodieren zu einer DecodingException führen. Mit dem xjc­Compiler von JAXB können Sie dann das Schema kompilieren, so dass automatisch die notwendigen annotierten Klassen aus den in Ihrem Schema definierten Elementen und nicht anonymen Typen erstellt werden: xjc pfad/zum/schema/name_des_schemas.xsd
Nur die durch xjc erstellten Klassen mit der Annotation @XmlRootElementdürfen
root­Elemente eines XML­Dokuments sein. Vergleichen Sie die aus Ihrem Schema erstellten Klassen mit der Musterlösung im Package de.uniluebeck.itm.vs.exercise2.task1.generated. Hinweis: Mit Hilfe der im Folgenden fett gedruckten Attribute in Ihrem Schema können Sie die von JAXB erstellten Klassennamen beeinflussen: <xs:schema targetNamespace="http://itm.uniluebeck.de/vs/exercise2/task1"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
jaxb:version="2.1"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://itm.uniluebeck.de/vs/exercise2/task1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/jaxb
http://www.oracle.com/webfolder/technetwork/jsc/xml/ns/jaxb/bindingschema_2_0.xsd">
<xs:complexType name="MenuType">
<xs:annotation>
<xs:appinfo>
<jaxb:class name="Menu"/>
</xs:appinfo>
</xs:annotation>
<xs:sequence>
<xs:element name="dish" type="DishType" minOccurs="0" maxOccurs="3"/>
</xs:sequence>
</xs:complexType>
.
.
</xs:schema>
Ohne die fett gedruckten Abschnitte hätte der xjc­Compiler eine Klasse “MenuType” erstellt. So wird stattdessen eine Klasse mit Namen “Menu” erstellt. Abgabe: keine (diese Aufgabe ist nur für Versuche mit JAXB und dem xjc­Compiler) B) Implementieren Sie die Klassen JAXBDecoder und JAXBEncoder. Beachten Sie dabei, dass der Decoder eine DecodingExceptionund
der Encoder eine EncodingExceptionwerfen
muss, wenn beim Encoding bzw. Decoding ein Fehler auftritt. Hinweis: Die Überprüfung von Typenbeschränkungen (Constraints) muss nicht durch Ihre Implementierung abgedeckt werden, da JAXB hier keine einfache annotationsbasierte Möglichkeit bietet. Die Validierung von Constraints ist daher bei JAXB standardmäßig deaktiviert und ist nur mit relativ großem Aufwand in Kombination mit der Schemadatei realisierbar. Wenn Sie an mehr Details dazu interesseiert sind, dann lesen Sie hier weiter: http://blog.bdoughan.com/2010/12/jaxb­and­marshalunmarshal­schema.html. Abgabe: Implementierungen von De­ und Encoder im Package de.uniluebeck.itm.vs.exercise2.task1 Aufgabe 2: Maßgeschneiderte Serialisierung Angelehnt an die Aufgabenstellung aus Übung 1 sollen jeweils Encoder und Decoder für eine Maßgeschneiderte Serialisierung entwickelt werden. Im Unterschied zum Serialisierungsformat auf Übungsblatt 1 sind jedoch die einzelnen Felder nicht bis auf das letzte Bit optimiert, sondern verwenden jeweils ein volles Byte bzw. mehrere volle Bytes um die Implementierung zu erleichtern. Die folgende Tabelle definiert das Serialisierungsformat für beide Datentypen (MenuRequest und MenuResponse): Feld Datentyp Beschreibung Kommentar Type Unsigned Int 1 Byte Typ des Pakets Type=0: Request Type=1: Response 0 <= Type <= 1 DayOfYear Unsigned Int 2 Byte Tag des Jahres 1 <= DayOfYear <= 366 DishCount (nur bei Response vorhanden) Unsigned Int 1 Byte Anzahl der Gerichte Bestimmt die Anzahl der Wiederholungen der Felder DescriptionLength und Description 0 <= DishCount <= 3 PriceInCent (nur bei Response vorhanden) Unsigend Int 2 Byte Preis des Gerichts in Cent PriceInCent >= 0 DescLength (nur bei Response vorhanden) Unsigned Int 1 Byte Länge des Description­Felds in Bytes 0 <= DescLength <= 255 Description (nur bei Response vorhanden) ASCII­kodierter String (8 Bit pro Zeichen) String Alle entsprechenden Klassen (MenuRequest.java, MenuResponse.java, Dish.javaund
Menu.java) finden Sie im Package de.uniluebeck.itm.vs.exercise2.noxml.messages. Implementieren sie die Klassen ● MenuRequestDecoder, ● MenuRequestEncoder, ● MenuResponseDecoder und ● MenuResponseEncoder aus dem Package de.uniluebeck.itm.vs.exercise2.noxml.task2. Die folgenden Randbedingungen müssen bei der Implementierung beachtet werden: ● Implementieren Sie Ihre Decoder und Encoder so, dass empfangene Daten validiert werden. Sind die “empfangenen” Daten nicht valide dann soll der Decoder eine DecodingExceptionwerfen,
der Encoder eine EncodingException. Dies ist z.B. der Fall, wenn ein Wert nicht im gültigen Wertebereich liegt oder z.B. das Feld DishCountmehr
oder weniger Gerichte zählt als im Paket enthalten sind. ● Das Paketformat muss (insbesondere beim Empfang) strikt überprüft werden. Zu dekodierende Pakete, die nicht exakt in jedem Detail der Definition entsprechen und zum Beispiel inkonsistente Werte enthalten (Längenangabe stimmt nicht mit der tatsächlich empfangen Anzahl an Bytes überein, ...) müssen als fehlerhaft behandelt werden und eine DecodingExceptiongeworfen
werden. ● Achten Sie auf Byte­Reihenfolge (Network Byte Order). ● Beachten Sie, dass Java keine unsigned­Datentypen enthält, die Protokolldefinition jedoch schon. ● Bei der Implementierung des ResponseEncoders und des ResponseDecoderskann
davon ausgegangen werden, dass der String für das Feld Descriptionnur
ASCII­kompatible Zeichen enthält. Abgabe: Implementierungen aller De­ und Encoder im Package de.uniluebeck.itm.vs.exercise2.noxml.task2 Nachrichtentrennung In diesem Aufgabenblock soll die Trennung mehrerer Nachrichten mit zwei verschiedenen Verfahren realisiert werden. Dadurch können mehrere Nachrichten (z.B. MenuRequests) auf einmal verschickt werden. Die Serialisierung der einzelnen Nachrichten erfolgt z.B. durch den in Aufgabe 2 realisierten Encoder. Diese serialisierten Einzelnachrichten sind danach durch das jeweilige Trennverfahren getrennt in ein byte­Array zu schreiben. Die zu realiserenden Decoder verfahren in umgekehrter Reihenfolge indem sie zunächst das zu deserialisierende byte­Array in einzelne serialiserte Nachrichten auftrennen, welche dann elementweise deserialisiert werden. Für die Realisierung beider Verfahren gilt: ● Sollte die dem Encoder übergebene Liste zu serialisierender Objekte die Länge 0 haben, so muss auch das resultierende byte­Array die Länge 0 haben, d.h. leer sein. ● Sollte der Decoder ein byte­Array der Länge 0 empfangen, so muss auch eine leere Liste des deserialisierten Typs zurück gegeben werden. ● Sollte ein durch den elementEncoderserialisiertes
Objekt die Länge 0 haben, so muss dieses Element dennoch durch ein Längenfeld im resultierenden byte­Array repräsentiert werden. ● Sollte in einem zu deserialisierenden byte­Array ein Längenfeld mit dem Wert 0 vorkommen dann soll dennoch ein leeres byte­Array zwecks Dekodierung an den elementDecoderübergeben
werden. Aufgabe 3: Nachrichtentrennung auf Basis von Längenfeldern Implementieren Sie jeweils einen Encoder und einen Decoder, welcher Nachrichten auf Basis von Längenfeldern trennt. Ein Längenfeld soll hierbei einen 32­bit Integer (d.h. 4 Bytes in Network Byte Order) enthalten. Jedes Längenfeld gibt die Länge der folgenden Nachricht in Bytes an. Die Implementierung erfolgt in den Klassen ● LengthFieldEncoder und ● LengthFieldDecoder im Package de.uniluebeck.itm.vs.exercise2.noxml.task3. Abgabe: Implementierungen von De­ und Encoder im Package de.uniluebeck.itm.vs.exercise2.noxml.task3 Aufgabe 4: Nachrichtentrennung über DLE STX … DLE ETX­Framings Implementieren Sie jeweils einen Encoder und einen Decoder, welcher Nachrichten auf Basis des aus der Vorlesung bekannten Byte Stuffing trennt. Der Paketanfang wird dabei mit den 2 Bytes DLE (Data Link Escape, 0x10) und STX (Start of Text, 0x02) markiert, das Paketende mit den 2 Bytes DLE und ETX (End of Text, 0x03). Das Byte­Stuffing im Inneren des Pakets erfolgt durch das Einfügen eines zusätzlichen DLE­Zeichens vor jedes im Inneren enthaltene DLE­Zeichen. Beachten Sie dass es möglich ist, dass Nachrichten nicht unmittelbar aufeinander folgen. Bytes vor, zwischen und nach einzelnen Nachrichten sind daher als Übertragungsfehler zu betrachten und zu ignorieren. Solche Übertragungsfehler könnten zum Beispiel durch Rauschen auf dem Übertragungsmedium entstehen. Abgabe: Implementierungen von De­ und Encoder im Package de.uniluebeck.itm.vs.exercise2.noxml.task4 
Herunterladen