Kategorie-Archiv: Azure

Hardening Azure Event Hub Solutions

Allgemein

In vielen IoT Scenarien stellt sich immer wieder die Frage wie der Daten Ingest von Devices (Things) zu einem zentralen Backend abgesichert werden kann. Hierbei ist neben der grundsätzlichen Absicherung des Transportweges auch die Absicherung des Dateningest einzelner Devices zu verstehen. Verwendet man den Azure IoT Hub kann jedes Device in dem zentralen Repository angelegt und mit entsprechenden Security Credentials versorgt werden. Dadurch ist eine feingranulare Verwaltung von Devices möglich. Letztendlich kann dadurch auf Device Ebene entschieden werden, ob die Daten des Device akzeptiert werden oder ggf. als kompromitiert betrachtet und verworfen werden.

Azure Event Hub stellt eine ähnliche Funktionalität zur Verfügung welche ebenfalls ermöglicht, den Daten Ingest von einzelnen Devices bereits auf Ebene des Event Hub zu blockieren.

Shared Access Policy

Nach Anlage eines Event Hub im Azure Portal können sogenannte „Shared Access Policies“ angelegt werden. Zu jeder Shared Access Policy werden zwei Keys erzeugt welche verwendet werden können, um ein Datenpaket zu signieren. D. h. Datenpakete welche von einem Device zu Azure Event Hub übertragen werden verwenden einen dieser Keys um einen Hash des Datenpaketes zu errechnen. Dieser Hash wird mit einem Key der erzeugten Shared Access Policy verschlüssen und zusammen mit anderen Informationen wie z. B. Event Hub Name und  Shared Access Policy Name zu einem String zusammengefasst. Dieser String wird nun jedem Datenpaket welches vom Device zum Event Hub übertragen wird beigefügt. Vereinfacht gesprochen handelt es sich bei diesem String um eine „Eintrittskarte“ welche das Datenpaket gegenüber dem Event Hub ausweist. Der Event Hub kann mittels der im String enthaltenen Informationen und einem privatem Schlüssel, der während der Anlage der Shared Access Policy ebenfalls erzeugt wurde und im Portal nicht sichtbar ist, prüfen ob die Signatur korrekt und damit das Datenpaket valide ist.

Der Key einer Shared Access Policy muss dementsprechend vertraulich behandelt werden. Viele Beispiele zu Übertragung von Daten von einem Device zu Event Hub verwenden jedoch den Key im Code des Devices. Insbesondere die Methode ServiceBusConnectionStringBuilder.CreateUseingSharedAccessKey() des aktuellen Azure Service Bus SDK (Azure Event Hub ist Teil des Azure Service Bus) macht es sehr einfach, auf Basis eines Shared Access Policy Key einen Connection String zum Event Hub zu erzeugen.

      

        public void TelemetryIngest()
        {
            string serviceBusNamespace = "<<Your Service Bus Namespace>> e. g. -> iotmc-ns";
            string eventHubName = "<<your Event Hub Name>> e. g. -> IoTMC";
            string eventHubSAPKeyName = "<<your Shared Access Policy Name>> e. g. -> Device01";
            string eventHubSAPKey = "<<your Key>> e.g. -> t0JK197745t345…s4N09aNI0s=";
            string eventHubConnectionString = ServiceBusConnectionStringBuilder.CreateUsingSharedAccessKey(
            ServiceBusEnvironment.CreateServiceUri("sb", serviceBusNamespace, string.Empty),
                eventHubSAPKeyName,
                eventHubSAPKey);
            EventHubClient eventHubClient = EventHubClient.CreateFromConnectionString(eventHubConnectionString, eventHubName);
            //Your code to ingest telemetry data
        }

Wurde das Device kompromitiert, muss serverseiting ein neuer Key generiert werden, damit Event Hub zukünftig Telemetry Ingests von diesem Device ablehnt. Dies ist solange machbar, wie eine geringe Anzahl von Devices installiert worden sind und für jedes Device eine eigene Shared Access Policy erzeugt wurde. Jedoch ist die Anzahl der erzeugbaren Shared Access Policies begrenzt, so dass mehrere (unter Umständen hunderte oder tausende) Devices mit dem Key einer einzigen Shared Access Policy Key provisioniert werden müssen. Wird nun ein einzelnes Device kompromitiert müssen unter Umständen hunderte oder tausende weitere Devices aktualisiert bzw. ausgetauscht werden.

Betrachtet man z. B. Devices die an einem Fließband z. B. die Tätigkeit von Robotern überwachen übermitteln so können diese in einer einfachen Anbindung den Key einer Shared Access Policy benützen, um Daten gegenüber einem Event Hub zu legitimitieren. In der Regel finden sich an einem Fließband sehr viele Sensoren und Devices so dass ein Key einer Shared Access Policy von ggf. vielen Devices verwendet werden muss.

Um diese Problematik zu adressieren, bietet sich eine Architektur an, bei der die Keys nicht auf dem Device gespeichert werden und sogenannte Shared Access Signature Tokens (SAS Token) „off-board“ erzeugt werden, die einen zeitlich begrenzten Daten-Ingest von den Devices erlauben.

„Off-Board“ Token Erzeugung

Bei der Erzeugung eines SAS Tokens „off-Board“ wird der Key der Shared Access Policy nicht auf den Devices  vorgehalten sondern von einem externen Service verwendet um ein SAS Token zu erzeugen, dass ebenfalls zur Legitimitierung von Telemetry Ingest am Event Hub verwendet werden kann. Diese Tokens beinhalten eine temporäre Komponente, d. h. sie sind nur für eine bestimmte definierbare Zeitspanne zur Legitimitierung am Event Hub gültig. Ein typischer Workflow bei der „off-Board“ Token Erzeugung stellt sich folgendermaßen dar:

  1. Device kontaktiert einen externen Service, in der Regel ein REST basierter Service (Discovery Service) und authorisiert sich mit den üblichen Verfahren (Pre-Shared-Key, OAuth etc.) I.d.R. werden hier noch zusätzliche Metadaten übertragen und die vom Discovery Service geprüft. Z. B. aktuelle IP Adresse oder GPS Daten um zu prüfen, ob das Device sich noch an der vorgesehen physikalischen oder netzwerktechnischen Position befindet. Sehr häufig findet sich hier auch eine Prüfung des letzten Daten Ingest. Diese Information kann im Backend ermittelt werden und ist hier bereits eine gewisse Zeitspanne seit dem letzen Daten Ingest verstrichen und es sind keine Wartungsarbeiten, Bandstillstand etc. aufgetreten kann dieses Device als zumindest „wartungsbedürftig“ oder im extremen Fall als kompromitiert betrachtet werden. In diesem Fall wird kein Token vom Service ausgestellt. Ohne gültiges Token ist auch kein Telemetry Ingest am Event Hub möglich.
  2. Ist die Authorisierung und Prüfung der Metadaten erfolgreich, kann der Discovery Service ein Token für das jeweilige Device erstellen und als Return Value eines potentiellen REST Call an das Device übermittelt werden. Die detailierte Beschreibung, wie dieses Token erzeugt wird, findet sich im weiteren Verlauf des Artikels.
  3. Das Device verwendet das erzeugte Token beim Telemetry Ingest an den Event Hub um diesen zu legitimitieren.

Erzeugung Shared Access Signature (SAS) Token

Ein SAS Token beinhaltet neben der bereits erwähnten zeitlichen Komponente zusätzlich die Möglichkeit ein einzelnes Device eindeutig zu identifizieren. Dies kann über einen String z. B. eine Guid oder einen beliebige andere Kennung erfolgen. Im SDK wird hierbei von einem Publisher gesprochen. Die Erzeugung eines SAS Token gestaltet sich nun mit Hilfe des Service Bus SDK sehr einfach. Die Methode SharedAccessSigantureTokenProvider.GetPublisherSharedAccessSignature() erzeugt ein entsprechendes SAS Token:

        string CreateSASToken()
        {
            Uri serviceBusEndPoint = new Uri("<<your service bus endpoint e.g. -> sb://iotvd-ns.servicebus.windows.net/");
            string eventHubName = "<<your Event Hub Name>> e.g. -> IoTMC"; ;
            string publisherId = "<<your device publisher id e.g. -> DeviceLocatedAtMachine01";
            string eventHubSAPKeyName = "<<your Shared Access Policy Name>> e. g. -> send";
            string eventHubSAPKey = "<<your Key>> e.g. -> t0JK197745t345…s4N09aNI0s=";
            TimeSpan ingestValidTimeSpan = new TimeSpan(0, 5, 0);

            return SharedAccessSignatureTokenProvider.GetPublisherSharedAccessSignature(
                            serviceBusEndPoint, 
                            eventHubName, 
                            publisherId, 
                            eventHubSAPKeyName, 
                            eventHubSAPKey, 
                            ingestValidTimeSpan);
      }

Auf dem Device kann das erzeugte Token nun verwendet werden um einen Telemetry Ingest zum Event Hub durchzuführen:

void IngestTelemetry()
 {
Uri serviceBusEndPoint = new Uri("< sb://iotvd-ns.servicebus.windows.net/");
 string eventHubName = "<> e.g. -> IoTMC";
 string publisherId = "< DeviceLocatedAtMachine01";
 string sASToken = "<>";
string eventHubConnectionString = ServiceBusConnectionStringBuilder.CreateUsingSharedAccessSignature(
serviceBusEndPoint,
eventHubName,
publisherId,
sAStoken);
var eventHubSender = EventHubSender.CreateFromConnectionString(eventHubConnectionString);
eventHubSender.Send(new EventData(Encoding.UTF8.GetBytes("<>>")));

Das Device kann nun bis zum Ablauf der vom Discovery Service gewählten Zeitspanne das SAS Token benützen, um Daten an den Event Hub zu senden. Sobald diese Zeitspanne abgelaufen ist wird das Token ungültig und beim Senden der Telemetry Daten tritt eine Exception auf. In diesem Fall kann das Device wieder den Discovery Service kontaktieren und ein neues SAS Token anfordern. Sollte der Discovery Service Unregelmäßigkeiten feststellen, kann er diese Ausstellung verweigern und der Telemetry Ingest von evtl. kompromitierten oder fehlerhaften Devices somit unterbinden.

 

Blockierung von einzelnen Devices

Solange die Zeitspanne die bei der Erzeugung eines SAS Tokens angegeben worden ist, kann dieses Token verwendet werden um Daten an einen Event Hub zu senden. Es gibt keine Möglichkeit, ein Token vor Ablauf der Gültigkeit als ungültig zu kennzeichnen und damit einen Telemetry Ingest zu unterbinden.

Um trotzdem den Ingest von einem als fehlerhaft oder kompromitiert eingestuftem Device vor Ablauf der Token Gültigkeit zu unterbinden kann die Publisher Id des jeweiligen Device verwendet werden. Diese Publisher Id wird der Methode ServiceBsConnectionStringBuilder.CreateUsingSharedAccessSignature() übergeben um einen ConnectionString zum Event Hub zu erzeugen.

        
        void IngestTelemetry()
        {

            Uri serviceBusEndPoint = new Uri("<<your service bus endpoint e.g. -> sb://iotvd-ns.servicebus.windows.net/");
            string eventHubName = "<<your Event Hub Name>> e.g. -> IoTMC";
            string publisherId = "<<your device publisher id e.g. -> DeviceLocatedAtMachine01";
 string sASToken = "<<Token generated by Discovery Service>>";
 
            string eventHubConnectionString = ServiceBusConnectionStringBuilder.CreateUsingSharedAccessSignature(
                serviceBusEndPoint, 
                eventHubName, 
                publisherId, 
                sAStoken);

            var eventHubSender = EventHubSender.CreateFromConnectionString(eventHubConnectionString);

            eventHubSender.Send(new EventData(Encoding.UTF8.GetBytes("<<Your Telemetry Data")));
        }

Diese Publisher Id kann wie bereits erwähnt beliebig gewählt werden und sollte jedes Device eindeuting kennzeichnen.

Soll nun der Telemetry Ingest von einem bestimmten Device vor Ablauf der Token Lebenszeit gesperrt werden, kann dies über die Methode RevokePublisher()  einer Instanz des Objektes NamespaceManger des Service Bus SDK erreicht werden. Zu beachten ist, dass hierfür eine Verbindung zum Service Bus Namespace in dem der Event Hub angelegt wurde notwendig ist. Eine Verbindung zum jeweiligen Event Hub auf dem der Telemetry Ingest eines Devices blockiert werden soll ist hierfür nicht ausreichend. Die Verbindung muss zusätzlich über die Berechtigung „manage“ verfügen. Am einfachsten ist es hierbei den notwendigen Connection String direkt aus dem Azure Portal zu kopieren. Nach erfolgreicher Instanzierung eines Namespace Manger Objektes können die Methoden RevokePublisher() und RestorePublisher() verwendet werden, um den Telemetry Ingest zu blockieren oder nach bereits erfolgter Blockierung wieder zuzulassen. Beide Methoden erwarten hierfür zum einen den Namen des Event Hub und die jeweilige Publisher Id des Devices:

        void IngestTelemetry()
        {
            Uri serviceBusEndPoint = new Uri("<<your service bus endpoint e.g. -> sb://iotvd-ns.servicebus.windows.net/");
            string eventHubName = "<<your Event Hub Name>> e.g. -> IoTMC";
            string publisherId = "<<your device publisher id e.g. -> DeviceLocatedAtMachine01";
            string sASToken = "<<Token generated by Discovery Service>>";
 
            string eventHubConnectionString = ServiceBusConnectionStringBuilder.CreateUsingSharedAccessSignature(
                serviceBusEndPoint, 
                eventHubName, 
                publisherId, 
                sAStoken);
            var eventHubSender = EventHubSender.CreateFromConnectionString(eventHubConnectionString);
            eventHubSender.Send(new EventData(Encoding.UTF8.GetBytes("<<Your Telemetry Data")));
        }

Fazit

Auch wenn es auf den ersten Blick kofortabel und schnell möglich ist, den Key einer Shared Access Policy direkt in einem Device zu verwenden, sollte man bei der Konzeption einer IoT Lösung einen sogenannten Discovery Service mit der „off-board“ Erzeugung von sogenannten Shared Access Policy Tokens berücksichtigen. Die dadurch gewonnenen Möglichkeiten eine IoT Lösung abzusichern wiegen in der Regel den zusätlichen Aufwand und die zusätzlichen Kosten zur Betreibung/Wartung des Discovery Service auf.

 

C# Entwicklung + Arduino/Genuino

Gerade im privaten Umfeld erfreuen sich die Arduino/Genuino Boards großer Beliebtheit um alle Arten von IoT  Projekten umzusetzen.  Auch im kommerziellen / professionellen Umfeld erfreuen sich die Boards großer Beliebtheit um prototypische Umsetzungen von Projekten bzw. Geschäftsideen schnell und kostengünstig zu verproben. Um Arduino Boards anzuprogrammieren kann die Open Source Arduino IDE erwendet werden. Die Programmierung von sog. Sketchen (d. h. Programme die auf den Arduino Boards ausgeführt werden) ähnelt C/C++ und ist einfach zu erlernen.

Für C# / VisualBasic.NET oder generell Windows Runtime Entwickler welche die Hardware Möglichkeiten eines Arduino nutzen möchten gibt es noch eine zusätzliche Möglichkeit. Windows Remote Arduino ist eine Open Source Windows Runtime Komponente die es ermöglicht die analogen und digitalen Ports eines Arduino Uno von einem beliebigen Windows 10 Device aus zu benützen. Gerade wenn ein User Interface, UMTS, WiFi, Storage etc.  zusammen mit dem Arduino Board benötigt wird lohnt es sich ggf. ein günstiges Windows 10 Device zusammen mit dem Arduino einzusetzen. Auf dem GitHub Account des Projektes findet sich eine einfache Step-by-Step Anleitung um ein Windows 10 Device via USB, Bluetooth, WiFi oder Ethernet mit dem Arduino zu verbinden.

Folgt man der Anleitung, verbindet den Arduino z. B. via USB, lädt die notwendige Firmata Implementierung auf den Arduino und beginnt in Visual Studio mit einem leeren UWP Projekt, könnenzwar mittels UsbSerial.listAvailableDevicesAsync()

RemoteArduiono_01

 

alle verbundenen Arduino(s) (in diesem Falle über USB angebunden) ohne Fehler ermittelt werden. Versucht man jedoch die Kommunikation mit dem Arduiono mittels .begin() RemoteArduiono_02aufzubauen. Kommt es zu folgender Fehlermeldung

UsbSerial::connectToDeviceAsync failed with a Platform::Exception type. (message: Catastrophic failure Unable to initialize the device. Did you forget your USB device capabilities in the manifest? SerialDevice::FromIdAsync returned null.)

Selbst wenn im Manifest der UWP Applikation explizit der Zugriff auf den USB Port erlaubt wurde tritt der Fehler auf. RemoteArduiono_03

Trotzdem gibt die Fehlermeldung den entscheidenden Hiweis auf fehlende Capabilities im Manifest der Applikation. Um die Kommunikation mit dem Arduino erfolgreich durchführen zu können, muß die folgende Device Capability im Manifest eingetragen werden:

<DeviceCapability Name=“serialcommunication“>
      <Device Id=“any“>
        <Function Type=“name:serialPort“ />
      </Device>
    </DeviceCapability>
  </Capabilities>

RemoteArduiono_04

 

Nach einem nochmaligem Deploy der UWP App kann auch die Kommunikation mit dem Arduino erfolgreich initiiert werden.

 

IoT Hackathon UG Nürnberg

image

Vielen Dank an alle Teilnehmer des Azure IoT TechCamp am 23.04.2014 in Nürnberg. Wie während des Event angekündigt hier noch einmal eine Zusammenfassung der Links zu Code-Snippets bzw. Hardware Intro sowie die verwendeten Slide – Decks:

Getting started:

Tessel: http://start.tessel.io/install

Arduino Yun: http://www.arduino.cc/en/Guide/ArduinoYun

Code Snippets / Dienste:

https://github.com/dx-ted-emea/azure-tessel

Hier finden sich komplette Hands-On-Labs wie ein Tessel Microcontroller (oder generell “Things” mit einem HTTP Stack) Azure basierte Resourcen wie z. B. EventHub, ServiceBus, Mobile Services, WebSites etc. benützen können.

https://github.com/dx-ted-emea/iot-labs

Unter dem Link findet sich ein komplettes End-To-End Szenario aufgeteilt in mehrere Labs. Die Labs decken den Daten Ingest als auch die Verarbeitung der Daten als Stream sowie Rückmeldungen (Command & Control) an die Endgeräte ab.

http://www.connectthedots.io

Ebenfalls ein komplettes Hands-On-Lab welches ein IoT Szenario abdeckt. Ein sehr interessantes Mittel zum Eigenstudium welches viele Azure Backend Dienste vorstellt.

https://github.com/RobertEichenseer/IoT_MasterClass

Sammlung von hilfreichen Code-Snippets wie z. B. das Senden von Telemetrie Daten an einen Azure Event Hub aus einer Universal App, einer Win32 App, .net Micro Framework etc.

https://github.com/crossbario/crossbarexamples/wiki/TechCamp

Crossbar.IO ein Open Source Produkt welches einfach über den Azure Marketplace installiert und benützt werden kann. Crossbar.IO adressiert unter anderem das “Command & Control” Paradigma welches in nahezu jeder IoT Lösung benötigt wird.  

Slide Decks:

Die verwendeten Slide Decks finden sich unter: http://1drv.ms/1DZhqR9

Netduino, IoT Applikationen mit VS 2013 erstellen

imageDas Netduino Prototyping Board ist ein in der .NET community beliebtes Board, welches auf dem .NET Micro Framework aufbaut. Das Netduino ist pin-kompatibel mit dem Arduino Board und damit steht eine große Anzahl an Sensoren, Aktoren und Gadgets zur Verfügung die in eigenen IoT Applikationen eingesetzt werden können. Für viele .NET Entwickler ist jedoch der größte Vorteil, dass zur Entwicklung von Applikationen C# und Visual Studio eingesetzt werden kann. Das Lernen von neuen Sprachen und Entwicklungsumgebungen ist dadurch nicht nötig. 

Colin Miller hat auf dem .NET Micro Framework Blog angekündigt, dass Microsoft das Investment in die Plattform wieder erhöhen wird. Erste Ankündigungen zeigen Investment im Bereich der asynchronen Entwicklung und der Integration in die aktuellen Visual Studio Versionen. Aktuell wird auf der Netduino Homepage noch Visual Studio 2010 als notwendige Entwicklungsumgebung genannt. Eine Side-By-Side Installation von VS 2010 mit VS2013 oder der Beta von VS2014 ist zwar möglich, trotzdem erscheint die Installation einer “alten” Version von VS nicht komfortabel, gerade wenn die “Device-Entwicklung” Bestandteil eines größeren Projektes ist und eine gemeinsame Solution für alle Komponenten gepflegt werden soll. Aktuell existiert eine Beta Integration, die es ermöglicht, Netduino Apps mit Visual Studio 2013 zu erstellen.

Folgende Schritte sind dazu nötig:

  1. Deinstallation aller evtl. vorhandenen .NET Micro Framework und Netduino SDKs vom Computer
  2. Deinstallation aller VS Extensions (Tools –> Extension and Updates; nach .NET Micro suchen)
  3. Installation des .NET MF SDK v4.3 R2 (beta)
  4. Installation des .NET MF v4.3 R2 (beta) add-in für VS 2013
  5. Installation des Netduino SDK v4.3.1

Nach Installation aller Komponenten sollte in VS 2013 neue Projekt Templates für das Micro Framework und die Netduino Entwicklung angezeigt werden.

image

Die nächste Herausforderung stellt i. d. R. das Netduino Board selbst dar. Meist ist nicht die in der Beta Version verwendete Firmware Version 4.3.1 sondern 4.2 bzw. 4.1 installiert. Dies äußert sich in einer Fehlermeldung

Cannot deploy the base assembly ‚mscorlib‘, or any of his satellite assemblies, to device – USB:Netduino twice. Assembly ‚mscorlib‘ on the device has version 4.2.0.0, while the program is trying to deploy version 4.3.1.0

Chris Walker hat auf seinem Blog eine Update Tool zur Verfügung gestellt um die Firmware auf dem Netduino (Achtung: nur für Netduino Plus 2) zu flashen. Folgende Schritte sind nötig:

  1. Netduino vom USB Port des Computers trennen um in auszuschalten
  2. Den Button auf dem Netduino drücken und gedrückt halten während dieser via USB mit dem Computer verbunden wird.
  3. Das oben verlinkte Update Tool starten und die Firmware 4.3.1 auf das Netduino Board übertragen.

Nach erfolgreichem Flash der Firmware können die Netzwerkeinstellungen (IP oder DHCP) des Board mit MFDeploy (Target –> Configuration –> Networking) neu vergeben werden.

Azure Event Hub; automatisierte Anlage

Die Anlage eines Event Hub bei bereits existierendem Service Bus Namespace ist kein großer Aufwand. Im NuGet Package WindowsAzure.Servicebus finden sich alle Objekte um einen Event Hub bequem in managed Code anzulegen, wie das nachfolgende Code-Beispiel zeigt.

   1: public async Task<EventHubDescription> CreateEventHubAsync()

   2: {

   3:  

   4:     string serviceBusNamespace = "iotmc-ns";

   5:     string serviceBusManageKey = "32GP81C2B/eWHQ/MlZomaV8Sr4nnzeRCrJQCrYr/Wi4=";

   6:     string eventHubName = "IoTMC";

   7:     string eventHubSASKeyName = "Device01";

   8:  

   9:     Uri serviceBusUri = ServiceBusEnvironment.CreateServiceUri("sb", serviceBusNamespace, string.Empty);

  10:     TokenProvider tokenProvider = TokenProvider.CreateSharedAccessSignatureTokenProvider("RootManageSharedAccessKey", serviceBusManageKey);

  11:     NamespaceManager nameSpaceManager = new NamespaceManager(string.Format("//{0}/", serviceBusUri.Host), tokenProvider);

  12:     string eventHubKey = SharedAccessAuthorizationRule.GenerateRandomKey();

  13:  

  14:     EventHubDescription eventHubDescription = new EventHubDescription(eventHubName)

  15:     {

  16:         PartitionCount = 8,

  17:         MessageRetentionInDays = 1

  18:     };

  19:     SharedAccessAuthorizationRule eventHubSendRule = new SharedAccessAuthorizationRule(eventHubSASKeyName, eventHubKey, new[] { AccessRights.Send, AccessRights.Listen });

  20:     eventHubDescription.Authorization.Add(eventHubSendRule);

  21:     eventHubDescription = await nameSpaceManager.CreateEventHubIfNotExistsAsync(eventHubDescription);

  22:  

  23:     string eventHubSASKey = ((SharedAccessAuthorizationRule)eventHubDescription.Authorization.First()).PrimaryKey;

  24:  

  25:     return eventHubDescription;

  26: }

Eine kleine Hürde gibt es jedoch, wenn auch der Service Bus Namespace via Code oder Powershell angelegt werden soll. Zum jetzigen Zeitpunkt gibt es einen Unterschied, wenn ein Service Bus Namespace via Management Portal oder via Powershell oder REST Api angelegt wird.

Bei Anlage über das Management Portal wird eine Shared Access Signature als Default Autorisierungsmechanismus angelegt. Legt man jedoch einen Service Bus Namespace via Powershell mit dem Komando:

   1: New-AzureSBNamespace -Name "CreatedUsingPowerShellDefaultValues" -Location "West Europe"

 
an, wird dieser als Default mit ACS Autorisierung erstellt. Versucht man im Nachgang in diesem Namespace einen Event Hub anzulegen, egal ob dies via Code oder Management Portal durchgeführt wird, kommt es zu einer Fehlermeldung “500 interner Server Error”.
 
Deshalb muss bei der Anlage des Service Bus Namespace via Powershell die Parameter –CreateACSNamespace und –NamespaceType mit Werten belegt werden.
 
   1: Param

   2: (

   3:         [bool]$falseValue = $false

   4: )

   5: New-AzureSBNamespace -Name "DelDel-ns" -Location "West Europe" -CreateACSNamespace $falseValue -NamespaceType Messaging

EchEd Europe 2014 – Architecting Globally Scalable Solutions

 TechEd2014

Mario Szpuszta und ich haben auf der diesjährigen TechEd Europe im Vortrag “Architecting Globaly Scalable Solutions” das Toolset an Produkten und Services von Microsoft Azure vorgestellt, mit dem globale, skalierende und ausfallsichere Applikationen in Microsoft Azure entwickelt und betrieben werden können.

Die horizontale Verteilung von Compute Workload (Scale Out) kann sehr einfach durch die Verwendung mehrere statusloser Compute Instanzen gelöst werden. Werden Statusinformationen auf den Instanzen benötigt, kann dies ebenfalls sehr elegant über Services wie z. B. Azure Cache gelöst werden. Hierbei sollte der auf Redis basierende Azure Cache verwendet werden.

Interessant wird es, wenn auch der Data Tier skalieren soll bzw. muss, weil der eingehende Workload nicht mehr von einem einzigen Datenbank Server verarbeitet werden kann. Die Aufrüstung des Servers mit mehr Speicher, HDD bzw. mehr Prozessoren (Scale Up) stellt hierbei i. d. R. nur eine zeitlich begrenzte Lösung dar. Vielmehr sollte auch das Datenbanksystem die eingehende Last auf mehrere Server (virtuell oder physikalisch) verteilen. Azure SQL Database Elastic Scale kann hierbei verwendet werden, um diese Last auf mehrere sog. Shards zu verteilen.

Die notwendigen Binaries um mit Azure SQL Database Elastic Scale zu arbeiten können via Nuget einfach in eigene Projekte eingebunden werden: 

install-package Microsoft.Azure.SqlDatabase.ElasticScale.Clientimage
 

Eine detaillierte Einführung in die Funktionalität stellt Microsoft in der Azure Dokumentation zur Verfügung.  Ebenfalls steht ein End-To-End Beispiel zum Download über den Visual Studio Project Wizzard zur Verfügung. Einfach unter “Online” – “Samples” nach “Elastic Scale” suchen und eines der Beispiele auswählen. Ein Utility zum migrieren von Azure SQL Federation Datenbanken auf Azure SQL Database Elastic Scale wird hierbei ebenso angeboten wie Beispiele für die Verwendung von Entity Framework und “bekannten” ADO.NET SqlCommands.

Im Überblick betrachtet stellt Azure SQL Database Elastic Scale die folgenden Komponenten / Funktionalitäten zur Verfügung:

  1. Funktionalität zur Anlage und Verwaltung einer “Global Shard Map” (GSM). Vereinfacht ausgedrückt ist die GSM eine Sammlung von Tabellen in einer Datenbank welche ConnectionStrings zu Daten Shards speichert. D. h. die GSM weiß, welche Daten in welchem Shard zu finden sind.
  2. Um die GSM als Bottleneck auszuschließen werden deren Informationen auch in den jeweiligen Daten Shards gespeichert (Local Shard Map) sowie in der Client Library gecached. image 
  3. Für den reinen Datenzugriff oder auch Data Dependent Routing genannt stehen Methoden die auf einzelne Daten Shards und auch Shard übergreifende Queries erlauben zur Verfügung. Zu beachten ist im speziellen bei Shard übergreifenden Queries dass es sich hierbei um eine Fan Out Query auf alle Shards handelt. Die Ergebnisse der einzelnen Queries werden in der Client Library ähnlich wie mit einem “Union All” zu einer Rückgabe kombiniert. 

Einige Code Snippets um Azure Elastic Scale zu verwenden finden sich in meinem GitHub Repository. Interessant ist im speziellen der Aufbau der Connection Strings zur GSM Datenbank und den lokalen Shards. Für die Verbindung zur GSM Datenbank (GetGsmConnectionString()) ist der Name der Datenbank (Initial Catalog) mit anzugeben. Die Connection Strings zu den jeweiligen Daten Shards sind jedoch ohne Name der Datenbank zu erstellen.

47         internal static string GetGsmConnectionString()
48         {
49             return new SqlConnectionStringBuilder
50             {
51                 InitialCatalog = Configuration.EsDataBase,
52                 DataSource = Configuration.EsServerName,
53                 UserID = Configuration.EsUserId,
54                 Password = Configuration.EsPassword,
55                 IntegratedSecurity = false,
56                 ApplicationName = "GlobalyScalable",
57                 ConnectTimeout = 30
58             }.ToString();
59         }
60

61         internal static string GetShardConnectionString()
62         {
63             return new SqlConnectionStringBuilder
64             {
65                 UserID = Configuration.EsUserId,
66                 Password = Configuration.EsPassword,
67                 IntegratedSecurity = false,
68                 ApplicationName = "GlobalyScalable",
69                 ConnectTimeout = 30,
70             }.ToString();
71         }
 

Developer Week 2014

WP_20140714_006

Auch dieses Jahr hatte ich wieder das Vergnügen, bei der Developer Week 2014 mit zwei Azure Vorträgen zum Erfolg beizutragen.

Der Vortrag “Architecting The Cloud” hatte zum Ziel ein Bewusstsein dafür zu schaffen, dass nicht einfach alle Herausforderung bezüglich Skalierung und Betriebssicherheit bei einem Lift-&-Shift von existierenden Systemen in die Cloud automatisch gelöst und adressiert sind. Vielmehr gibt es doch etliche Herausforderungen die in der Architektur berücksichtigt werden müssen wenn man einen ausfallsicheren Dienst in der public oder private Cloud betreiben möchte. Nach dem Vortrag sollten Begriffe wie Failure Point bzw. Failure Mode, Availability Plan und Life Cycle Model und deren Einsatz bei der Architektur eines Cloud Services bekannt sein. Das Deck was ich zur Präsentation benützt habe findet sich hier.

WP_20140714_005Im zweiten Vortrag drehte sich alles um das Debugging in der Cloud. Gerade die Verwendung von Visual Studio bietet viele Möglichkeiten einen Cloud Service oder eine einfache WebSite zu debuggen. Die Möglichkeiten reichen hierbei von:

 

 

Development Debugging

  1. Remote Desktop, RDP “on the fly” (Cloud Service)
  2. Remote Debutgging (Cloud Service / WebSite)
  3. Intellitrace (CloudService)

Production Debugging

  1. Azure Diagnostics Framework (Cloud Service)
  2. Intellitrace “on the fly” (Cloud Service)
  3. Online Configuration (WebSite)

Wer den Vortrag mit Hilfe der Powerpointfolien nachvollziehen möchte, findet diese hier.

Advanced Developers Conference 2013

ADC_LogoAm Erfolg der diesjährigen Advanced Developers Conference durfte ich mit zwei Vorträgen beitragen. Der erste Vortrag beleuchtete die Funktionalitäten der Windows Azure Mobile Services und der zweite Vortrag gab Einblicke und Tips in das Troubleshooting von Windows Azure SQL Database.

Das Windows Azure Mobile Services Beispielprogramm welches ich im Talk benützt habe, steht zum Download auf meinem GitHub Account zur Verfügung. Um die App zu Starten, muss der Demosource in App.xaml.cs um Uri und App Key eines neu angelegten Mobile Service erweitert werden.

   1: //TODO: Add specific mobile service information

   2: public static MobileServiceClient MobileService = new MobileServiceClient(

   3:     "https://<<add-mobile-service-name-here>>.azure-mobile.net/,

   4:     "<<add-mobile-service-app-key-here>>"

   5:     ,new RequestInterceptor()

   6: );

Um schnell zu den jeweiligen Schwerpunkten im Democode zu gelangen, kann nach folgenden Begriffen gesucht werden:

Thema

Suchbegriff

Authentication

01_

Push Notification

02_

Existing DB

03_

Caching Logon Credentials

04_

Request Interception

05_

Aufgrund von Zeitproblemen kamen manche Themen im Talk zu kurz, die ich auf diesem Weg noch einmal ansprechen möchte.

Caching Logon Credentials

Um zu vermeiden, dass bei jedem Start der Win8 App die Eingabe von User Credentials über den WebAuthentication Broker nötig werden, können diese, in der mit Windows 8 eingeführten PasswordVault, gechached werden. Folgende Hilfsklasse kann hierfür verwendet werden:

   1: class LogonCacher

   2: {

   3:     private const string RESOURCE = "RobEichMobileService";

   4:

   5:     public static void SaveCredential(string userName, string password)

   6:     {

   7:         PasswordVault passwordVault = new PasswordVault();

   8:         PasswordCredential passwordCredential = new PasswordCredential(RESOURCE, userName, password);

   9:

  10:         passwordVault.Add(passwordCredential);

  11:     }

  12:

  13:     public static PasswordCredential GetCredential()

  14:     {

  15:         PasswordCredential passwordCredential = null;

  16:         PasswordVault passwordVault = new PasswordVault();

  17:         try

  18:         {

  19:             passwordCredential = passwordVault.FindAllByResource(RESOURCE).FirstOrDefault();

  20:             if (passwordCredential != null)

  21:             {

  22:                 passwordCredential.Password = passwordVault.Retrieve(RESOURCE, passwordCredential.UserName).Password;

  23:             }

  24:         }

  25:         catch (Exception)

  26:         {

  27:             //TODO: implement error handling

  28:         }

  29:

  30:         return passwordCredential;

  31:     }

  32: }

Der Aufruf der Methoden SaveCredentials bzw. GetCredentials gestaltet sich sehr einfach:

   1: private MobileServiceUser user;

   2: private async System.Threading.Tasks.Task Authenticate()

   3: {

   4:     PasswordCredential passwordCredential = LogonCacher.GetCredential();

   5:     if (passwordCredential != null)

   6:     {

   7:         App.MobileService.CurrentUser = new MobileServiceUser(passwordCredential.UserName);

   8:         App.MobileService.CurrentUser.MobileServiceAuthenticationToken = passwordCredential.Password;

   9:         user = App.MobileService.CurrentUser;

  10:     }

  11:     while (user == null)

  12:     {

  13:         string message;

  14:         user = await App.MobileService.LoginAsync(MobileServiceAuthenticationProvider.MicrosoftAccount);

  15:         message = string.Format("You are now logged in - {0}", user.UserId);

  16:         var dialog = new MessageDialog(message);

  17:         dialog.Commands.Add(new UICommand("OK"));

  18:         await dialog.ShowAsync();

  19:     }

  20:     LogonCacher.SaveCredential(App.MobileService.CurrentUser.UserId, App.MobileService.CurrentUser.MobileServiceAuthenticationToken);

  21: }

Request Interception

Häufig steht man vor der Herausforderung, dass Aufrufe von Mobile Service Funktionen, wie z. B. CRUD Funktionen für die verbundene Datenbank, an zentraler Stelle um zusätzliche Parameter erweitert werden sollen. Dies kann insbesondere für ein Versionsmanagement am Backend verwendet werden.

Hierzu muss in einer Klasse welche von DelegationHandler erbt, die asynchrone Methode SendAsync() überschrieben werden und mit Code, welche z. B. die QueryParameter erweitert, versehen werden.

   1: class RequestInterceptor  : DelegatingHandler

   2: {

   3:     protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)

   4:     {

   5:         var withVersion = request.RequestUri.AbsoluteUri;

   6:

   7:         withVersion += (string.IsNullOrEmpty(request.RequestUri.Query)) ? "?" : "&";

   8:         withVersion += "version=2.0";

   9:

  10:         request.RequestUri = new Uri(withVersion);

  11:         return base.SendAsync(request, cancellationToken);

  12:     }

  13: }

Um die Klasse zu verwenden muss eine Instanz bei der Erzeugung des MobileServiceClient mit übergeben werden:

   1: public static MobileServiceClient MobileService = new MobileServiceClient(

   2:     "https://<<add-mobile-service-name-here>>.azure-mobile.net/",

   3:     "<<add-mobile-service-app-key-here>>",

   4:     new RequestInterceptor()

   5: );

Am Backend der Mobile Services kann im Node.JS Code der Parameter “version” über das Objekt request.parameters ausgelesen werden.

   1: function read(query, user, request) {

   2:

   3:     console.log("Content: " + request.parameters.version);

   4:     if (request.parameters.version == "2.0")

   5:     {

   6:         console.log("Do V2.0 specific thing");

   7:     }

   8:     request.execute();

   9: }

Artikelserie “Speichern unter Windows 8” in der dotnetpro

Bei meinem Vortrag auf der diesjährigen Developer Week in Nürnberg zum Thema “Win8 Apps – jetzt auch mit Speichern!” kam die Idee auf, den Inhalt des auf ca. 1 Stunde (ja ich hatte wieder mal überzogen Smiley) angesetzten Talks in einer Artikelreihe für die dotnetpro weiter zu vertiefen.

dnp_112013

Mittlerweile ist aus der Idee bereits eine dreiteilige Artikelreihe mit dem Titel “Nur Feiglinge speichern” geworden. In der aktuellen Ausgabe der dotnetpro, die am 17. Oktober im Handel erscheint, findet sich der erste Teil.

Dieser ist auch als kostenloser Onlineartikel hier als Download erhältlich.

Viel Spaß beim Lesen!

Dotnet Day Franken–Keynote

Ich hatte die Ehre den DDF 2013 mit einer Keynote zum Thema “Devices & Services“ zu eröffnen. Für all diejenigen, die am sehr gelungen und gut besuchtem Community Tag der Nürnberger doddneder nicht teilnehmen konnten, stehen Aufzeichnungen von vielen Sessions zum Download zur Verfügung.

Zum DDF wurde auch die Idee geboren diese Videos nicht nur als MP4 Download zur Verfügung zu stellen sondern diese auch als Stream in einer speziellen “Konferenzapp” zur Verfügung zu stellen. Die Frage nach dem Backend, welches Videos und die Informationen der jeweiligen Sessions hosten soll hat sich sehr schnell geklärt. Windows Azure stellt hierzu ideale Dienste, wie z. B. die Mobile Services, die Media Services oder die WebSites zur Verfügung.

ClassicApp01Mittlerweile wurde die Idee schon recht konkret und ein erstes Template sowie Designideen für die Win8 App stehen zur Verfügung.

Details folgen in späteren Posts.