Windows Azure Mobile Services–Zugriff auf eine existierende Datenbank

Herausforderung

Häufig sieht man sich bei der Verwendung von Windows Azure Mobile Services der Herausforderung gegenüber auf bereits existierende Datenbanken bzw. Tabellen zugreifen zu müssen. Auch wenn es auf den ersten Blick keine Möglichkeit gibt diese Anforderungen mit den Bordmitteln der Windows Azure Mobile Services umzusetzen ist dies doch einfach zu realisieren.

image

Im Reiter “CONFIGURE” des Mobile Service kann unter anderem auch die Azure SQL DB, auf die im Rahmen des Mobile Service zugegriffen werden soll, ausgewählt werden. Durch Klick auf “Change Database” kann eine bereits existierende Datenbank ausgewählt werden. Hierbei sollte man aus Performance Gründen darauf achten, dass sich die existierende Datenbank im gleichen Rechenzentrum wie der Mobile Service befindet.

Hat man die Verbindung zur gewünschten Datenbank konfiguriert, stellt sich die Problematik, dass der Azure Mobile Service i. d. R. nicht auf die existierenden Tabellen zugreifen kann. Dies ist darin begründet, dass der Mobile Service die Tabellen in einem bestimmten Schema voraussetzt. Das Schema ist dabei identisch mit den Namen des Mobile Service. Existierende Tabellen sind jedoch i. d. R. dem Schema dbo zugeordnet und damit ist auch kein Zugriff auf diese Tabellen möglich.

image

Das Problem zeigt sich deutlich, wenn man beim Azure Mobile Service eine Tabelle mit gleichem Namen wie eine bereits existierende anlegt. Im nebenstehenden Beispiel existiert eine Tabelle DownloadItem bereits in der Datenbank und ist dem Schema dbo zugeordnet. Nach Anlage einer gleichnamigen Tabelle über die Mobile Services wird statt auf die existierende Tabelle zuzugreifen eine neue Tabelle unter dem Schema des Mobile Service angelegt. Im Beispiel ist das RobEichMobileService.DownloadItem.

Schema Änderung

Theoretisch wäre es möglich, das Schema der existierenden Tabellen mit dem T-SQL ALTER SCHEMA möglich.

ALTER SCHEMA RobEichMobileService TRANSFER dbo.DownloadItem

Dadurch ist der Zugriff auf die Tabelle vom Mobile Service möglich, jedoch existierende Applikationen welche die Tabelle ansprechen müssen geändert werden, um auf die Tabelle mit dem geänderten Schema zugreifen zu können. Aus diesem Grund ist der Weg via ALTER SCHEMA zwar möglich, kann in der Praxis jedoch i. d. R. nicht eingesetzt werden.

 
View
 
Um auf die existierenden Tabellen zugreifen zu können, kann innerhalb der Datenbank ein View angelegt werden, der als Schema den Namen des Mobile Service aufweist. Der View selbst kann wiederum auf die existierenden Tabellen zugreifen.
 
   1: CREATE VIEW RobEichMobileService.DownloadItem

   2: AS

   3: SELECT * FROM dbo.DownloadItem

 
Von Seiten des Mobile Service kann nun einen neue “Tabelle” mit Namen <<DownloadItem>> angelegt werden. Es wird jedoch keine neue Tabelle angelegt, vielmehr wird der existierende View verwendet. Der Zugriff auf die existierende Tabelle ist dadurch möglich.

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!

video2brain, Windows Azure Video Training

1221_azureBei video2brain haben mein Kollege Mario Szpuszta und ich ein ca. 6 stündiges Training zum Thema Windows Azure aufgenommen. 

Wir behandeln in dem Training die Grundlagen von Windows Azure wie z. B.:

      • – Virtuelle Maschinen und deren Einbindung in Netzwerke
  • – Storage Optionen (SQL Database, BLOB Storage, Table Storage)
  • – Mobile Services
  • – Websites
  • – …

Mario und ich hatten sehr viel Spaß bei den Aufnahmen in den Grazer Studios von video2brain und wünschen viel Spaß beim Betrachten der Videos. Einen ersten Einstimmung auf das Thema gibt unser Teaser Video.

Basta 2013

WP_20130926_001

Zusammen mit meinem Kollegen Mario Szpuszta hatte ich eine Session auf der diesjährigen Basta in Mainz zum Thema „Global Skalierende Anwendungen mit Windows Azure”.

Mario und ich konnten hier aus unserer täglichen Arbeit mit Partnern berichten. Alle der gezeigten Szenarien konnten wir bereits erfolgreich in Projekten implementieren und in “Real-World-Szenarien” deren Validität beweisen.

Die Slides zur Session finden sich hier. Bei Interesse am Source Code, insbesondere am Source des Anti-Pattern, welches zu einem Crash des Backend geführt hat bitte direkt an mich wenden.

Developer Week Nürnberg 2013

WP_20130626_002Auf der diesjährigen Developer Week in Nürnberg hatte ich einen Talk zum Thema “Win8 Apps; jetzt auch mit Speichern”.

Ziel war es zu zeigen, wie einfach ein leistungsfähiges und ausfallsicheres Backend mit Hilfe von Windows Azure aufgebaut werden kann. Im Live-Coding (auch bei eingeschränkter Internet Bandbreite) konnte ich zeigen wie mit ein paar Mausklicks eine SQL Server Datenbank angelegt und von einer lokalen Win8 App aus benützt werden kann.

Auch die Besonderheiten, die in der Entwicklung und beim Betrieb eines Backend in Windows Azure beachtet werden müssen konnte ich im Live-Coding ansprechen und zeigen.

Aufgrund des sehr positiven Feedbacks und der vielen Fragen werde ich in den nächsten Wochen bzw. Monaten eine dreiteilige Artikel Serie zum Thema in der dotnetpro veröffentlichen. 

Die Slides der Session finden sich hier zum Download.

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.