Institut für Architektur von Anwendungssystemen Universität Stuttgart Universitätsstraße 38 D–70569 Stuttgart Bachelorarbeit Konzept und Implementierung einer TOSCA-basierten Lösung zur Provisionierung von IoT Devices Dominik Wagner Studiengang: Softwaretechnik Prüfer/in: Prof. Dr. Dr. h. c. Frank Leymann Betreuer/in: Dipl.-Inf. Lukas Reinfurt, Michael Falkenthal, M.Sc. Beginn am: 19. Juni 2017 Beendet am: 19. Dezember 2017 Kurzfassung Das Internet of Things ist ein neuer Trend der das Potenzial hat viele Bereiche des Lebens zu ver- ändern [AIM10]. Das Verbinden von physikalischen Objekte untereinander oder mit dem Internet bietet viele Möglichkeiten. Sensoren können zum Beispiel den Verkehrsfluss analysieren und ihn über Aktuatoren wie Ampeln steuern. Es existieren viele Bereiche in denen IoT Anwendungen den Menschen unterstützen können. Dazu zählen unter anderem Logistik, Smart Home oder das Gesundheitswesen [AIM10]. Abhängig von der Anwendung werden verschiedenste Geräte im Internet der Dinge eingesetzt. Die kleinsten bestehen oft nur aus einem RFID Tag, während die leistungsstärksten Dinge mit Desktop PCs vergleichbar sind. Auch bei den Kommunikationstech- nologien gibt es große Unterschiede. Geräte können zum Beispiel über WLAN, Bluetooth oder kabelgebunden über unterschiedlich Protokolle wie HTTP oder MQTT kommunizieren. Darüber hinaus werden IoT Geräte oft in großer Anzahl eingesetzt. All diese Geräte müssen mit Software und Konfiguration bespielt werden, was aus mehrere Gründen schwierig ist. Zunächst sind die Geräte sehr unterschiedlich und haben keine einheitliche Schnittstelle um Software und Konfigu- ration zu übertragen. Weiterhin ist das manuelle Installieren von Software sehr fehleranfällig und teuer, vor allem wenn viele Geräte eingesetzt werden. Zusätzlich wiederholt sich der Aufwand für das Provisionieren bei jedem Update. Deshalb sollten IoT Geräte automatisch provisioniert werden. Für Cloud-Umgebungen gibt es die Topology and Orchestration Specification for Cloud Applications (TOSCA) von OASIS die es erlaubt komplexe Cloud-Anwendungen zu modellieren und automatisch zu provisionieren [OAS13b]. Die Modelle sind dabei Cloud-Anbieter unabhängig [OAS13b]. In dieser Arbeit werden mehrere Konzepte vorgestellt um IoT Geräte mit TOSCA zu modellieren, um so die Komplexität zu reduzieren und eine automatische Provisionierung zu er- möglichen. Hierfür werden Geräte aus unterschiedlichen Leistungsklassen und Rollen untersucht. Neben den Geräten lassen sich auch die anderen Komponenten einer IoT Umgebung mit TOSCA modellieren und provisionieren. 3 Inhaltsverzeichnis 1 Einleitung 13 1.1 Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 1.2 Ziele . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 2 Grundlagen 17 2.1 Internet of Things . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 2.2 Topology and Orchestration Specification for Cloud Applications (TOSCA) . . . 18 2.3 Geräte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 2.4 Linux Container . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 2.5 MQTT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 2.6 Related Work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 3 Lösungskonzepte 33 3.1 Constrained devices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 3.2 Unconstrained devices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 4 Implementierung der Prototypen 53 4.1 Beschreibung des Prototyps für das NodeMCU . . . . . . . . . . . . . . . . . . . 53 4.2 Beschreibung des Prototyps für den Raspberry Pi . . . . . . . . . . . . . . . . . 61 4.3 Beschreibung des Prototyps für die MICA . . . . . . . . . . . . . . . . . . . . . . 63 4.4 Anwendungsszenario . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 5 Zusammenfassung und Ausblick 69 Literaturverzeichnis 71 5 Abbildungsverzeichnis 2.1 Internet of Things Komponenten . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 2.2 Elemente eines Service Templates . . . . . . . . . . . . . . . . . . . . . . . . . . 19 2.3 WordPress Topologie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 2.4 NodeMCU . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 2.5 Raspberry Pi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 2.6 MICA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 2.7 Architektur von IoT Geräten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 2.8 Container Virtualisierung Architektur . . . . . . . . . . . . . . . . . . . . . . . . 27 3.1 Constrained device Topologie . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 3.2 Node Template eines Linux Container Node Types. . . . . . . . . . . . . . . . . 40 3.3 Modellierungsansatz: Smart TOSCA Container . . . . . . . . . . . . . . . . . . . 42 3.4 Modellierungsansatz: Smart Containerhost . . . . . . . . . . . . . . . . . . . . . 45 3.5 Modellierungsansatz: Unterschiedliche Node Types . . . . . . . . . . . . . . . . 47 4.1 MQTT Nachrichtenformat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 4.2 Kommunikationsstruktur für den NodeMcuManager . . . . . . . . . . . . . . . 56 4.3 Topologie für einen MQTT Server . . . . . . . . . . . . . . . . . . . . . . . . . . 58 4.4 Prototyp Raspberry Pi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 4.5 Prototyp MICA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 4.6 Anwendungsszenario . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 4.7 Dashboard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 7 Tabellenverzeichnis 2.1 Klassen von constrained devices . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 3.1 Lifecycle Interface der NodeMCU_App . . . . . . . . . . . . . . . . . . . . . . . 36 3.2 Auswertung der Modellierungsansätze . . . . . . . . . . . . . . . . . . . . . . . 49 4.1 Lifecycle Interface des LXContainerRaspberryPi Node Type . . . . . . . . . . . 63 9 Verzeichnis der Listings 4.1 Minimal Bootstrap NodeMcuManager . . . . . . . . . . . . . . . . . . . . . . . . 59 11 1 Einleitung Das Internet of Things (IoT, auf Deutsch: Internet der Dinge) bezeichnet das Konzept sogenannte Dinge untereinander oder mit dem Internet zu verbinden [AIM10]. Ein Ding kann über Sen- soren, Aktuatoren und verschiedenste Kommunikationstechnologien verfügen [AIM10]. Die Verbundenheit ermöglicht das Zusammenarbeiten der Dinge untereinander oder mit Services die im Internet verfügbar sind. Das Internet of Things kann Menschen in vielen Bereichen des Le- bens unterstützen, zum Beispiel bei Heimautomatisierung, Transport oder im Gesundheitswesen [AIM10]. Straßen oder Autos mit entsprechender Sensorik könnten einen Stau melden und eine andere Routenführung für den nachfolgenden Verkehr vorschlagen [AIM10]. Auch könnte eine Heimautomatisierung eine zentrale Steuerung für Heizung, Lichter und Entertainment-Systeme anbieten, die vom Nutzer zuhause oder von einem mobilen Endgerät benutzt werden kann. Die Dinge sollen eine hohe Integration in die Umgebung erreichen und möglichst unsichtbar für die Nutzer agieren. Am Markt existieren sehr viele verschiedene IoT Geräte. Sie verwenden unterschiedliche Datenmodelle und Protokolle zur Kommunikation [FBH+17]. Gartner erwartet dass bis 2020 ca. 20 Milliarden solcher, auch als smarte Geräte bezeichneten, Dinge im Einsatz sind [Meu17]. Durch die Dinge werden große Datenmengen erfasst, die gefiltert oder verarbeitet werden müssen [GBMP13]. Meistens können die Dinge die Daten nicht lokal verarbeiten da der größere Kontext fehlt oder nur wenig Rechenleistung zu Verfügung steht. Darüber hinaus sind viele der Dinge batteriebetrieben, was eine rechenintensive Verarbeitung einschränkt. Bei der Datenverarbeitung und bei der Koordination der Dinge kann zum Beispiel Cloud-Computing helfen. Cloud-Computing bedeutet, dass Nutzer über das Internet einen einfachen Zugriff auf einen Pool von Ressourcen nach dem On-Demand Prinzip erhalten [MG+11]. Die Ressourcen können zum Beispiel Speicherplatz, Rechenleistung oder auch komplette Anwendungen als Ser- vice sein [MG+11]. Daten die von den einzelnen Dingen erfasst wurden, können über Gateways oder direkt in die Cloud zum Verarbeiten weitergeleitet werden [GBMP13]. Mit der Topology and Orchestration Specification for Cloud Applications (TOSCA) [OAS13b] existiert ein Standard zum Modellieren, Provisionieren und Managen von komplexen Cloud-Anwendungen. Mithilfe von TOSCA kann die Topologie der jeweiligen Anwendung in einer portablen Form beschrieben werden. 1.1 Motivation Es existieren viele unterschiedliche Lösungen und Produkte im IoT Umfeld. Manche Dinge nutzen WLAN oder Ethernet zur Kommunikation, andere zum Beispiel Bluetooth Low Energy1, 6LoW- PAN2, ZigBee3, NFC oder RFID [AIM10]. Darüber hinaus gibt es noch viele unterschiedliche 1https://www.bluetooth.com (zuletzt besucht 17.12.2017) 2https://tools.ietf.org/html/rfc4944 (zuletzt besucht 17.12.2017) 3http://www.zigbee.org/ (zuletzt besucht 17.12.2017) 13 1 Einleitung Protokolle welche über die gerade genannten Technologien übertragen werden. Hier sind zum Beispiel MQTT4, MQTT-SN5, CoAP6 oder HTTP zu nennen. Auch die einzelnen Dinge sind sehr unterschiedlich, sie haben verschiedene Sensoren oder Aktuatoren, manche haben viel Rechen- leistung und Speicher, andere haben nur vergleichsweise begrenzte Kapazitäten [BEK14; FBH+17]. Darüber hinaus gibt es auch Unterschiede in der Stromversorgung, hier reicht die Bandbreite von passiv mit Strom versorgten Dingen, über batteriebetriebene Dinge, zu Dinge mit Netzbetrieb [BEK14]. Zudem können Dinge in unterschiedlichen Rollen agieren, das heißt mit einer Konfigu- ration agieren sie zum Beispiel nur als Sensorknoten und mit einer anderen Konfiguration agieren sie als Gateway. Die Art und Weise wie Software- oder Konfigurationsupdates auf die Dinge übertragen werden, hängt von den jeweiligen Dingen ab. Hier gibt es viele verschiedene Ansätze. Diese Heterogenität endet nicht mit den Geräten. Es gibt eine große Anzahl an verschiedenen IoT Middleware und Plattformen, Postscapes [Pos] listen 123 verschiedene. Franco da Silva et al. [FBH+17] zählen Message Broker zu der IoT Middleware und somit steigt die Zahl an mögli- chen Kombinationen weiter. Über die Middleware erhalten Anwendungen Zugriff auf die Daten und die Funktionalität der Dinge [FBH+17]. IoT Anwendungen können aber unterschiedliche Middleware voraussetzen [FBH+17]. Ein weiterer Aspekt der berücksichtigt werden sollte, ist die Speicherung der anfallenden Daten. Diese können zum Beispiel in einer cloudbasierten Lösung oder vor Ort in eine Datenbank gespeichert werden. Hier gibt es viele Möglichkeiten. Um diese Vielfältigkeit zu meistern, wird in Zukunft noch viel Arbeit und Forschung benötigt. In dieser Bachelorarbeit werden mehrere Konzepte vorgestellt, um die einzelnen Geräte zu modellieren und zu provisionieren. Mithilfe des Models können die Geräte auf eine einheitliche Weise ange- sprochen werden. Durch diese Abstraktion ist eine automatische Provisionierung möglich ohne die Eigenschaften der Geräte genauer zu kennen. Alle Informationen die zum Provisionieren benötigt werden, sind im Model enthalten. Dazu zählen unter anderem eine IP-Adresse oder Zugangsdaten. Die Modelle enthalten auch eine Schnittstelle um den Lebenszyklus der Geräte oder der Anwendungen die repräsentiert werden zu steuern. Dies kann verwendet werden um zum Beispiel auf den Geräten Software zu installieren oder Konfiguration zu ändern. Dabei ist es egal ob die eigentliche Kommunikation mit dem jeweiligen Gerät über SSH, MQTT oder eine andere Technologie stattfindet. Die modellierten Geräte lassen sich dann in eine Topologie einfügen, welche die Abhängigkeiten von den Geräten und den Komponenten einer IoT Umgebung darstellt. Wenn die gesamte Topologie automatisch provisioniert wird, können keine Geräte und keine Abhängigkeiten vergessen werden. Diese Topologie kann die Geräte, die Software welche auf ihnen läuft, die eventuell benötigte Middleware, die IoT Anwendungen und zum Beispiel eine Datenbank enthalten. Die Topologien können dabei sehr viel Geräte enthalten und es entfällt das aufwendige und fehleranfällige manuelle Provisionieren aller Geräte. Zur Repräsentation wird TOSCA verwendet, mit dem schon jetzt der gesamte cloudbasierte Teil einer IoT Umgebung modelliert und provisioniert werden kann [BBKL14; FBH+17]. 4http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html (zuletzt besucht 17.12.2017) 5http://mqtt.org/new/wp-content/uploads/2009/06/MQTT-SN_spec_v1.2.pdf (zuletzt besucht 17.12.2017) 6https://tools.ietf.org/html/rfc7252 (zuletzt besucht 17.12.2017) 14 1.2 Ziele 1.2 Ziele Um die Geräte die in einem IoT Umfeld vorkommen, in einer TOSCA Topologie zu repräsentieren werden sogenannte Node Types benötigt. Es ist daher Ziel dieser Arbeit Node Types für drei ausgewählte Geräte zu entwickeln. Es ergeben sich folgende Aufgaben: 1. Konzeption von TOSCA Node Types zur Abstraktion der Konfiguration der Basisbetriebs- systeme der IoT Geräte Harting MICA, Raspberry Pi und NodeMCU 2. Erweiterung der Node Types um ein Installationsinterface für zusätzliche Softwarekompo- nenten 3. Definition eines Anwendungsszenarios mit zusätzlich zu installierenden Softwarekompo- nenten als Basis für eine Implementierung der Node Types 4. Modellierung und Implementierung der Node Types sowie des Anwendungsszenarios mittels Winery7 und OpenTOSCA8 Hierbei sollte eine Klassifizierung der einzelnen Geräte vorgenommen und eine oder mehrere Lösungsstrategien entwickelt werden die nicht nur auf die ausgewählten Geräte passen. Gliederung Die Arbeit ist in folgender Weise gegliedert: Kapitel 2 – Grundlagen: In den Grundlagen werden Technologien und Konzepte erklärt auf denen die Arbeit aufbaut. Das beinhaltet unter anderem eine Beschreibung von TOSCA, den einzelnen Geräten und Related Work. Kapitel 3 – Lösungskonzepte: In diesem Kapitel werden die Konzepte für die unterschiedli- chen Klassen von Geräte vorgestellt und analysiert. Für jede Klasse wird der Modellie- rungsansatz beschreiben und die Umsetzung in TOSCA erklärt. Es wird auch auf mögliche alternative Modellierungsansätze eingegangen. Kapitel 4 – Implementierung der Prototypen: Hier werden die Prototypen welche, nach den Konzepten aus dem vorherigen Kapiteln, entwickelt wurden vorgestellt. Sie dienen auch als Ansatzpunkt für Entwickler die Node Types für ähnliche Geräte konzeptionieren und implementieren müssen. Ein Anwendungsszenario das den Einsatz der Prototypen und der Konzepte beispielhaft demonstriert befindet sich am Ende des Kapitels. Kapitel 5 – Zusammenfassung und Ausblick: Beinhaltet eine Zusammenfassung der Ergeb- nisse dieser Arbeit und stellt Anknüpfungspunkte für zukünftige Arbeiten vor. 7https://projects.eclipse.org/projects/soa.winery (zuletzt besucht 17.12.2017) 8http://www.opentosca.org/(zuletzt besucht 17.12.2017) 15 2 Grundlagen 2.1 Internet of Things Sensoren Aktuatoren Verarbeitung Kommunikation Kommunikation Gateway Daten- verarbeitung Geräte- management Kommunikation Anwendungen Andere Komponenten Geräte Backend Server Abbildung 2.1: Zeigt die Komponenten eines IoT Szenarios [basiert auf RBF+16]. In Zukunft könnten viele Geräte des täglichen Lebens über das Internet miteinander interagieren. RFID Tags erlauben zum Beispiel heute schon in Firmen die Verfolgung eines Werkstücks durch die komplette Produktion. Auch könnten Parkplätze die über entsprechende Sensoren verfügen über das Internet Informationen zu freie Parkplätze an Navigationssysteme übermitteln. Das Verbinden von Geräten oder Dingen mit- und untereinander wird auch als Internet of Things bezeichnet [AIM10]. Die verbundenen und adressierbaren Geräte sammeln Daten, interagieren mit Menschen, anderen Geräten oder Services im Internet um neue Dienste für private Benutzer oder Firmen zu ermöglichen. Dieses verteilte dynamische Netzwerk besteht aus heterogen Geräten. Die schwächsten Geräte im Punkt Arbeitsspeicher und Prozessorleistung haben oft zu wenig Leistung um sicher mit dem Internet kommunizieren zu können und benötigen Gateways um die Daten weiterzuleiten [BEK14]. Die leistungsfähigsten Geräte sind oft mit handelsüblichen Computern vergleichbar [BEK14]. Das Internet der Dinge bietet aber nicht nur Möglichkeiten, sondern hat auch Herausforderungen wie, zum Beispiel schlechte Verbindungsqualität der verwendeten Netz- werke, unterschiedliche Standards und Datenformate oder hohe Kosten für die Provisionierung und die Wartung von einer großen Anzahl an Geräten. Wie 2016 das Mirai IoT Botnet gezeigt hat 17 2 Grundlagen ist eine weitere wichtige Herausforderung die Sicherheit der verwendeten Geräte [BI17]. Also sollten gefundene Sicherheitslücken durch Updates behoben werden. Außer den Geräten gibt es oft noch mehrere andere Komponenten die in einer IoT Umgebung vorkommen. Eine Middleware vermittelt zwischen den Geräten und den Anwendungen [AIM10]. Sie abstrahiert den Zugriff auf die Geräte und Daten die sie produzieren. Dadurch verringert sich die Komplexität für den Entwickler von IoT Anwendungen. Er muss nicht die Details von jedem Gerät und jeder Kommu- nikationstechnologie kennen um die Geräte nutzen zu können. So muss er nicht wissen das zum Beispiel ein Teil der Geräte MQTT und ein anderer ein REST Interface zur Datenübermittlung nutzt. Für den Entwickler einer Anwendung funktioniert durch die Middleware die Interaktion mit den Geräten auf die gleiche Weise. Eine weitere Komponente von IoT Umgebungen sind die Anwendungen. Sie können auf der Middleware aufbauen und bieten dem Endnutzer die Funktionalität des Systems [AIM10]. Ein Dashboard das alle Sensordaten visualisiert oder eine App für ein Smartphone mit der sich alle Geräte eines Smart Home Szenarios steuern lassen sind zum Beispiel solche Anwendungen. 2.2 Topology and Orchestration Specification for Cloud Applications (TOSCA) Cloud-Computing erlaubt den Zugriff auf einen Pool von Ressourcen nach dem On-Demand Prinzip [MG+11]. So können zum Beispiel Speicherplatz, Rechenleistung oder auch Services nach Bedarf genutzt werden [MG+11]. Der Nutzer kann die Ressourcen dynamisch hinzufügen oder entfernen. So kann ein Onlineshop mehr Leistung nutzen, wenn er ein Angebot veröffentlicht oder weniger Leistung buchen, wenn nachts nicht viele Kunden bestellen. Er bezahlt dabei nur für die tatsächlich genutzten Ressourcen. Der Shop könnte auch einige Teile seiner Infrastruktur wie die Datenbank oder das Shopsystem als Service von einem Cloud-Anbieter beziehen. So benötigt er kein eigenes Fachwissen und kein Personal in diesem Bereich. Nutzer heutiger Cloud-Lösungen schätzen die Flexibilität die Cloud-Computing bietet. Doch durch die Nutzung eines bestimmten Anbieters entsteht laut Armbrust et al. [AFG+10] und Kratzke [Kra14] ein Vendor Lock-In oder Data Lock-In. Dieser hält einen Nutzer davon ab den Cloud-Anbieter zu wechseln oder mehrere Anbieter für eine bessere Verfügbarkeit zu kombinieren. Armbrust et al. [AFG+10] identifizierten dieses Problem als einen der Hauptbeweggründe gegen die Nutzung von Cloud-Computing. Um dieses Problem zu lösen wurde 2013 von OASIS die TOSCA Spezifikation 1.0 veröffentlicht [BSW14; OAS13b]. TOSCA ermöglicht das Modellieren von komplexen Cloud-Anwendungen in einer portablen Form und erleichtert so die Provisionierung und das Management über die Grenzen von einem Cloud-Anbieter hinweg [BSW14; OAS13b]. Die Spezifikation sieht in der Version 1.0 eine XML-basierte Sprache zur Beschreibung von Cloud-Anwendungen vor [OAS13b]. Es existieren auch neuere Versionen des Simple Profile welche auf YAML basieren [OAS13c]. Im Weiteren wird aber nur die XML Version (1.0 Version) betrachtet. Die Beschreibung der Cloud- Anwendung enthält die Topologie aus der die Anwendung besteht. Die Topologie ist ein gerichteter Graph der nicht zusammenhängend sein muss, dieser wird als Topology Template bezeichnet. In Abbildung 2.2 sind die Elemente eines Topology Templates dargestellt. Die Knoten im Topologie Template werden als Node Templates bezeichnet und repräsentieren die Komponenten aus denen eine Anwendung besteht. Die Kanten in dem Graph werden als Relationship Templates bezeichnet. Diese drücken aus wie die Komponenten in Beziehung zueinanderstehen. Wie in Abbildung 2.2 18 2.2 Topology and Orchestration Specification for Cloud Applications (TOSCA) Node Template Relationship Template }{ P ro p e rt ie s Interfaces Node Types Relationship Templates }{ P ro p er ti es In terfaces type of type of Topology Template Plans Service Template Abbildung 2.2: Elemente eines Service Templates [Basiert auf OAS13b]. zu sehen ist sind alle Templates typisiert. So haben Node Templates Node Types als Typen und Relationship Templates Relationship Types als Typen. Die Typen sind wiederverwendbar und können in mehreren Typologien enthalten sein [BBKL14]. Ein konkretes Beispiel anhand von WordPress ist in der Abbildung 2.3 gezeigt. Hier wird durch die HostedOn Verbindung zwischen den Knoten Apache und WordPress ausgedrückt, dass WordPress auf dem Apache Webserver gehostet wird [BBH+13]. Der ApacheWebserver läuft auf Ubuntu 16.04 welches in einer virtuellen Maschine läuft. Die Virtuelle Maschine wird von der Amazon Server Cloud bereitgestellt. Die Datenbank MySQL läuft auf einem ähnlichen Stack und ist über das ConnectsTo“ Relationship Template mit WordPress verbunden. Über DependsOn wird im Topology Template ausgedrückt, dass WordPress das PHPModule benötigt. In TOSCA wird die Verarbeitung von Service Templates in der imperativen und in der deklarativen Art unterstützt [OAS13a]. Bei der deklarativen Art wird modelliert was in der Topologie enthalten ist. Das genaue Verhalten welches zum Provisionieren und Management benötigt wird, kann anhand der verwendeten Node Types und der Struktur der Topologie bestimmt werden [OAS13a]. So wird im Beispiel in Abbildung 2.3 definiert das Ubuntu auf einem Virtuellen Server bei Amazon laufen soll, die exakten Schritte um das zu erreichen sind aber nicht vorhanden. Die ausführende TOSCA Umgebung, welche auch als TOSCA Container bezeichnet wird, muss hier durch einen Model Interpreter die nötigen Schritte erkennen [OAS13a]. Anhand des Relationship Templates zwischen dem Betriebssystem und dem virtuellen Server kann zum Beispiel erkannt werden, dass der virtuelle Server vor dem Betriebssystem provisioniert wer- den muss [OAS13a]. Bei der imperativen Art werden Pläne zum Topology Template hinzugefügt [OAS13a]. Diese definieren welche Schritte erfolgen müssen um ein bestimmtes Node Template oder das gesamte Topology Template zu provisionieren. Ein solcher Plan zu dem in Abbildung 2.3 dargestellten Topology Template könnte zum Beispiel vorgeben dass zuerst die install-Operation auf dem Apache Webserver aufgerufen werden muss, bevor die install-Operation bei WordPress 19 2 Grundlagen PHPModule (PHPModule) Apache (ApacheWebServer) Betriebssystem (Ubuntu-16.04 VM) Virtual Server (AWS EC2 Server) WordPress (WebApplication) MySQL DB (MySQL-DB) MySQL DBMS (MySQL-DBMS) Betriebssystem (Ubuntu-16.04 VM) Virtual Server (OpenStack Liberty) ConnectsTo HostedOn DependsOn Abbildung 2.3: Das Topology Template enthält die Struktur einerWordPress Anwendung welche eine Datenbank und einen Webserver benötigt. Basiert auf [Basiert auf BBH+13]. aufgerufen werden kann. Der Model Interpreter welcher beim deklarativen Ansatz verwendet wird, hätte hier die gleiche Reihenfolge bestimmt. Diese Pläne in Verbindung mit einem Topology Template ergeben ein Service Template [OAS13a]. Viele Node Templates benötigen zusätzliche Artefakte um zu funktionieren. Das WordPress Node Template könnte zum Beispiel ein komprimiertes Archiv mit den Installationsdateien benötigen, welches auf dem Apache Webserver entpackt wird. Solche Artefakte werden Deployment Artifacts genannt [OAS13a]. Diese Artefakte werden benötigt um den Node Templates das Erfüllen ihrer Aufgaben zu ermöglichen. Außerdem gibt es die Implementation Artifacts welche die Management Operationen implementieren. Zum Beispiel die install-Operation oder auch die start- und stop- Operationen, welche oft von Node Templates implementiert werden, sind durch Implementation Artifacts realisiert. Auch hier sind beide Arten von Artefakte mit einem Typen versehen, dem Artifact Type [OAS13a]. Natürlich muss der verwendete TOSCA Container diese Typen von den Implementation Artifacts kennen, sonst kann er die Management Operationen nicht ausführen. Häufig verwendete Typen im OpenTOSCA1 Ökosystem sind Skript und WAR. Bei dem Skript Typen werden Bash-Skripte genutzt um die Management Operationen zu implementieren und bei dem WAR Typen Java Web Anwendungen [BSW14; OAS13a; OAS13b]. Die Node Types können Properties und Interfaces definieren [OAS13b]. Bei der Erstellung eines Node Templates von einem Node Type der Properties definiert hat, können den Properties Werte zugewiesen werden. Die Interfaces die in einem Node Type definiert sind, werden von den Implementation Artifacts implementiert und geben an welche Operationen auf einem Node Template von dem Node Type zulässig sind [OAS13a; OAS13b]. Jede Operation in einem Interface kann keinen, einen, oder mehrere Parameter haben [OAS13a; OAS13b]. Das Lifecycle Interface wie es in „Topology and Orchestration Specification for Cloud Applications (TOSCA) Primer Version 1.0“ [OAS13a] beschrie- 1http://www.opentosca.org/(zuletzt besucht 17.12.2017) 20 2.2 Topology and Orchestration Specification for Cloud Applications (TOSCA) ben ist besteht aus den Operationen install, configure, start, stop und uninstall. Diese Operationen repräsentieren den Lebenszyklus einer Komponente. Node Types können Requirements und Ca- pabilities deklarieren, um Abhängigkeiten zwischen Node Types auszudrücken [OAS13a]. Eine Anwendung für ein Raspberry Pi könnte zum Beispiel über ein Requirement ausdrücken das sie WLAN benötigt. Ein Node Type für den Raspberry Pi 3 könnte dann die Capability WLAN definieren. Ein Node Type für einen Raspberry Pi 1 würde diese Capability nicht definieren, da der Raspberry Pi 1 kein WLAN hat. So könnte zum Beispiel von einem Modellierungswerkzeug sichergestellt werden das die Anwendung auf einem Raspberry Pi läuft der WLAN aufweist. In [OAS13a] werden die Rollen Type Architect, Artifact Developer und Application Architect defi- niert. Ein Type Architect definiert unter anderem Node Types und Relationship Types. Er muss wissen welche Properties, Interfaces, Requirements und Capabilities ein Node Type oder Rela- tionship Type benötigt und muss somit auch Wissen über die jeweiligen Komponenten haben. Ein Artifact Developer entwickelt die Deployment- und Implementation Artifacts. Er liefert über die Implementation Artifacts die Implementierungen der Operationen der Node Types. Auch die Deployment Artifacts, also zum Beispiel kompilierte Anwendungen, WAR Archive die auf ein Java Anwendungsserver provisioniert werden oder zum Beispiel ein Archiv das auf einem Webserver entpackt wird, fallen in den Verantwortungsbereich des Artifact Developers. Die letzte Rolle ist der Application Architect, er kennt die Struktur der gesamten Cloud-Anwendung, ihrer Artefakte und ihres Managementverhaltens. Er muss zum Beispiel nicht die einzelnen Implementierungen der Operationen kennen, da diese vom Artifact Developer bereitgestellt werden. Aber er muss die Semantik der Operation kennen um diese zum Beispiel in einem Plan verwenden zu können. Er benötigt auch Wissen über die einzelnen Typen, um sie in einem Topology Template verwenden zu können. Der Application Architect fügt dann die einzelnen Node Templates und Relationship Templates zu einer komplexen Topologie zusammen. Ein Type Architect kann den Application Architect beim Modellieren zum Beispiel mit Requirements und Capabilities unterstützen, da hierdurch die sonst verborgenen Abhängigkeiten deutlich werden. Das gesamte Service Template und alle zugehörigen Typen und Artefakte können in ein Archiv zusammengefügt werden. Diese Archive können dann mithilfe einem TOSCA Container provisioniert werden [OAS13a; OAS13b]. Dieses Archiv wird als Cloud Service ARchive (CSAR) bezeichnet [OAS13b]. In dieser Arbeit wird auf Kompatibilität mit OpenTOSCA2, einer Open Source Implementierung von einem TOSCA Container und Eclipse Winery2 geachtet. Winery ist ein Open Source Mo- dellierungswerkzeug für die Erstellung von TOSCA Service Templates. Ebenfalls wird davon ausgegangen das der TOSCA Container das Lifecycle Interface wie es in „Topology and Orches- tration Specification for Cloud Applications (TOSCA) Primer Version 1.0“ [OAS13a] beschrieben ist für das deklarative Verfahren der Topology Template Verarbeitung unterstützt. Es gibt nicht viele Container die dieses Lifecycle Interface unterstützen. Derzeit ist als einziger OpenTOSCA bekannt. OpenTOSCA unterstützt das generieren von Build Plänen, das heißt diese müssen nicht explizit modelliert werden [BBK+14]. Die Parameter von Operationen werden dabei auch in Node Templates weiter unten in der Topologie gesucht [BBK+14]. Benötigt zum Beispiel eine Operation des Lifecycle Interfaces von dem Apache Server die SSH Zugangsdaten des Betriebssystems, wird das Node Template des Betriebssystems und des virtuellen Servers nach den nötigen Properties durchsucht. 2https://projects.eclipse.org/projects/soa.winery (zuletzt besucht 17.12.2017) 21 2 Grundlagen 2.3 Geräte Für das Internet der Dinge gibt es eine große Auswahl an Geräten die sich je nach Verwendungs- zweck unterscheiden können. In dieser Arbeit werden das NodeMCU, der Raspberry Pi und die MICA genauer betrachtet und dafür in den folgenden Abschnitten vorgestellt. 2.3.1 NodeMCU Abbildung 2.4: NodeMCU: Rechts befindet sich der Micro-USB Anschluss und links der ESP8266 mit seiner Antenne. Das NodeMCU ist eine Open Source Software- und Hardwareplattform auf Basis des WLAN System on a Chip (SoC) ESP8266 [Nod17a]. Das SoC unterstützt unter anderem SPI, I2C, UART, 802.11 b/g/n/e/i und hat einen Tensilica L106 32-bit Mikrocontroller mit einem Takt von bis zu 160 MHz [Esp17]. Darüber hinaus gibt es digitale GPIO Pins zur Interaktion mit Sensoren und Aktuatoren [Hd17]. Auch ein Analog-Digital Wandler ist vorhanden, um zum Beispiel analoge Sensoren auszulesen [Hd17]. Es gibt das ESP8266 SoC auch in verschiedenen Versionen einzeln zu kaufen, dort ist jedoch keine USB Stromversorgung und keine USB Datenverbindung zum Flashen dabei. Auf der NodeMCU Platine ist, um das Flashen über USB zu ermöglichen, die USB zu UART Brücke CP2102 dabei [Nod15; Sil13]. Es befinden sich aber mehrere verschiedene Versionen im Verkauf. So existiert zum Beispiel auch eine Version die einen CH340G Chip als USB zu UART Brücke einsetzt. Außerdem ist ein Spannungsregler mit einer Ausgangsspannung von 3,3V integriert. Dadurch kann das NodeMCU über USB (5V) versorgt werden. Auch hier gibt es mehrere Versionen. Dadurch ermöglicht das NodeMCU eine einfache Verwendung. Durch das integrierte WLAN und die geringen Kosten pro Stück eignet sich die Plattform für das Internet of Things. Zu der Hardware Plattform mit den Devkits gibt es eine Firmware die in LUA geschrieben Programme ausführt [Nod17b]. Diese Firmware wird hier nicht verwendet. Stattdessen wird das Projekt Arduino core for ESP8266 WiFi chip3 verwendet um eine größere Kompatibilität mit anderen Arduinoboards und Bibliotheken zu erreichen [ESP17]. Arduino4 ist ein Open-Source Hardware und Software Ökosystem das eine große Verbreitung hat. Es existieren viele Software Tools und Dokumentation. Es gibt eine große Bandbreite an Bibliotheken die bei der Entwicklung eigener Software als Basis genutzt werden können. In dieser Arbeit wird auch auf Kompatibilität mit der Arduino IDE geachtet. Im Folgenden wird der Begriff NodeMCU deshalb für die Hardware Plattform in Verbindung mit dem Arduino ESP8266 Projekt verwendet. Es ist möglich einen NodeMCU über WLAN mit neuer Software zu bespielen. 3https://github.com/esp8266/Arduino (zuletzt besucht 17.12.2017) 4https://www.arduino.cc/ (zuletzt besucht 17.12.2017) 22 2.3 Geräte 2.3.2 Raspberry Pi Abbildung 2.5: Raspberry Pi 3 Model B: Am oberen Ende der Platine befindet sich die GPIO Leiste, rechts die USB-Buchsen und der Netzwerkanschluss. Unten befinden sich von links nach rechts der Micro-USB Anschluss, der HDMI-Anschluss und der Audio-Anschluss. Der Raspberry Pi ist ein Einplatinencomputer der im Februar 2012 auf den Markt gekommen ist [Upt12b]. Er wurde von der gemeinnützigen Raspberry Pi Foundation mit dem Ziel entwickelt, einen günstigen Computer „to learn, solve problems and have fun“ [Rasa] anzubieten. Die Foun- dation möchte mehr Menschen den Zugang zu einem Computer ermöglichen und erstellt viel Material um den Umgang mit dem Raspberry Pi zu erklären [Rasa]. Der Raspberry Pi bietet für einen geringen Preis eine hohe Leistung und verfügt über GPIO Pins um direkt mit Sensorik oder Aktuatoren zu interagieren [Rasa; Rasd]. Im Jahr 2015 wurde das Model 2 veröffentlicht und 2016 das Model 3 [Rasc; Rasd]. Inzwischen gibt es unter andrem die Varianten Raspberry Pi 3 Model B, Raspberry Pi 2 Model B, Raspberry Pi 1 Model B+, Raspberry Pi ZERO W und die Compute Module in unterschiedlichen Ausführungen [Rasb]. In der hier verwendeten Version 3B verfügt der Raspberry Pi über 1 GB Arbeitsspeicher und einen 1,2 GHz Quadcore 64Bit ARMv7 Prozessor [Rasd]. Als Schnittstellen bietet er außerdem einen Mirco-SD Karten Slot, 4 USB Typ A Anschlüsse, einen Micro-USB Anschluss zur Verbindung mit einem Netzteil, HDMI, WLAN, Bluetooth und Ethernet 10/100 Mbit/s [Ada16]. Auf ihm laufen mehrere Betriebssysteme darunter auch das auf Debian basierende Raspbian5 [XSN+17]. Der Raspberry Pi wird inzwischen häufig als Basis für andere Produkte verwendet [KH14]. Ein Großteil der Software die auf ihm läuft ist Open Source und es lassen sich einfach Prototypen oder Produkte entwickeln. Vor allem die große Community und die hohe Verbreitung (über 12,5 Millionen verkaufte Raspberry Pis [The17]) machen das Arbeiten mit dem Raspberry Pi einfach, da sehr viele Artikel, Dokumentation, Software und Zubehör existieren. 5https://www.raspbian.org/ (zuletzt besucht 17.12.2017) 23 2 Grundlagen 2.3.3 Harting MICA Abbildung 2.6: Modular Industry Computing Architecture: Von rechts nach links befinden sich zwei USB Anschlüsse, ein M12 Anschluss für die GPIO Pins und ein M12 An- schluss für den Netzwerkanschluss. Die Modular Industry Computing Architecture (MICA) von Harting ist ein Industrie Computer mit einem 1 GHz ARM Prozessor, 1 GB Arbeitsspeicher und 4 GB eMMC Flashspeicher [HARa]. Außerdem sind ein M12 Ethernet 10/100 Mbit/s Anschluss, ein Micro-SD Karten Anschluss und 8 digitale GPIO Pins mit 12V oder 24V verfügbar [HARa]. Die USB Version verfügt dazu über 2 USB Typ A Anschlüsse [HARa]. Zur Spannungsversorgung kann Power over Ethernet, ein 12V Netzteil oder ein 24V Netzteil genutzt werden [HARa]. Die MICA erfüllt unter anderem die Schutzart IP67 und die Normen EN 301489, EN 60950, EN 50364, EN 50155 [HARa]. Die MICA ist aufgeteilt in die Versorgungsplatine mit dem Stromanschluss und dem Netzwerkanschluss, die Prozessorplatine und die Funktionsplatine [HARb]. Die Platinen kommunizieren untereinander per USB [HARb]. Bei manchen MICA Modellen ist die Funktionsplatine schon vorbelegt, so nutzt die USB Variante die Funktionsplatine für die USB Anschlüsse [HAR17g]. Die Funktionsplatine kann aber auch vom Kunden bestimmt werden. Inzwischen existieren viele Versionen der MICA, unter anderem kann ein anderer Prozessor gewählt werden, es gibt Möglichkeiten Bluetooth, LTE, WLAN oder Modbus zu integrieren [HAR17g]. Auch eine Variante mit RFID ist verfügbar [HAR17g]. Die Firmware basiert auf Linux und alle Anwendungen laufen virtualisiert in Linux Containern (siehe Abschnitt 2.4) [WR]. Die MICA Firmware bietet eine auf JSON-RPC 2.0 basierte Single Sign On Schnittstelle [HAR17a]. Darüber können Dienste die auf Container laufen berechtig- te Nutzer identifizieren und die Container können darüber gemanagte werden [HAR17a]. Es ist unter anderem möglich Container zu starten, zu stoppen, zu installieren oder zu löschen [HAR17a]. In dieser Arbeit wird die Version 1 in der USB Variante verwendet und im Folgenden als MICA bezeichnet. Harting stellt zur Entwicklung Linux Container bereit, die als Basis für eigene Lösungen eingesetzt werden sollen. Es existieren unterschiedliche Container auf Basis von Debian und BusyBox [HAR17c; HAR17d]. Auch Container für zum Beispiel Java, Python oder mit vorinstallieren MQTT-Server und Node.js sind vorhanden [HAR16b; HAR16c; HAR17e; HAR17f]. 24 2.3 Geräte 2.3.4 Klassifizierung Es gibt sehr viele Geräte die sich für das Internet of Things eignen. Diese Geräte haben unter- schiedlichste Ausstattungsmerkmale in Bezug auf Arbeitsspeicher, CPU-Leistung, Flashspeicher und eingebauter oder verbundener Sensorik. Bormann, Ersue und Keranen [BEK14] beschreiben in Ihrer Arbeit unterschiedliche Klassen von constrained devices (beschränkten Geräten). Die Geräte werden nach verfügbarem Arbeitsspeicher und Flashspeicher in die, in Tabelle 2.1 beschriebenen Klassen C0 bis C2 eingeteilt. Klasse Arbeitsspeicher Flashspeicher Klasse C0 « 10 KiB « 100 KiB Klasse C1 10 KiB 100 KiB Klasse C2 50 KiB 250KiB Tabelle 2.1: Klassen von constrained devices [basiert auf BEK14]. Die Klasse C0 beschreibt Geräte die stark eingeschränkt sind und nicht sicher und direkt mit dem Internet kommunizieren können. Geräte dieser Art erhalten selten Software- oder Konfigurati- onsupdates. Stärkere Geräte in Klasse C1 haben weniger Einschränkungen, können aber noch keinen ganzen Protokoll Stack für die Kommunikation über das Internet nutzen. C2 beschreibt Geräte die wenig Einschränkungen aufweisen und ähnliche oder die gleichen Protokoll Stacks wie normale Computer, mit viel Speicherplatz, Arbeitsspeicher und Rechenleistung, nutzen können. Sie profitieren aber von schlanken Protokoll Stacks. Bormann, Ersue und Keranen [BEK14] be- schreiben darüber hinaus noch Klassen für den Energieverbrauch von Geräten und verschiedene Strategien zur Verwendung der vorhandenen Energie. In die Klassen C0 bis C2 passt von den in Abschnitte 2.3.1 bis 2.3.3 vorgestellten Geräten nur das NodeMCU. Es passt mit ca. 50 kB Arbeitsspeicher in die Klasse C2, hat aber mit 4 MB Flashspeicher mehr Speicher als die Klasse C2 vorsieht [BEK14; Esp17]. Trotzdem kann das NodeMCU in die Klasse C2 eingeordnet werden, da für die Provisionierung mit TOSCA wie es in Abschnitt 3.1 beschrieben ist Software Updates über WLAN benötigt werden. In diesem Prozess wird das gesamte Update auf dem Flashspeicher abgelegt und dann wird das Update durchgeführt. Es muss also genug Platz für ein Update auf dem Flashspeicher frei gelassen werden. Außerdem sind seit der Veröffentlichung der Klassifizierung drei Jahre vergangen, dadurch verschieben sich die Klassen ebenfalls [BEK14]. Der Raspberry Pi und die MICA passen nicht in die hier vorgestellten Klassen C0 bis C2. Ihre Ausstattung ist mit 1 GB Arbeitsspeicher und einer Speicherkarte als Flashspeicher um Größenordnungen größer wie die Klasse C2 [HARa; Rasd]. Auch die jeweilige Rechenleistung liegt um ein vielfaches höher als bei dem NodeMCU. Sie sind also keine constrained devices, sondern unconstrained devices. Kruger und Hancke [KH14] beschreiben zwei Arten von Internet of Things Geräten, zum einen die Gateway Geräte (Abbildung 2.7a) und zum anderen die Sensorknoten Geräte (Abbildung 2.7b). Die Gateway Geräte weißen eine Architektur auf die hauptsächlich auf einem Bus basiert. Alle Peripheriegeräte, der Arbeitsspeicher und der Flashspeicher sind einzeln auf dem Gerät vorhanden und über Busse verbunden [KH14]. Bei dem Raspberry Pi sind ICs für Arbeitsspeicher, Bluetooth / WLAN und der Ethernet Controller / USB-Hub einzeln ausgeführt und miteinander verbunden. Der Ethernet Controller und der USB-Hub (LAN9514-JZX) sind über USB mit dem Prozessor verbunden [Inc16]. Hier wären wie bei dem Raspberry Pi 1 unterschiedliche Kombinationen möglich. Das Raspberry Pi 1 Model A hat 256 MB Arbeitsspeicher und das Model B 512 MB 25 2 Grundlagen Prozessor Ethernet Strom- versorgung FLASH RAM WLAN (a) Architektur eines Gateways Radio Strom- versorgung Prozessor FLASHRAM AktuatorSensor (b) Architektur eines Sensorknoten Abbildung 2.7: Vergleich der Architekturen von zwei Arten von IoT Geräten [basiert auf KH14] Arbeitsspeicher [Upt12a]. Auch bei den Raspberry Pi Zero Modellen gibt es Unterschiede, das Model Zero hat kein WLAN während das Model Zero W WLAN hat [Rase]. Das ist durch die Architektur wie sie Gateway Geräte aufweisen möglich. Der genaue interne Aufbau des MICA ist in der Dokumentation nicht genau beschrieben aber die Unterteilung in Prozessor Modul und Supply Modul deutet auf eine Gateway Architektur hin [HAR17b]. Das NodeMCU entspricht eher einem Sensorknoten. Es sind viele Module die bei Gateway Geräten über Busse angebunden und als einzelne ICs ausgeführt sind, direkt in das SoC integriert. Deshalb sind hier auch keine andere Konfiguration möglich. Auch wenn der ESP8266 einen externen Flashspeicher über SPI unterstützt ist auf dem NodeMCU kein externes Flash Modul vorhanden, sondern es ist direkt im ESP8266 Modul integriert und lässt sich nicht austauschen [Esp17]. Das WLAN Modul ist wie der Arbeitsspeicher beim NodeMCU direkt im SoC enthalten [Esp17]. Ein weiteres Kriterium zu Einteilung in verschiedene Klassen von Geräte ist das unterstützte Betriebssystem. Hier unterstützen MICA und Raspberry Pi jeweils mindestens Linux [HARa; XSN+17]. Auf dem NodeMCU dagegen läuft kein Linux. Ebenfalls verfügt das NodeMCU als einziges einen Analog-zu-Digital Wandler und kann somit analoge Sensoren direkt verwenden [Esp17; HAR16a; LSN17]. Zusammenfassend gilt das sich die hier betrachteten Geräte in zwei Kategorien einteilen lassen. Die MICA und der Raspberry Pi sind unconstrained devices oder Gateways welche über mehr Leistung und Speicher verfügen. Das NodeMCU ist ein constrained device der Klasse C2 oder ein Sensorknoten. Obwohl es noch Geräte der Klassen C0 und C1 gibt ist das NodeMCU in seiner Leistung beschränkt und benötigt eine andere Lösung zur Provisionierung wie der Raspberry Pi oder die MICA. 2.4 Linux Container Virtualisierung bezeichnet zumeist das Nachbilden von hardwarebasierten Ressourcen in Software. Das erlaubt zum Beispiel das parallele und isolierte Ausführen von mehreren Betriebssystemen 26 2.4 Linux Container (1) (2) (3) (4) Hardware Host-Betriebssystem Container Engine Container App Dependencies Container App Dependencies Container App Dependencies Abbildung 2.8: Container Virtualisierung Architektur [basiert auf Bui15] oder Anwendungen auf einem Computer [Vau06]. Die Software greift dabei nicht mehr direkt auf die Hardware zu, sondern nutzt dafür eine Abstraktionsschicht. Die Nutzung von Virtualisierungs- techniken erlaubt schon seit Mitte der 1960er Jahre die bessere Nutzung von Hardware Ressourcen [Vau06]. Auch heute ist Virtualisierung in vielen Bereichen wichtig, zum Beispiel wären viele der heute im Cloud-Computing Bereich üblichen Techniken wie Infrastructure as a Service (IaaS) ohne Virtualisierung nicht möglich. Eines der frühen Beispiele für Virtualisierungslösungen ist VM/370 von IBM, aktuell sind unter anderem auch KVM6, Xen7, VirtualBox8, VMware9 und Hyper-V10 verfügbar [Vau06]. Bei diesen Hypervisor basierten Produkten wird zumindest ein Teil oder die gesamte Hardware auf der die virtualisierten Betriebssysteme laufen emuliert [Vau06]. Der Hypervisor verwaltet den Zugriff auf die vorhandenen Ressourcen und isoliert alle virtualisierten Betriebssysteme voneinander [Vau06]. Jede Instanz eines virtualisierten Betriebssystems bringt hier seine eigene Version des kompletten Betriebssystems inklusive Kernel mit [MKK15]. Neben den Hypervisor basierten Lösungen gibt es die oft als leichtgewichtige Virtualisierung bezeichnete Containerbasierte Virtualisierung. Als Beispiele sind OpenVZ11, Docker12, rkt13, Jetpack14 und LXC15 zu nennen. OpenVZ benötigt einen eigenen Kernel und funktioniert daher nicht mit einer Standard Raspbian Installation auf dem Raspberry Pi [RRN16]. Jetpack ist aktuell (Sep. 2017) noch ein Prototyp und läuft nur mit FreeBSD [PD15]. Im Folgenden werden daher nur Docker und LXC näher betrachtet. 6https://www.linux-kvm.org/ (zuletzt besucht 17.12.2017) 7https://www.xenproject.org/ (zuletzt besucht 17.12.2017) 8https://www.virtualbox.org/ (zuletzt besucht 17.12.2017) 9https://www.vmware.com/ (zuletzt besucht 17.12.2017) 10https://www.microsoft.com/de-de/cloud-platform/server-virtualization (zuletzt besucht 17.12.2017) 11https://openvz.org/Main_Page (zuletzt besucht 17.12.2017) 12https://www.docker.com/ (zuletzt besucht 17.12.2017) 13https://coreos.com/rkt/ (zuletzt besucht 17.12.2017) 14https://github.com/3ofcoins/jetpack (zuletzt besucht 17.12.2017) 15https://linuxcontainers.org/ (zuletzt besucht 17.12.2017) 27 2 Grundlagen Bei containerbasierter Virtualisierung teilen sich alle Container den Kernel des Betriebssys- tems auf dem sie laufen [MKK15]. Die einzelnen Container sind als isolierte Prozesse im Host- Betriebssystem realisiert [Bui15]. Wie Abbildung 2.8 zeigt läuft das Host-Betriebssystem (2) zwischen Hardware (1) und Container Engine (3). Dadurch benötigt die Container Engine keine eigenen Treiber, da sie durch das Host-Betriebssystem auf die Hardware zugreift. Die Container Engine (3) kümmert sich um das Management von den Containern, hierzu gehört vor allem das Starten und Stoppen von Containern. Die Container (4) beinhalten die Anwendungen und alle Abhängigkeiten. Obwohl Docker und LXC unterschiedliche Ziele verfolgen, verwenden beide die Kerneltechniken cgroups and namespaces [MKK15; SAN+17]. Docker verfolgt einen auf Anwendungen fokussierten Ansatz während LXC versucht den Hypervisor basierten virtuellen Maschinen so nah wie möglich zu kommen [BH017; SAN+17]. Namespaces sorgen dafür, dass die Ressourcen des Betriebssystems für einzelne Prozessgruppen isoliert zur Verfügung stehen. Heo et al. [HWD+17] beschreiben in der Dokumentation, dass durch cgroups Prozesse in eine baumartige Datenstruktur eingeordnet werden. Jedem Knoten können bestimmte Limits für Systemressourcen wie CPU und Arbeitsspeicher zugeordnet werden. Alle Prozesse die unterhalb des Knotens in der Datenstruktur eingeordnet sind, teilen sich die Ressourcenlimits, die für den Knoten gelten. Durch namespaces und cgroups sind Container voneinander getrennt und können mit Limits belegt werden. Auf unconstrained devices steht mehr Rechenleistung zur Verfügung wie auf den constrained devices. Trotzdem sollten keine ineffizienten Techniken verwendet werden, da IoT Geräte in großer Menge eingesetzt werden können und keine Energie verschwendet werden soll. Also sollte die verwendete Container Technologie keine oder nur wenige Leistungsminderungen mit sich bringen. Morabito, Kjällman und Komu [MKK15] untersuchen die Leistung von unter anderem Docker und LXC im Vergleich mit der nativen Ausführung ohne Container. Sie kommen zu dem Ergebnis das der Leistungsverlust durch Container fast vernachlässigbar ist. In dem Multi-Core Efficiency Benchmark von y-cruncher liegen LXC und Docker nicht mal ein halbes Prozent hinter der nativen Ausführung des Benchmarks. Ähnliche Ergebnisse wurden mit anderen Benchmarks wie NBENCH und noploop erzielt. In dieser Arbeit wird aber Serverhardware wie ein Intel Xeon Prozessor, eine SSD und eine 10 Gigabit Netzwerkschnittstelle eingesetzt. Beserra et al. [BPS+17] nutzen für ihre Tests ein ARM SoC das mit dem SoC des Raspberry Pi vergleichbar ist. Sie identifizieren einen etwas größeren Leistungsverlust von Containern im Vergleich mit der nativen Ausführung. Werden vier Instanzen des HPL Benchmarks parallel ausgeführt, ergibt sich ein Leistungsnachteil von ca. 4% im Vergleich mit nativer Ausführung bei LXC und Docker. 2.5 MQTT Geräte im Internet of Things unterscheiden sich hauptsächlich durch ihre Verbindung mit dem Internet von Geräten die momentan im Einsatz sind. Doch Verbindungen mit hoher Latenz und häufigen Störungen sind auch heute noch weit verbreitet. Auch müssen Geräte wie das NodeMCU mit vergleichbar wenig Leistung an der Kommunikation teilnehmen können. Dadurch kann das verwendete Protokoll nicht zu große Anforderungen in Bezug auf Rechenleistung, Arbeitsspeicher und Flashspeicher voraussetzen. Der folgende Absatz basiert auf der MQTT Spezifikation Version 3.1.1 [OAS14]. Das Message Queue Telemetry Transport (MQTT) Protokoll eignet sich für den beschriebenen Anwendungsfall gut, da es nur wenige Ressourcen benötigt. Es existieren viele Implementierungen für unterschiedliche Sprachen und Plattformen, darunter auch für das NodeMCU mit dem Arduino Core Projekt und für Java. Das Protokoll dient dazu 28 2.6 Related Work das Nachrichten von einem Sender zu einem oder mehreren Empfängern übertragen werden. Es arbeitet nach dem publish/subscribe Message Pattern. Das heißt Sender ordnen Nachrichten beim Versenden einem bestimmten Topic zu. Topics sind UTF-8 Zeichenketten die über das Schrägstrich Symbol eine hierarchisch gegliederte Baumstruktur darstellen. Ist ein Empfänger an einem bestimmten Topic interessiert, kann er dieses abonnieren. Alle Nachrichten die von Sendern versendet werden und diesem Topic zugeordnet sind, werden dann zu den interessierten Empfänger weitergeleitet. Das Protokoll unterstützt unterschiedliche Zusicherungen für die Übertragung von Nachrichten. Das niedrigste Quality of Service (QoS) Level übertragt die Nachricht, ohne zu garantieren das die Nachricht ankommt. Wenn die Nachricht unterwegs verloren geht fällt das weder Sender noch Empfänger auf. Das nächste höhere QoS Level 1 bietet die Zusicherung das Nachrichten auch beim Empfänger ankommen. Dafür wird der Erhalt einer Nachricht vom Kommunikationspartner bestätigt. Wenn nach einer bestimmten Zeit keine Bestätigung empfangen wurde, verschickt der Sender die Nachricht noch einmal. Das wiederholt der Sender bis er eine Bestätigung für den Erhalt der Nachricht empfangen hat. Durch das erneute Versenden der Nachricht können Duplikate entstehen. Diese Duplikate müssen dann in der vom Empfänger eingesetzten Software erkannt werden. Hierfür bietet das in den Nachrichten enthaltene DUP Bit einen Anhaltspunkt. Alternativ kann das QoS Level 2 verwendet werden. Das höchste QoS Level 2 garantiert über den sicheren Erhalt der Nachricht hinaus auch das diese nur einmal vom Empfänger verarbeitet wird. Im höchsten Level werden pro versendeter Nachricht vier MQTT Nachrichten ausgetauscht. Auch müssen alle Nachrichten die empfangen oder versendet werden länger im Speicher verbleiben. Höhere QoS Level erhöhen den Aufwand den Sender und Empfänger unternehmen müssen [OAS14]. Es sollte daher das niedrigste Level gewählt werden das für den Anwendungsfall passt. Es gibt Anwendungsfälle bei denen Duplikate nicht weiter stören, hier bietet sich das QoS Level 1 an. Sensordaten die häufig erhoben werden, können per QoS Level 0 versendet werden, da ein verlorener Wert meistens nicht schlimm ist und der nächste Wert innerhalb kurzer Zeit zu Verfügung steht. 2.6 Related Work In diesem Kapitel werden Arbeiten vorgestellt die zur Aufgabenstellung dieser Bachelorarbeit verwandt sind. Im Detail wurden Arbeiten ausgewählt die zur Provisionierung von Internet of Things Geräte TOSCA verwenden. 2.6.1 Towards Automated IoT Application Deployment by a Cloud-Based Approach Li et al. [LVCD13] beschreiben wie IoT Umgebungen mit TOSCA modelliert werden können. Es werden dafür sogenannte base Node Types eingeführt. Diese repräsentieren die Geräte die in einer IoT Umgebung vorkommen auf einem hohen Abstraktionsniveau. Die base Node Types die gezeigt werden sind Gateway, Driver, Controller und Sensor. Die ersten drei Node Types werden auch näher beschrieben. Sie definieren jeweils ein Lifecycle Interface, das jedoch nicht mit dem in „Topology and Orchestration Specification for Cloud Applications (TOSCA) Primer Version 1.0“ [OAS13a] gezeigten Lifecycle Interface übereinstimmt. Auch haben die base Node Types Properties. Zum Beispiel hat das Gateway die Properties User und Password während der Driver 29 2 Grundlagen das Property Version hat. In dieser Arbeit wird eine Vererbungshierarchie aufgebaut, bei der die base Node Types das oberste und abstrakteste Level darstellen. Das nächste Level bilden die domain-specific Node Types. Sie erben von jeweils einem base Node Type. Diese Node Types sind wie der Name sagt domänenspezifisch. Li et al. [LVCD13] nutzen das Beispiel einer komplexen Lüftungsanlage, in der ein domain-specific Node Type zum Beispiel ein AirFlowController ist. Dieser erbt von dem base Node Type Controller. Auch Node Types auf diesem Level weisen Properties und Interfaces auf. Das unterste Level in der Vererbungshierarchie bilden die concrete Node Types. Sie erben wiederum von den domain-specific Node Types und bilden die Node Types die spezifisch für eine konkrete Anwendung sind. Sie enthalten Informationen wie zum Beispiel die verwendete Hardware. Es müssten nicht immer alle Level in der Vererbungshierarchie vorhanden sein. Außerdem werden Artifact Types für die Verwendung mit dem Sedona-16 und dem Niagara-Framework17 definiert. Diese Frameworks helfen beim Verbinden und Erstellen von IoT Geräten. Es wird beschrieben das diese grundlegenden Artifact Typen auf base artifact types wie die von OASIS [OAS13a] definierten SourceArtifact, FileArtifact und ArchiveArtifact basieren. Weiterhin werden mehrere Relationship Types definiert, welche die Beziehungen zwischen den verschiedenen base Node Types repräsentieren. In dem Diskussionsteil der Arbeit wird die große Heterogenität von IoT Umfeldern hervorgehoben und TOSCA als eine Lösung beschrieben, um mit dieser umzugehen. Als ein Problem wird die zum Veröffentlichungszeitpunkt noch schwach ausgeprägte Toolunterstützung identifiziert. In dieser Arbeit werden den IoT Geräte durch die Vererbungshierarchie Rollen zugeteilt. Ein Geräte Node Type ist entweder ein Gateway, Controller oder ein Sensor. IoT Geräte können aber ab einer bestimmten verfügbaren Leistung viele Rollen annehmen oder auch gleichzeitig erfüllen. Ein Gerät kann Controller und Sensor gleichzeitig sein. Ein leistungsfähiges Gerät kann je nach der Konfiguration und der installieren Software ein Gateway, Sensor oder auch ein Controller sein. Ein Gerät in dieser Kategorie ist zum Beispiel ein Raspberry Pi. Es kann entweder als Gateway für kleinere Sensorknoten dienen oder aber selbst ein Sensorknoten sein. In dieser Bachelorarbeit werden die Node Types für die einzelnen Geräte nicht über die Rollen welche die Geräte erfüllen definiert. 2.6.2 Internet of Things Out of the Box: Using TOSCA for Automating the Deployment of IoT Environments Franco da Silva et al. [FBH+17] zeigen wie ganze Internet of Things Umgebungen mithilfe von TOSCA provisioniert werden können. Es wird gezeigt wie diese Umgebungen modelliert werden können und mithilfe mehrerer Fallstudien und eines Prototyps wird der Ansatz validiert. In der Arbeit wird eine Teilung in drei Bestandteile einer IoT Umgebung beschrieben. Der erste Teil der Umgebung ist der smart device stack, dieser enthält die IoTGeräte wie zumBeispiel einen Raspberry Pi. Diese IoT Geräte enthalten device software welche das Auslesen der Sensoren übernimmt und diese Werte an die IoT Middleware sendet. Der Stack besteht aus der Hardware der Geräte und der Software welche auf den Geräten läuft. Also zum Beispiel das Gerät auf unterster Ebene, darüber ein Betriebssystem und dann die device software. Der Node Type welcher das Gerät repräsentiert hat Properties wie die MAC-Adresse und die Fähigkeiten der Hardware. Implementation Artifacts oder Deployment Artifacts werden hier keine benötigt. Das Betriebssystem hat einen Node Type der Properties wie zum Beispiel die IP-Adresse aufweist. Auch hat der Betriebssystem Node Type 16http://www.sedonadev.org/ (zuletzt besucht 17.12.2017) 17https://www.tridium.com/products-services/niagara-ax (zuletzt besucht 17.12.2017) 30 2.6 Related Work Deployment- und Implementation Artifacts die ein installieren des Betriebssystems erlauben. Der zweite Teil einer Umgebung ist der IoT middleware stack. Er beinhaltet die IoT Middleware welche eine Brücke zwischen den Geräten untereinander oder mit den IoT Anwendungen darstellt. Es gibt hierfür viele verschiedene Lösungen und Produkte wie Eclipse Mosquitto18 oder OpenMTC19. Der Stack besteht aus der Infrastruktur auf welcher die Middleware läuft, zumeist ein Betriebssystem und der Middleware selbst. Diese kann wiederum Implementation- und Deployment-Artifacts haben. Dieser Stack kann auch als Service von einem Cloud-Anbieter bereitgestellt werden. Hier gibt es viele verschiedene Ansätze die Middleware bereitzustellen und somit auch viele verschiedene Modellierungsansätze. Der letzte Teil der Internet of Things Umgebung ist der IoT application stack. Er kann die gleiche Infrastruktur wie der IoT middleware stack nutzen und somit gleich modelliert werden. Allgemein werden die Anwendungen und alle Abhängigkeiten als Node Types modelliert und in der Topologie als Node Template dargestellt. So benötigt eine in Python geschriebene Anwendung auch Python das sie funktioniert. Deshalb wird auch Python als Node Type modelliert. Die IoT Anwendung selbst dient zur Visualisierung und Auswertung der Daten. Das kann zum Beispiel ein Dashboard sein auf dem die Daten dargestellt werden. Nachfolgend zu der Beschreibung der Modellierung, werden in dieser Arbeit drei Fallstudien betrachtet. Es werden die unterschiedlichen Protokolle zur Kommunikation zwischen den IoT Geräten und der Middleware hervorgehoben. Jede beschriebene Fallstudie weist alle drei Stacks einer IoT Umgebung auf. Sie unterscheiden sich bei der genutzten Middleware. Es muss in den gezeigten Topologien immer nur dieMiddleware und die mit ihr kommunizierenden Komponenten ausgetauscht werden. Die grundsätzliche Struktur der Topologien bleibt erhalten. Franco da Silva et al. [FBH+17] konzentriert sich auf die gesamte IoT Umgebung und hierbei vor allem auf die Middleware und die einfache Austauschbarkeit dieser. Der Fokus dieser Bachelorarbeit liegt auf dem Modellieren der einzelnen Geräte. Franco da Silva et al. [FBH+17] beachtet die Unterschiede der einzelnen Geräte nicht. Dies ist vermutlich dem kompakten Formfaktor der Arbeit geschuldet. Es gibt zum Beispiel auch Geräte die kein Betriebssystem in diesem Sinn aufweisen. Im Anwendungsszenario dieser Bachelorarbeit werden aber Konzepte von Franco da Silva et al. [FBH+17] aufgegriffen um eine komplette IoT Umgebung zu provisionieren. 18https://mosquitto.org/ (zuletzt besucht 17.12.2017) 19http://www.open-mtc.org/ (zuletzt besucht 17.12.2017) 31 3 Lösungskonzepte Ein einziges Lösungskonzept für alle IoT Geräte zu finden ist aufgrund der Heterogenität der verschiedenen Geräte nur schwer möglich. Ein solcher Ansatz würde die verschiedenen Stärken und Schwächen der einzelnen Geräte nicht beachten. In dieser Arbeit werden deshalb zwei Konzepte vorgestellt die sich für unterschiedliche Arten von Geräten eignen. Die betrachteten Geräte wurden schon in den Grundlagen vorgestellt. Diese Geräte wurden in Abschnitt 2.3.4 in die zwei Klassen constrained devices und unconstrained devices eingeteilt. In Abschnitt 3.1 wird das Lösungskonzept für die constrained devices vorgestellt. Sie verfügen generell über wenig Leistung und eine andere Architektur wie die unconstrained devices. Die unconstrained devices verfügen über vergleichsweise viel Leistung und benötigt ein anderes Lösungskonzept, dass in Abschnitt 3.2 vorgestellt wird. 3.1 Constrained devices Constrained devices wie das NodeMCU verfügen generell über wenig Leistung, Arbeitsspeicher und Flashspeicher [BEK14]. Außerdem erfüllen sie häufig einen anderen Zweck wie die in Ab- schnitt 3.2 beschrieben unconstrained devices. Das NodeMCU eignet sich besonders um Sensoren auszulesen und Aktuatoren zu steuern. Dies kann auch periodisch passieren, sodass das NodeMCU in regelmäßigen Abständen aus dem Schlafzustand des Prozessors aufwacht, den angeschlossenen Sensor ausliest, sich per WLAN verbindet und die gemessenen Daten überträgt. Der hier gewählt Ansatz für eine Provisionierung mithilfe von TOSCA sollte aufgrund der wenigen verfügbaren Ressourcen keine hohen Anforderungen an die CPU Leistung, Arbeitsspeicher und Flashspeicher stellen. Darüber hinaus sollten bei einer Installation einer Anwendung auf dem NodeMCU die Anwendung asynchron verteilt werden, sodass nicht alle Geräte gleichzeitig online sein müssen. Um constrained devices und die Anwendungen welche auf ihnen laufen in einem Topologie Template zu repräsentieren wird im Folgenden ein Ansatz wie er in Abbildung 3.1 gezeigt ist vor- gestellt. Der Ansatz ist zum besseren Verständnis direkt auf das NodeMCU bezogen, er würde sich aber generell auf constrained devices anwenden lassen. Hierfür müssen die im Folgenden beschrie- ben Node Templates durch constrained device Anwendung und constrained device Hardware ausgetauscht werden. Voraussetzung dafür ist das die installiere Anwendung auf dem constrained device über eine Netzwerkverbindung ausgetauscht werden kann und dass es möglich ist eine bidirektionale Verbindung zur Steuerung des Gerätes aufzubauen. Das oberste Node Template repräsentiert die Anwendung welche auf das NodeMCU provisioniert wird. Sie beinhaltet die eigentliche Geschäftslogik und setzt das Anwendungsszenario um. Der Node Type des Templates ist NodeMCU_App, in ihm werden die Properties und das Interface deklariert. Den im Node Type deklarierten Properties werden im Node Template Werte zugewiesen. Mehr Information zum Interface des Node Types gibt es in Abschnitt 4.1.1. Das einzige Property das der Node Type NodeMCU_App hat ist appConfig. Es kann vom Nutzer dazu benutzt werden während des Model- lierens der Anwendung eine Konfiguration zu übergeben. Es gibt auch TOSCA Container die das 33 3 Lösungskonzepte NodeMCU Anwendung (NodeMCU_App) NodeMCU Hardware (NodeMCU) Properties: appConfig: „Configuration“ Deployment Artifacts: NodeMCU_Anwendung.bin Properties: hardwareIds: [ "ID0", "ID1",…] pubSubServer: „tcp://…“ controlTopic: „ control“ responseTopic: „ response“ (HostedOn) Abbildung 3.1: Zeigt die Topologie eines constrained device und der Software die provisioniert wird, anhand des NodeMCUs. Abfragen von Properties kurz vor dem Provisionieren ermöglichen. Dafür muss das Property zum Beispiel durch einen bestimmten Wert gekennzeichnet sein oder leer gelassen werden. Das ist bei vielen Anwendungen die auf constrained devices laufen nützlich. So müssen Zugangsdaten und Einstellungen nicht fest in die Anwendung kompiliert werden, sondern können je nach Umgebung in welche, die Anwendung provisioniert wird angepasst werden. Eine Änderung der Konfiguration erfordert durch dieses Property nicht mehr das neu kompilieren der Anwendung, sondern nur noch eine Änderung am Node Template. Auch proprietäre Anwendungen, welche bei geänderten Einstellungen vom Artifact Developer nicht neu kompiliert werden können, könnten so eine Konfiguration ermöglichen ohne ihren Source Code zu Verfügung zu stellen. Wenn die Anwendung zum Beispiel einen Sensor ausliest, könnte hier das Intervall in dem der Sensor gelesen werden soll oder der Server welcher die Messungen verarbeitet eingestellt werden. Das Deployment Artifact der NodeMCU Anwendung beinhaltet die kompilierte Anwendung. Ein HostedOn Relationship Template verbindet die NodeMCU Anwendung mit der NodeMCU Hard- ware. Das NodeMCU Hardware Node Template repräsentiert jeweils mindestens ein NodeMCU in der Topologie. Da bei vielen Internet of Things Anwendungsszenarien viele Geräte mit gleicher Konfiguration benötigt werden, repräsentiert das Node Template viele physikalische NodeMCUs. Theoretisch könnte der Application Architect der das Topologie Template erstellt einfach alle NodeMCUs einzeln modellieren. Das ist aber bei vielen Geräten zeitaufwendig und fehleranfällig. 34 3.1 Constrained devices So erleichtert das Zusammenfassen von NodeMCUs mit gleicher Konfiguration zu einem Node Template das Modellieren für den Application Architect. Auch Management Operationen wie start und stop können nach der Provisionierung einfacher ausgeführt werden da nur noch einmal die Operation aufgerufen werden muss. So kann kein NodeMCU beim Ausführen von Management Operationen vergessen werden. Der Node Type von NodeMCU Hardware heißt NodeMCU und beinhaltet die Properties hardwareIds, pubSubServer, controlTopic und responseTopic. Das Property hardwareIds beinhaltet eine Liste an Hardware IDs. Eine Hardware ID wird beim NodeMCU mit dem Arduino Core Projekt anhand der MAC-Adresse errechnet. Sie dient zur Identifizierung der einzelne NodeMCUs. Bei constrained devices die keine eingebaute Funktion zur Bestimmung von einer Hardware ID haben kann die MAC-Adresse verwendet werden. Es eignen sich aber auch andere eindeutige Hardwaremerkmale. Dadurch kann sichergestellt werden, dass alle NodeMCUs die in der Hardware ID Liste enthalten sind von den Management Operationen erfasst werden. Die Management Operationen gelten erst als abgeschlossen, wenn alle aufgeführten NodeMCUs die Operation durch eine Antwort bestätigt haben. Es müssen nicht alle NodeMCUs aufgezählt werden, die Liste kann sogar leer gelassen werden. Nach jeder Management Operation ist eine Wartezeit vorgesehen, sodass auch wenn keine Hardware IDs hinterlegt sind die NodeMCUs Zeit haben die Operation abzuschließen. Es kann dann aber nicht sichergestellt werden das alle Geräte die Management Operation empfangen haben und diese überall abgeschlossen sind. Mehr Informationen zu den Management Operation gibt es in Abschnitt 3.1.1. Alle Operationen des Lifecycle Interfaces sind Management Operationen, da alle vom Type Architect am Node Type definierte Operationen Management Operationen sind [OAS13a]. Operationen die nicht zum Lifecycle Interface gehören, sind demnach trotzdem Management Operationen. Das Property pubSubServer ist die Adresse des Servers über den die Kommunikation mit den NodeMCUs stattfindet. Eine Kommunikation nach dem publish-subscribe Prinzip hat den Vorteil, dass nicht alle Kommunikationspartner im Voraus bekannt sein müssen. Alle NodeMCUs die verwendet werden, melden sich beim Server und registrieren sich auf ein Topic. Dadurch ist es möglich alle NodeMCU zu erreichen, egal ob diese in der Hardware ID Liste hinterlegt sind oder nicht. Durch den Server zwischen dem TOSCA Container und den NodeMCUs muss der TOSCA Container nicht mit allen NodeMCUs direkt kommunizieren, das kann der publish-subscribe Server übernehmen. Dieser ist oft auf die Kommunikation mit sehr vielen Verbindungspartnern ausgelegt ist. Mehr Informationen dazu gibt es im Abschnitt 2.5. Die Properties controlTopic und responseTopic definieren die Topics auf denen die Kommunikation stattfindet. Nachrichten zu den NodeMCUs werden auf den im controlTopic konfigurierten Topic publiziert. Antworten werden von den NodeMCUs auf den im responseTopic eingestellten Topic publiziert. Der NodeMCU Node Type hat kein Lifecycle Interface, da der Lebenszyklus der Anwendung gesteuert werden soll und nicht der von der Hardware. Also hat der Node Type NodeMCU_App ein Lifecycle Interface. Die Hardware des NodeMCU kann nicht ohne installierter Software initialisiert werden, auch ein starten und stoppen ist so nicht möglich. Ein stoppen würde dazu führen, dass ein NodeMCU für den TOSCA Container nicht mehr erreichbar ist. Constrained devices wie das NodeMCU könnten aber mit einer Firmware oder einem Betriebssystem ausgeliefert werden, die eine Konfiguration oder eine Kontrolle über das Netzwerk erlaubt. Für diese Geräte könnte ein Lifecycle Interface an dem Hardware Node Type relevant sein. In diesem Fall könnten auch Deployment Artifacts nötig sein, welche zum Beispiel ein Firmware-Update enthalten. Es ist außerdem möglich Node Types durch Service Templates zu ersetzen [OAS13a]. So könnte ein Service Template definiert werden, dass den Hardware Node Type und weitere Plane enthält. Ein solche Plan kann zum Beispiel in BPMN verfasst sein und User Tasks enthalten [OAS13b; 35 3 Lösungskonzepte Obj14]. Der Plan könnte User Tasks definieren die als Aufgabe das Verbinden der constrained devices mit Sensoren oder Aktuatoren enthalten. Auch das Aufstellen und initiale Bespielen mit Software könnte definiert werden. Die verwendete Sprache für den Plan und die genauen Abläufe die definiert werden, hängen aber stark vom Anwendungsfall des Service Templates und vom verwendeten TOSCA Container ab. Alternativ zum Modellierungsansatz mit zwei Node Types könnte auch ein Ansatz mit nur einem Node Type gewählt werden. Dieser repräsentiert die Hardware, die Software und hat als Properties die Vereinigungsmenge aus den Properties aus beiden Node Types. Nur ein Node Type für beides zu verwenden ist aber für constrained devices nachteilig, bei denen sich die Hardware durch eine Firmware über eine Netzwerkverbindung managen lässt. In dem Modellierungsansatz mit nur einem Node Type könnte die Hardware kein eigens Lifecycle Interface bekommen, obwohl das durch eine solche Firmware notwendig ist. Auch wenn das NodeMCU nicht in diese Kategorie fällt, gibt es mit dem MICA zum Beispiel ein unconstrained device das eine solche Firmware aufweist. Darüber hinaus hat der Ansatz mit zwei Node Types den Vorteil das sich mehrere Hardware Versionen durch mehrere Node Types für die Hardware ausdrücken lassen. Der NodeMCU_App Node Type lässt sich aber unverändert verwenden. 3.1.1 Lifecycle Interface NodeMCU_App Operation Input Parameters Output Parameters install hardwareIds, pubSubServer, controlTopic, responseTopic installedDevicesCount configure appConfig, hardwareIds, pubSubServer, controlTopic, responseTopic configuredDevicesCount start hardwareIds, pubSubServer, controlTopic, responseTopic startedDevicesCount stop hardwareIds, pubSubServer, controlTopic, responseTopic stoppedDevicesCount uninstall hardwareIds, pubSubServer, controlTopic, responseTopic uninstalledDevicesCount Tabelle 3.1: Enthält alle Operationen des Lifecycle Interfaces für den Node Type NodeMCU_App und deren Parameter. Der NodeMCU_App Node Type implementiert das Lifecycle Interface wie es in „Topology and Or- chestration Specification for Cloud Applications (TOSCA) Primer Version 1.0“ [OAS13a] beschrieben ist. Nur der Name des Interfaces wurde von „http://www.example.com/interfaces/lifecycle“ auf „http://opentosca.org/interfaces/lifecycle“ geändert um mit OpenTOSCA1 und Eclipse Winery2 wie Kopp [Kop17] beschrieben hat kompatibel zu sein. In der Spezifikation werden nur die Na- men der Operationen definiert und welche Semantik hinter den Operationen steckt. Die Input Parameter und die Output Parameter werden dort nicht definiert. Diese sind je nach Kontext un- terschiedlich. Die Operationen des Lifecycle Interfaces bilden den Lebenszyklus der Anwendung 1http://www.opentosca.org/(zuletzt besucht 17.12.2017) 2https://projects.eclipse.org/projects/soa.winery (zuletzt besucht 17.12.2017) 36 3.1 Constrained devices welche auf dem NodeMCU läuft ab. Tabelle 3.1 zeigt alle Operationen mit allen Parametern die in dem NodeMCU_App Node Type definiert sind. Andere Anwendungen die auf constrained devices laufen können noch mehr Parameter erfordern. Diese Input Parameter sind aber mindestens notwendig, wenn der Ansatz eine publish-subscribe Kommunikation nutzt und über eine Liste von Hardware IDs sicher gestellt wird das alle Geräte die Operationen ausführen. Es muss nicht jede Operation für jedes constrained device umgesetzt werden. Die configure-Operation muss zum Beispiel nicht implementiert werden, wenn sie nicht benötigt wird. Die Output Parameter sind genauso optional und müssen von einer Implementierung dieses Ansatzes nicht umgesetzt werden. Sie helfen aber bei der Erkennung von Geräten die nicht in der Hardware ID Liste aufge- führt sind, da der Output Parameter die Anzahl der betroffenen Geräte repräsentiert. Wenn der Output Parameter größer ist als die Kardinalität der Liste, müssen Geräte existieren die nicht in der Liste enthalten sind. Im Folgenden wird die generelle Semantik der einzelnen Operationen beschrieben. Install: Die install-Operation installiert die kompilierte Anwendung welche im Deployment Artifact vom Node Template hinterlegt ist, auf den NodeMCUs. Sie benötigt als einzige der Ope- rationen des Lifecycle Interfaces Zugriff auf das Deployment Artifact des Node Templates. Die NodeMCUs registrieren sich bei einem publish-subscribe Server auf das im Property control- Topic konfigurierte Topic. Die install-Operation benötigt daher den Parameter pubSubServer, controlTopic und responseTopic um mit den NodeMCUs kommunizieren zu können. Nachdem erfolgreichen Verbinden mit dem pubSubServer publiziert die install-Operation eine Nachricht auf dem im Property controlTopic konfigurierten Topic. Die install-Nachricht enthält Informationen wie das NodeMCU das Deployment Artifact erhält. Hier sind mehrere Lösungswege denkbar, zum Beispiel kann die Nachricht eine URL enthalten bei der das Deployment Artifact herunter- geladen werden kann. Das Deployment Artifact kann auch komplett in der install oder einer weiteren Nachricht enthalten sein. Nachdem Erhalt des Deployment Artifacts antworten die NodeMCUs über den im response Topic konfigurierten Topic mit einer Antwortnachricht. Die Antwortnachricht enthält die hardwareId des Gerätes sodass die Nachricht einem bestimmten NodeMCU zugeordnet werden kann. Dadurch ist es möglich auf die Antwort aller im Parameter hardwareIds enthaltenen NodeMCUs zu warten. Es wird generell mindestens eine gewisse Zeit gewartet, um auch NodeMCUs die nicht in der Hardware ID Liste aufgeführt sind Zeit zum Verarbeiten der Nachrichten zu geben. Diese Wartezeit ist so dimensioniert das NodeMCUs die Nachrichten erhalten können, diese verarbeiten und genug Zeit zum Antworten haben. Geräte die ausgeschaltet sind werden so aber nicht erfasst. Um auch Geräte die aktuell ausgeschaltet sind, aber wieder online kommen, zu berücksichtigen kann eine Funktion genutzt werden die Nachrichten für ein Gerät auf dem pubSubServer speichert, bis diese wieder online kommen. Bei MQTT kann diese Funktionalität über das Clean Session Flag gesteuert werden [OAS14]. Die install-Operation kann trotz dieser Funktionalität nur auf Geräte warten die über die Hard- ware ID Liste bekannt sind. Nachdem Ablauf der Wartezeit, aber frühestens nachdem von allen bekannten Geräten eine Antwortnachricht erhalten wurde meldet die install-Operation die An- zahl der Geräte die betroffen sind als installedDevicesCount zurück. Der installedDevicesCount kann größer sein als die Anzahl der in hardwareIds gelisteten NodeMCUs, da auch NodeMCUs auf den in controlTopic übergebenen Topic hören können die nicht gelistet sind. Wichtig ist zu beachten, dass immer nur eine Anwendung gleichzeitig auf dem NodeMCU installiert sein kann. Ein erneuter Aufruf überschreibt die bereits installierte Anwendung. Bei dem NodeMCU ist der Flashspeicher in einen Teil für die Anwendungen und einen Teil für Daten geteilt. Bei der install-Operation wird nur der Anwendungsspeicher überschrieben, da Anwendungen bei einem 37 3 Lösungskonzepte Update Zugriff auf die Daten der vorherigen Version haben sollten. Diese Semantik kann auch auf anderen constrained devices umgesetzt werden, wenn der Mechanismus um eine Anwendung auf dem Gerät zu installieren dies zulässt. Benötigt die Anwendung einen leeren Datenspeicher muss diese das selbständig umsetzen. Configure: Die configure-Operation benötigt die gleichen Input Parameter wie die install- Operation. Darüber hinaus braucht sie noch den Parameter appConfig. Die configure-Operation bietet die Möglichkeit, die in der install-Operation installierte NodeMCU Anwendung zu konfigu- rieren. Anwendungen können aus den verschiedensten Gründen eine Konfiguration benötigen. Die Konfiguration welche in appConfig enthalten ist kann vom Application Architect frei gewählt werden. Die Konfiguration könnte die Informationen enthalten über welche Pins am NodeMCU ein Sensor oder Aktuator angeschlossen ist. Auch Zeitangaben für ein Intervall in dem der Sensor ausgelesen wird können enthalten sein. Zugangsdaten für einen Online-Service oder eine Daten- bank werden meistens auch nicht statisch in die Anwendung kompiliert. Es sind alle Arten von Daten oder Objekten möglich, die sich als Zeichenkette kodieren lassen solange diese auf dem constrained device wieder interpretiert werden können. Die configure-Operation publiziert eine configure-Nachricht auf den im controlTopic übergebenen Topic. In der Nachricht ist die Informa- tion aus dem appConfig Property enthalten. Nachdem die Nachricht auf allen Geräten empfangen und verarbeitet wurde, senden sie eine Antwortnachricht zurück. Die configure-Operation wartet eine gewisse Zeit auf die Antwortnachrichten, aber mindestens bis alle in dem Parameter hard- wareIds übergeben NodeMCUs geantwortet haben. Dadurch ist sichergestellt das alle NodeMCUs welche die Konfiguration erhalten sollen, diese nach Abschluss der configure-Operation auch erhalten haben. Nachdem Erhalt der Antwortnachrichten meldet die configure-Operation über den Output Parameter configuredDevicesCount die Anzahl der konfigurierten Geräte zurück. Die configure-Operation wird normalerweise beim Provisionieren des Service Templates bei jedem Node Template das diese unterstützt nach der install-Operation aufgerufen. Sie kann aber auch später, falls der TOSCA Container das unterstützt, genutzt werden um die Konfiguration von NodeMCUs zu ändern. Hier muss im Einzelfall überprüft werden ob es nicht besser ist das Service Template mit der neuen Konfiguration anzupassen und dann das gesamte Service Template neu zu provisionieren. Das hat den Vorteil das die Geräte und ihre Repräsentation im Service Template kohärent sind. Start: Die start-Operation hat die gleichen Properties wie die install-Operation. Sie publiziert die start-Nachricht auf dem im Parameter controlTopic übergebenen Topic. Die NodeMCUs erhalten diese Nachricht und starten daraufhin die Geschäftslogik. Die Anwendung an sich muss zu diesem Zeitpunkt schon ausgeführt werden, da die Nachricht sonst nicht empfangen werden kann. Das liegt dran, dass bei der Konfiguration der NodeMCUs die hier verwendet wird nur eine Anwendung parallel installiert sein kann. Das muss bei anderen constrained devices nicht der Fall sein. Die generelle Semantik der start-Operation bleibt aber erhalten. Sie startet die Geschäftslogik. Es ist nicht wichtig ob hierfür eine separate Anwendung gestartet wird oder ob der Geschäftslogik Teil einer Anwendung ausgeführt wird. Nachdem Verarbeiten der start-Nachricht publizieren die NodeMCUs eine Antwortnachricht auf den in responseTopic konfigurierten Topic. Diese Nachricht signalisiert der start-Operation, dass die Anwendung auf dem jeweiligen NodeMCU gestartet wurde. Die start-Operation wartet ähnlich wie die install und die configure-Operation eine gewisse Zeit, mindestens aber bis sich alle im Parameter hardwareIds aufgeführten NodeMCUs zurückgemeldet haben. Auch die start-Operation meldet über den Output Parameter startedDevicesCount die Anzahl der gestarteten Geräte zurück. 38 3.1 Constrained devices Stop: Die stop-Operation funktioniert ähnlich wie die start-Operation. Sie publiziert eine stop- Nachricht über den im Parameter controlTopic übergebenen Topic. Es ist wichtig das die An- wendung welche vom Artifact Developers entwickelt wurde nicht einfach gestoppt wird. Es ist nur schwer beurteilbar in welchem Zustand sich die Anwendung gerade befindet. Sie könnte gerade ein Ventil geöffnet haben und muss dieses noch vor dem Stoppen wieder schließen. Die stop-Operation sollte die Anwendung also nur informieren das diese anhalten soll. Es gibt viele Anwendungen in denen vor einem Stopp erst in einen sicheren Zustand übergegangen werden muss. Ein weiteres Beispiel wäre ein Signal welches gerade auf Grün steht. Vor dem Stoppen müsste die Anwendung überprüfen ob es nicht besser ist das Signal wieder auf Rot zustellen. Allgemein lässt sich nicht vorhersehen welche Aktionen unternommen werden müssen um die Aktuatoren welche an einem NodeMCU angeschlossen sind in einem sicheren Zustand zu überfüh- ren. Also kann nur die Anwendung vom Nutzer die auf dem NodeMCU läuft darüber entscheiden was bei einem Stopp zu erledigen ist. Weiter zu beachten ist das trotz der stop-Nachricht wei- ter auf Nachrichten über den pubSubServer gewartet werden muss. Sonst ist zum Beispiel das Ausführen der uninstall-Operation nicht möglich. Nachdem Stopp der Anwendung senden die betroffenen Geräte eine Antwortnachricht die es der stop-Operation ermöglicht auf das Stoppen aller im Parameter hardwareIds definierter NodeMCUs zu warten. Vergleichbar wie die start- und install-Operation wird auch hier eine gewisse Zeit gewartet um nicht bekannte Geräte zu berücksichtigen. Am Ende meldet die stop-Operation die Anzahl der gestoppten Geräte zurück. Uninstall: Die uninstall-Operation funktioniert ähnlich wie die stop-Operation und benötigt auch die gleichen Input Parameter. Sie publiziert eine uninstall-Nachricht über den im Parameter controlTopic übergebenen Topic an den im Parameter pubSubServer übergebenen Server. Dieser leitet die Nachricht dann an die NodeMCUs weiter. Auf dem NodeMCU kann die installierte Anwendung nicht deinstalliert werden, da sie auch die Nachrichten verarbeitet und durch kom- plettes Löschen der Anwendung keine weiteren install-Nachrichten mehr empfangen werden können. Auf anderen constrained devices muss dies nicht der Fall sein. Die Anwendung welche deinstalliert werden soll muss aber trotzdem vor dem möglichen Löschen informiert werden. Ebenfalls wie bei der stop-Operation kann es sein, dass die Anwendung noch in einen sicheren Zustand übergehen muss, der über das was bei einem Stopp unternommen wird hinausgeht. Ein einfaches Beispiel ist mögliche Nutzer der vom NodeMCU bereitgestellten Funktionalität über die Deinstallation zu informieren. Das kann zum Beispiel über ein angeschlossenes Display passieren. In viele Fällen wäre es auch empfehlenswert das die Anwendung das Flash Dateisystem löscht, wenn sie diesen benutzt hat und wenn die gespeicherten Daten nicht von einem späteren Update benötigt werden. Das genaue Vorgehen hängt auch in diesem Fall vom Anwendungsszenario ab. Nachdem die Anwendung die erforderlichen Schritte unternommen hat sendet das NodeMCU eine Antwortnachricht auf den im responseTopic übergebenen Topic. Die uninstall-Operation wartet ähnlich wie die anderen Operationen eine gewisse Zeit, mindestens aber bis sich alle im Parameter hardwareIds definierten NodeMCUs zurückgemeldet haben. Auch diese Operation meldet über den Output Parameter uninstalledDevicesCount die Anzahl der betroffenen Geräte zurück. Wie in den start-, stop- und uninstall-Operationen beschrieben ist besteht die Anwendung welche auf dem NodeMCU installiert wird aus zwei Teilen. Zum einen gibt es den Teil der die Kommuni- kation mit dem publish-subscribe Server und die Verarbeitung der Nachrichten übernimmt, zum anderen gibt es den Teil der die Geschäftslogik des Anwenders umsetzt. Auf anderen constrained devices können die Teile auch in zwei unterschiedlichen Anwendungen umgesetzt sein oder die Tosca Funktionalität kann in ein eventuell vorhandenes Betriebssystem integriert werden. Die 39 3 Lösungskonzepte genaue Vorgehensweise zur Kommunikation mit dem publish-subscribe Server und der Verar- beitung der Nachrichten hängt vom konkreten Nachrichtenformat, Kommunikationsprotokoll und vom eingesetzten constrained device ab. Es ist aber meistens sinnvoll diese Funktionalität in einer Bibliothek zu bündeln, sodass alle Artifact Developer die eine Anwendung entwickeln diese nutzen können. Eine mögliche Implementierung dieser Bibliothek für MQTT, JSON Nachrichten und das NodeMCU wird in Abschnitt 4.1.1 vorgestellt. Auch ist es möglich den publish-subscribe Server mithilfe von TOSCA zu provisionieren. 3.2 Unconstrained devices Anwendung (LXContainer) Deployment Artifacts: ContainerImage Requirements: HardwareRequirement Abbildung 3.2: Node Template eines Linux Container Node Types. Geräte der unconstrained devices Klasse wie der Raspberry Pi oder die MICA haben generell andere Fähigkeiten wie Geräte der constrained devices Klasse. Sie haben um Größenordnungen mehr Rechenleistung, Flashspeicher und Arbeitsspeicher. Darüber hinaus weisen sie eine andere Architektur wie die constrained devices auf und verwenden meistens ähnliche Betriebssysteme wie Desktop PCs oder Server. Mehr Informationen zu den verwendeten Geräten und zur Klassifi- zierung gibt es in der Abschnitten 2.3.1 bis 2.3.4 auf den Seiten 22–25. Durch diese Unterschiede benötigen die unconstrained devices einen anderen Lösungsansatz wie die constrained devices. Auf den unconstrained devices können mehrere Anwendungen parallel unabhängig voneinander ausgeführt werden. Es muss also dafür gesorgt werden das sich die Anwendungen nicht gegensei- tig stören. Um eine einfache Provisionierung der Anwendungen und all ihrer Abhängigkeiten zu ermöglichen und eine Isolierung der Anwendungen untereinander sicherzustellen, werden bei diesem Ansatz Container eingesetzt. Dadurch können sich Anwendungen nicht gegenseitig stören weil zum Beispiel zwei Anwendungen inkompatible Abhängigkeiten haben oder im gleichen Verzeichnis arbeiten. Es bieten sich mehrere Container-Technologien an, darunter Docker oder Linux Container. Im Folgenden wird das Konzept mit Linux Container beschreiben, da sich diese Technologie für den Raspberry Pi und die MICA gut eignet. Das liegt daran das Linux Container auf beiden Gräten funktionieren und die Container in den meisten Fällen sogar einfach zwischen den Geräten ausgetauscht werden können. Darüber hinaus unterstützt die Firmware der MICA Linux Container ohne Anpassungen. Eine genauere Beschreibung zu Linux Containern gibt es in Abschnitt 2.4 auf Seite 26. Der Modellierungsansatz ist aber von der verwendeten Container- Technologie unabhängig und würde mit Docker genauso gut funktionieren. Im Weiteren wird 40 3.2 Unconstrained devices davon ausgegangen das immutable Container verwendet werden. Diese werden nachdem Erstellen nicht mehr verändert. Die Konfiguration wird nicht angepasst und es werden auch keine Updates eingespielt. Werden Änderungen notwendig, wird der Container gelöscht und ein neuer mit den Anpassungen provisioniert. Um die Provisionierung mit OpenTOSCA zu ermöglichen wird ein Node Type benötigt der die Linux Container im Topology Template repräsentiert. Der Node Type wird in Abbildung 3.2 dargestellt. Er hat keine Properties, dafür hat das Node Template das von ihm erstellt wurde aber ein Deployment Artifact und ein mögliches Requirement. Das Deployment Artifact enthält den Linux Container als ein komprimiertes Archiv des Da- teisystems des Linux Containers. Der Artifact Developer der den Linux Container entwickelt, erstellt diesen auf dem Raspberry Pi oder der MICA. Dann installiert er alle benötigte Software im Container und nimmt die Konfiguration der Software vor. Anschließend komprimiert er das Dateisystem und erhält das Deployment Artifact. Alternativ ist es auch möglich einen Container automatisch beim oder nachdem Build-Prozess zu erzeugen. Wichtig ist das die Container welche erzeugt werden auf ARMv7 lauffähig sind, sodass die Container auf beiden Geräten funktionieren. Es kann sein das bestimmte Container Hardware benötigen die entweder nur auf dem Raspberry Pi oder nur auf der MICA vorhanden ist. Dazu zählen die Funktionsplatine auf der MICA oder Bluetooth und WLAN auf dem Raspberry Pi 3. Deshalb gibt es die Requirements RaspberryPiHard- ware undMicaHardware. Natürlich gibt es dazu auch die passenden Capabilities. Für jedes weitere unconstrained device das unterstützt werden soll, kann von einem Type Architect ein weiteres Requirement-Capability Paar erstellt werden. Wenn ein Artifact Developer einen Container mit speziellen Hardware Requirements erstellt, kann er dies dem Application Architect mitteilen und dieser modelliert dann die Anforderung im Node Template. Um den Container auf den Raspberry Pi zu übertragen, entpacken und zu kontrollieren wird ein Zugang über SSH benötigt. Über diesen Zugang können dann die einzelnen Operationen des Lifecycle Interfaces realisiert werden. Die MICA kann nicht direkt per SSH angesprochen werden. Aber für die MICA gibt es eine vom Hersteller in die Firmware integrierte JSON-RPC 2.0 Schnittstelle. Über diese können wie beim Raspberry Pi über SSH alle Operationen des Lifecycle Interfaces realisiert werden. Für andere unconstrained devices könnten noch mehr Zugriffsarten notwendig sein. Für die unterschiedlichen Schnittstellen werden mehrere verschiedene Implemen- tierungen benötigt. Der Container, der im Deployment Artifact hinterlegt ist, läuft prinzipiell auf beiden Geräten er muss aber auf unterschiedliche Weise dorthin gelangen. Um das zu ermöglichen gibt es mehrere Modellierungsansätze die in den nachfolgenden Kapitellen aufgezeigt werden. In Abschnitt 3.2.6 gibt es eine tabellarische Zusammenfassung deren Vor- und Nachteile. 3.2.1 Smart TOSCA Container Um den Linux Container der die Geschäftslogik enthält entweder auf den Raspberry Pi oder auf die MICA zu übertragen werden zwei unterschiedliche Kommunikationstechnologien benötigt. Sollen weitere unconstrained devices unterstützt werden, werden vermutlich noch mehr Kommunikati- onstechnologien benötigt und es müssen mehr Schnittstellen unterstützt werden. Diese können in je einem Implementation Artifact realisiert werden. Das heißt es wird ein Node Type für den Linux Container benötigt. Der Node Type enthält das Lifecycle Interface um die Provisionierung zu ermöglichen. Für das Interface gibt es mindestens zwei Node Type Implementations, eine Node Type Implementation für den Raspberry Pi und eine Node Type Implementation für die MICA. Dazu noch eine für jedes Gerät das eine andere Schnittstelle hat als diese zwei Geräte. Die Node 41 3 Lösungskonzepte Anwendung (LXContainer) Deployment Artifacts: ContainerImage Anwendung (LXContainer) Deployment Artifacts: ContainerImage Raspbian (RaspbianStretchLXC) MICA (HartingMICA) RaspberryPi (RaspberryPi3) HostedOn a) b) Abbildung 3.3: Ein Linux Container kann entweder auf einen Raspberry Pi a) oder auf einen MICA b) provisioniert werden. Type Implementations verweisen jeweils wieder auf ein Implementation Artifact. Die Implemen- tation Artifacts beinhalten die eigentliche Implementierung für die Kommunikation über SSH, JSON-RPC oder anderen Technologien die zur Kommunikation mit den Geräten benötigt wird. Der TOSCA Container muss dann erkennen welche der vielen Node Type Implementations für das Service Template das verarbeitet wird geeignet ist. Beispielhaft wurden beide Situationen für den Raspberry Pi und die MICA in Abbildung 3.3 dargestellt. Für jedes weitere Gerät das unterstützt werden soll kommt ein weiteres Paar aus Linux Container Node Type und Gerä- te Node Type dazu. In Möglichkeit a) sind drei Node Templates dargestellt. Das oberste Node Template repräsentiert die Anwendung im Linux Container und ist vom Typ LXContainer. Das Deployment Artifact enthält das Dateisystem des Linux Containers als komprimiertes Archiv. In der Mitte ist das Node Template Raspbian, es ist vom Typ RaspbianStretchLXC. Es repräsentiert das Betriebssystem Raspbian in der Version Stretch mit der Software LXC installiert. Der Node Type existiert getrennt vom RaspberryPi3 Node Type um den Austausch des Betriebssystems zu ermöglichen, denn es existieren mehrere Betriebssysteme für den Raspberry Pi auf denen Linux Container laufen. Darüber hinaus muss auf dem Raspberry Pi LXC installiert sein. Das letzte Node Template repräsentiert den Raspberry Pi. Die Verbindungen sind HostedOn Relationship Templates. Sie haben die Semantik das jeweils das Node Template auf welches das Ende vom Pfeil zeigt auf dem Node Template auf welches die Spitze vom Pfeil zeigt gehostet wird. Verarbeitet der TOSCA Container ein Service Template das diesen Fall enthält, muss er dies erkennen und bei der Auswahl der Node Type Implementation berücksichtigen. Der TOSCA Container muss also darauf achten welchen Node Type das Node Template hat, auf den das HostedOn Relationship Template ausgehend von dem LXContainer zeigt. Es muss die Node Type Implementation für das Lifecycle Interface gewählt werden, welche das Implementation Artifact für SSH referenziert. Im 42 3.2 Unconstrained devices Fall b) ist im Service Template ebenfalls oben ein Node Template enthalten das die Anwendung in einem Linux Container repräsentiert. Der Fall b) unterscheidet sich von Fall a) durch das jeweils zweite Node Template. Im Fall a) ist es das Betriebssystem Raspbian, aber im Fall b) ist es direkt die MICA. Bei dem MICA existiert kein Betriebssystem Node Template zwischen der Anwendung und dem MICA, da es vom Hersteller des MICAs nicht vorgesehen ist das Betriebssystem zu ändern. Auch dieser Fall muss vom TOSCA Container erkannt werden, dass die Anwendung im Linux Container korrekt provisioniert werden kann. Der TOSCA Container muss aus den Node Type Implementations für das Lifecycle Interface des Node Template Anwendung, die richtige Node Type Implementation für die MICA auswählen. Die richtige Node Type Implementation referenziert das Implementation Artifact das JSON-RPC verwendet. Der Vorteil ist das bei diesem Ansatz nur ein Node Type für den Linux Container existiert. Dieser hat aber mehreren Node Type Implementations für sein Lifecycle Interface. Application Architecten können diesen einen Node Type verwenden und die Node Templates die ein Gerät repräsentieren je nach Anwendungsfall ändern. Der eine Node Type für den Linux Container muss dabei nicht geändert werden. Es kann also sehr schnell der Raspberry Pi durch ein MICA ersetzt werden. Es müssen nur die Geräte Node Templates angepasst werden. Nachteilig ist das für den Application Architect beim Modellieren eines Service Templates nicht ersichtlich ist welche Geräte unterstützt werden. Er muss einerseits wissen, für welche Geräte Node Type Implementations bereitstehen. Andererseits muss er aber auch wissen welche Fälle und Fallkombinationen vom dem eingesetzten TOSCA Container unterstützt werden. Ein weiterer Nachteil ist das der TOSCA Container die komplette Logik für die Auswahl der passenden Node Type Implementation enthalten muss. Diese Logik wird nicht im Model repräsentiert. Dafür muss der TOSCA Container angepasst werden, da momentan kein TOSCA Container bekannt ist der eine solche Funktionalität unterstützt. Bei OpenTOSCA existiert aber eine Plugin Schnittstelle um Funktionen wie diese umzusetzen. Ein solches Plugin muss aber für jedes weitere unterstützte Gerät erweitert werden und der Implementierungsaufwand muss für jeden TOSCA Container wie- derholt werden. Auch steht die Anpassung des TOSCA Containers um ein Service Template richtig interpretieren zu können, im Widerspruch zu der in der Spezifikation geforderten Portabilität von Service Templates [OAS13b]. 3.2.2 Smart Implementation Artifact Der Linux Container in dem die Anwendung enthalten ist, funktioniert auf dem Raspberry Pi oder auf dem MICA. Die Übertragung des Linux Containers auf die jeweiligen Geräte erfordert aber das Unterstützten unterschiedlicher Kommunikationstechnologien und Schnittstellen. Bei dem Raspberry Pi funktioniert der Zugriff über SSH und bei dem MICA über JSON-RCP. Die Service Templates können wie in Abbildung 3.3 dargestellt ist aufgebaut sein. Zusätzlich können die Service Templates noch weitere Komponenten enthalten. Der TOSCA Container geht bei diesem Ansatz immer gleich vor. Um ein Node Template vom Typ LXContainer zu verarbeiten reicht es, wenn der TOSCA Container die einzige Node Type Implementation für das Lifecycle Interface lädt. Der TOSCA Container muss keine Auswahl aus mehreren Alternative auf Basis der Topologie treffen. Die gesamte Logik zu Auswahl der verwendeten Kommunikationstechnologie steckt im Implementation Artifact. Diese wird von der Node Type Implementation referenziert. Das Implementation Artifact hat dafür zwei Möglichkeiten. Einerseits kann das Implementation Artifact das Service Template selbst verarbeiten und ähnlich vorgehen wie der TOSCA Container imAbschnitt 3.2.1. Das Implementation Artifact kann, wenn der TOSCAContainer die Information 43 3 Lösungskonzepte welches Node Template gerade verarbeitet wird bereitstellt, überprüfen welches Ziel die HostedOn Kante vom Node Template hat. Mithilfe der Kante kann das Implementation Artifact den Typ von dem Ziel der Kante bestimmen und die richtige Kommunikationsart wählen. Andererseits kann das Implementation Artifact alle ihm bekannten möglichen Kommunikationsarten und Schnittstellen durchprobieren und überprüfen welche funktioniert. Eine Provisionierung über JSON-RPC würde bei einem Raspberry Pi nicht funktionieren. Es kann aber schwierig sein zu unterscheiden ob ein bestimmtes Gerät falsch oder gar nicht auf eine bestimmte Kommunikationsart reagiert und somit ein Fehlerfall vorliegt oder ob nur die falsche Kommunikationsart probiert wurde. Darüber hinaus können Änderungen in der Semantik von Schnittstellen in neueren Geräteversionen nicht erkannt werden. Allgemein ist es bei diesem Ansatz schwer viele verschiedene unconstrained devices zu unterstützen, da zwei Geräte ähnliche Schnittstellen aufweisen können und es so nicht in jedem Fall möglich ist zu erkennen um welches Gerät oder welche Geräteversion es sich handelt. Der Vorteil an diesem Ansatz ist, dass der TOSCA Container nicht angepasst werden muss und auch keine spezielle Logik für den Linux Container Node Type enthalten sein muss. Ein Nachteil ist wie beim vorherigen Ansatz das der Application Architect wissen muss welche Geräte vom Implementation Artifact unterstützt werden. Diese Information ist bei diesem Ansatz nicht im Model enthalten. Auch ist die Implementierung des Implementation Artifact komplexer und wird bei jedem neuen Gerät das in der Zukunft unterstützt werden muss noch komplexer. 3.2.3 Einheitliche Schnittstelle für alle unterstützten Geräte Dieser Ansatz zielt drauf ab das alle unconstrained devices über eine einheitliche Schnittstel- le angesprochen werden können. Dafür muss eine einheitliche Schnittstelle gefunden werden und auf allen zu unterstützenden Geräten implementiert werden. Alternativ kann eine vorhan- dene Schnittstelle von einem Gerät ausgewählt werden, die dann auf allen anderen Geräten implementiert wird. Um das Vorgehen zur Auswahl der Schnittstelle und der vorhandenen Imple- mentierungsmöglichkeiten für unconstrained devices darzustellen, werden im Folgenden einige Gesichtspunkte bei der Auswahl der Schnittstelle für den Raspberry Pi und die MICA aufgezeigt. Bei dem Raspberry Pi und dem MICA bedeutet eine einheitliche Schnittstelle das entweder die JSON-RPC Schnittstelle des MICAs auf dem Raspberry Pi zu implementieren oder eine Kontrolle des MICA über SSH zu ermöglichen. Auch möglich ist die Definition einer neuen Schnittstelle die auf beiden Geräten implementiert werden muss. Die meisten Linux Container die von MICA bereitgestellt werden, können über SSH angesprochen werden. Aber zur Kontrolle des MICA wurde eine JSON-RPC Schnittstelle vom Hersteller definiert [HAR17a]. Diese ist auch in der Firmware des MICAs enthalten und muss nicht installiert werden. Der Raspberry Pi kann über viele Wege angesprochen werden, die meisten benötigen zusätzliche Software auf dem Raspberry Pi. Am einfachsten ist SSH, da dies in Raspbian integriert ist und ohne das Starten des Raspberry Pi über eine Datei auf der SD Karte aktiviert werden kann [Rasf]. Eine SSH Schnittstelle auf dem MICA lässt sich über ein Linux Container der auf dem MICA installiert wird erreichen. Dieser Container kann über eine SSH Schnittstelle verfügen und in ihm kann eine Software laufen welche die SSH Kommunikation auf JSON-RPC übersetzt. Das würde den Vorteil der im MICA integrierten JSON-RPC Schnittstelle zunichtemachen. Der Vorteil ist das auf dem MICA wenn JSON-RPC verwendet wird, keine zusätzliche Software installiert werden muss um die MICA anzusprechen. Eine Implementierung von JSON-RCP auf dem Raspberry Pi ist hier die bessere Lösung. Die JSON-RCP Schnittstelle für den Raspberry Pi muss dann vor dem ersten Verwenden zusammen mit Raspbian und LXC auf dem Raspberry Pi installiert werden. Alternativ kann auch 44 3.2 Unconstrained devices ein Image von Raspbian angefertigt werden das LXC und die JSON-RCP Schnittstelle enthält. Dieses Image kann dann auf eine SD-Karte kopiert werden. Eine neue Schnittstelle für beide Geräte hätte den Nachteil das sie auf beiden Geräten installiert und implementiert werden muss. Für unconstrained devices allgemein müssen bei diesem Ansatz die gleichen Überlegungen wie beim Raspberry Pi oder beim MICA gemacht werden. Welche Schnittstelle soll für alle Geräte gewählt werden? Wie lässt sich diese am besten in das Gerät integrieren? Dieser Ansatz hat den Vorteil das nur ein Implementation Artifact existieren muss und das dieses weniger Komplexität aufweist im Vergleich mit dem Ansatz in Abschnitt 3.2.2. Nachteilig an diesem Ansatz ist das auf jedem unconstrained device das unterstützt werden soll eine einheitliche Schnittstelle implementiert werden muss. Wird wie im Beispiel vom Raspberry Pi und dem MICA eine herstellerspezifische Schnittstelle verwendet (JSON-RPC Schnittstelle) muss bei jeder Anpas- sung dieser Schnittstelle jede andere Implementierung angepasst werden. Darüber hinaus ist für den Application Architect auch bei diesem Ansatz nicht offensichtliche welche Geräte unterstützt werden. Die originale Implementierung der JSON-RPC Schnittstelle ist auch proprietär, so kann es schwierig sein jedes Detail der Schnittstelle korrekt umzusetzen und eventuelle Geräte spezifische Teile der Schnittstelle lassen sich auf dem Raspberry Pi gar nicht umsetzen. 3.2.4 Smart Containerhost Anwendung (LXContainer) Deployment Artifacts: ContainerImage Containerhost (Containerhost) (HostedOn) { installContainer(File,ContainerName) startContainer(ContainerName) stopContainer(ContainerName) removeContainer(containerName) Abbildung 3.4: Zeigt das Interface zur Provisionierung des Containers auf den Host [basiert auf End15]. Dieser Ansatz überlässt die Logik zum Provisionieren von Container dem Node Template auf welches der Linux Container provisioniert werden soll. In den Ansätzen von den Abschnitten 3.2.1 bis 3.2.3 wird immer das Lifecycle Interface am Node Type Linux Container mit einem oder mehre- ren Node Type Implementations umgesetzt. Viele bestehende Containerverwaltungen überlassen aber nicht dem Container wie er provisioniert wird. Als Beispiel ist hier Apache Tomcat3 oder die Java List Schnittstelle4 zu nennen. Der Apache Tomcat unterstützt über eine Weboberfläche 3http://tomcat.apache.org/ (zuletzt besucht 17.12.2017) 4https://docs.oracle.com/javase/8/docs/api/java/util/List.html (zuletzt besucht 17.12.2017) 45 3 Lösungskonzepte das Provisionieren von Java Webanwendungen. Über diese Weboberfläche können die Java Web- anwendungen gestartet, gestoppt und gelöscht werden. Diese Funktionalität wird nicht von der Java Webanwendung bereitgestellt. Ähnlich verhält es sich bei der Java List Schnittstelle. Objekte werden über Methoden die von der Implementierung der List Schnittstelle bereitgestellt werden zur Liste hinzugefügt oder gelöscht. Die Objekte haben normalerweise keine Funktionalität um sich selber einer Liste hinzuzufügen. Endres [End15] beschreibt diesen Ansatz unter dem Namen „Container Component Interface“ als ein Muster zur Provisionierung von Anwendungen. Abbildung 3.4 verdeutlicht diesen Ansatz. Das obere Node Template in diesem Service Template ist vom Typ LXContainer. Der Node Type LXContainer hat bei diesem Ansatz kein Lifecycle Interface. Das zweite Node Template ist vom Typen Containerhost und steht für ein unconstrai- ned device auf dem ein Container betrieben werden soll. Der Containerhost kann ein Lifecycle Interface und unterschiedliche Properties aufweisen, je nachdem welches Gerät modelliert wird. Der Containerhost hat zusätzlich zu einem eventuell vorhandenen Lifecycle Interface noch ein Interface das die Verwaltung von Containern erlaubt. Die Operationen des Interfaces sind ihrer Semantik nach benannt und dem Lifecycle Interface nachempfunden, die genauen Parameter können aber je nach konkretem Gerät abweichen. Die Node Type Implementations welche die Operationen umsetzen sind dem jeweiligen Containerhost Node Type zugeordnet. Es kann also zum Beispiel eine Implementierung für die MICA und eine für den Raspberry Pi existieren. Diese sind dem jeweiligen Geräte Containerhost Node Type zugeordnet. Der TOSCA Container muss nicht aus mehrere Node Type Implementations auswählen (Ab- schnitt 3.2.1), da es pro Operation oder Interfaces nur eine Implementierung gibt und eine Imple- mentierung muss auch nicht mit mehreren unterschiedlichen Geräten umgehen (Abschnitt 3.2.2) können. Darüber hinaus muss auf keinem Gerät eine Schnittstelle von einem anderen Gerät nach implementiert werden (Abschnitt 3.2.3). Ein weiterer Vorteil ist das für den Application Architect ersichtlich ist welche Geräte unterstützt werden. Existiert ein Node Type für ein Gerät das diese Schnittstelle implementiert, wird es unterstützt. Nachteilig ist bei diesem Ansatz das entweder der TOSCA Container die Semantik der Containerhost Schnittstelle kennen muss oder dass der genaue Ablauf in einem Plan festgelegt werden muss. Wenn der TOSCA Container die Semantik der Schnittstelle kennen muss um ein solches Service Template verarbeiten zu können, muss er dafür modifiziert werden. Das widerspricht der in der Spezifikation geforderten Portabilität von Service Templates [OAS13b]. Der Einsatz von Build Plänen erhöht die Komplexität des Models und ist auch nicht unbedingt zwischen unterschiedlichen Implementierungen von TOSCA Containern portabel, da die Sprache in der Pläne formuliert werden nicht in der Spezifikation definiert ist. 3.2.5 Unterschiedliche Node Types Dieser Ansatz verwendet unterschiedliche Linux Container Node Types für jedes unconstrained device. In Abbildung 3.5 wird dies beispielhaft für den Raspberry Pi und die MICA dargestellt. Jeder Node Type hat jeweils eine Node Type Implementation für das Lifecycle Interface. Der jeweilige Node Type kann Besonderheiten für das Gerät für das er gedacht ist aufweisen. Gemein- samkeiten der Node Types für die unconstrained devices werden in dem abstrakten Node Type LXContainer zusammengefasst. Die Node Types mit konkreten Implementierungen erben vom abstrakten Node Type LXContainer. Somit erhalten sie alle Eigenschaften und Interfaces welche auch der abstrakte Node Type aufweist. Der Node Type LXContainerRaspberryPi ist ein Node Type der weitere Properties und Operationen hat. Das Property lxcConfiguration und die Operation configure gibt es im LXContainerRaspberryPi Node Type aber nicht im LXContainerMICA Node 46 3.2 Unconstrained devices LXContainer + install() + start() + stop() + uninstall() LXContainerRaspberryPi + lxcConfiguration : String + configure(…) LXContainerMica Abbildung 3.5: Zeigt die Vererbungshierarchie der Node Types. Alle Container die vom abstrak- ten LXContainer erben, erhalten auch die Definition des Lifecycle Interface. Type. Das zusätzliche Property repräsentiert die LXC Konfiguration die jeder Linux Container haben kann. Auf dem Raspberry Pi lässt sich diese für jeden Linux Container festlegen, auf dem MICA ist diese Konfiguration aber für jeden Linux Container fest eingestellt. Aus diesem Grund hat nur der LXContainerRaspberryPi Node Type das Property. Die restlichen Operationen des Lifecycle Interface erben beide Node Types vom abstrakten Node Type LXContainer. Für andere unconstrained devices können andere Properties notwendig sein. Beide konkreten Node Types haben jeweils eine eigene Implementierung für die Operationen. Der LXContainerRaspberryPi Node Type verwendet SSH zur Kommunikation mit dem Raspberry Pi und realisiert darüber die Operationen. Beim LXContainerMICA Node Type verwendet die Implementierung JSON-RPC zur Kommunikation mit dem MICA. Der Application Architect kann dann zur Modellierung eines Service Templates ein Node Template vom jeweiligen unconstrained device Linux Container Node Type verwenden, wenn er einen Linux Container auf einem Gerät darstellen möchte. Der Vorteil ist das für den Application Architect immer klar ist welche Geräte verwendet werden können. Er kann davon ausgehen, dass wenn ein Linux Container Node Type für das Gerät existiert, dieses Gerät auch unterstützt wird. Er muss sich nicht darum kümmern ob eine bestimmte Kombination aus einem Linux Container und einem Gerät vom TOSCA Container unterstützt wird. Auch muss der TOSCA Container nicht die Semantik vom speziellen Interface des Containerhosts verstehen. Er benötigt nur die Unterstützung für das in „Topology and Orchestration Specification for Cloud Applications (TOSCA) Primer Version 1.0“ [OAS13a] definierten Lifecycle Interface. Auch muss die Implementierung der Operationen nicht zwischen unterschiedlichen Geräten unterscheiden können. Darüber hinaus ist es einfach ein weiteres unterstütztes Gerät hinzuzufügen, dafür muss keine der existierenden Implementierungen angepasst werden. Anstatt neue Geräte können so auch unterschiedliche Versionen von einem Gerät erstellt werden. Darüber hinaus werden zusätz- liche Properties und Operationen für einzelne Geräte unterstützt. Nachteilig ist bei diesem Ansatz, dass ein Type Architect der einem speziellen Linux Container mehr Properties oder Operationen geben möchte einen konkreten Node Type eines Gerätes erweitern muss um die vorhandene Implementierung für ein Gerät zu nutzen. In dem Beispiel das in Abbildung 3.5 dargestellt wird muss also entweder vom LXContainerMICA Node Type oder vom LXContainerRaspberryPi Node Type eine Spezialisierung erstellt werden. Der Type Architect kann mit seiner Erweiterung nicht automatisch kompatible zu beiden Geräten sein, ohne auch eine Spezialisierung von beiden Node 47 3 Lösungskonzepte Types zu erstellen. Das ist mit dem Ansatz der in Abschnitt 3.2.4 vorgestellt wurde möglich, da es nur einen Node Type für den Linux Container gibt der erweitert werden kann. Wie viele Spezialisierungen des Linux Container Node Type nicht inhärent Geräte spezifisch sind und dadurch nur mit einem der Geräte funktionieren lässt sich schwierig abschätzen. Auch sollten keine Spezialisierungen des Linux Container Node Types notwendig sein, da immutable Contai- ner verwendet werden sollten. Diese benötigen nachdem Erstellen keine weitere Konfiguration. Darüber hinaus muss, wenn ein Gerät im Service Template gegen ein anderes ausgetauscht wird, auch der Node Type des Linux Container Node Templates geändert werden. 3.2.6 Tabellarischer Vergleich aller gezeigten Ansätze Die Abschnitte 3.2.1 bis 3.2.5 zeigen mehrere Ansätze wie mit dem Problem von einem Linux Container Node Type und mehreren verschiedene Vorgehensweisen um ein Linux Container auf ein Gerät zu provisionieren umzugehen ist. Alle aufgezeigten Ansätze haben verschiedene Vor- und Nachteile. In diesem Abschnitt werden die einzelnen Ansätze anhand eines Fragenkatalogs untersucht. Die erste Frage ist „Ansatz funktioniert ohne Änderungen am Tosca Container?“. Das heißt ob der verwendete TOSCA Container für die Verwendung dieses Ansatzes angepasst werden muss. Es ist wichtig das Service Templates ohne solche Anpassungen funktionieren, da die Portabilität von Service Templates in der TOSCA Spezifikation [OAS13b] explizit gefordert ist. Portabilität bei Service Templates bedeutet das ein Service Template, welches von einem Anbieter erstellt wurde auch von einem anderen Anbieter verstanden wird [OAS13b]. Die Portabilität eines Service Templates geht verloren, wenn der TOSCA Container der ein Service Template verarbeitet angepasst werden muss um das Service Template zu verstehen. Die zweite Frage lautet „Für den Application Architect ist erkennbar welche Geräte unterstützt werden?“. Das heißt ob ein Application Architect der ein Service Template erstellen möchte am Model, an den verfügbaren Node Types, an den verfügbaren Node Type Implementations oder den Implementation Artifacts erkennen kann welche Geräte unterstützt werden. Wenn zum Beispiel Anpassungen am TOSCA Container notwendig sind, ist für den Application Architect nicht klar welche Kombination vom LXContainer und den Geräten unterstützt werden. Das ist aber nicht der einzige Fall in dem es nicht offensichtlich ist welche Geräte unterstützt werden. Der Ansatz „Smart Implementation Artifact“ benötigt keine Anpassungen am TOSCA Container. Da die Logik welche Geräte unter- stützt werden aber trotzdem nur durch die Implementierung von einem Implementation Artifact bestimmt werden und sich nicht im Model widerspiegelt ist nicht offensichtlich klar welche Geräte unterstützt werden. Diese Frage ist bei zwei Geräten nicht so wichtig, aber im Internet of Things existieren sehr viele unterschiedliche Geräte und dadurch ist es wichtig das diese Frage berücksichtigt wird. Die dritte Frage ist „Ansatz funktioniert ohne spezielle Anpassungen an min- destens einem Gerät?“, das heißt dass Geräte eine spezielle Software oder Hardwarekomponente benötigen um zu funktionieren. Diese muss entweder vom Service Template selbst oder vor der Verwendung der Geräte installiert werden. Für den Ansatz „Einheitliche Schnittstelle“ muss auf allen unterstützten Geräten eine einheitliche Schnittstelle existieren. Selbst wenn dafür eine schon existierende Schnittstelle gewählt wird, muss diese auf allen Geräten die nicht über diese verfügen implementiert werden. Die nächste Frage lautet „Der Ansatz ermöglicht das gerätespezifisch Properties modelliert werden?“. Gerätespezifische Properties können notwendig sein, wenn be- stimmte Geräte zum Provisionieren von Containern noch weitere Properties benötigen. Das kann zum Beispiel beim Raspberry Pi eine Konfiguration für den Linux Container sein. Es ist aber auch denkbar das der Pfad in dem der Container auf dem Gerät gespeichert wird oder welche Rechte der Container auf dem Gerät hat als Property hinterlegt wird. Die fünfte Frage ist „Neue Geräte 48 3.2 Unconstrained devices können ohne Anpassungen an existierenden Implementation Artifacts unterstützt werden?“. Das ist wichtig da nicht alle Implementation Artifact vom gleichen Autor stammen müssen und nicht unbedingt Open Source sind. Das heißt eine Anpassung bestehender Implementation Artifacts ist unter Umständen aus rechtlichen und technischen Gründen nicht möglich. Die sechste Frage lautet „Aufwand neue Geräte zu unterstützen?“. Muss zum Beispiel der TOSCA Container oder andere Implementation Artifacts angepasst werden, ist der Aufwand hoch. Ein neues Implementation Artifact zu ergänzen ist ein vergleichsweise geringerer Aufwand, da dieser Aufwand mindestens bei jedem Ansatz entsteht. Die letzte Frage heißt „Aufwand im ServiceTemplate ein Gerät durch ein anderes zu tauschen?“. Hier deutet die Antwort auf den Aufwand hin der nötig ist, wenn ein existierendes Service Template für ein anderes Gerät angepasst werden soll. Das kann eine neue Hardware Version sein oder ein ganz anderes Gerät. Die Frage wird unter dem Kontext gestellt, dass auch das neue Gerät vom TOSCA Container oder vom Implementation Artifact unterstützt wird und eventuell nötige Anpassungen am Gerät vorhanden sind. Es geht ausschließlich um den Aufwand der Anpassungen im Model. Sm ar tT O SC A C on ta in er Sm ar tI m pl em en ta ti on A rt if ac t Ei nh ei tl ic he Sc hn it ts te lle Sm ar tC on ta in er ho st U nt er sc hi ed lic he N od e Ty pe s Ansatz funktioniert ohne Änderungen am Tosca Container? ✗ X X X* X Für den Application Architect ist erkennbar wel- che Geräte unterstützt werden? ✗ ✗ ✗ X X Ansatz funktioniert ohne spezielle Anpassungen an mindestens einem Gerät? X X ✗ X X Der Ansatz ermöglicht das gerätespezifisch Pro- perties modelliert werden? ✗ ✗ ✗ ✗ X Neue Geräte können ohne Anpassungen an exis- tierenden Implementation Artifacts unterstützt werden? X ✗ X X X Aufwand neue Geräte zu unterstützen? hoch hoch hoch gering gering Aufwand im ServiceTemplate ein Gerät durch ein anderes zu tauschen? gering gering gering gering hoch Tabelle 3.2: Vergleich der einzelne Modellierungsansätze. *Kann auch mit Plänen umgesetzt werden, die Sprache in der die Pläne formuliert werden ist aber nicht fest definiert [OAS13b]. 49 3 Lösungskonzepte 3.2.7 Fazit Die in den vorangestellten Abschnitten vorgestellten Ansätze haben alle Vor- und Nachteile. Am geeignetsten für die Umsetzung ist der in Abschnitt 3.2.5 vorgestellte Ansatz mit zwei unterschiedlichen Node Types. Er erfordert zwar beim Anpassen existierender Service Templates vom Application Architect mehr Aufwand, widerspricht der Portabilität von Service Templates aber nicht. Auch ist für den Application Architect selbst bei vielen unterstützten Geräten immer ersichtlich welche Geräte alle verwendet werden können. Existiert ein Linux Container Node Type für das Gerät, wird es auch unterstützt. Der Nachteil das es aufwendiger ist Spezialisierungen des Linux Container Node Type für alle Geräte zu erstellen wird durch die Verwendung von immutable Container abgeschwächt. Auch ist dies der einzige Ansatz der spezielle Properties und Operationen für einzelne Geräte am Linux Container Node Type des Gerätes erlaubt. 3.2.8 Lifecycle Interface des Linux Containers Für jedes unterstützte Gerät gibt es einen Node Type der von dem abstrakten Linux Container Node Type erbt. Da der abstrakte Linux Container Node Type das Lifecycle Interface enthält muss auch jeder davon erbende Node Type das Lifecycle Interface enthalten. Eine Ausnahme davon stellt die configure-Operation des Lifecycle Interface dar, da diese nicht von jedem Gerät benötigt wird. Ein Node Type der vom abstrakten Linux Container Node Type erbt, überschreibt bei der Definition eines eigenen Lifecycle Interfaces die Operationen mit gleichem Namen [OAS13b]. Das heißt ein gerätespezifischer Linux Container Node Type kann zum Beispiel eine install-Operation mit eigenen Parametern definieren. Die Operation mit Parameter im gerätespezifischen Linux Container Node Type überschreibt dann die install-Operation welche vom abstrakten Linux Container Node Type geerbt wurde. Das ist wichtig da unterschiedliche Geräte unterschiedliche Parameter benötigen. Bei manchen kann zum Beispiel ein Zertifikat zum Anmelden notwendig sein, bei anderen reicht Benutzername und Password. Auch kann jeder gerätespezifischer Linux Container Node Type seine eigene Node Type Imple- mentation und sein eigenes Implementation Artifact haben. Die Implementation Artifacts können von unterschiedlichen Node Type Implementations verwendet werden, wenn mehrere Geräte über die gleiche Schnittstelle verfügen. Im Abschnitt 3.1 auf Seite 33 wurde beschreiben das für die Kommunikation mit den constrained devices ein Protokoll welches das publish-subscribe Prinzip umsetzt verwendet wird. Dieses Prinzip könnte bei den unconstrained devices auch eingesetzt werden. Es sollte hier aber nicht erzwungen werden, da für viele unconstrained devices schon eine erprobte Schnittstelle existiert. Die MICA verfügt zum Beispiel über eine vomHersteller integrierte Schnittstelle zur Provisionierung von Software. Auch verfügen viele Geräte die ein Linux-basiertes Betriebssystem nutzen schon über eine SSH Schnittstelle. Hier das publish-subscribe Prinzip einzusetzen würde mehr Implementierungsaufwand bedeuten, als die vorhandenen Schnittstel- len zu nutzen. Natürlich können Artifact Developer entscheiden, dass die Eigenschaften des publish-subscribe Prinzip den höheren Implementierungsaufwand rechtfertigen. Sie können dann das Lifecycle Interface für ihre Geräte über ein publish-subscribe Protokoll realisieren. Wenn ohnehin eine Schnittstelle für ein neues Gerät implementiert werden soll, ist es empfehlenswert hierfür ein publish-subscribe Protokoll einzusetzen. Es können sogar mehrere Node Types die vom Linux Container Node Type erben für ein Gerät existieren, welche die Operationen des Lifecycle Interfaces über unterschiedliche Technologien und Schnittstellen implementieren. Die einzelnen Geräte müssen dann aber alle Schnittstellen aufweisen. Dann kann der Application Architect 50 3.2 Unconstrained devices entscheiden welchen Node Type er für ein Gerät verwendet. Alle Linux Container Node Types für Geräte müssen mindestens die Operationen install, start, stop und uninstall implementieren. Die configure-Operation ist bei Node Types die vom abstrakten Linux Container Node Type erben optional. Aber es muss möglich sein einen Linux Container zu installieren, zu starten, zu stoppen und wieder zu löschen. 3.2.9 Node Type für unconstrained devices In diesem Abschnitt geht es um die Node Types welche die einzelnen unconstrained devices repräsentieren. Die Properties und Interfaces dieser Node Types hängen stark vom jeweiligen Gerät ab. Es kann Geräte geben die keine Properties und kein Interface benötigt, wenn das Gerät keine Konfiguration hat und zum Provisionieren keine weiteren Daten notwendig sind. Ein solches Verfahren könnte die Geräte zum Beispiel mithilfe von mDNS5 finden. Meistens benötigen die Operationen des Lifecycle Interfaces vom zugehörigen Linux Container Node Type aber zumindest die Netzwerk Adresse in Form der IP-Adresse, des Hostnames oder allgemein einer URI unter der das Gerät erreichbar ist als Property. Aus Sicherheitsgründen sollte auch immer ein Nutzername und ein Passwort oder ein Zertifikat zur Authentifizierung verwendet werden. Die Datenübertragungen sollten auch immer verschlüsselt erfolgen. Also benötigt ein Node Type für ein Gerät meistens Properties für die Adresse, für einen Nutzernamen und ein Passwort. Zusätzliche Operationen in einem Interface können hinzukommen, wenn das Gerät vor dem Provisionieren der Linux Container noch konfiguriert werden muss. Auch sollte jedes Property vorhanden sein, das von den Operationen des zugehörigen Linux Container Node Type als Parameter benötigt wird und von ihm selbst nicht als Property bereitsteht. Bei den unconstrained devices für die mehrere Betriebssysteme zur Auswahl stehen, sollte das Be- triebssystemwie von Franco da Silva et al. [FBH+17] beschrieben als eigener Node Type dargestellt werden. Im Topologie Template befindet sich das Node Template von dem Betriebssystem Node Type zwischen dem eigentlichen Geräte Node Type und dem Linux Container Node Type. Ein Topologie Template das diesen Fall enthält ist in Abbildung 3.3 auf Seite 42 dargestellt. Dadurch ist es möglich, dass ein Betriebssystem unabhängig von der Hardware ausgetauscht oder aktualisiert werden kann. Auch ist es möglich das die install-Operation an dem Geräte Node Type das Be- triebssystem über die Netzwerkschnittstelle installiert, falls dies von dem Gerät unterstützt wird. Der Betriebssystem Node Type kann dann zum Beispiel in seiner install-Operation auch noch LXC installieren, bevor später vom Lifecycle Interface des zugehörigen Linux Container Node Type der eigentlich Linux Container provisioniert wird. Soll ein anderes Betriebssystem verwendet werden, kann das entsprechende Node Template einfach im Service Template ausgetauscht werden. Bei Geräten die kein auswechselbares Betriebssystem haben, ist es sinnvoll nur einen Node Type zu verwenden, da die Hardware und die Software eine Einheit bilden. Das Betriebssystem in dem Fall als eigenen Node Type zu modellieren würde dem Application Architect ein eigenes Verhalten des Node Types und eine Austauschbarkeit suggerieren die nicht vorhanden ist. Die Linux Container Node Types können bestimmte Requirements definieren. In den Geräte Node Types sollten die Capabilities die zu den Requirements passen bereitgestellt werden. Wenn die Capabilities nicht modelliert werden, schlagen Modellierungswerkzeuge welche überprüfen ob jedes Requirement erfüllt ist fehl. Eine Folge davon ist das ein Topology Template vielleicht nicht validiert werden kann oder dass ein TOSCA Container ein Service Template nicht provisioniert, weil er auf diese Fehler stößt. 5https://tools.ietf.org/html/rfc6762 (zuletzt besucht 17.12.2017) 51 4 Implementierung der Prototypen In den folgenden Abschnitten geht es um die Prototypen für das NodeMCU, den Raspberry Pi und die MICA. Alle Interfaces wurden in Java implementiert. Sie nutzen als Artifact TypeWAR. Alle Implementierungen wurden mit OpenTOSCA1 getestet. Der OpenTOSCA Container provisioniert die WAR Archive auf einen Tomcat Server und führt sie dort aus. Für jede Operation des Lifecycle Interfaces existiert imWARArchiv eineMethode. DieseMethodenwerden über SOAP-Nachrichten vom TOSCA Container aufgerufen. Diese SOAP-Nachrichten enthalten alle Input Parameter und weitere Header. Damit während der install-Operation des Lifecycle Interfaces das Deployment Artifact verwendet werden kann, wurde im Rahmen dieser Arbeit ein zusätzlicher Header zum TOSCA Container hinzugefügt. Dieser beinhaltet eine Liste aller Deployment Artifacts mit Namen und URLs zum Download der einzelnen Dateien. 4.1 Beschreibung des Prototyps für das NodeMCU UninstallMessage messageType: String = "uninstall" InstallMessage messageType: String = "install" installUrl : String binarySize : int hash: String StopMessage messageType: String = "stop" StartMessage messageType: String = "start" ResponseMessage messageType: String = "response" response: String hardwareId: String ConfigureMessage messageType: String = "configure" appConfig: String Abbildung 4.1: Diese Nachrichten werden im JSON Format zwischen den Operationen des Lifecycle Interfaces und den NodeMCUs ausgetauscht. Der Prototyp für constrained devices folgt dem im Abschnitt 3.1 auf Seite 33 beschrieben Lösungs- ansatz und ist im speziellen für das NodeMCU implementiert. Das Lifecycle Interface wird in Java implementiert und verwendet MQTT als publish-subscribe Protokoll. Die Semantik der einzelnen Operationen ist auch in Abschnitt 3.1 beschrieben. Für MQTT gibt es viele Implementierungen. Es existieren zum Beispiel Implementierungen in Java und für das NodeMCU in C/C++. Die Anwendung für das NodeMCU welche als Deployment Artifact im Node Template des Node 1http://www.opentosca.org/(zuletzt besucht 17.12.2017) 53 4 Implementierung der Prototypen Type NodeMCU_App hinterlegt wird kann mithilfe der Arduino IDE kompiliert und in C++ pro- grammiert werden. Für die einzelnen Operationen des Lifecycle Interfaces werden Nachrichten im JSON Format versendet. Das erlaubt auf beiden Seiten der Kommunikation eine einfache Interpretation der Nachrichten. Obwohl es kompaktere Formate als JSON gibt, hat JSON den Vorteil das es für einen Menschen lesbar ist und es dafür Bibliotheken in vielen Sprachen gibt. Die Nachrichten welche die Implementierung des Lifecycle Interfaces mit dem NodeMCU austauschen, werden in Abbildung 4.1 dargestellt. Es folgt eine Beschreibung der einzelnen Nachrichten in der Reihenfolge in welcher sie während der Verwendung des Lifecycle Interfaces genutzt werden. Die install-Nachricht enthält wie jede Nachricht den String messageType. Er enthält Informationen um welche Nachricht es sich handelt und ist statisch definiert. Die Nachricht enthält weiterhin den String installUrl. Dieser String enthält die URL unter der das Deployment Artifact über HTTP heruntergeladen werden kann. Das Deployment Artifact könnten auch in einer MQTT-Nachricht übertragen werden, da MQTT-Nachrichten bis zu einer Größe von 256 MB möglich sind und Anwendungen nicht größer sein können als der Flashspeicher der maximal 16 MB groß ist [Esp17; OAS14]. Da eine so große Nachricht nicht auf dem NodeMCU zwischengespeichert werden kann, muss während dem Empfangen der Nachricht direkt die neue Anwendung installiert werden. Das ist zwar möglich hat aber den Nachteil das, wenn ein Fehler auftritt und zum Beispiel die Netzwerkverbindung abbricht die gesamte Nachricht nochmal angefordert werden muss. Es könnte auch ein höheres Quality of Service Level verwendet werden, sodass bei einem Fehler die Nachricht vom MQTT Server noch einmal gesendet wird. Das hätte aber zur Folge das die große Nachricht beim MQTT Server im Speicher verbleiben müsste, bis diese vom NodeMCU bestätigt wird. Auch wird bei einem Fehler immer die gesamte Nachricht noch einmal übertragen, was zu einer höheren Belastung für das Netzwerk führt. Das ist vor allem wichtig, wenn viele NodeMCUs eingesetzt werden. Der Download über HTTP hat den Vorteil, das abgebrochene Downloads wiederaufgenommen werden können, wenn das vom Server unterstützt wird. Auch kann HTTP Caching nahe an den NodeMCUs verwendet werden um die Übertragung zu beschleunigen oder weniger Daten über eine limitierte Verbindung zu übertragen. Dies können zum Beispiel un- constrained devices die als Gateway konfiguriert sind übernehmen. Darüber hinaus kann das NodeMCU den Download von sich aus erneut starten und es werden kleinere Nachrichten über das MQTT Protokoll übertragen. Es sollte trotzdem mindestens das Quality of Service Level 1 verwendet werden, dass die Nachrichten bei einem Übertragungsfehler erneut versendet werden [OAS14]. Da immer zwischen Java Implementierung des Lifecycle Interface und einem einzelnen NodeMCU sich immer nur eine Nachricht auf demWeg befindet, ermöglicht das Quality of Service Level 1 auch eine geordnete Übertragung. Es wird keine start-Nachricht gesendet bevor nicht von allen NodeMCUs eine Antwort auf die install-Nachricht erhalten wurde. Eine Ausnahme hiervon bilden die NodeMCUs die nicht über das hardwareIds Property des NodeMCU Node Type bekannt sind. Das Property enthält eine JSON Liste von NodeMCU Hardware IDs die provisioniert werden sollen. Es kann nur auf NodeMCUs gewartet werden, die dem System bekannt sind. Die install-Nachricht enthält außerdem die binarySize des Deployment Artifacts. Diese Information könnte auch über das Content-Length Header Feld von HTTP erhalten werden, dieses Feld muss aber nicht immer vorhanden sein und der Update Mechanismus auf dem NodeMCU benötigt die Größe des Updates bevor die ersten Daten des Updates geschrieben werden [FGM+99]. Der letzte String heißt hash und enthält das Ergebnis einer kryptographischen Hashfunktion. Es bieten sich hier mehrere Hashfunktionen an unter anderem SHA-3 und SHA-2 an. Leider unterstützt 54 4.1 Beschreibung des Prototyps für das NodeMCU das Arduino Core for ESP8266 Projekt2 momentan nur MD5 [LGm+]. Der Hash soll gegen Über- tragungsfehler schützen, da wenn der Hash oder die Anwendung während der Übertragung beschädigt wurden, die Berechnung des MD5 Hashes auf dem NodeMCU höchst wahrscheinlich zu einem anderen Ergebnis kommt. Es stimmt dann der auf dem NodeMCU berechnete Hash nicht mehr mit dem übertragenen Hash überein. Dieses Verfahren schützt nicht gegen Man- in-the-Middle-Angriffe. Ein Angreifer der einen solchen Angriff durchführt kann einfach Hash und Anwendung zusammen austauschen. Dagegen helfen aber Transport Verschlüsselungen wie TLS. Auch sollte eine geschützte WLAN Verbindung (wie WPA2) bei dem NodeMCU genutzt werden. Auf dem NodeMCU läuft der OpenTOSCA NodeMcuManager der in Abschnitt 4.1.1 näher beschrieben ist. Dieser verarbeitet die install-Nachricht, ruft ein vom Nutzer des NodeMcu- Manager gesetztes Callback auf und führt anschließend die Installation der Anwendung die als URL gegeben ist durch. Nachdem Abschluss der Installation sendet der NodeMcuManager eine response-Nachricht an die Java Implementierung des Lifecycle Interfaces zurück und startet neu. Die response-Nachricht enthält neben dem Nachrichtentypen den String response. Dieser String beschreibt ob die Installation erfolgreich war. Wenn die Installation nicht erfolgreich war ist auch eine Fehlermeldung enthalten. Es kann zum Beispiel zu wenig Platz auf dem NodeMCU vorhanden sein, der MD5 Hash stimmt nicht mit dem lokal berechneten MD5 Hash überein oder die kompilierte Anwendung hat das falsche Magic Byte enthalten. Der String hardwareId ist in der response-Nachricht enthalten das die Nachricht in der Java Implementierung einem NodeMCU zu geordnet werden kann. Es wird vor dem Abschluss der install-Operation auf Antwort von allen be- kannten NodeMCUs gewartet. Die nächste Nachricht ist die configure-Nachricht. Sie enthält eine vom Application Architect bestimmte Anwendungskonfiguration. Diese Konfiguration wird vom NodeMcuManager über einen Callback der Anwendung übergeben. Auch diese Nachricht wird mit einer response-Nachricht beantwortet. Die start, stop und uninstall-Nachrichten führen bei der Verarbeitung durch den NodeMcuManager dazu das jeweils ein Callback in der Anwendung aufgerufen wird. Auch diese Nachrichten werden mit je einer response-Nachricht beantwortet. Die Nachrichten wurden für die Verwendung mit dem NodeMCU entworfen, sollten aber ohne oder mit wenig Anpassungen auch für andere constrained devices verwendbar sein. Einzig die install-Nachricht kann Anpassungen erforderlich machen, wenn das constrained device einen anderen Mechanismus zum Installieren von Anwendungen aufweist. 4.1.1 OpenTOSCA NodeMcuManager Das NodeMCU kann so wie es hier verwendet wird nur eine Anwendung gleichzeitig ausführen und installiert haben. Die Anwendung welche dem Node Template als Deployment Artifact mitgegeben wird überschreibt also bei der Installation die Anwendungen welche davor installiert war. Deshalb muss auch die Anwendung vom Nutzer die provisioniert wird über MQTT weitere Nachrichten von der Implementierung des Lifecycle Interfaces empfangen können. Sonst würden die configure-, start-, stop- und uninstall-Nachrichten nicht verarbeitet werden. Im Folgenden wird der Teil der Anwendung die vom Nutzer stammt, also ohne die Funktionalität für die Provi- sionierung und der Nachrichtenverarbeitung Geschäftslogik genannt. Es kann viele verschiedene Geschäftslogiken geben, die aber alle die gleiche Funktionalität benötigen. Diese Funktionalität ist das Verbinden mit dem MQTT Server und das Verarbeiten der Nachrichten. Deshalb wird 2https://github.com/esp8266/Arduino (zuletzt besucht 17.12.2017) 55 4 Implementierung der Prototypen TOSCA Container MQTT MQTT Server MQTT NodeMCU NodeMcu Manager Geschäfts- logik Methodenaufrufe und Callbacks WLAN Abbildung 4.2: Verbindungen zwischen den einzelnen Komponenten und dem NodeMcu- Manager. diese Funktionalität in eine eigene Bibliothek ausgelagert. Die Bibliothek wird im Folgenden als OpenTOSCA NodeMcuManager oder kurz als NodeMcuManager bezeichnet. Diese Bibliothek enthält alle Funktionalität die zur Provisionierung mithilfe von TOSCA notwendig ist. Wie in Abbildung 4.2 zu sehen ist vermittelt der NodeMcuManager über den MQTT Server zwischen dem TOSCA Container und der Geschäftslogik. Der TOSCA Container kümmert sich um die Provisionierung des gesamten Service Templates und wird im Laufe dessen die Operationen des Lifecycle Interfaces aufrufen. Diese sind als Webanwendung in Form eines Web Application Archive (WAR) in Java implementiert und werden innerhalb des TOSCA Containers ausgeführt. Die einzelnen Operationen sind in Abschnitt 3.1.1 genauer beschrieben. Sie tauschen MQTT- Nachrichten über einen MQTT Server mit dem NodeMcuManager aus. Der NodeMcuManager kommuniziert mit Methodenaufrufen und Callbacks mit der Geschäftslogik. Um den NodeMcu- Manager zu implementieren gibt es generell zwei verschiedene Arten. Da das Projekt Arduino core for ESP8266 WiFi chip3 genutzt wird, könnte der NodeMcuManager direkt in dieses Projekt integriert werden. Ein Arduino Sketch besteht im Wesentlichen am Anfang aus zwei Funktio- nen, der setup- und der loop-Funktion. Die setup-Funktion wird vom Entwickler des Sketches dazu genutzt Pins zu initialisieren, angeschlossene Sensorik oder Aktuatoren zu initialisieren oder zum Beispiel eine WLAN Verbindung aufzubauen. Die loop-Funktion wird immer wieder aufgerufen und hier ist meistens die eigentliche Funktionalität der Sketches enthalten. Durch eine Implementierung des NodeMcuManager im Arduino Core könnte man das Aufrufverhalten für diese Methoden verändern. So könnte die Initialisierung des NodeMcuManager vor dem ersten Aufruf der setup-Funktion ausgeführt werden. Die Arbeiten die für das Aufrechterhalten der MQTT Verbindung nötig sind könnten einfach vor jedem loop Aufruf durchgeführt werden. Außerdem könnte nach einer stop-Nachricht die loop-Funktion nicht mehr ausgeführt werden. Im Abschnitt 3.1.1 wurde beschrieben das die Geschäftslogik welche auf dem NodeMCU läuft nicht ohne Weiteres gestoppt werden darf, da diese in einen sicheren Zustand zurückkehren können muss. Das würde sich bei diesem Ansatz durch Funktionen wie stop und uninstall im- plementieren lassen. Diese müssten ähnlich wie setup und loop im Sketch enthalten sein und vom Entwickler der Geschäftslogik implementiert oder leer gelassen werden. Das hätten den Vorteil das sich der Entwickler der Geschäftslogik um sehr wenig kümmern müsste und sich die eigentliche Struktur eines Sketches nicht verändert. Weiterhin müsste ein Entwickler von einer Geschäftslogik keine zusätzlichen Konzepte lernen und für den Sketch wäre es schwerer die 3https://github.com/esp8266/Arduino (zuletzt besucht 17.12.2017) 56 4.1 Beschreibung des Prototyps für das NodeMCU Funktionalität des NodeMcuManager zu stören. Aber diese Art der Implementierung hat auch Nachteile. So müssen die Änderungen welche für den NodeMcuManager notwendig sind bei jedem Update des Arduino Core Projekt auf Kompatibilität mit dem Update überprüft werden. Selbst wenn die Funktionalität des NodeMcuManager und die Funktionalität des Arduino Cores getrennt implementiert wurde und diese nur über Schnittstellen kommunizieren, könnte bei einer Änderung der internen Struktur des Arduino Cores eine komplette Neuimplementierung der Schnittstelle innerhalb des Arduino Core nötig sein. Auf Updates ganz zu verzichten ist aus mehreren Gründen nicht empfehlenswert. Einerseits können die Updates sicherheitsrelevante Änderungen enthalten. Anderseits wären Nutzer des NodeMcuManager ohne Updates für immer von neuen Features des Arduino Cores abgeschnitten. Darüber hinaus wäre ein NodeMcuManager der in den Arduino Core für den ESP8266 integriert ist, schwerer auf andere Arduino kompatible Hardware zu portieren. Die andere Möglichkeit ist den NodeMcuManager als Arduino Bibliothek zu implementieren. Diese Lösung funktioniert unabhängig vom Arduino Core und lässt sich vom Nutzer einfach in die Arduino IDE einbinden. Updates für den NodeMcuManager und den Arduino Core können weitgehend unabhängig voneinander durchgeführt werden. Auch ist es weniger kompliziert den NodeMcuManager auf andere Arduinos zu portieren. Nachteilig an dieser Lösung ist vor allem das der Entwickler der Geschäftslogik das Konzept eines Konstruktors und das Konzept von Callbacks in C++ verstehen muss. Das ist vor allem problematisch da sich das Arduino Ökosystem unter anderem auch an Programmieranfänger richtet und die Voraussetzung dieser Kenntnisse diesem Ziel widerspricht. Da für das Verwenden des NodeMcuManagers aber allgemein eine umfangreiche Kenntnis der TOSCA Spezifikation empfehlenswert ist, richtet sich der NodeMcuManager eher an eine fortgeschrittene Zielgruppe. Aus den beiden Möglichkeiten den NodeMcuManager für das NodeMCU zu implementieren wurde die Umsetzung als Arduino Bibliothek gewählt da diese einfache Updates ermöglicht und bessere Portabilität bietet. Im Folgenden wird diese Variante näher beschrieben. NodeMcuManager als Bootstrap-Anwendung Um ein NodeMCU über TOSCA mit Software zu provisionieren muss das NodeMCU eine WLAN Verbindung aufgebaut habe. Sonst kann sich der NodeMcuManager nicht über einen MQTT Server mit dem TOSCA Container verbinden. Dazu muss auf dem NodeMCU der Name des WLAN- Netzwerks und die Anmeldedaten vorliegen. Auch der NodeMcuManager auf dem NodeMCU muss wissen zu welchemMQTT Server eine Verbindung aufgebaut werden soll und welches Topic später genutzt wird. Diese Informationen sind von dem jeweiligen Einsatzort der NodeMCUs und von der Netzwerktopologie in der sie eingesetzt werden abhängig. Der MQTT Server kann wie das NodeMCU von TOSCA provisioniert werden. Für diesen Zweck kann ein eigenes Service Template wie es in Abbildung 4.3 dargestellt wird, verwendet werden. In diesem Service Template gibt es ein MQTT Server der Mosquitto4_3.1 als Node Type hat. Mosquitto ist ein Open Source MQTT Server der in diesem Beispiel auf einem Ubuntu 16.04 läuft. Das Betriebssystem läuft auf einer virtuellen Maschine die von OpenStack verwaltet wird. Es könnte aber genauso gut ganz andere Software in einer anderen Topologie verwendet werden, wichtig ist das der NodeMcu- Manager einen MQTT Server hat mit dem er sich verbinden kann. Da der NodeMcuManager die Verbindungsinformationen für MQTT, die WLAN Anmeldedaten und den WLAN Name benötigt, 4https://mosquitto.org/ (zuletzt besucht 17.12.2017) 57 4 Implementierung der Prototypen (HostedOn) (HostedOn) MQTT Server (Mosquitto_3.1) Betriebssystem (Ubuntu-16.04 VM) OpenStack (OpenStack-Liberty-12) Abbildung 4.3: Das Topology Template enthält einen MQTT Server, das Betriebssystem und mit OpenStack eine Infrastrukturkomponente [basiert auf FBH+17]. bevor er über TOSCA mit Software provisioniert werden kann, muss er mit einer minimalen Anwendung über USB bespielt werden. Diese Anwendung welche vor dem Provisionieren über TOSCA auf den NodeMCU übertragen werden muss wird im Folgenden als Bootstrap-Anwendung bezeichnet. Die Bootstrap-Anwendung muss aber nur einmal über USB übertragen werden, da der NodeMcuManager so ausgelegt ist, dass er immer das Provisionieren einer weiteren Anwendung erlaubt. Eine Ausnahme ist, wenn ein NodeMCU in eine neue Umgebung gebracht wird und sich nicht mit dem WLAN verbinden kann. Dann muss auch wieder die Bootstrap-Anwendung installiert werden. Im Listing 4.1 ist eine minimale Version von einer solchen Bootstrap-Anwendung unter Verwen- dung des NodeMcuManager zu sehen. In den Zeilen 1 und 2 werden der Name des zu verwenden- den WLAN Netzwerkes und das WLAN Passwort definiert. In Zeile 3 wird die IP-Adresse des MQTT Brokers eingetragen. Zeile 4 enthält Deklaration und Initiation des NodeMcuManager. In diesem Beispiel wird dem Konstruktor die Adresse des MQTT Server übergeben und die Stan- dartwerte für Port, controlTopic und responseTopic genutzt. Werden im Node Template des Node Types NodeMCU andere Werte für controlTopic und responseTopic verwendet, müssen hier die gleichen Werte gesetzt werden. In Zeile 6 beginnt die setup-Funktion, sie wird vom Arduino Core aufgerufen und beinhaltet Code der nur einmal nachdem Start des NodeMCUs ausgeführt wird. Die Zeilen 7 bis 11 beinhalten die Logik um eine Verbindung per WLAN herzustellen. Danach wird in Zeile 12 dem NodeMcuManager mitgeteilt das er eine MQTT Verbindung aufbauen soll und mit seiner Arbeit beginnen kann. Die loop-Funktion wird dazu genutzt den NodeMcuManager periodisch immer wieder aufzurufen. Das ist nötig da der NodeMcuManager nur dann aktiv wird und neue Nachrichten verarbeitet und zum Beispiel MQTT PINGREQ Nachrichten versendet um den Server zu signalisieren das der Client noch aktiv ist [OAS14]. Der in Listing 4.1 gezeigt Code ist aber nur die minimalistische Form des NodeMcuManager. Der Artifact Developer kann je nach Verwendung der NodeMCUs den Code noch erweitern. Ein automatischer Neuaufbau der WLAN Verbindung bei einer Unterbrechung wäre zum Beispiel noch empfehlenswert. Auch ist der Nutzer nicht gezwungen die WLAN Daten statisch in das Programm einzubetten, sondern kann diese 58 4.1 Beschreibung des Prototyps für das NodeMCU ebenfalls vom Flashspeicher lesen oder die Daten per I2C erhalten. Eine weitere Möglichkeit ist ein Display und eine Tastatur zu verwenden um die Daten nachdem Start von einem Benutzer abzufragen. Listing 4.1Minimal Bootstrap NodeMcuManager 1 const char* ssid = "WLAN-SSID"; 2 const char* password = "password"; 3 String mqttServer = "192.168.0.10"; 4 ToscaManager tManager(mqttServer); 5 6 void setup() { 7 WiFi.mode(WIFI_STA); 8 WiFi.begin(ssid, password); 9 while(WiFi.waitForConnectResult() != WL_CONNECTED){ 10 WiFi.begin(ssid, password); 11 } 12 tManager.connect(); 13 } 14 void loop() { 15 tManager.loopManager(); 16 } Integration des NodeMcuManager in die Geschäftslogik Nachdem die Bootstrap-Anwendung per USB hochgeladen wurde und das NodeMCU per WLAN verbunden ist, kann sich der NodeMcuManager mit dem MQTT Server verbinden. Ab diesem Zeitpunkt kann der NodeMcuManager von dem TOSCA Container über MQTT angesprochen werden. Dieser führt dann die install-Operation aus. Die install-Operation überträgt die im Deployment Artifacts des Node Templates vom Typen NodeMCU_App enthaltene Anwendung des Nutzers auf den NodeMCU. Die NodeMCU Anwendung ist eine Kombination aus Geschäftslogik und NodeMcuManager. Der NodeMcuManager muss enthalten sein, da es sonst nicht möglich wäre die Management Operationen nach Installation der Anwendung zu nutzen. So müssen die Operationen configure, start, stop und uninstall nach der Installation nutzbar sein. Auch install muss erneut ausgeführt werden können um die Installation einer anderen Anwendung zu ermöglichen. Die Kommunikation zwischen dem NodeMcuManager und der Geschäftslogik erfolgt über Callbacks und Methodenaufrufe wie in Abbildung 4.2 auf Seite 56 zu sehen ist. Die Geschäftslogik kann auf Basis des Quellcodes wie er in Listing 4.1 gezeigt ist entwickelt werden. Es müssen bei der Geschäftslogik die gleichen Schritte befolgt werden wie bei der Bootstrap- Anwendung. Der NodeMcuManager bietet für die Operationen des Lifecycle Interfaces jeweils eine Methode an, um ein Callback zu setzen zu können. Alle Callbackswurden so gestaltet das diese über Funktionen ähnlich der setup und der loop Funktion realisiert werden können. Hierzu wird vom Entwickler der Geschäftslogik jeweils eine Funktion für jedes Callback im Sketch implementiert. Für die install-Operation des Lifecycle Interfaces existiert setCallbackInstall. Hier muss nur der Funktionsname mit einem Referenz Operator (&) als Präfix übergeben werden. Diese Funktion wird aufgerufen kurz bevor eine andere Geschäftslogik oder ein Update installiert wird. Die Geschäftslogik sollte in dieser Funktion sicherstellen das alle geöffneten Netzwerkverbindungen geschlossen werden und alle Aktionen beenden die ein Update stören können. Dazu zählt zum Beispiel der Neustart des NodeMCU oder das Aktivieren eines Energiesparmodus. Darüber hinaus sollte die Geschäftslogik die WLAN-Verbindung nicht trennen und alle Aktuatoren die 59 4 Implementierung der Prototypen angeschlossen sind in einen sicheren Zustand überführen. Das genaue Vorgehen ist aber vom Anwendungsfall abhängig. Nachdem diese Funktion beendet ist führt der NodeMcuManager die Installation durch und startet das NodeMCU neu. Das Callback für die configure-Operation des Lifecycle Interfaces wird mit setCallbackConfigure gesetzt. Die Funktion welche hier als Callback gesetzt wird hat die Besonderheit das sie einen Parameter vom Typen String aufweisen muss. Dieser Parameter enthält die appConfig welche im Node Template gesetzt wurde. Der Inhalt von appConfig ist komplett dem Entwickler der Geschäftslogik überlassen. Es könnte zum Beispiel eine Pinbelegung eines angeschlossenen Sensors sein. Wichtig ist das der NodeMcuManager die Konfiguration nicht speichert. Die Geschäftslogik könnte die Konfiguration aber auf dem Dateisystem des Flashspeichers ablegen welches vom NodeMcuManager niemals überschrieben wird. Das Setzen des Callback für die start-Operation geht ähnlich zu der install- und configure- Operation. Wird die Funktion aufgerufen soll das Ausführen der Geschäftslogik gestartet werden. Offensichtlich läuft die Anwendung schon bevor das start Callback ausgeführt wurde, da bei dem hier verwendeten Arduino core for ESP8266 WiFi chip immer nur eine Anwendung gleichzeitig auf dem NodeMCU installiert sein kann und die configure-Operation gewöhnlich vor start aufgerufen wird. Die start-Operation signalisiert der Geschäftslogik also nur das sie ab diesem Zeitpunkt mit ihrer eigentlichen Arbeit beginnen kann. Das könnte zum Beispiel das Auslesen eines Sensors sein. Wichtig ist das die Methode loopManager (Zeile 14 in Listing 4.1) unabhängig davon aufgerufen wird. Diese Methode muss periodisch nachdem Aufruf der connect-Methode (Zeile 12) ausgeführt werden, sodass der NodeMcuManager die MQTT Verbindung aufrecht halten kann. Wird die stop-Nachricht empfangen, stoppt die Ausführung der Geschäftslogik nicht, sie wird nur durch den Aufruf des Callbacks darüber informiert, dass die Geschäftslogik nicht mehr ausgeführt werden soll. Das heißt die Anwendung muss ähnlich wie bei der install-Operation alle eigenen geöffneten Verbindungen schließen und alle angeschlossenen Aktuatoren in einen sicheren Zustand überführen. Die letzte Operation im Lifecycle Interface welche noch nicht betrachtet wurde ist die uninstall-Operation. Auch hier wird eine Funktion als Callback vom Entwickler der Geschäftslogik implementiert. Diese Funktion muss alle angeschlossenen Aktuatoren in einen sicheren Zustand überführen, wenn das noch nicht durch Aufrufen von stop passiert ist und alle nicht gespeicherten Werte übertragen oder im Flashspeicher Dateisystem speichern. Nachdem Ausführen des stop Callback kann immer wieder eine start-Nachricht kommen um die Geschäftslogik zu starten. Dies kann nachdem Ausführen von uninstall nicht mehr passieren. Wenn nicht davon auszugehen ist, dass eine zukünftige Version der Anwendung die Daten auf dem Flashspeicher Dateisystem noch benötigt, sollte dieser gelöscht werden. Die uninstall-Operation des Lifecycle Interfaces löscht also die Anwendung nicht, sondern teilt ihr nur mit das sie nie wieder starten wird. Die Geschäftslogik kann nicht im eigentlichen Sinn von uninstall gelöscht werden da hierbei auch der NodeMcuManager entfernt werden würde und somit keine weitere install-Operationen mehr möglich wären. Das NodeMCU würde dann nicht mehr vom TOSCA Container erreichbar sein. Dadurch würde das Aufspielen der Bootstrap-Anwendung über USB wieder notwendig werden. Es wäre möglich das während der uninstall-Operation einfach wieder die Bootstrap-Anwendung installiert wird. Dies würde aber zusätzliche Logik erfordern ohne, dass ein Mehrwert entsteht. Auch müsste die Bootstrap-Anwendung dann auf dem NodeMCU oder auf einem Server gespeichert werden. Das Verhalten der Geschäftslogik kann vom NodeMcuManager nicht überprüft werden. Es ist Aufgabe des Entwicklers der Geschäftslogik die in diesem Abschnitt beschriebene Semantik umzusetzen. Weiterhin zu beachten ist, dass keine Verbindung mit dem NodeMCU aufgebaut werden kann und die MQTT Verbindung abbricht sobald die Geschäftslogik den NodeMCU in einen Energiesparmodus versetzt. Das NodeMCU wird auch unerreichbar, wenn in der Geschäftslogik ein Fehler auftritt der eine Exception ausgelöst. Auch darf die Geschäftslogik 60 4.2 Beschreibung des Prototyps für den Raspberry Pi den RAM nicht komplett füllen. Bei der Entwicklung des NodeMcuManagers wurde darauf geachtet, dass weiterhin die Arduino IDE verwendet werden kann. Der NodeMcuManager ist als Arduino Bibliothek implementiert und wird nach der Installation der Bibliothek auch in der IDE angezeigt. Dies wurde mit der Arduino IDE Version 1.8.3 getestet. 4.2 Beschreibung des Prototyps für den Raspberry Pi Für den Raspberry Pi gibt es einen anderen Lösungsansatz als für das NodeMCU, deshalb unter- scheiden sich auch die Prototypen. Der Prototyp für den Raspberry Pi folgt dem in Abschnitt 3.2 beschrieben Ansatz. Es kann ein Topology Template wie in Abbildung 4.4 dargestellt wird verwen- det werden um einen Linux Container auf den Raspberry Pi zu provisionieren. Die Node Types RaspbianStretchLXC und LXContainerRaspberryPi enthalten jeweils das Lifecycle Interface. Der Node Type LXContainerRaspberryPi verfügt über alle Operationen des Lifecycle Interfaces, der RaspbianStretchLXC Node Type hat nur die install-Operation. Für jedes der Interfaces existiert ein Implementation Artifact. Das Implementation Artifact ist ein Java Web Archiv das vom TOS- CA Container ausgeführt wird. In dem Web Archiv existiert für jede Operation eine Methode. Die install-Operation am RaspbianStretchLXC nutzt die Properites userName, userPassword und addresses um sich per SSH mit den Raspberry Pis zu verbinden. Ähnlich wie beim NodeMCU repräsentiert ein Node Template vom Typ RaspbianStretchLXC im Topology Template mehrere Raspberry Pis. Das unterstützt den Application Architect beim Modellieren von einer großen Anzahl an Geräten. Man könnte sich das Ganze auch als Cluster von Raspberry Pis vorstellen. Damit eine Verbindung per SSH möglich ist, muss das Betriebssystem auf der microSD Karte installiert und SSH aktiviert sein. Auch benötigt der angegebene User root-Rechte. SSH kann bei Raspbian auch über eine Datei auf der microSD Karte aktiviert werden. Anders als bei dem NodeMCU muss keine spezielle Schnittstelle zur Provisionierung entwickelt werden, es kann das schon bestehende SSH Protokoll genutzt werden. Nachdem sich die Implementierung der install-Operation per SSH mit dem Raspberry Pi verbunden hat, wird überprüft ob LXC installiert ist. Wenn das nicht der Fall ist, wird es installiert. Das wird für jeden Raspberry Pi in dem JSON Array das in addresses gespeichert ist durchgeführt. Der Prototyp wurde mit Raspbian Stretch (Veröffentlichungsdatum: 07.09.2017) getestet. Das oberste Node Template in der Abbildung 4.4 heißt Anwendung und repräsentiert die An- wendung, welche in Form eines Linux Containers, auf den Raspberry Pi provisioniert wird. Das Node Template verfügt über ein Deployment Artifact. Es enthält ein komprimiertes Archiv des Dateisystemes des Linux Containers. Jeder Linux Container hat eine Konfiguration, die mit dem Property lxcConfiguration festgelegt werden kann. Bleibt das Property leer, so wird eine Standart- konfiguration verwendet bei der Wert auf hohe Kompatibilität gelegt wurde. Die Implementierung des Lifecycle Interfaces nutzt die Properties des RaspbianStretchLXC Node Types um per SSH mit den Raspberry Pis zu verbinden. Alle Operationen die der Node Type LXContainerRaspberryPi aufweist sind in Tabelle 4.1 dargestellt. Deshalb sind die Properties auch als Input Parameter in jeder Operation vorhanden. Während der install-Operation lädt sich die Implementierung der in- stall-Operation das Deployment Artifact herunter. Dieses Deployment Artifact wird dann per SFTP auf die Raspberry Pis übertragen. Das Archiv wird dort entpackt. Die configure-Operation nimmt als Input Parameter zusätzlich zu den anderen Properties des RaspbianStretchLXC Node Types noch das Property lxcConfiguration. In der configure-Operation wird entweder die Konfiguration aus dem Property auf den Raspberry Pi übertragen oder wenn das Property keine Konfiguration 61 4 Implementierung der Prototypen Anwendung (LXContainerRaspberryPi) Deployment Artifacts: lxContainerImage Properties: lxcConfiguration: „lxcConfig“ Requirements: HardwareReqRaspberryPi3 Raspbian (RaspbianStretchLXC) Properties: userName: „user“ userPassword: „password“ addresses: [ "192.168…" ] RaspberryPis (RaspberryPi3) Capability: HardwareCapRaspberryPi3 (HostedOn) (HostedOn) Abbildung 4.4: Die Topologie enthält alle Komponenten die zur Provisionierung der Raspberry Pis benötigt werden. Die Anwendung welche provisioniert wird, das Betriebs- system welches auf dem Raspberry Pi läuft und den Raspberry Pi selbst. enthält eine Standartkonfiguration zusammengestellt und übertragen. Die Konfiguration zusam- men mit dem Dateisystem des Linux Container bilden einen Linux Container der von der Software LXC verwendet werden kann. Die start-Operation verbindet sich per SSH mit den Raspberry Pis und startet den Linux Container. Die stop-Operation stoppt den Container auf allen Raspberry Pis. Eine aufwendige Logik um die Anwendungen im Container über ein Stoppen zu informieren, sodass diese in einen sicheren Zustand übergehen können, ähnlich wie bei dem Prototyp für das NodeMCU ist hier nicht notwendig da lxc-stop genutzt wird. Lxc-stop führt, wenn möglich 62 4.3 Beschreibung des Prototyps für die MICA einen clean shutdown durch auf den Anwendungen im Container reagieren können [Lez17]. Die uninstall-Operation löscht den Container von allen Raspberry Pis. Wie in Tabelle 4.1 dargestellt weisen alle Operationen einen Output Parameter auf. Dieser gibt immer die Anzahl der Geräte die betroffen sind an. Dadurch kann überprüft werden ob die jeweilige Operation auf allen Raspberry Pis ausgeführt wurde. Prinzipiell laufen Linux Container die für die MICA erstellt wurden auch auf dem Raspberry Pi, da diese zwei Geräte über eine kompatible Prozessorarchitektur verfügen. Linux Container die auf dem Raspberry Pi erstellt wurden laufen aber nicht unbedingt auf der MICA, da diese eine vorgegebene Linux Container Konfiguration hat. Mit dieser Konfiguration sind nicht alle Linux Container die auf dem Raspberry Pi erstellt wurden kompatible. Aus diesem Grund wurden alle Tests mit den von Harting bereit gestellten Container durchgeführt. Diese laufen bis auf die Container mit Abhängigkeiten zu den Services des MICA oder zu Hardware die nur auf dem MICA vorhanden ist auf dem Raspberry Pi. Im Speziellen wurde der Container Debian_Stretch in der Version v1.0.0_r verwendet. Das Requirement HardwareReqRaspberryPi3 kann von einem Application Architect im Node Template gesetzt werden, wenn er sicherstellen möchte das als Hardware auch wirklich ein Raspberry Pi 3 eingesetzt wird. Das ist vor allem hilfreich, wenn mehrere Application Architecten an dem Service Template arbeiten. So können Fehler vermieden werden. Das letzte Node Template repräsentiert die Raspberry Pi Hardware. In diesem Node Template kann die Capability HardwareCapRaspberryPi3 gesetzt werden. Diese Capability erfüllt dann das Requirement des Anwendungs Node Templates. Operation Input Parameters Output Parameters install userName, userPassword, addresses installedDeviceCount, availableSpace configure lxcConfiguration, userName, userPassword, addresses configuredDeviceCount start userName, userPassword, addresses startedDeviceCount stop userName, userPassword, addresses stoppedDeviceCount uninstall userName, userPassword, addresses uninstalledDeviceCount, availableSpace Tabelle 4.1: Enthält alle Operationen des Lifecycle Interfaces für den Node Type LXContainer- RaspberryPi. 4.3 Beschreibung des Prototyps für die MICA Die MICA hat anders wie der Raspberry Pi oder das NodeMCU eine vom Hersteller in die Firm- ware eingebaute Schnittstelle um Anwendungen zu provisionieren. Die Anwendungen werden in Form von Linux Container über eine JSON-RCP 2.0 Schnittstelle übertragen und gemanag- te. Außerdem bietet die MICA eine Weboberfläche für diese Funktionalität an. Der Prototyp wurde mit dem Linux Container Debian_Stretch in der Version v1.0.0_r, der Firmware Version 1.5.0 und der Interface Version 1.2.0 getestet. Die Abbildung 4.5 zeigt das Topologie Template welches für den Prototypen des MICA verwendet wird. Das obere Node Template Anwendung enthält das Deployment Artifact welches auf die MICA übertragen wird. Das Deployment Arti- fact enthält auch hier ein komprimiertes Archiv des Linux Container Dateisystems. Der Node 63 4 Implementierung der Prototypen Anwendung (LXContainerMICA) Requirements: HardwareReqMICA MICA (MICA) Properties: userName: „user“ userPassword: „password“ addresses: [ "192.168…" ] certificates: [ "–BEGIN…" ] (HostedOn) Deployment Artifacts: lxcContainerImage Capability: HardwareCapMICA Abbildung 4.5: Die Topologie enthält alles was zur Provisionierung einer Anwendung auf die MICA benötigt wird. Type LXContainerMICA definiert das Lifecycle Interface und es werden alle Operationen außer die configure-Operation verwendet. Die Implementierung der Operationen wird wie bei dem Prototypen für den Raspberry Pi und für das NodeMCU mit einem Java Web Archiv realisiert. Um die Verbindungen zu einem MICA aufzubauen werden die Properties aus dem MICA Node Type benötigt. Die Adresse aus dem Property addresses wird benötigt um die MICAs zu finden. Die Properties userName und userPassword werden benötigt um sich gegenüber dem MICA zu authentifizieren und ein Authentifikationstoken zu erhalten. Da von den MICAs selbst signierten Zertifikaten verwendet werden und diese nicht von einem übergeordneten Zertifikat signiert wurden, müssen alle vor der ersten Verbindung bekannt sein. Sonst könnte ein Angreifer einfach ein eigenes selbst signiertes Zertifikat generieren und dies bei einem Man-in-the-Middle-Angriff gegenüber der Java Implementierung präsentieren. Da auch beim MICA Prototypen das MICA Node Template mehrere MICAs repräsentiert werden die Operationen Lifecycle Interfaces auf jedem MICA ausgeführt. Die einzelnen MICAs werden über die Adressen in dem als JSON Array formatierten Property addresses repräsentiert. Auch müssen die Zertifikate von allen MICAs im PEM Format hinterlegt sein. Die Zertifikate werden ähnlich wie die Adressen als JSON Array hinterlegt. Die install-Operation übertragt den Linux Container aus dem Deployment Artifact 64 4.4 Anwendungsszenario in Teilen auf die MICA und startet den Installationsvorgang. Ist dieser auf jedem bekannten MICA abgeschlossen, meldet die install-Operation die Anzahl der MICAs auf denen der Container installiert wurde an den TOSCA Container über einen Output Parameter zurück. Mithilfe der start-Operation kann ein Container auf den MICAs gestartet werden. Diese Operation wird im Lifecycle Interface normalerweise nach der configure-Operation ausgeführt. Da die Container als immutable Container betrachtet werden und die LXC Konfiguration fest voreingestellt ist, gibt es bei diesem Node Type keine configure-Operation. Die stop-Operation stoppt den Container auf allen MICAs. Auch hier wird ähnlich wie beim Raspberry Pi ein clean shutdown durchgeführt sodass keine weitere Logik benötigt wird um die Anwendungen im Container über ein Stoppen zu informieren. Die uninstall-Operation löscht den Container von allen MICAs. Der Node Type MICA hat kein Lifecycle Interface, da alles was zum Verwenden der Container benötigt wird, schon vom Hersteller des MICAs in die Firmware integriert wurde. Es muss also nichts Installiert werden. 4.4 Anwendungsszenario (HostedOn) (HostedOn) (HostedOn) (HostedOn) (ConnectsTo) (ConnectsTo) Deployment Artifacts InFluxDBContainer (LXContainerMICA) InFlux… InFlux… LinuxC… RaspberryPi3 (RaspberryPi3) userName pi userPasswordraspberry addresses [ "192.168.0.19" ] Properties RaspbianStretchLXC (RaspbianStretchLXC) lxcConfigurationEmpty Properties Deployment Artifacts NodeRedContainer (LXContainerRaspberryPi) NodeR… NodeR… LinuxC… appConfig{ "interval" : 3000 } Properties Deployment Artifacts SensorPublisher (NodeMCU_App) Sensor… Sensor… NodeM… hardwareIds [ "1345963", "1361877", "8797990" ] mqttServer tcp://192.168.0.27:1883 controlTopic controlTopic responseTopicresponseTopic Properties NodeMCU (NodeMCU) userNameMica admin userPasswordMicaadmin addressesMica [ "https://192.168.0. certificatesMica ["-----BEGIN CERTIFICATE----- Properties MICA (MICA) Pa le tte Save Print View Split Match Import Topology Layout Align-h (|) Align-v (-) Ids Deployment Artifacts Requirements & Capabilities Policies Target Locations Other Types Properties Abbildung 4.6: Enthält das Anwendungsszenario als Model in Eclipse Winery5. Das Anwendungsszenario basiert auf den Prototypen aus den Abschnitten 4.1 bis 4.3. Es orientiert sich an Szenarien die oft im Internet of Things vertreten sind. Von den NodeMCUs werden Sensor- werte erfasst. Diese werden anschließend in einem Zwischenschritt verarbeitet und schlussendlich in einer Datenbank gespeichert. Die gesamte Topologie wird mit den in Kapitel 3 vorgestellten 5https://projects.eclipse.org/projects/soa.winery (zuletzt besucht 17.12.2017) 65 4 Implementierung der Prototypen Konzepten und den in Kapitel 4 gezeigten Prototypen umgesetzt. In Abbildung 4.6 ist die Topo- logie des Anwendungsszenarios dargestellt. Die Topologie wurde mit Eclipse Winery erstellt1. Die meisten Properties sind von der jeweiligen Umgebung und den einzelnen Geräten abhängig. Links oben in der Abbildung befindet sich das Node Template SensorPublischer. Dabei handelt es sich um eine Anwendung die unter Verwendung des NodeMCU Prototypen für das NodeMCU entwickelt wurde. Sie liest einen angeschlossenen DHT22 Sensor aus und übermittelt die aus- gelesenen Temperatur- und Luftfeuchtigkeitswerte per MQTT. Diese Anwendung befindet sich in kompilierter Form in dem SensorPublischer Node Template als Deployment Artifact. Da das Node Template SensorPublischer mit einem HostedOn Relationship Template mit dem NodeMCU Node Template verbunden ist, wird die NodeMCU Anwendung auf den NodeMCUs provisioniert. In diesem Anwendungsszenario steht das Node Template NodeMCU für drei NodeMCUs. Ihre Hardware IDs werden in dem entsprechenden Property als JSON Array gesetzt, sodass bei der Provisionierung auf die Antworten von allen NodeMCUs gewartet werden kann. In der Mitte oben befindet sich das Node Template NodeRED. Das ist ein Linux Container der NodeRED6 und alle Abhängigkeiten inklusive Node.js7 enthält. NodeRED ist ein Tool mit dem unter Verwendung von Bausteinen und Verbindungen komplexe Regeln für die Verarbeitung von Daten erstellt und angewendet werden können. Das komprimierte Dateisystem des Linux Containers ist das Deploy- ment Artifact des NodeRED Node Templates. NodeRED erhält die Werte von den Sensoren, bildet einen Mittelwert und visualisiert die Daten in einem Dashboard8. Ein Screenshot des Dashboards ist in Abbildung 4.7 zu sehen. NodeMCU 1 17.9 °C0 50 40.4 RH0 90 NodeMCU 2 23.2 °C0 50 48.5 RH0 90 NodeMCU 3 23 °C0 50 49.6 RH0 90 Durchschnitt 20.5 °C0 50 45 RH0 90 Temperatur Luftfeuchtigkeit Temperatur Luftfeuchtigkeit Temperatur Luftfeuchtigkeit Temperatur Luftfeuchtigkeit Home Abbildung 4.7: Das Dashboard zeigt die letzten Temperatur- und Luftfeuchtigkeitswerte aller NodeMCUs und Durchschnittswerte an. Das Dashboard wurde mithilfe des NodeRED Module node-red-dashboard8 erstellt. Dieser Linux Container wird auf ein Raspberry Pi provisioniert. Der Raspberry Pi nutzt das Be- triebssystem Raspbian9. Auf diesem wird im Lifecycle Interface des entsprechenden Node Types die Software LXC installiert. Das Raspbian Betriebssystem ist mit einem HostedOn Relationship Template mit der Hardware des Raspberry Pi 3 verbunden. NodeRED speichert die Werte in 6https://nodered.org/ (zuletzt besucht 17.12.2017) 7https://nodejs.org/en/ (zuletzt besucht 17.12.2017) 8https://github.com/node-red/node-red-dashboard (zuletzt besucht 17.12.2017) 9https://www.raspbian.org/ (zuletzt besucht 17.12.2017) 66 4.4 Anwendungsszenario der Datenbank InfluxDB10. InfluxDB ist eine Datenbank die unter anderem auf Sensordaten von IoT Geräten spezialisiert ist. Sie läuft in einem Linux Container der auf die MICA provisioniert wird. Auch bei diesem Linux Container wurde das Dateisystem komprimiert und als Archiv im Deployment Artifact des Node Templates InfluxDB gespeichert. Die in diesem Anwendungsfall enthaltene Linux Container sind unter den unconstrained devices austauschbar. Es wäre ohne Änderungen an den Container möglich NodeRED auf der MICA und InfluxDB auf dem Raspberry Pi zu betreiben. Es müssten nur die Node Types von den zwei Komponenten zusammen mit den Geräte spezifischen Node Templates ausgetauscht werden. Genau wie die Node Templates SensorPublisher und NodeRED sind auch die Node Templates NodeRED und InfluxDB über ein ConnectsTo Relationship Template verbunden. Diese Relationship Templates drücken eine Verbindung zwischen den Komponenten aus. Bei zwei Node Templates die über ein ConnectsTo Relationship Template verbunden sind wäre es empfehlenswert das Ziel der Verbindung als erstes zu provisionieren. Das sich zum Beispiel NodeRED direkt nachdem Provisionieren mit InfluxDB verbinden kann, sollte diese davor provisioniert werden. Wird diese Reihenfolge nicht eingehalten unternimmt NodeRED immer wieder Verbindungsversuche bis die Verbindung erfolgreich her- stellt werden konnte. Die HostedOn Relationship Templates legen eine Reihenfolge vor. Das Node Template welches das Ziel einer solchen Verbindung ist wird immer zuerst provisioniert. Da zum Beispiel der NodeRED Linux Container auf Raspbian läuft, muss Raspbian zuerst provisioniert werden. Wie in Abschnitt 4.1.1 beschrieben benötigen die NodeMCUs für die Provisionierung noch einen MQTT Server. Dieser kann auch über ein Service Template provisioniert werden. Hier wird davon ausgegangen das ein MQTT Server schon im Netzwerk vorhanden ist und sich alle Geräte im glei- chen Netzwerk befinden. Die unterschiedlichen Komponenten können sich dann gegenseitig über mDNS finden. Auch wird davon ausgegangen, dass die Geräte aufgestellt wurde, eingeschaltet sind und die Sensoren mit den NodeMCUs verbunden sind. Weiterhin muss sich auf den NodeMCUs eine Bootstrap-Anwendung befinden und auf dem Raspberry Pi muss Raspbian mit aktiviertem SSH laufen. Die gezeigte Topologie wurde mithilfe des Modellierungswerkzeug Winery erstellt. Diese kann von OpenTOSCA verarbeitet und provisioniert werden. Eine Provisionierung dieser Topologie dauert mehrere Minuten. Die benötigte Zeit ist dabei hauptsächlich von der Größe der Linux Container abhängig, der Netzwerkverbindung und der Schreibgeschwindigkeit der jeweiligen Geräte abhängig. 10https://www.influxdata.com/ (zuletzt besucht 17.12.2017) 67 5 Zusammenfassung und Ausblick Das Ziel dieser Bachelorarbeit ist es TOSCA Node Types für die IoT Geräte MICA, Raspberry Pi und NodeMCU zu entwickeln, mithilfe von Eclipse Winery1 zu modellieren und diese zu Imple- mentieren. Die Node Types sollen das Installieren zusätzlicher Softwarekomponenten erlauben. Für den Einsatz der Node Types soll ein Anwendungsszenario mit der Hilfe von OpenTOSCA2 verwirklicht werden. Um ein besseres Verständnis für die einzelnen Geräte zu entwickeln wurden sie in den Grundlagenkapiteln vorgestellt und in zwei Klassen eingeteilt. Danach wurde für jede Klasse ein Lösungskonzept erarbeitet das die Vor- und Nachteile der jeweiligen Klasse beachtet. Die constrained devices werden mit zwei Node Types modelliert, wobei die Kommunikation mit den einzelnen Geräten über ein publish-subscribe Protokoll abläuft. Für die unconstrained devices wurden fünf Modellierungsansätze vorgestellt und anhand von mehreren Kriterien bewertet. Die Softwarekomponenten werden zum leichteren Provisionieren und zur Isolierung voneinander in Container verpackt. Diese Container werden als eigene Node Types modelliert. Die Geräte werden entweder als Paare von Betriebssystem Node Type und Geräte Node Type oder wenn das Betriebssystem auf dem Gerät nicht austauschbar ist nur als Geräte Node Type modelliert. Die Ansätze wurden jeweils anhand von mindestens einem Beispiel Gerätes vorgestellt, es wurde aber drauf geachtet das die Ansätze für Geräte aus der jeweiligen Klasse anwendbar sind. In den Prototypen Kapiteln werden die Prototypen für jedes Gerät genauer vorgestellt. Sie können als Anhaltspunkt für die Implementierung von weiteren Node Types für andere Geräte dienen. Sie enthalten auch die kompletten Node Types wie sie zur Umsetzung des Prototypens mit Eclipse Winery1 modelliert wurden. Am Ende wurde ein Anwendungsszenario vorgestellt das alle Proto- typen mit einbindet und ein im IoT übliches Szenario abdeckt. Es werden von den constrained devices Daten erfasst. Diese werden dann auf unconstrained devices verarbeitet und gespeichert. Auch eine Visualisierung der Daten für den Anwender findet statt. Ausblick In dieser Arbeit wurden Konzepte für zwei Klassen von Geräten entwickelt. Beide Klassen haben die Anforderung das Software und Konfiguration über eine Netzwerkverbindung ausgetauscht werden kann. Wie Geräte bei denen das nicht möglich ist modelliert werden, könnte Gegenstand zukünftiger Arbeiten sein. DesWeiteren existiert eine großeAnzahl an IoTMiddleware die auf unterschiedlicheArt undWeise angesprochenwerden und vielfältige Datenmodelle haben. InweiterenArbeiten könnte untersucht werden wie sich diese Heterogenität mithilfe von TOSCA erfassen und auflösen lässt. Vielleicht ist es möglich eine einheitliche Schnittstelle zu abstrahieren. Es könnte auch ein Relationship 1https://projects.eclipse.org/projects/soa.winery (zuletzt besucht 17.12.2017) 2http://www.opentosca.org/(zuletzt besucht 17.12.2017) 69 5 Zusammenfassung und Ausblick Template genutzt werden das einen Proxy zwischen die einzelnen Kommunikationspartner einbaut, welcher die Protokolle übersetzt und Daten zwischen den Datenmodellen transformiert. Weiterhin könnte ein Konzept gesucht werden um nicht funktionale Anforderungen von IoT Geräte auszudrücken. Das könnte unter anderem über Requirements und Capabilities oder zum Beispiel über Properties umgesetzt werden. Eine solche Lösung würde es zum Beispiel ermögliche die Qualität der Verbindungen zwischen den einzelnen Geräten und Komponenten der IoT Umge- bung zu erfassen. Auch wie viele Sensorwerte pro Zeiteinheit eine Middleware verarbeiten kann ist ein Beispiel für eine solche Anforderung. Durch eine solche Hilfe könnte ein Modellierungstool dem Application Architect mitteilen das zum Beispiel zu viele Geräte Sensordaten liefern und die Middleware diese nicht mehr verarbeiten kann. Auch Anforderungen für Security und Safety könnten so erfasst werden. Danksagung Für den Zeitraum der Bachelorarbeit wurde mir von der Daimler AG eine MICA bereitgestellt. Dafür möchte ich mich herzlich bedanken. 70 Literaturverzeichnis [Ada16] J. Adams. Raspberry Pi 3 Model B (Reduced Schematics). Raspberry Pi Foundation, Apr. 2016 (zitiert auf S. 23). [AFG+10] M. Armbrust, A. Fox, R. Griffith, A. D. Joseph, R. Katz, A. Konwinski, G. Lee, D. Pat- terson, A. Rabkin, I. Stoica, M. Zaharia. „A View of Cloud Computing“. In: Commun. ACM 53.4 (Apr. 2010), S. 50–58. issn: 0001-0782. doi: 10.1145/1721654.1721672. url: http://doi.acm.org/10.1145/1721654.1721672 (zitiert auf S. 18). [AIM10] L. Atzori, A. Iera, G. Morabito. „The Internet of Things: A survey“. In: Computer Networks 54.15 (2010), S. 2787–2805. issn: 1389-1286. doi: 10.1016/j.comnet.2010. 05.010. url: http://www.sciencedirect.com/science/article/pii/S1389128610001568 (zitiert auf S. 3, 13, 17, 18). [BBH+13] T. Binz, U. Breitenbücher, F. Haupt, O. Kopp, F. Leymann, A. Nowak, S. Wagner. „OpenTOSCA – A Runtime for TOSCA-Based Cloud Applications“. In: Service- Oriented Computing: 11th International Conference, ICSOC 2013, Berlin, Germany, December 2-5, 2013, Proceedings. Hrsg. von S. Basu, C. Pautasso, L. Zhang, X. Fu. Berlin, Heidelberg: Springer Berlin Heidelberg, 2013, S. 692–695. isbn: 978-3-642- 45005-1. doi: 10.1007/978-3-642-45005-1_62. url: https://doi.org/10.1007/978-3-642- 45005-1_62 (zitiert auf S. 19, 20). [BBK+14] U. Breitenbücher, T. Binz, K. Képes, O. Kopp, F. Leymann, J. Wettinger. „Combining Declarative and Imperative Cloud Application Provisioning Based on TOSCA“. In: 2014 IEEE International Conference on Cloud Engineering. März 2014, S. 87–96. doi: 10.1109/IC2E.2014.56 (zitiert auf S. 21). [BBKL14] T. Binz, U. Breitenbücher, O. Kopp, F. Leymann. „TOSCA: Portable Automated Deployment and Management of Cloud Applications“. In: Advanced Web Services. Hrsg. von A. Bouguettaya, Q. Z. Sheng, F. Daniel. New York, NY: Springer New York, 2014, S. 527–549. isbn: 978-1-4614-7535-4. doi: 10.1007/978-1-4614-7535-4_22. url: https://doi.org/10.1007/978-1-4614-7535-4_22 (zitiert auf S. 14, 19). [BEK14] C. Bormann, M. Ersue, A. Keranen. Terminology for Constrained-Node Networks. Techn. Ber. 2014 (zitiert auf S. 14, 17, 25, 33). [BH017] C. Brauner, S. Hallyn, 0x0916 (Github-User). README.md. Version 616e059. 2017. url: https://github.com/lxc/lxc/blob/616e0593cd18d8568dec36b6258a67693d649f50/ README.md (zitiert auf S. 28). [BI17] E. Bertino, N. Islam. „Botnets and internet of things security“. In: Computer 50.2 (Feb. 2017), S. 76–79. issn: 0018-9162. doi: 10.1109/MC.2017.62 (zitiert auf S. 18). 71 Literaturverzeichnis [BPS+17] D. Beserra, M. K. Pinheiro, C. Souveyet, L. A. Steffenel, E. D. Moreno. „Performance Evaluation of OS-Level Virtualization Solutions for HPC Purposes on SoC-Based Systems“. In: 2017 IEEE 31st International Conference on Advanced Information Net- working and Applications (AINA). März 2017, S. 363–370. doi: 10.1109/AINA.2017.73 (zitiert auf S. 28). [BSW14] A. Brogi, J. Soldani, P. Wang. „TOSCA in a Nutshell: Promises and Perspectives“. In: Service-Oriented and Cloud Computing: Third European Conference, ESOCC 2014, Manchester, UK, September 2-4, 2014. Proceedings. Hrsg. von M. Villari, W. Zim- mermann, K.-K. Lau. Berlin, Heidelberg: Springer Berlin Heidelberg, 2014, S. 171– 186. isbn: 978-3-662-44879-3. doi: 10.1007/978- 3- 662- 44879- 3_13. url: https: //doi.org/10.1007/978-3-662-44879-3_13 (zitiert auf S. 18, 20). [Bui15] T. Bui. „Analysis of docker security“. In: arXiv preprint arXiv:1501.02967 (2015) (zitiert auf S. 27, 28). [End15] C. Endres. A Pattern Language for Modeling the Provisioning of Applications. Master Thesis No. 38. Universitätsstraße 38 D–70569 Stuttgart, 4. Nov. 2015 (zitiert auf S. 45, 46). [ESP17] ESP8266 Community Forum. Arduino core for ESP8266 WiFi chip. Version 2ffcb3e. 2017. url: https://github.com/esp8266/Arduino/tree/2ffcb3e57b4c376286334d6c0e 8d34218a02be56 (zitiert auf S. 22). [Esp17] Espressif Systems. ESP8266EX Datasheet. V5.4. Apr. 2017 (zitiert auf S. 22, 25, 26, 54). [FBH+17] A. C. Franco da Silva, U. Breitenbücher, P. Hirmer, K. Képes, O. Kopp, F. Leymann, B. Mitschang, R. Steinke. „Internet of Things Out of the Box: Using TOSCA for Automating the Deployment of IoT Environments“. In: Proceedings of the 7th Inter- national Conference on Cloud Computing and Services Science - Volume 1: CLOSER, INSTICC. SciTePress, 2017, S. 358–367. isbn: 978-989-758-243-1. doi: 10 . 5220 / 0006243303580367 (zitiert auf S. 13, 14, 30, 31, 51, 58). [FGM+99] R. Fielding, J. Gettys, J. Mogul, H. Frystyk, L. Masinter, P. Leach, T. Berners-Lee. Hypertext transfer protocol–HTTP/1.1. Techn. Ber. Request for Comments: 2616. 1999 (zitiert auf S. 54). [GBMP13] J. Gubbi, R. Buyya, S. Marusic, M. Palaniswami. „Internet of Things (IoT): A vision, architectural elements, and future directions“. In: Future Generation Computer Sys- tems 29.7 (2013). Including Special sections: Cyber-enabled Distributed Computing for Ubiquitous Cloud and Network Services & Cloud Computing and Scientific App- lications — Big Data, Scalable Analytics, and Beyond, S. 1645–1660. issn: 0167-739X. doi: 10.1016/j.future.2013.01.010. url: http://www.sciencedirect.com/science/ article/pii/S0167739X13000241 (zitiert auf S. 13). [HARa] HARTING IT Software Development GmbH & Co. KG. HARTING IIC MICA. MICA Datenblatt, am 10.09.2017 abgerufen (zitiert auf S. 24–26). [HARb] HARTING IT Software Development GmbH & Co. KG. HARTING IIC MICA Die Plattform für die Integrated Industry. Whitepaper, am 10.09.2017 abgerufen (zitiert auf S. 24). [HAR16a] HARTING IT Software Development GmbH & Co. KG. HAIIC MICA Hardware De- velopment Guide. 3. Edition. Doc No 20 95 100 0003 / 99.01, am 03.08.2017 abgerufen. 2016 (zitiert auf S. 26). 72 Literaturverzeichnis [HAR16b] HARTING IT Software Development GmbH & Co. KG. HARTING MQTT Broker for HAIIC MICA. Version 1.2.2. Doc No 20 95 100 0003 / 99.01 Es werden im Dokument unterschiedliche Versionsnummern genannt: v1.2.3 und v1.2.2. 2016 (zitiert auf S. 24). [HAR16c] HARTING IT Software Development GmbH & Co. KG. HARTING Node.js Envi- ronment for HAIIC MICA. Version 1.3. Whitepaper, am 10.09.2017 abgerufen. 2016 (zitiert auf S. 24). [HAR17a] HARTING IT Software Development GmbH & Co. KG. HAIIC MICA Programming Guide. 3. Edition. Version V1.5.0. Am 03.08.2017 abgerufen. 2017 (zitiert auf S. 24, 44). [HAR17b] HARTING IT Software Development GmbH & Co. KG. HARTING HAIIC MICA Bausatz. 1. Edition. Doc No 20 95 100 0003 / 99.01. 2017 (zitiert auf S. 26). [HAR17c] HARTING IT Software Development GmbH & Co. KG. HARTING HAIIC MICA Busybox Container v1.1.0_r. 1. Edition. Doc No 20 95 100 0003 / 99.01. 2017 (zitiert auf S. 24). [HAR17d] HARTING IT Software Development GmbH & Co. KG. HARTING HAIIC MICA Debian Jessie Container v1.1.1_r. 1. Edition. Doc No 20 95 100 0003 / 99.01. 2017 (zitiert auf S. 24). [HAR17e] HARTING IT Software Development GmbH & Co. KG. HARTING HAIIC MICA Java 8 Container v1.1.0_r. 1. Edition. Doc No 20 95 100 0003 / 99.01. 2017 (zitiert auf S. 24). [HAR17f] HARTING IT Software Development GmbH & Co. KG. HARTING HAIIC MICA Python 3.4 Container v1.1.0_r. 1. Edition. Doc No 20 95 100 0003 / 99.01. 2017 (zitiert auf S. 24). [HAR17g] HARTING IT Software Development GmbH & Co. KG. IP67 Industrie-Computer- Hardware, die überall passt. 2017. url: https://www.harting-mica.com/de/mica- varianten (besucht am 21. 11. 2017) (zitiert auf S. 24). [Hd17] R. Huang, djchou (Github-User). NodeMCU DEVKIT V1.0. Version 5ee78f5. 2017. url: https://github.com/nodemcu/nodemcu-devkit-v1.0/blob/5ee78f58bfd2f2dd5accd 0a1d27e9f6947c75ccd/README.md (zitiert auf S. 22). [HWD+17] T. Heo, J. Weiner, V. Davydov, L. Torvalds, P. Parav, W. T. King, T. Klauser, S. Hallyn, K. Khlebnikov. Control Group v2. Version v2 Commit:ec39225. 2017. url: https : //github.com/torvalds/linux/blob/8fac2f96ab86b0e14ec4e42851e21e9b518bdc55/ Documentation/cgroup-v2.txt (zitiert auf S. 28). [Inc16] M. T. Inc. LAN9514/LAN9514i. Version DS00002306A. 16. Feb. 2016. url: http://ww1. microchip.com/downloads/en/DeviceDoc/00002306A.pdf (besucht am 01. 10. 2017) (zitiert auf S. 25). [KH14] C. P. Kruger, G. P. Hancke. „Benchmarking Internet of things devices“. In: Industrial Informatics (INDIN), 2014 12th IEEE International Conference on. Juli 2014, S. 611–616. doi: 10.1109/INDIN.2014.6945583 (zitiert auf S. 23, 25, 26). [Kop17] O. Kopp. Custom URI for lifecycle interface. Version b9a1de9. 27. Sep. 2017. url: https: //github.com/eclipse/winery/blob/b9a1de938d59440b6f46495175b8ba0a718e7950/ docs/adr/0007-custom-URI-for-lifecycle-interface.md (zitiert auf S. 36). 73 Literaturverzeichnis [Kra14] N. Kratzke. „Lightweight virtualization cluster how to overcome cloud vendor lock- in“. In: Journal of Computer and Communications 2.12 (2014), S. 1. doi: 10.4236/jcc. 2014.212001 (zitiert auf S. 18). [Lez17] D. Lezcano. lxc-stop. Webseite wurde erstellt von man2html. 18. Nov. 2017. url: https://linuxcontainers.org/lxc/manpages/man1/lxc- stop.1.html (besucht am 18. 11. 2017) (zitiert auf S. 63). [LGm+] Links2004 (Github-User), I. Grokhotkov, me-no-dev (Github-User), N. Kolban, P. Gol- lor. Updater.h. Version 01e1c58. Updater Header Datei von dem Arduino Core for ESP8266 Projekt. ESP8266 Community Forum. url: https://github.com/esp8266/ Arduino / blob / 01e1c586cb67dca7d22ee69de64187142260f6a2 / cores / esp8266 / Updater.h (besucht am 12. 11. 2017) (zitiert auf S. 55). [LSN17] L. Lynch, M. Scott, B. Nuttall.Analogue Inputs. Version bf6d528. Raspberry Pi Founda- tion. 9. März 2017. url: https://github.com/raspberrypilearning/physical-computing- with-python/blob/bf6d52812d81431d58a1c70dd780a0133f29aa94/analogue.md (be- sucht am 09. 10. 2017) (zitiert auf S. 26). [LVCD13] F. Li, M. Vögler, M. Claeßens, S. Dustdar. „Towards Automated IoT Application Deployment by a Cloud-Based Approach“. In: 2013 IEEE 6th International Conference on Service-Oriented Computing and Applications. Dez. 2013, S. 61–68. doi: 10.1109/ SOCA.2013.12 (zitiert auf S. 29, 30). [Meu17] R. van der Meulen. Gartner Says 8.4 Billion Connected "Things"Will Be in Use in 2017, Up 31 Percent From 2016. Gartner. 7. Feb. 2017. url: http://www.gartner.com/ newsroom/id/3598917 (besucht am 02. 10. 2017) (zitiert auf S. 13). [MG+11] P. Mell, T. Grance et al. The NIST definition of cloud computing. Techn. Ber. Com- puter Security Division, Information Technology Laboratory, National Institute of Standards und Technology Gaithersburg, 2011 (zitiert auf S. 13, 18). [MKK15] R. Morabito, J. Kjällman, M. Komu. „Hypervisors vs. lightweight virtualization: a performance comparison“. In: Cloud Engineering (IC2E), 2015 IEEE International Conference on. März 2015, S. 386–393. doi: 10.1109/IC2E.2015.74 (zitiert auf S. 27, 28). [Nod15] NodeMCU Team. NODE MCU DEVKIT V1.0. 1.0. www.nodemcu.com, Jan. 2015. url: https://github.com/nodemcu/nodemcu-devkit-v1.0/blob/aff7512acda74d79a6f17e 5a27b271f7357eeb9f/NODEMCU_DEVKIT_V1.0.PDF (zitiert auf S. 22). [Nod17a] NodeMCU Team. NodeMcu - Connect Things EASY. 2017. url: http://www.nodemcu. com/index_en.html (besucht am 22. 11. 2017) (zitiert auf S. 22). [Nod17b] NodeMCU Team. README.md. Version 787379f. 2017. url: https://github.com/ nodemcu/nodemcu-firmware/blob/787379f0f59c0d1aced809a44cb922293447e447/ README.md (zitiert auf S. 22). [OAS13a] OASIS. Topology and Orchestration Specification for Cloud Applications (TOSCA) Primer Version 1.0. Organization for the Advancement of Structured Information Standards (OASIS). 2013. url: http://docs.oasis-open.org/tosca/tosca-primer/v1.0/ cnd01/tosca-primer-v1.0-cnd01.html (besucht am 03. 10. 2017) (zitiert auf S. 19–21, 29, 30, 35, 36, 47). 74 Literaturverzeichnis [OAS13b] OASIS. Topology and Orchestration Specification for Cloud Applications Version 1.0. Organization for the Advancement of Structured Information Standards (OASIS). 2013. url: http://docs.oasis-open.org/tosca/TOSCA/v1.0/os/TOSCA-v1.0-os.pdf (zitiert auf S. 3, 13, 18–21, 35, 43, 46, 48–50). [OAS13c] OASIS. TOSCA Simple Profile in YAML Version 1.1. Organization for the Advancement of Structured Information Standards (OASIS). 2013. url: http://docs.oasis-open.org/ tosca/TOSCA-Simple-Profile-YAML/v1.1/csprd02/TOSCA-Simple-Profile-YAML- v1.1-csprd02.pdf (besucht am 03. 10. 2017) (zitiert auf S. 18). [OAS14] OASIS. MQTT Version 3.1.1. Organization for the Advancement of Structured Infor- mation Standards (OASIS). 2014. url: http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/ os/mqtt-v3.1.1-os.doc (zitiert auf S. 28, 29, 37, 54, 58). [Obj14] Object Management Group. Business Process Model and Notation (BPMN). Versi- on 2.0.2. Auf der Webseite steht Publication Date: January 2014, aber im Dateinamen und im Dokuemnt wird Dezember 2013 aufgeführt. Auf http://schema.omg.org/ spec/BPMN/index.htm wird Dezember 2013 als Release Date genannt. 2014. url: http://www.omg.org/spec/BPMN/2.0.2/ (besucht am 08. 11. 2017) (zitiert auf S. 36). [PD15] M. Pasternacki, L. Damme. README.md. Version 1a213c7. 2015. url: https://gi thub.com/3ofcoins/jetpack/blob/1a213c7e0099b806c0948573c3bc791f4b37b4f0/ README.md (zitiert auf S. 27). [Pos] Postscapes. IoT Cloud Platform Landscape. url: https : / /www.postscapes .com/ internet-of-things-platforms/ (zitiert auf S. 14). [Rasa] Raspberry Pi Foundation. About Us. url: https://www.raspberrypi .org/about/ (besucht am 01. 10. 2017) (zitiert auf S. 23). [Rasb] Raspberry Pi Foundation. Buy a Raspberry Pi. url: https://www.raspberrypi.org/ products/ (besucht am 01. 10. 2017) (zitiert auf S. 23). [Rasc] Raspberry Pi Foundation. Raspberry Pi 2 Model B. url: https://www.raspberrypi. org/products/raspberry-pi-2-model-b/ (besucht am 01. 10. 2017) (zitiert auf S. 23). [Rasd] Raspberry Pi Foundation. Raspberry Pi 3 Model B. url: https://www.raspberrypi. org/products/raspberry-pi-3-model-b/ (besucht am 01. 10. 2017) (zitiert auf S. 23, 25). [Rase] Raspberry Pi Foundation. Raspberry Pi Zero W - Technical Specifications. url: https: //www.raspberrypi.org/products/raspberry-pi-zero-w/ (besucht am 01. 10. 2017) (zitiert auf S. 26). [Rasf] Raspberry Pi Foundation. SSH (Secure Shell). url: https://www.raspberrypi.org/ documentation/remote-access/ssh/ (besucht am 04. 11. 2017) (zitiert auf S. 44). [RBF+16] L. Reinfurt, U. Breitenbücher, M. Falkenthal, F. Leymann, A. Riegg. „Internet of Things Patterns“. In: Proceedings of the 21st European Conference on Pattern Lan- guages of Programs. EuroPlop ’16. Kaufbeuren, Germany: ACM, 2016, 5:1–5:21. isbn: 978-1-4503-4074-8. doi: 10.1145/3011784.3011789. url: http://doi.acm.org/10.1145/ 3011784.3011789 (zitiert auf S. 17). [RRN16] R. Rizki, A. Rakhmatsyah, M. A. Nugroho. „Performance analysis of container-based hadoop cluster: OpenVZ and LXC“. In: Information and Communication Technology (ICoICT), 2016 4th International Conference on. IEEE. 2016, S. 1–4 (zitiert auf S. 27). 75 [SAN+17] M. Stanley-Jones, R. Anderson, NonCreature0714 (Github-User), V. Bialas, gdevillele (Github-User), J. Fernandes, travis-rodman (Github-User), J. Mulhausen, M. Friis, A. Duermael. Docker frequently asked questions (FAQ). Version 88e6e28. Docker Inc. 2017. url: https://github.com/docker/docker.github.io/blob/88e6e2852bddf2ce5d 33b46620df0d1cc69f5c3d/engine/faq.md (zitiert auf S. 28). [Sil13] Silicon Laboratories Inc. CP2102/9. 1.6. Dez. 2013 (zitiert auf S. 22). [The17] The MagPi. Sales soar and Raspberry Pi beats Commodore 64. The official Raspberry Pi magazine. 2017. url: https://www.raspberrypi.org/magpi/raspberry-pi-sales/ (besucht am 21. 11. 2017) (zitiert auf S. 23). [Upt12a] L. Upton. First Model A samples off the line! Raspberry Pi Foundation. 2012. url: https://www.raspberrypi.org/blog/first-model-a-samples-off-the-line/ (besucht am 01. 10. 2017) (zitiert auf S. 26). [Upt12b] L. Upton. Two things you thought you weren’t going to get: a manufacturing date and an SoC datasheet. Raspberry Pi Foundation. 6. Feb. 2012. url: https://www. raspberrypi.org/blog/two-things-you-thought-you-werent-going-to-get/ (besucht am 02. 10. 2017) (zitiert auf S. 23). [Vau06] S. J. Vaughan-Nichols. „New Approach to Virtualization Is a Lightweight“. In: Com- puter 39.11 (Nov. 2006), S. 12–14. issn: 0018-9162. doi: 10.1109/MC.2006.393 (zitiert auf S. 27). [WR] K. Walther, J. Regtmeier. Virtualisierung für Produktion und IoT. Whitepaper, am 10.09.2017 abgerufen. HARTING IT Software Development GmbH & Co. KG (zitiert auf S. 24). [XSN+17] XECDesign (Github-User), A. Scheller, B. Nuttall, L. Lynch, lauraclay (Github-User), J. Hughes, yskywalker (Github-User), P. Borreli, L. Upton, K. Marinov, conan (Github- User). NOOBS. Version a804cb8. 2017. url: https://github.com/raspberrypi/docume ntation/blob/a804cb8b92f94090d6a5d1d8197076cde79e5b4e/installation/noobs.md (besucht am 01. 10. 2017) (zitiert auf S. 23, 26). Alle URLs wurden zuletzt am 17. 12. 2017 geprüft. Erklärung Ich versichere, diese Arbeit selbstständig verfasst zu haben. Ich habe keine anderen als die angegebenen Quellen benutzt und alle wörtlich oder sinngemäß aus anderen Werken übernommene Aussagen als solche gekennzeichnet. Weder diese Arbeit noch wesentliche Teile daraus waren bisher Gegenstand eines anderen Prüfungsverfahrens. Ich habe diese Arbeit bisher weder teilwei- se noch vollständig veröffentlicht. Das elektronische Exemplar stimmt mit allen eingereichten Exemplaren überein. Ort, Datum, Unterschrift