Mobile services
This presentation is the property of its rightful owner.
Sponsored Links
1 / 129

Mobile Services PowerPoint PPT Presentation


  • 58 Views
  • Uploaded on
  • Presentation posted in: General

Mobile Services. Paolo Salvatori Microsoft. Paolo Salvatori. Senior Program Manager Microsoft. Agenda. 1 st Hour: Introduction to Mobile Services (45 minutes ) General Architecture Management Portal REST API Break (15 minutes). why is mobile so important?.

Download Presentation

Mobile Services

An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript


Mobile services

Mobile Services

Paolo Salvatori

Microsoft


Paolo salvatori

Paolo Salvatori

Senior Program Manager

Microsoft


Agenda

Agenda

  • 1st Hour: Introduction to Mobile Services (45 minutes)

    • General Architecture

    • Management Portal

    • REST API

    • Break (15 minutes)


Mobile services

why is mobile so important?


App development challenges

App DevelopmentChallenges

Enterprises want to manage internal mobile apps and consumer facing event- or product-specific mobile apps from the same portal as core LOB apps

Small Businesses require solutions that accelerate development time and decrease development costs.

Developers shouldn’t have to constantly reinvent the wheel and reproduce common backend functionality

Consumers expect a continuous experience across all devices


Windows azure mobile services addresses each of those challenges

Windows Azure Mobile Servicesaddresses each of those challenges.


Mobile services

Windows Azure Mobile Services accelerates connected client application development by streamlining common backend tasks like structuring storage, authenticating users, and sending push notifications.


Key scenarios

Key Scenarios

Rapid Development

Time is money. Get your app up and running sooner when you use Mobile Services to configure a secure backend in less than five minutes.

Make your app social

Whether your customers use Google, Facebook, Twitter, or Microsoft Account, no matter what devices they run your app on, with Mobile Services you can makes your app social and personable fast.

Make your app engaging and dynamic

Push notifications and Live Tiles is the premier way to engage your customers. Make your app engaging and dynamic using Mobile Services Push.


Basic features

Basic Features

Data in the Cloud

SQLTableBlob

Connected Apps

Windows Store iOS

Android

Windows Phone 8

iOS

Android

HTML 5/JS

Server-Side Scripts

&

Scheduler

User Authentication

FacebookTwitter Microsoft Google

Push Notifications

WNS &APNSGCM

MPNS

SDKs


Supported platforms

Supported Platforms

Windows 8

iOS

Windows Phone 8

Android

HTML5 & Javascript


Architecture

Architecture

Zumo Resource Provider

Portal

RDFE

SQL N

SQL 1

SQL 2

Zumo Mgmt DB

Site 2

Site N

Site 1

Azure LB\ARR

Scheduler

Zumo Runtime

App Scripts

Zumo

Antares

Stamp

Win8 Device

Azure SDK

3rd party SDKS

iPhone


Management portal

Management Portal


Dashboard

Dashboard

  • Quick glance

    • Displays relevant mobile service information, including the service URL, status, location, database and subscription

  • Usage Timeline:

    • Displays a scalable chart of CPU time, API calls and data reads over a specific period of time.

  • Usage Overview:

    • Displays an overview of the total compute time and storage used by this mobile service

  • Manage Keys

    • Manage Keys

  • Delete

    • Delete the Mobile Service


Mobile services

Data

  • In Windows Azure Mobile Services, data is stored in tables, which are maintained in the Windows Azure SQL Database that is associated with your mobile service.

  • Click the Create button to add a new table to your mobile service.

  • By default, you don’t need to predefine the schema of tables in your database.

  • Mobile Services automatically add columns to a table based on the data you insert. To change this dynamic schema behavior, use the Dynamic Schema setting on the Configure tab.

  • To browse data, manage permissions and indexes on tables, or add server scripts, click on a table in the list.

  • To delete a table, click to select a table row, and then click Delete.


Browse

Browse

  • The Browse tab lets you browse data rows in a selected table.

  • Click the forward and back arrows to navigate through multiple pages of data.

  • Click on table names in the left navigation bar to switch between tables.

  • Click on the large left arrow to go back to the Data tab.


Script

Script

  • Mobile Services enables you to register JavaScript code to be executed by the service when an insert, update, delete, or read operation occurs against a specific table.

  • For each table there are 4 CRUD operations (insert, read, update, del)

  • These scripts provide the ability to inject business logic into table operation, stop an operation from taking place, change or enrich values supplied to the operation or change the results.

  • For authenticated clients, you can also perform user-specific authorizations based on the userId value of the supplied userobject.


Columns

Columns

  • To delete columns, click the column and then click Delete.

  • To add additional columns to the table, simply send an insert request including the new properties from your app with dynamic schema enabled.

  • Once a column is created, its data type cannot be changed by Mobile Services.

  • Insert or update operations fail when the type of a property in the JSON object cannot be converted to the type of the equivalent column in the table.

  • You can improve the performance of queries by defining an index on the table.

  • To add a column to the index, select the column and click Set as Index.


Permissions

Permissions

  • Mobile Services enables you to set the following permissions on table operations:

    • Everyone: request for the operation against the table is accepted. This option leaves your data wide-open for everyone to access.

    • Anybody with the Application Key: The application key is required to perform the operation. The application key is distributed with the application. Note: Because this key is not securely distributed, it cannot be considered a security token. To secure access to your mobile service data, you must instead authenticate users before accessing.

    • Only Authenticated Users: Only authenticated users are permitted to perform the operation. Scripts can be used to further restrict access to tables based on an authenticated user.

    • Only Scripts and Admins: The operation requires the service master key, which limits the operation only to registered scripts or to administrator accounts


Scheduler

Scheduler

  • Mobile Services enables you to register JavaScript code to be executed by the service either on a schedule that you define or on-demand from the Management Portal.

    • Removing duplicate records from a table.

    • Backing up a database.

    • Send a report via email.

  • When your mobile service runs in free mode, you can create only one scheduled job at a time; in reserved mode, you can create up to ten scheduled jobs at the same time.


Mobile services

Push

  • Mobile Services can send push notifications to your apps.

  • The way that you configure and send push notifications depends on your app.

  • You can send push notifications to the following applications:

    • Windows Store app by using the Windows Push Notification Service (WNS). To send push notifications to your app, you must configure your mobile service to work with WNS.

    • iPhone and iPad apps by using the Apple Push Notification Service (APNS). To send push notifications to your app, you must configure your mobile service to work with APNS. Do this by generating a special push notification certificate at the iOS Provisioning Portal

    • Android: You can send push notifications to Android apps by using the Google Cloud Messaging (GCM) service. To send push notifications to your app, you must configure your mobile service to work with GCM.

    • Windows Phone 8 app by using the Microsoft Push Notification Service (MPNS). Mobile Services does not require you to register your Windows Phone 8 app to send push notifications.


Identity

Identity

  • Mobile Services integrates with the following identity providers to make it easy to authenticate users from your app:

    • Microsoft Account

    • Facebook login

    • Twitter login

    • Google login

  • To enable authentication, you must first register your app with one or more of these identity providers and then configure your mobile service.

  • You must also add authentication code to your app.

  • When a user login is authenticated by Mobile Services, the value of the userId property on the userobject passed to server scripts is set to a value that uniquely identifies a user. This value can then be used to authorize access to data.


Configure

Configure

  • You can directly access to the database used by your mobile service just clicking the link.

  • You can change the database used by your mobile service to store data with a new or existing DB by clicking Change DB and select one of the following options.

  • Enable/disable dynamic schema.

  • In reserved mode, you can configure endpoint monitoring.


Scale

Scale

  • On the Scale tab, you can scale your mobile service by switching to reserved mode and adding role instances.

  • You can also scale the Windows Azure SQL Database instance used by the service.

    • Note: When you set the Mobile service mode to Reserved, all of your mobile services in the same region run in Reserved mode.

  • To estimate the cost required to scale your mobile service, see the Mobile Services Pricing Calculator.


Mobile services

Log

  • Mobile Services writes system and script errors to the log.

  • Click on a log entry to view details and copy to the clipboard.

  • Click the link in the Source column to directly jump to the script that generated the error.

    • Note: Existing log entries can be viewed in the Management Portal for 7 days.

  • Your registered server scripts can also write information directly to the log by using the consoleobject.


Create your first mobile service

Create your first Mobile Service


Rest api

REST API


Rest api1

REST API


Login

Login

  • Verb: POST

  • URL: https://<service-name>.azure-mobile.net/login?mode=authenticationToken

  • UriParameter: mode

  • Request Headers:

  • Body: JSON object{"authenticationToken":“<authentication-provider-token>"} for Microsoft{“access_token":“<authentication-provider-token>"} for Facebook and Google

  • Response: JSON object{"user":{"userId":"<authentication-provider>:cb392ceae24a44408ed863482b20f274"},"authenticationToken":"<mobile-service-authentication-token>"}


Query records

Query Records

  • Verb: GET

  • URL: https://<service_name>.azure-mobile.net/tables/<table_name>

  • URI Parameters: $filter, $inlinecount, $orderby, $select, $skip, $top

  • Request Headers:

  • Response: data in JSON format

  • Samples:

    • GET https://plunko.azure-mobile.net/tables/todoitem

    • GET https://plunko.azure-mobile.net/tables/todoitem/1

    • GET https://plunko.azure-mobile.net/tables/todoitem?$filter=(complete%20eq%20false)

    • GET https://plunko.azure-mobile.net/tables/todoitem?$filter=(complete%20eq%20false)&$orderby=text%20asc


Insert record

Insert Record

  • Verb: POST

  • URL: https://<service_name>.azure-mobile.net/tables/<table_name>

  • Request Headers:

  • Body: new record in JSON format

  • Response: The JSON representation of the inserted item, which includes the ID for the item generated by the mobile service.

  • Sample:

    • POST https://plunko.azure-mobile.net/tables/todoitem

    • Body: {"text" : "Go to Las Vegas", "complete": false, "when" : "don't know"}


Update record

Update Record

  • Verb: PATCH

  • URL: https://<service_name>.azure-mobile.net/tables/<table_name>/<item_id>

  • Request Headers:

  • Body: The updated values encoded in JSON format, along with the optional id value of the object.

  • Response: The JSON representation of the updated item

  • Sample:

    • PATCH https://plunko.azure-mobile.net/tables/todoitem/1

    • Body: {"text" : "Go to Barcelona", "complete": false, "when" : "don't know"}


Delete record

Delete Record

  • Verb: DELETE

  • URL: https://<service_name>.azure-mobile.net/tables/<table_name>/<item_id>

  • Request Headers:

  • Body: none

  • Response: none

  • Sample:

    • DELETE https://plunko.azure-mobile.net/tables/todoitem/6


Httpclient and mobile services

HttpClient and Mobile Services

privateasyncvoidbtnSend_Click(object sender, EventArgs e)

{

try

{

varhttpClient = newHttpClient();

var uri = newUri("https://<your-mobile-service>.azure-mobile.net/tables/TodoItem");

httpClient.DefaultRequestHeaders.Accept.Add(newMediaTypeWithQualityHeaderValue("application/json"));

httpClient.DefaultRequestHeaders.Add("x-zumo-application", “<application-key>");

httpClient.DefaultRequestHeaders.Host = uri.Host;

vartodoItem = newTodoItem {Text = txtText.Text, Complete = false};

varserializer = newDataContractJsonSerializer(typeof (TodoItem));

using (var stream = newMemoryStream())

{

serializer.WriteObject(stream, todoItem);

stream.Seek(0, SeekOrigin.Begin);

//use a Stream reader to construct the StringContent (Json)

using (var reader = newStreamReader(stream))

{

var response = awaithttpClient.PostAsync(uri, newStringContent(reader.ReadToEnd(), Encoding.UTF8, "application/json"));

WriteToLog(response.IsSuccessStatusCode

? string.Format("Message <{0}> successfully inserted!", txtText.Text)

: string.Format("HTTP Status: <{0}> Reason: <{1}>", response.StatusCode, response.ReasonPhrase));

}

}

}

catch (Exception ex)

{

WriteToLog(ex.Message);

}

}


Break

Break


Agenda1

Agenda

  • 2nd Hour: Server Scripts (45 minutes)

    • Server script objects

    • Server script modules

    • Configure user authentication:

      • Windows Live

      • Facebook

      • Twitter

      • Google

    • User object and integration with identity providers

    • Data validation and duplicate detection

    • Administer Mobile Services using Windows Azure Cross-Platform Command Line tool

    • Break (15 minutes)


Server script objects

Server Script Objects


Objects

Objects


Samples

Samples

console object

console.log("Inserting item '%j'.", item); // %j for 'JSON'

console.error("Operation failed: ", error);

mssql object

mssql.query('select * from orders where country = "Russia"', {success: function (results) {console.log(results); }});


Samples1

Samples

Query object: is passed to read scripts

function read(query, user, request) {

query.where({ userId: user.userId });

request.execute();

}

Requestobject: is passed to all scripts

request.execute(); //Executes the default behavior for the operation

request.respond(); //Writes the default response

request.respond(error); //Writes a response with the specified error


Samples2

Samples

Tables and Table objects

function insert(item, user, request) {

varaddressTable= tables.getTable('address');

addressTable.where({userId: user.userId})

.read({success: function (results) {

item.address = results.length > 0 ?

results[0] :

'unknown';

request.execute(); }

});

}


Server script modules

Server Script Modules


Modules

Modules


Samples3

Samples

Request

varrequest = require('request');

varurl = 'https://api.twitter.com/1/users/show.json?screen_name=babosbird';

request(url, function(error, response, body) {

if (error) {

console.error(error);

} else {

var data = JSON.parse(body);

console.log(data);

}

});


Samples4

Samples

SendGrid

functionsendEmail(text) {

varsendgrid = newSendGrid('<user-name>', ('<password>');

sendgrid.send({

to: [email protected]',

from: [email protected]',

subject: ‘ACME Newsletter',

text: text

}, function (success, message) {

// If the email failed to send, log it as an error so we can investigate

if (!success) {

console.error(message);

}

});

}


Client libraries

Client Libraries


Portable class library

Portable Class Library

  • The Portable Class Library project supports a subset of assemblies from the .NET Framework, Silverlight, .NET for Windows Store apps, Windows Phone, and Xbox 360, and provides a Visual Studio template that you can use to build assemblies that run without modification on these platforms.

  • Mobile Services support the Portable Class Library model and this offers several advantages for developers, since they can now share the codebase of client applications between the different platforms.

  • The Portable Class Library needs a platform extension assembly (.Ext.dll) to work correctly.

  • We provide platform extension assemblies for:

    • Windows Phone 7.5

    • Windows Phone 8

    • Windows Store apps.


Portable class library1

Portable Class Library

  • The Portable Class Librarycannot contain all the classesof the managed clients for all the platforms.

  • Some functionality is only available on one platform, while other functionality differs between platforms.

  • Therefore, to be able to use the new Managed Client you also need a platform specific assembly, which contains code to be able to use features available on that specific platform.

  • UI authentication is an example of a feature that works different on different platforms and is not portable.

  • For you as a developer this means you need two assemblies for your Windows Store App to use Mobile Services.

  • For Windows Phone there is an additional assembly which contains functionality which is not allowed in background agents (e.g. login)


Windows store app

Windows Store App

App.xaml.cs

usingMicrosoft.WindowsAzure.MobileServices;

sealedpartialclassApp : Application

{

// This MobileServiceClient must be configured to communicate with

// your Mobile Service's url and application key.

// The MobileServiceClientclass provides basic access to Mobile Services.

publicstaticreadonlyMobileServiceClientMobileService =

newMobileServiceClient("https://<your-mobile-service>.azure-mobile.net/", “XXXXXXXXXXXXXXXXXXXX");

}


Windows store app1

Windows Store App

MainPage.xaml.cs

usingMicrosoft.WindowsAzure.MobileServices;

usingNewtonsoft.Json;

publicclassTodoItem

{

publicint Id { get; set; }

[JsonProperty(PropertyName = "text")]

publicstring Text { get; set; }

[JsonProperty(PropertyName = "complete")]

publicbool Complete { get; set; }

}

publicsealedpartialclassMainPage : Page

{

privateMobileServiceCollection<TodoItem, TodoItem> items;

// the IMobileServiceTable interface Provides operations on a table for a Mobile Service.

privateIMobileServiceTable<TodoItem> todoTable = App.MobileService.GetTable<TodoItem>();

privateasyncvoidRefreshTodoItems()

{

// This code refreshes the entries in the list view by querying the TodoItems table.

items = awaittodoTable

.Where(todoItem => todoItem.Complete == false)

.ToCollectionAsync();

}

}


Httpmessagehandlers

HttpMessageHandlers

  • In the new version of the managed client, HttpMessageHandlersreplaceServiceFilters.

  • The MobileServiceClientinternallyuses an instance of the HttpClient to send HTTP requests and receive HTTP responses to Mobile Services REST services.

  • In a managed client, HttpMessageHandlers can be used to intercept and handleoutgoingrequeststo Mobile Services.

  • You can defineone or more handlers for a a single MobileServiceClient.


Sample 1

Sample 1

publicclassBusyHandler : DelegatingHandler

{

privateintcallCount;

privatereadonlyAction<bool> busyIndicator;

publicBusyHandler(Action<bool> busyIndicator)

{

this.busyIndicator= busyIndicator;

}

protectedoverrideasyncTask<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationTokencancellationToken)

{

varoutgoingCount = Interlocked.Increment(refcallCount);

if (outgoingCount == 1)

{

busyIndicator(true);

}

var response = awaitbase.SendAsync(request, cancellationToken);

varincomingCount = Interlocked.Decrement(refcallCount);

if (incomingCount == 0)

{

busyIndicator(false);

}

return response;

}

}


Sample 2

Sample 2

publicclassDebugHandler : DelegatingHandler

{

// Sends an HTTP request to the inner handler to send the request to the server as an async operation

protectedoverrideasyncTask<HttpResponseMessage> SendAsync(HttpRequestMessage request,

CancellationTokencancellationToken)

{

if (request != null && request.Method == HttpMethod.Post && request.Content != null)

{

Debug.WriteLine("REQUEST: {0}", awaitrequest.Content.ReadAsStringAsync());

}

var response = awaitbase.SendAsync(request, cancellationToken);

if (response != null && response.Content != null)

{

Debug.WriteLine("RESPONSE: {0}", awaitresponse.Content.ReadAsStringAsync());

}

return response;

}

}


Html 5 client

HTML 5 Client

HTML Page: inset the following script references

<scriptsrc='//ajax.aspnetcdn.com/ajax/jQuery/jquery-1.9.1.min.js'></script>

<scriptsrc='https://<your-service-name>.azure-mobile.net/client/MobileServices.Web-1.0.0.min.js'></script>

JavaScript File

// In the editor, open or create a JavaScript file, and add the following code that defines the // MobileServiceClient variable. Supply the application URL and application key from the mobile service in

// the MobileServiceClient constructor.

var client = newWindowsAzure.MobileServiceClient('https://<your-service-name>.azure-mobile.net/', ‘AppKey')

// You get a reference to a table by calling the getTable() function on the MobileServiceClient object

vartodoItemTable= client.getTable('todoitem');

functionrefreshTodoItems() {

// Filter data by including a where clause in a query that returns all items whose complete field is equal to false

varquery = todoItemTable.where({ complete: false});

// Reads all data from the table

query.read().then(function(todoItems) {

// Use jQuery and JavaScript to update controls on the page.

});

}


Authentication

Authentication


Authentication1

Authentication

  • Mobile Services integrates with the following identity providers to make it easy to authenticate users from your app:

    • Microsoft Account

    • Facebook login

    • Twitter login

    • Google login

  • To enable authentication, you must first register your app with one or more of these identity providers and then configure your mobile service.

  • You must also add authentication code to your app.

  • When a user login is authenticated by Mobile Services, the value of the userId property on the user object passed to server scripts is set to a value that uniquely identifies a user. This value can then be used to authorize access to data.


Oauth authentication flow

OAuth Authentication Flow

* By Carlos Figueira, see references


Windows store apps

Windows Store Apps

privatestaticasyncSystem.Threading.Tasks.Task Authenticate()

{

while (App.MobileService.CurrentUser == null)

{

string message;

try

{

awaitApp.MobileService.LoginAsync(MobileServiceAuthenticationProvider.Facebook);

message = string.Format("User successfully authenticated: UserId = {0}",

App.MobileService.CurrentUser.UserId);

}

catch (InvalidOperationException)

{

message = "Login failed!";

}

varmessageDialog = newMessageDialog(message, "Login Status");

awaitmessageDialog.ShowAsync();

}

}


Windows phone 8 apps

Windows Phone 8 Apps

privateasyncTask Authenticate()

{

while (user == null)

{

string message;

try

{

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

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

}

catch (InvalidOperationException ex)

{

message = ex.Message;

}

MessageBox.Show(message);

}

}


Html 5 app

HTML 5 App

HTML Page

<divid="logged-out">

You are not logged in.

<button>Log in</button>

<selectid="authentication-providers">

<optionselected="selected"value="MicrosoftAccount">Microsoft</option>

<option>Twitter</option>

<option>Facebook</option>

<option>Google</option>

</select>

</div>


Html 5 app1

HTML 5 App

JavaScript File

functionlogIn() {

client.login($("#authentication-providers :selected")

.val())

.done(refreshAuthDisplay, function (error) {

alert(error);

});

}

functionlogOut() {

client.logout();

refreshAuthDisplay();

$('#summary').html('<strong>You must login to access data.</strong>');

}


User object

User Object

// The User object which is passed to all scripts

// has a function called getIdentities(),

// which returns an object with provider-specific data

// which can be used to query their user information.

// Facebook

{

"facebook":{

"userId":"Facebook:<user-id>",

"accessToken":“<access-token>"

}

}

// Microsoft:

{

"microsoft":{

"userId":“MicrosoftAccount:<user-id>",

"accessToken":“<access-token>"

}

}

//Google:

{

"google":{

"userId":"Google:<user-id>",

"accessToken":“<access-token>"

}

}

//And for Twitter:

{

"twitter":{

"userId":"Twitter:<user-id>",

"accessToken":“<access-token>",

"accessTokenSecret":“<access-token-secret>"

}

}


Get user name 1 2

Get User Name (1/2)

functiongetUserName() {

// Set default name

item.userName = '<unknown>';

// Get credentials for the authenticated user

var identities = user.getIdentities();

varreq = require('request');

varurl;

// Create url to query the authentication provider for user name

if (identities.microsoft) {

url = 'https://apis.live.net/v5.0/me/?method=GET&access_token=' + identities.microsoft.accessToken;

} elseif (identities.facebook) {

url = 'https://graph.facebook.com/me?access_token=' + identities.facebook.accessToken;

} elseif (identities.google) {

url = 'https://www.googleapis.com/oauth2/v1/userinfo?access_token=' + identities.google.accessToken;

} elseif (identities.twitter) {

url = 'https://api.twitter.com/1/users/show.json?user_id=' +

user.userId.substring(user.userId.indexOf(':') + 1);

}


Get user name 1 21

Get User Name (1/2)

// Call authentication provider

if (url) {

req(url, function (error, response, body) {

if (error) {

console.error('An error occurred while sending data to Facebook Graph API: ', error);

}

else {

try {

var data = JSON.parse(body);

item.userName = data.name ? data.name : '<unknown>';

}

catch (ex) {

console.error('An error occurred while parsing response data from the auth provider: ', ex);

}

}

if (f) {

f();

}

});

}

}


Data validation and duplicate detection

Data Validation and Duplicate Detection


Data validation

Data Validation

function insert(item, user, request) {

// Validation

if (!item.text) {

request.respond(statusCodes.BAD_REQUEST, "The text cannot be null");

return;

}

}


Duplicate detection

Duplicate Detection

function insert(item, user, request) {

vartodoItemTable = tables.getTable("TodoItem");

todoItemTable.where({userId: user.userId, text: item.text, complete: false})

.read({

success: function(results) {

if(results && results.length> 0) {

console.log("Duplicate detected: userId = ["+ user.userId+

"] text = ["+ item.text+ "]")

request.respond(statusCodes.OK, results[0]);

} else{

request.execute();

}

}

});

}


Authorization

Authorization

function insert(item, user, request) {

varpermissionsTable = tables.getTable('permissions');

permissionsTable.where({

userId: user.userId,

permission: 'submit order'

}).read({

success: function (results) {

if (results.length > 0) {

// Permission record was found. Continue normal execution.

request.execute();

} else {

console.log('User %s attempted to submit an order without permissions.', user.userId);

request.respond(statusCodes.FORBIDDEN, 'You do not have permission to submit orders.');

}

}

});

}


Administer mobile services using windows azure cross platform command line tool

Administer Mobile Services using Windows Azure Cross-Platform Command Line tool


Mobile services

CLI

  • This tool can be used on the following platforms:

    • Windows

    • Linux

    • Mac

  • Mobile Services can be managed using CLI


Agenda2

Agenda

  • 3rd Hour: Push Notifications and integration with other services

    • Send push notifications using WNS and MPNS

    • Windows mobile and Windows Store Apps notifications

    • Invoke REST services via request Node.js module and HTTP protocol

    • Integrate Mobile Services with on-premises LOB applications:

      • Via Service Bus Relay Services

      • Via Service Bus Queues, Topics and Subscriptions

    • Break (15 minutes)


Push notifications

Push Notifications


Mobile services

Push

  • Mobile Services can send push notifications to your apps.

  • The way that you configure and send push notifications depends on your app.

  • You can send push notifications to the following applications:

    • Windows Store app by using the Windows Push Notification Service (WNS). To send push notifications to your app, you must configure your mobile service to work with WNS.

    • iPhone and iPad apps by using the Apple Push Notification Service (APNS). To send push notifications to your app, you must configure your mobile service to work with APNS. Do this by generating a special push notification certificate at the iOS Provisioning Portal

    • Android: You can send push notifications to Android apps by using the Google Cloud Messaging (GCM) service. To send push notifications to your app, you must configure your mobile service to work with GCM.

    • Windows Phone 8 app by using the Microsoft Push Notification Service (MPNS). Mobile Services does not require you to register your Windows Phone 8 app to send push notifications.


Push notifications1

Push Notifications


Windows store app2

Windows Store App

privatestaticasyncSystem.Threading.Tasks.TaskAcquirePushChannel()

{

// Create a channel to receive notifications

varcurrentChannel = awaitPushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();

varuriAsString = currentChannel.Uri;

// Check if the channel already exists in the Channel table

varchannelTable = App.MobileService.GetTable<Channel>();

var enumerable = awaitchannelTable.

Where(c => c.Uri == uriAsString).ToEnumerableAsync();

if (enumerable.Any())

{

// Exit if the channel already exists in the Channel table

return;

}

var channel = newChannel { Uri = currentChannel.Uri, Type = "WNS" };

awaitchannelTable.InsertAsync(channel);

}


Make your app toast capable

Make your App Toast Capable

  • To configure the Windows Store App to receive push notifications, open the Package.appxmanifest file and make sure that in the Application UI tab, Toast capable is set to Yes


Windows phone 8 app

Windows Phone 8 App

privateHttpNotificationChannelCurrentChannel;

privatevoidAcquirePushChannel()

{

CurrentChannel = HttpNotificationChannel.Find("MyPushChannel");

if (CurrentChannel == null)

{

CurrentChannel = newHttpNotificationChannel("MyPushChannel");

CurrentChannel.Open();

CurrentChannel.BindToShellTile();

CurrentChannel.BindToShellToast();

}

varchannelTable = App.MobileService.GetTable<Channel>();

var channel = newChannel { Uri = CurrentChannel.ChannelUri.ToString() };

channelTable.InsertAsync(channel);

}


Configure the app

Configure the App

  • To configure the Windows Phone 8 App to receive push notifications, open the WMAppManifest.xmlfile and make sure that in the Capabilities tab, ID_CAP_PUSH_NOTIFICATION is checked.


Server script code

Server Script Code

functionsendPushNotification() {

varchannelTable = tables.getTable('Channel');

channelTable.read({

success: function (channels) {

channels.forEach(function (channel) {

if (channel.type === "WNS") {

push.wns.sendToastText02(channel.uri, { text1: "New Todo Item", text2: item.text},

{success: function (pushResponse) {

console.log("Sent push:", pushResponse);

}

});

}

if (channel.type === "MPNS") {

push.mpns.sendToast(channel.uri, {

text1: 'TodoList',

text2: item.text

}, {

success: function (pushResponse) {

console.log("Sent push:", pushResponse);

}

});

}

});

}

});

}


Push notifications2

Push Notifications


Integrate mobile services with on premises lob applications

Integrate Mobile Services with on-premises LOB applications


Hybrid solutions

In today’s IT landscape, it is not uncommon that data and services used by a system are located in multiple application domains.

Resources may be stored in a corporate data center, while other services may be located across the organizational boundaries, in the cloud or in the data centers of business partners.

There are many reasons for requiring a hybrid approach to cloud applications:

Certain types of data come under national regulations which explicitly forbid data from being stored in another country.

Data may need to be shared locally with on –premise applications and services.

Hybrid Solutions


Windows azure service bus

Windows Azure Service Bus

  • The Windows Azure Service Bus is an Internet Service Bus that offers secure, scalable and highly available connectivity and messaging capabilities.

  • The Service Bus is part of Windows Azure and is designed to provide connectivity, queuing, and routing capabilities that allow on-premises and cloud applications to exchange messages across the boundaries of logical and physical domains.

  • The Service Bus can be used as the foundation to create a new range of hybrid and distributed applications that span the cloud and corporate environments.

  • The Service Bus provides 2 messaging types:

    • Relayed Messaging

    • Brokered Messaging


Service bus relayed messaging

Service Bus Relayed Messaging

  • The Service Bus allows a WCF service to expose an endpoint in a Windows Azure data center that can be accessed by consumer applications in a mediated and secure way using different transport protocols (TCP, HTTP/S) and message formats (SOAP and REST).

  • The relay service provides a rendezvous connection point in the cloud between the client application and the service provider.

  • Both the client and service can reside in the cloud or on-premises.

  • The Service Bus supports the WCF programming model and provides a rich set of bindings (BasicHttpRelayBinding, NetTcpRelayBinding, NetEventRelayBinding, etc.) to cover a wide variety of design patterns and Message Exchange Formats.

    • One-way communications

    • Publish/Subscribe

    • Peer-to-peer communications

    • Multicast messaging


Service bus brokered messaging queues

Queues provide messaging capabilities that enable a large and heterogeneous class of applications running on premises or in the cloud to exchange messages in a secure and reliable fashion across trust boundaries.

Queues are based on a new messaging infrastructure backed by a replicated, durable store - up to 5GB per Queue.

The max message size is 256KB, but the session feature allows creating unlimited-size sequences of related messages.

Queues are available through a .NET API, WCF, HTTP/REST and AMQP Interfaces

Service Bus Brokered Messaging - Queues


Queues capabilities

Session-based message correlation.

Message Scheduled Delivery.

Reliable delivery patterns via Peek/Lock Receive Mode.

Transactions support to ensure batches of messaging operations are committed atomically.

Detection of inbound message duplicates, allowing clients to send the same message multiple times without adverse consequences (Idem-potency).

Dead-letter facility for messages that cannot be processed or expire before being received.

Deferring messages for later processing.

Queues - Capabilities


Queues scenarios

Loosely-Coupled Asynchronous Communication allows to establish an asynchronous and loosely-coupled communication between autonomous systems that run in different application domains, on-premises or in the cloud.

Load Leveling allows to flatten a highly-variable traffic into a predictable stream of work.

Load Balancing allows to distribute the load across a set of worker processes which size can vary dynamically to accommodate the incoming message volume.

In a Competing Consumers scenario, when a publisher writes a message to a queue, multiple consumers compete with each other to receive the message, but only one of them will receive and process the message in question.

Temporal Decoupling allows to work on independent schedules. The producers and consumers are not required to be online at the same time. This allows to publish messages to workers that are temporarily offline.

Queues - Scenarios


Service bus brokered messaging topics

Topics provide all the Features of Queues + Publish/Subscribe capabilities.

A Topic consists of a sequential message store just like a Queue, but it supports up to 2000 concurrent and durable subscriptions

Each Subscription is a virtual queue getting message copies

A Subscription may have a single consumer that gets all the messages or a set of competing consumers that fetch messages on a first-come-first-served basis.

Subscriptions can have filters expressions and filter actions

Service Bus Brokered Messaging - Topics


Topics scenarios

Publish Events to many subscribers

Each subscription can be shared by a set of competing consumers

Secondary subscriptions can be used for auditing purposes.

Distribute workload across partitioned pools of workers, each defined by a different subscription

Decoupled message fan-out scenario to send messages to many consumers requiring the same information

As the foundation in event-driven architecture implementations

Topics - Scenarios


Topics rules filters

Rules:

Rules select messages based on conditions defined on system or application-specific properties

Topics support more than one rule for each subscription

Filter Conditions and Actions:

Conditions are represented by filter expressions expressed in SQL’92 syntax:

ShipCountry=“Russia” AND ShipCity=“Moscow”

Actions are expressed by action expressions and can add and modify message properties during retrieval

Set Priority='High';Set Severity=1

Topics – Rules & Filters


Messages

Messages are modeled by the BrokeredMessage class

Messages can have user-defined:

Time-To-Live periods (with no enforced maximum lifetime)

Lock duration

Duplicate detection history time

Messages expose the following properties:

MessageId that can be used for duplicate detection

CorrelationId to correlate a message to a specific request

SessionId for session-enabled communication

ReplyTo that can be used to implement a request-reply MEP.

Label for custom use

User defined properties are key/value pairs

Brokered messaging properties are not SOAP headers

Messages


Service bus explorer

Service Bus Explorer


How to call a service bus relay service 1 3

How to call a Service Bus relay service (1/3)

functiongetUserAddress(f) {

// Set default value

item.userAddress = '<unknown>';

// Create the SOAP Envelope

var body = '<s:Envelopexmlns:s="http://schemas.xmlsoap.org/soap/envelope/">' +

'<s:Body>' +

'<user xmlns="http://windowsazure.cat.microsoft.com/samples/mobileservices">' +

'<userId>' + user.userId + '</userId>' +

'</user>' +

'</s:Body>' +

'</s:Envelope>';

// Import the request module

varreq = require('request');

* You can the xmlbuilder, sax and js2xml Node.js modules to create the SOAP message


How to call a service bus relay service 2 3

How to call a Service Bus relay service (2/3)

// Create call options

var options = {

method: 'POST',

url: 'http://paolosalvatori.servicebus.windows.net/basichttp/todoitem',

headers: {

'Content-Type': 'text/xml',

'SOAPAction': 'GetUserAddress'

},

body: body

};

// Call the Service Bus Relay Service

req(options, function(error, response, body) {

if (error) {

console.log('An error occurred while invoking the service: ', error);

} else {

// Import xml2js module

var xml2js = require('xml2js');

// Create a xml2js parser

var parser = new xml2js.Parser();


How to call a service bus relay service 3 3

How to call a Service Bus relay service (3/3)

// Parse the SOAP envelope of the response from XML to JSON

parser.parseString(body, function (err, result) {

try {

// Read the address from the JSON object

var address = result["s:Envelope"]["s:Body"][0]["userAddress"][0]["text"][0];

if (address) {

// Set the userAddress property of the item

item.userAddress = address;

}

}

catch (ex) {

// Log the error

console.log("An error occurred while parsing the response: ", error);

}

});

if (f) {

// Invoke a continuation function, if any

f();

}

}

});

}


How to use send a message to queue 1 2

How to use Send a message to queue (1/2)

functionsendMessageToServiceBus() {

// Import the azure module

var azure = require('azure');

// Create a ServiceBusService object

varserviceBusService = azure.createServiceBusService('<your-service-bus-namespace-name>',

'<your-service-bus-namespace-key>');

// Define queue options

varqueueOptions = {

EnableBatchedOperations: true,

RequiresDuplicateDetection: true,

DuplicateDetectionHistoryTimeWindow: 'PT8H'

};


How to use send a message to queue 2 2

How to use Send a message to queue (2/2)

// Create queue if it does not exist

serviceBusService.createQueueIfNotExists('mobileservices/todoitem', queueOptions, function (error) {

if (error) {

console.error("An error occurred creating/accessing the Service Bus queue: ", error);

}

else {

// Create a message

var message = {

body: 'Hello World!',

messageId: item.id,

customProperties: {

source: 'Mobile Services',

author: 'Paolo Salvatori'

}

};

// Send the message to the queue

serviceBusService.sendQueueMessage('mobileservices/todoitem', message, function (error) {

if (!error) {

console.log('Sent message: ' + message);

}

});

}

});

}


Integration via service bus

Integration via Service Bus


Integrate mobile services with on premises lob applications1

Integrate Mobile Services with on-premises LOB applications


Agenda3

Agenda

  • 4th Hour: Storage Services, Scheduler, SendGrid

    • Store data to Table Storage using the azure Node.js module

    • Use Shared Access Signatures and Blobs with Mobile Services

    • Create and schedule jobs with the scheduler

    • Send emails using SendGridNode.js module

    • Break (15 minutes)


Table storage

Table Storage


Choose the partitionkey and rowkey wisely

Choose the PartitionKey and RowKey wisely

  • Tables are partitioned to support load balancing across storage nodes.

  • A table's entities are organized by partition.

    • A partition is a consecutive range of entities sharing the same partition key value.

  • The partition key is a unique identifier for the partition within a given table, specified by the PartitionKey property.

  • The partition key forms the first part of an entity's primary key.

  • The second part of the primary key is the row key, specified by the RowKey property.

  • The row key is a unique identifier for an entity within a given partition.

  • Together the PartitionKey and RowKey uniquely identify every entity within a table.

  • An entity can have up to 255 properties, including 3 system properties described in the following section.


Insert script simplified

Insert Script (simplified)

function insert(item, user, request) {

// Access table service

var azure = require('azure');

vartableService = azure.createTableService('<your-storage-account-name>', '<your-storage-account-key>');

// Create table if not exists

tableService.createTableIfNotExists('TodoItems', function(error) {

if (error) {

request.respond(statusCodes.BAD_REQUEST, error);

} else {

var entity = {

PartitionKey: user.userId || 'default',

RowKey: (new Date()).getTime(),

text: item.text,

complete: item.complete,

};

// Insert the item in the storage table

tableService.insertEntity('TodoItems', entity, function (error) {

if (error) {

request.respond(statusCodes.BAD_REQUEST, error);

}

else {

request.respond(statusCodes.OK, entity);

}

});

}

});

}


Table storage1

Table Storage


Shared access signatures

Shared Access Signatures

  • A shared access signature (SAS) is a URI that grants restricted access rights to containers, blobs, queues, and tables.

  • You can provide a SAS to clients that are not trusted to use the storage account key but to whom you wish to delegate access to certain storage account resources.

  • By distributing a SAS URI to these clients, you can grant them access to a resource for a specified period of time, with a specified set of permissions.

  • A shared access signature can grant any of the following operations to a client that possesses the signature:

    • Reading and writing page or block blob content, block lists, properties, and metadata

    • Deleting, leasing, and creating a snapshot of a blob

    • Listing the blobs within a container

    • Adding, removing, updating, and deleting queue messages

    • Getting queue metadata, including the message count

    • Querying, adding, updating, deleting, and upserting table entities


Blobs and shared access signature

Blobs and Shared Access Signature

  • The Windows Store app creates a new album

  • The Mobile Service insert a new record in the Album table

  • Thw Windows Store app creates a new picture

  • The Mobile service calls the storage account to get a SAS for the image and its thumbnail

  • The Mobile Services saves the image data in the Picture table

  • The Insert script returns a SAS for the image and thumbnail in the item object

  • The Windows Store app uses the storage account client API and the SAS returned by the Mobile Service to save the image and thumbnail as blobs.

*Sample by Nick Harris, see references for more info


Server script and sas

Server Script and SAS

  • The insert script uses the following line of code to build a SAS URL:

    • return'https://' + host + blobRelativePath + '?' + sasQueryString;

  • A typical SAS query string contains many parameters which depend on the storage resource (blob, container, table, queue)

  • se=2013-05-21T15%3A37%3A15Z&sr=b&sp=w&sig=dj9zqN%2BSM1UX

    • se = signedexpiry: the time at which the shared access signature becomes invalid

    • sr= signedresource: b to grant access to a blob, c to grant access to a container

    • sp = signedpermissions: the permissions associated with the Shared Access Signature (w = write)

    • sig = signature: the signature part of the URI is used to authenticate the request made with the SAS.

  • See http://msdn.microsoft.com/en-us/library/windowsazure/dn140255.aspx


Blobs and sas

Blobs and SAS


What is the azure scheduler service

What is the Azure Scheduler service?

  • Platform service that allows users a simple way to schedule recurring actions against other services in the cloud

  • Examples:

    • Store a daily backup of my SQL database to blob storage.

    • Clean up my To Do app’s done items every day

    • Check the health of my service every few minutes

    • Send a newsletter every day


Azure scheduler capabilities

Azure Scheduler Capabilities

  • Azure Portal integrated experience

  • Actions can be scheduled to fire once or on a regular recurring schedule

  • Reliably and securely invoke services inside and outside of Azure using Node.js modules


Use a job to backup a sql database

Use a Job to backup a SQL Database

  • The scheduler calls the backup job

  • The backup job uses the request module to invoke the WA SQL Database Import/Export service by calling its REST endpoint

  • The Import/Export service reads the DB schema and data

  • The service exports DB schema and data to Windows Azure Blob Storage as a BACPAC

*Sample by Josh Twist, see references for more info


Code 1 2

Code (1/2)

function backup() {

varrequest = require('request');

varutil = require('util');

vardate = new Date();

varyear = date.getUTCFullYear();

varmonth = date.getUTCMonth() + 1;

varday = date.getUTCDate();

varbody = {

BlobCredentials: {

__type: "BlobStorageAccessKeyCredentials:#Microsoft.SqlServer.Management.Dac.ServiceTypes",

Uri: util.format("https://<your-storage-account-name>.blob.core.windows.net/bacpac/%s-%s-%s.bacpac", year, month, day),

StorageAccessKey: "<your-storage-account-key>"

},

ConnectionInfo: {

DatabaseName: "<your-database-name>",

Password: "<your-server-password>",

ServerName: "<your-server-name>.database.windows.net",

UserName: “<your-server-username>"

}

}


Code 2 2

Code (2/2)

varpostUri = "https://am1prod-dacsvc.azure.com/DACWebService.svc/Export";

request.post({

uri: postUri,

headers: {

'Content-Type': 'application/json',

},

body: JSON.stringify(body)

}, function (e, r, b) {

if (e || r.statusCode != 200) {

console.error('backup failed', e || r.statusCode, b);

}

else {

console.log('backup successful', b);

}

});

}


Schedule sql database backup

Schedule SQL Database Backup


Send a report via email

Send a Report via Email

  • The scheduler calls the job function

  • The script reads data from SQL tables and/or Storage tables

  • The script aggregates and formats data in a report.

  • The script sends the report via email using the the sendgrid Node.js module


Code 1 3

Code (1/3)

functionCountTodoItems() {

varSendGrid = require('sendgrid').SendGrid;

// Get access to the storage table

var azure = require('azure');

vartableService = azure.createTableService('<your-storage-account-name>',

'<your-storage-account-name>');

// Define query to retrieve todo items

vartableQuery = azure.TableQuery

.select()

.from('TodoItems')

.where('complete eq ?', 'false');

// Retrieve todo items

queryEntities();


Code 2 3

Code (2/3)

functionqueryEntities() {

tableService.queryEntities(tableQuery, function (error, entities) {

if (error) {

var message = 'Failed to retrieve todo items from the TodoItems table.';

console.error(message);

}

else {

var text = 'The TodoItems table actually contains ' + entities.length + ' rows:\r\n\r\n';

for (vari = 0; i < entities.length; i++) {

text = text + ' - UserId: ' + entities[i].PartitionKey;

text = text + ' Item: ' + entities[i].text + '\r\n';

}

text = text + '\r\nMessage sent by TodoItems site at ' + (new Date()).toString();

sendEmail(text);

console.log(text);

}

});

}


Code 3 3

Code (3/3)

functionsendEmail(text) {

varsendgrid = newSendGrid('babosbird', 'Trustno1');

sendgrid.send({

to: [email protected]',

from: [email protected]',

subject: 'Number of Todo Items',

text: text

}, function (success, message) {

// If the email failed to send, log it as an error so we can investigate

if (!success) {

console.error(message);

}

});

}

}


Send a report via email1

Send a Report via Email


Trigger a worker role with a service bus msg

Trigger a Worker Role with a Service Bus Msg

  • The scheduler calls the job function.

  • The script creates and send a message to a Service Bus queue or topic.

  • One instance of the Worker Role reads the message from the queue/subscription.

  • The Worker Role instance processes the message.


Mobile services

Code

functionSendMessageToServiceBus() {

var azure = require('azure');

varserviceBusService = azure.createServiceBusService('paolosalvatori',

'PgTi69pNLU2Me58C3xiEDT5xosclhfEgQs6NsUCY9Qs=');

serviceBusService.createQueueIfNotExists('mobileservices/scheduler', function (error) {

if (!error) {

var builder = require('xmlbuilder');

var root = builder.create('job',

{ 'version': '1.0', 'encoding': 'UTF-8' })

.att('xmlns', 'http://windowsazure.cat.microsoft.com/samples/mobileservices');

root.ele('command', 'read');

root.ele('date', (new Date()).toUTCString());

var message = root.end({ 'pretty': true, 'indent': ' ', 'newline': '\n'});

serviceBusService.sendQueueMessage('mobileservices/scheduler', message, function (error) {

if (!error) {

console.log('Sent message: ' + message);

}

});

}

});

}


Trigger a worker role with a service bus msg1

Trigger a Worker Role with a Service Bus Msg


References

References

  • Windows Azure Mobile Services

    • http://www.windowsazure.com/en-us/develop/mobile/

  • Tutorials and Resources

    • http://www.windowsazure.com/en-us/develop/mobile/resources-html/

  • Upload File to Windows Azure Blob Storage using Windows Azure Mobile Services

    • http://code.msdn.microsoft.com/Upload-File-to-Windows-c9169190

  • Getting user information on Azure Mobile Services

    • http://blogs.msdn.com/b/carlosfigueira/archive/2012/10/25/getting-user-information-on-azure-mobile-services.aspx

  • Troubleshooting authentication issues in Azure Mobile Services

    • http://blogs.msdn.com/b/carlosfigueira/archive/2012/10/23/troubleshooting-authentication-issues-in-azure-mobile-services.aspx


References1

References

  • Using the scheduler to backup your Mobile Service database

    • http://www.thejoyofcode.com/Using_the_scheduler_to_backup_your_Mobile_Service_database.aspx

  • Getting started with the CLI and backing up your scripts

    • http://www.thejoyofcode.com/Getting_started_with_the_CLI_and_backing_up_your_scripts_Day_4_.aspx

  • More CLI – changing your Mobile Services workflow

    • http://www.thejoyofcode.com/More_CLI_ndash_changing_your_Mobile_Services_workflow_Day_5_.aspx

  • New Windows Azure Mobile Services Getting Started Content

    • http://blogs.msdn.com/b/windowsazure/archive/2013/01/09/new-windows-azure-mobile-services-getting-started-content.aspx

  • How to use Windows Azure Table Storage in Windows Azure Mobile Services

    • http://code.msdn.microsoft.com/windowsazure/Use-Table-Storage-in-0b6bcbc7


References2

References

  • Howto Use the Table Service from Node.js

    • http://www.windowsazure.com/en-us/develop/nodejs/how-to-guides/table-services/

  • How to Use Service Bus Queues

    • http://www.windowsazure.com/en-us/develop/nodejs/how-to-guides/service-bus-queues/

  • How to Use Service Bus Topics/Subscriptions

    • http://www.windowsazure.com/en-us/develop/nodejs/how-to-guides/service-bus-topics/

  • How to Send Email Using SendGrid from Node.js

    • http://www.windowsazure.com/en-us/develop/nodejs/how-to-guides/sendgrid-email-service/


Blogs

Blogs

  • Josh Twist Blog

    • http://www.thejoyofcode.com/

  • Nick Harris Blog

    • http://www.nickharris.net/

  • Carlos Figuera

    • http://blogs.msdn.com/b/carlosfigueira/

  • Paolo Salvatori Blog

    • http://blogs.msdn.com/b/paolos


Contacts

Contacts

Paolo Salvatori

Email: [email protected]

Blog: http://blogs.msdn.com/b/paolos/

Twitter: @babosbird


  • Login