<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>All things must PaaS</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/petsablog/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/petsablog/feed.xml</link>
    <description>Look Ma, No IT</description>
    <lastBuildDate>Tue, 16 Apr 2019 05:23:10 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Simple and robust way to operationalise Spark models on Azure</title>
      <link>https://docs.microsoft.com/archive/blogs/petsablog/simple-and-robust-way-to-operationalise-spark-models-on-azure</link>
      <pubDate>Wed, 16 May 2018 14:45:07 GMT</pubDate>
      <dc:creator><![CDATA[petsablog]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/petsablog/?p=365</guid>
      <description><![CDATA[Let's operationalise a DataBricks regression model
Lately I've been doing a lot of work with Azure...]]></description>
      <content:encoded><![CDATA[<h1>Let's operationalise a DataBricks regression model</h1>
Lately I've been doing a lot of work with <a href="https://azure.microsoft.com/en-us/services/databricks/">Azure DataBricks</a> which is a superb Spark-based analytics platform fully integrated with Azure. It gives you everything that Open Source Spark does and <a href="https://databricks.com/product/comparing-databricks-to-apache-spark">then some</a>. I've been especially enjoying the effortless ways to move large datasets around and the ease of <a href="https://docs.azuredatabricks.net/spark/latest/mllib/index.html">MLlib</a> for my AI-projects.

<a href="https://azure.microsoft.com/en-us/services/databricks/"><img src="https://msdnshared.blob.core.windows.net/media/2018/05/databricks-1024x405.png" alt="" width="1024" height="405" class="alignnone size-large wp-image-405" /></a>

One of the questions with the simpler models like regressions and clusterings is always how to operationalise the models so that the rest of the organisation could consume the models by calling webservices. Luckily there exists <a href="https://databricks.com/blog/2018/03/07/announcing-machine-learning-model-export-in-databricks.html">model export functionality</a> that takes us almost there. It exports Spark MLlib models so that they can be run anywhere where there is a JVM available ... no Spark needed.

<strong>So I decided to build the missing half</strong> : wrap the model inside a simple java web app and deploy to Azure to be consumed.

<a href="https://msdnshared.blob.core.windows.net/media/2018/05/assembly.png"><img src="https://msdnshared.blob.core.windows.net/media/2018/05/assembly-1024x731.png" alt="" width="1024" height="731" class="alignnone size-large wp-image-415" /></a>
<h4>Some theory</h4>
<strong>First</strong> read this article to properly understand the model export feature:<a href="https://docs.databricks.com/spark/latest/mllib/model-export.html">https://docs.databricks.com/spark/latest/mllib/model-export.html</a>

<strong>Then</strong> you might want to take a look at some sample code on instancing the exported models and how to use them for predicting stuff:
<a href="https://github.com/databricks/databricks-ml-examples/tree/master/model-export-demo">https://github.com/databricks/databricks-ml-examples/tree/master/model-export-demo</a>

<strong>Finally</strong> you should download my sample IntelliJ project and use it as base for you own operationalising :
<a href="https://petsablob.blob.core.windows.net/share/siirto/modeltestwebapp.zip">https://petsablob.blob.core.windows.net/share/siirto/modeltestwebapp.zip</a>

<a href="https://msdnshared.blob.core.windows.net/media/2018/05/slice.png"><img src="https://msdnshared.blob.core.windows.net/media/2018/05/slice-1024x382.png" alt="" width="1024" height="382" class="alignnone size-large wp-image-425" /></a>
<h4>Important bits</h4>
The solution itself is ridiculously simple and I'll go throug it here for your pleasure.
I set up a basic maven archetype web app project with IntelliJ Idea and added one utility class and one library (read the docs if in doubt).

This is my index.jsp-file that does the interfacing with the caller.

Here we basically set up the parameter block structure that goes into the model and take values from the web request that was sent to us. The request could be something like this: <em>https://YOURSERVER.azurewebsites.net/?topic=sci.space&amp;text=space%20the%20final%20frontier</em>
Then the values are handed over to our utility class to be reacted upon and the result is returned to the caller ... not too complex , eh ?.

<a href="https://msdnshared.blob.core.windows.net/media/2018/05/jsp_code.png"><img src="https://msdnshared.blob.core.windows.net/media/2018/05/jsp_code-1024x597.png" alt="" width="1024" height="597" class="alignnone size-large wp-image-375" /></a>

The utility class is even simpler ...
It knows how azure treats java apps and how you can refer to files contained in the war-package (our model files, that is).
Knowing all this it creates a static instance of the model and starts churning out predictions when asked to do so.

<a href="https://msdnshared.blob.core.windows.net/media/2018/05/util_code.png"><img src="https://msdnshared.blob.core.windows.net/media/2018/05/util_code-1024x607.png" alt="" width="1024" height="607" class="alignnone size-large wp-image-385" /></a>

I then used <a href="https://docs.microsoft.com/en-us/java/azure/intellij/azure-toolkit-for-intellij">Microsofts excellent IntelliJ Azure plugin</a> to deploy this project to ... you guessed it ... to Azure.
<h4>Technical side of things</h4>
So this becomes a Java web app running on Azure.
Web Apps can scale automatically (so can our model now), web apps can use Azure Ad authentication  (<a href="https://docs.microsoft.com/en-us/azure/app-service/app-service-authentication-overview">Easy Auth</a>, and yes, it works with Java too) . Web Apps are fully in GA and they support  VNets and all kinds of metrics and professional monitoring.
Not a very bad place to host your models as web service ...

Next step would of course be to make this wrapper into Azure Function so I would only pay for the actual seconds my model is creating predictions. So, why don't I ... well, in this particular case my customer does not want any "preview" software on their stack and <a href="https://azure.microsoft.com/en-us/blog/announcing-the-preview-of-java-support-for-azure-functions/">Azure Functions Java is not in GA yet</a> ... but it will get there one day and once it does I'll create a sequel to this post.

The other obvious thing of course is containers, we could wrap this up in a container , and maybe I'll do that next time when I have some free time on my hands.
<h4>Summary</h4>
The funny thing is that done this way your service is automagically enjoying the benefits of autoscaling, authentication, monitoring and all other Azure perks making this a real production ready enterprise solution.
The power of PaaS once again.]]></content:encoded>
    </item>
    <item>
      <title>Simple trix: Deploy Azure ML Workbench - trained model to Raspberry Pi</title>
      <link>https://docs.microsoft.com/archive/blogs/petsablog/simple-trix-deploy-azure-ml-workbench-trained-model-to-raspberry-pi</link>
      <pubDate>Mon, 02 Oct 2017 05:47:54 GMT</pubDate>
      <dc:creator><![CDATA[petsablog]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/petsablog/?p=315</guid>
      <description><![CDATA[The new Azure Machine Learning tools got published last week at Ignite 2017. It was a...]]></description>
      <content:encoded><![CDATA[<a href="https://msdnshared.blob.core.windows.net/media/2017/10/alku1.png"><img width="1024" height="428" class="alignnone size-large wp-image-325" alt="" src="https://msdnshared.blob.core.windows.net/media/2017/10/alku1-1024x428.png" /></a>

<section class="ember-application" id="app">
<div class="ember-view" id="ember554"><article class="ember-view publishing-page" id="ember1007"><section class="ember-view slate-container" id="ember1115"><section class="post-container">
<div class="ember-view post-editor ql-container ql-slate" id="ember1220">
<div class="ql-editor">

The new <a target="_blank" href="https://azure.microsoft.com/en-us/overview/machine-learning/" rel="noopener noreferrer">Azure Machine Learning</a> tools got published last week at Ignite 2017. It was a a major upgrade, in fact I would say a revolution. You can train your models locally, with Spark, with containers, with GPU's , whatever suits your timetable and budget.

Then the deployment of models is totally separate action. An interesting feature of the runtime toolstack is heavy emphasis on containers. You can take trained models and deploy to <a target="_blank" href="https://azure.microsoft.com/en-us/services/container-service/" rel="noopener noreferrer">Azure Container Services</a> which will host your containers in professionally managed scalable environment <strong>or</strong> you can run locally on your own <a target="_blank" href="https://www.docker.com/" rel="noopener noreferrer">Docker</a> <strong>or</strong> you can instance your containers from your <a target="_blank" href="https://azure.microsoft.com/en-us/services/container-registry/" rel="noopener noreferrer">Azure private register</a> with <a target="_blank" href="https://azure.microsoft.com/en-us/services/container-instances/" rel="noopener noreferrer">Azure Container Instances</a> <strong>or</strong> you can deploy your container on <a target="_blank" href="https://azure.microsoft.com/en-us/campaigns/iot-edge/" rel="noopener noreferrer">edge devices</a> <strong>or </strong>... you get the picture, the architecture is just great. A true "model once, run everywhere"-architecture.

But what if you want to do something less great ?

Like deploy your models to some very small computing environment where running docker containers would be an overkill or what if you wanted to deploy to such environment where containers just don't make any sense, like in most PaaS environments.

Luckily there's a way. If you look at the <a target="_blank" href="https://docs.microsoft.com/en-us/azure/machine-learning/preview/tutorial-classifying-iris-part-1" rel="noopener noreferrer">Iris-tutorial</a> which defines a simple neural network for identifying flowers you'll quickly realise that the code to run the resulting network is <strong>not dependent on containers in any way</strong>. In fact the minimum needed code is downright simple if you choose to run your network directly without the boilerplate which makes the large-scale serving with container infrastructure possible.
<h3>So I decided to take a look at bringing a trained model to Raspberry Pi.</h3>
When I dug up and ran my old Raspberry 2 board I quickly noticed that the old "Wheezy"- image was a little rusty and left behind for modern python deployments. So I quickly installed <a target="_blank" href="https://www.raspberrypi.org/downloads/raspbian/" rel="noopener noreferrer">Jessie</a> onto my sd card using <a target="_blank" href="https://etcher.io/" rel="noopener noreferrer">etcher</a>.
<a href="https://msdnshared.blob.core.windows.net/media/2017/10/alku2.png"><img width="1024" height="566" class="alignnone size-large wp-image-335" alt="" src="https://msdnshared.blob.core.windows.net/media/2017/10/alku2-1024x566.png" /></a>

<section class="ember-application" id="app">
<div class="ember-view" id="ember554"><article class="ember-view publishing-page" id="ember1007"><section class="ember-view slate-container" id="ember1115"><section class="post-container">
<div class="ember-view post-editor ql-container ql-slate" id="ember1220">
<div class="ql-editor">

Next I had to get the needed scientific python libraries there as well and I first tried the usual way by using pip ... <strong>don't, it doesn't work that way</strong>, at least now in October 2017 it doesn't. I had to go:

sudo apt-get install python3-scipy and sudo apt-get install python3-sklearn

After that we were good to go. My little python program was basically a stripped down version of the <a target="_blank" href="https://docs.microsoft.com/en-us/azure/machine-learning/preview/tutorial-classifying-iris-part-2#review-irissklearnpy-and-configuration-files" rel="noopener noreferrer">sklearn.py</a> found in the original Iris tutorial. I saved just the bits that load back the serialized model from disk and feed it a new line of data to be analysed.

&nbsp;

<a href="https://msdnshared.blob.core.windows.net/media/2017/10/alku3.png"><img width="643" height="638" class="alignnone wp-image-345" alt="" src="https://msdnshared.blob.core.windows.net/media/2017/10/alku3-1024x1017.png" /></a>

</div>
</div>
</section></section></article></div>
</section></div>
</div>
</section></section></article></div>
</section><strong>... and sure enough ... it worked !</strong>

<a href="https://msdnshared.blob.core.windows.net/media/2017/10/alku4.png"><img width="1024" height="411" class="alignnone size-large wp-image-355" alt="" src="https://msdnshared.blob.core.windows.net/media/2017/10/alku4-1024x411.png" /></a>

So, there you have it. You can train your models with all the Spark awesomeness you can imagine but still when it comes down to it you can squeeze the models to almost any imaginable computing environment.

<section class="ember-application" id="app">
<div class="ember-view" id="ember554"><article class="ember-view publishing-page" id="ember1007"><section class="ember-view slate-container" id="ember1115"><section class="post-container">
<div class="ember-view post-editor ql-container ql-slate" id="ember1220">
<div class="ql-editor">

<em>(I was thinking of trying android phone next)</em>

enjoy.

&nbsp;

Here are my onedrive shares for the two files (might require microsoft account login):

<a target="_blank" href="https://1drv.ms/u/s!AlLclI9f-hCuznEPWu8xW-34mCgG" rel="noopener noreferrer">model file</a> and the <a target="_blank" href="https://1drv.ms/u/s!AlLclI9f-hCuznOccV0O-llW5HNF" rel="noopener noreferrer">python file</a>

<em>oh btw, did you know that you can run these on a regular computer as well ? Just download and run "python small.py" and if you get complaints about the nonexistence of sklearn just install it the usual way "pip install sklearn" ...</em>

</div>
</div>
</section></section></article></div>
</section>]]></content:encoded>
    </item>
    <item>
      <title>Serverless Azure Architecture: Node.js, Azure Functions and API Management</title>
      <link>https://docs.microsoft.com/archive/blogs/petsablog/serverless-azure-architecture-node-js-azure-functions-an-api-management</link>
      <pubDate>Mon, 06 Jun 2016 13:25:05 GMT</pubDate>
      <dc:creator><![CDATA[petsablog]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/petsablog/?p=255</guid>
      <description><![CDATA[Have I told You that I really enjoy playing with Node.js ?
So I needed to demo some Azure API...]]></description>
      <content:encoded><![CDATA[<h4>Have I told You that I really enjoy playing with Node.js ?</h4>
So I needed to demo some Azure API Management and I decided to write the functions stubs with Node.js. Easy enough when using Azure Functions, just create new Function and specify that You want to use Node.js instead of C#.  BUT WAIT ... there's always a BUT ... This time there are three buts actually.
<h2>First hurdle</h2>
Since Azure Functions is designed to be simple , it is ... well simple.  If You want to provide several pieces of functionality , like You would in a typical REST CRUD situation, You would have to write several separate disconnected functions or use some sort of dispatcher inside one function the keep the working code in one place. This time I chose to use a dispatcher :

<a href="https://msdnshared.blob.core.windows.net/media/2016/06/2016_06_code.png"><img class="alignnone  wp-image-265" src="https://msdnshared.blob.core.windows.net/media/2016/06/2016_06_code-1024x479.png" alt="2016_06_code" width="637" height="298" /></a>
I've agreed with myself that there has to be a parameter called "op" which decides the functionality to be served, other parameters are then related to the contents of the actual service. Not maybe the best thing in the world but doable , understandable and simple enough even for maintaining after one year.
<h2>Second hurdle</h2>
When making stuff like this there is no automagically produced swagger file to describe the functionality to API Manager, and Api Management needs it, not badly, but things are definitely easier if You have your swagger-description. So I decided write one by hand and emit it when my function is approached with parameter "swag=true".

Swagger is quite verbose so my swagger definition occupies many lines ... many many ... many lines. The best way (that I know of) to deal with multiline strings in javascript-environment is to use the backticks  to contain them. Like this:
var multiline = 'this
is
my multiline
string';
<a href="https://msdnshared.blob.core.windows.net/media/2016/06/2016_06_swag.png"><img class="alignnone  wp-image-275" src="https://msdnshared.blob.core.windows.net/media/2016/06/2016_06_swag-1024x484.png" alt="2016_06_swag" width="689" height="326" /></a>
as I mentioned, the swagger string is quite lengthy and it won't fit in one screenful but it is included in the resources section.
<h2>Third Hurdle</h2>
After importing the Api's swagger-definition to Azure APi Management we have something that almost works, but not quite. We are missing some important pieces of information like the keys to use when accessing Azure Functions and the variable required by the dispatcher naming-scheme (remember, op ?). So I have to edit the automatically generated function signatures slightly by manually adding rewrite-rules where I add the code-variable which contains the key that allows Api Management to call my function and a reasonable value for "op" :
<a href="https://msdnshared.blob.core.windows.net/media/2016/06/2016_06_apim_func.png"><img class="alignnone  wp-image-285" src="https://msdnshared.blob.core.windows.net/media/2016/06/2016_06_apim_func-1024x754.png" alt="2016_06_apim_func" width="727" height="535" /></a>
Now the Api Management is able to call my function and distinguish between the services that I expose and by managing the keys inside Api Management I get an extra layer of security as a bonus.
[sidetrack: If You need to make sure that your Function is not being called from internet You can choose to put it inside an <a href="https://azure.microsoft.com/en-us/documentation/articles/app-service-app-service-environment-intro/" target="_blank">App Service Environment</a> which can have a totally isolated virtual network that has vpn-connection to Your other networks like on-prem or so]
<h2>Testing</h2>
I'm using the API Managements Developer Portal and tools found there to call my API. APIM automatically creates input boxes for all ingoing parameters:
<a href="https://msdnshared.blob.core.windows.net/media/2016/06/2016_06_apim_dev.png"><img class="alignnone  wp-image-305" src="https://msdnshared.blob.core.windows.net/media/2016/06/2016_06_apim_dev-1024x514.png" alt="2016_06_apim_dev" width="805" height="404" /></a>
and here's what the call produced to Azure Functions log once executed:
<span style="color: #000000">RequestUri=https://xxxxxxx.azurewebsites.net/api/swagtest2?id=testblog&amp;code=gncemex906oujh&amp;op=findblogById</span>
<span style="color: #000000">You called :findblogById</span>
<span style="color: #000000">{"id":"testblog","code":"gncemex906oujh","op":"findblogById"}</span>
<span style="color: #000000">Function completed (Success, Id=a8eb2ccc-8d44-40eb-9f95-444ac7951b8b)</span>

Seems to be working just fine.
<h2>Conclusion</h2>
By using really simple tools I was able to create, manage and publish real enterprise API's and I did it before lunch. Now I can play with Autoscale settings and when I later on decide to change my implementation to live inside a real Api App or start using Scala or something cool I can just redefine the API Management definition to point to the new implementation <strong>without any other implications to the existing clients of my API</strong>.

Not that I needed to reimplement, Azure Functions scales just fine, which will be a topic for another future post. See Ya.
<h2>Resources</h2>
<a href="https://msdnshared.blob.core.windows.net/media/2016/06/2016_06_function_code.txt" target="_blank">2016_06_function_code</a>]]></content:encoded>
    </item>
    <item>
      <title>Serverless Azure Architecture pt III, Realtime Power Bi Dashboards for Free !</title>
      <link>https://docs.microsoft.com/archive/blogs/petsablog/serverless-azure-architecture-pt-iii-realtime-power-bi-dashboards-for-free</link>
      <pubDate>Thu, 12 May 2016 08:12:37 GMT</pubDate>
      <dc:creator><![CDATA[petsablog]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/petsablog/?p=215</guid>
      <description><![CDATA[This is Part III of articles in series discussing Azure Functions, a serverless way to execute...]]></description>
      <content:encoded><![CDATA[This is Part III of articles in series discussing Azure Functions, a serverless way to execute custom logic on Azure.

<a title="Part I - SImple Forms" href="https://blogs.msdn.microsoft.com/petsablog/2016/04/25/serverless-azure-architecture-simple-forms/">Part I - Simple Forms</a>
<a title="Part II - Adding Authentication" href="https://blogs.msdn.microsoft.com/petsablog/2016/04/29/serverless-azure-architecture-pt-ii-adding-user-authentication/">Part II  - Adding Authentication</a>
<a title="Part III - POwer BI Dashboarding" href="https://blogs.msdn.microsoft.com/petsablog/2016/05/12/serverless-azure-architecture-pt-iii-realtime-power-bi-dashboards-for-free/">Part III - Power Bi Dashboarding</a>

So You've seen cool Power Bi Dashboards and would like to deliver something similar to Your 50 000 users ?
Luckily You can, and in some cases You can do it for free ...
<h1>Power Bi Dashboards with Azure Functions</h1>
There are basically 4 ways to integrate your own software with Power Bi.
<h3>1. Power BI Embedded</h3>
This is basically embedding an iframe to Your own page. Users do not need to have licenses but the App need to purchase renders.  App creates  app tokens and attaches them to iframe requests to prove the license.
Very good for delivering full blown dashboards with drill-in capabilities.
<a title="Read more" href="https://azure.microsoft.com/en-us/documentation/articles/power-bi-embedded-what-is-power-bi-embedded/" target="_blank">Read more.</a>
<h3>2. Using Publish To Web</h3>
You can publish a report in Power BI by choosing File/Publish TO Web. You will get embed code for an iframe that does not require user licenses, but BEWARE , anyone can see this if they know the address.
Good for more general reports, like publishing some public domain data in blogs and such.
<a title="Read more." href="https://powerbi.microsoft.com/en-us/publishtoweb/" target="_blank">Read more.</a>
<h3>3. Using Power BI Rest Api's to push data into Power BI</h3>
In this option we are creating a virtual database table inside Power BI and pushing in rows with your own code. You can try this live with our nice apiary page: <a title="Try it live." href="http://docs.powerbi.apiary.io/#" target="_blank">try it</a>
<a title="Read more." href="https://powerbi.microsoft.com/en-us/documentation/powerbi-developer-walkthrough-push-data/" target="_blank">Read more.</a>
<h3> 4. Using Power Bi Visuals javascript  library</h3>
So this is what our little article is actually about today.
We are including the Power BI visuals javascript - framework and using it directly to visualize some of our own data on a web page.

The possibilities are endless since we are free to get the data from where ever we see fit and have Power BI components visualize the dashboard with refresh rates that we are able to fully control (compare to Power Bi fed by Azure Stream analytics where you get refresh rates something between 2 - 10 seconds, randomly).
In this example I am using Azure Functions as a very flexible source of data. With few lines of scripting we can get our hands on blobs, tables, queues ... what have You.

To actually get the needed javascript library ,go here and download it :
<a title="PowerBI-Visuals" href="https://github.com/Microsoft/PowerBI-Visuals/" target="_blank">https://github.com/Microsoft/PowerBI-Visuals/</a>

To use the library You do pretty much what You expect to do with this kind of libraries. Get some data, format it the way the library can consume it, point out the div that the library can use to create the canvas on and ... that's it really.
Let's take a quick look at some important pieces of code:
<div>This is javascript function on my html-page doing the necessary setup :</div>
<div><span class="sc41"><span style="font-family: Courier New;font-size: small">    </span></span><span class="sc47"><b><i><span style="color: #000080;font-family: Courier New;font-size: small">function</span></i></b></span> <span class="sc46"><span style="font-family: Courier New;font-size: small">createVisual</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">()</span></b></span> <span class="sc50"><b><span style="font-family: Courier New;font-size: small">{</span></b></span><span class="sc41">
<span style="font-family: Courier New;font-size: small">        </span></span><span class="sc47"><b><i><span style="color: #000080;font-family: Courier New;font-size: small">var</span></i></b></span> <span class="sc46"><span style="font-family: Courier New;font-size: small">pluginService</span></span> <span class="sc50"><b><span style="font-family: Courier New;font-size: small">=</span></b></span> <span class="sc46"><span style="font-family: Courier New;font-size: small">powerbi.visuals.visualPluginFactory.create</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">();</span></b></span><span class="sc41">
<span style="font-family: Courier New;font-size: small">        </span></span><span class="sc47"><b><i><span style="color: #000080;font-family: Courier New;font-size: small">var</span></i></b></span> <span class="sc46"><span style="font-family: Courier New;font-size: small">defaultVisualHostServices</span></span> <span class="sc50"><b><span style="font-family: Courier New;font-size: small">=</span></b></span> <span class="sc46"><span style="font-family: Courier New;font-size: small">powerbi.visuals.defaultVisualHostServices</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">;</span></b></span><span class="sc41">
<span style="font-family: Courier New;font-size: small">        </span></span><span class="sc47"><b><i><span style="color: #000080;font-family: Courier New;font-size: small">var</span></i></b></span> <span class="sc46"><span style="font-family: Courier New;font-size: small">element</span></span> <span class="sc50"><b><span style="font-family: Courier New;font-size: small">=</span></b></span><span class="sc41"><span style="font-family: Courier New;font-size: small"> $</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">(</span></b></span><span class="sc49"><span style="color: #808080;font-family: Courier New;font-size: small">'.visual'</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">);</span></b></span><span class="sc41">
<span style="font-family: Courier New;font-size: small">        </span></span><span class="sc46"><span style="font-family: Courier New;font-size: small">element.height</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">(</span></b></span><span class="sc46"><span style="font-family: Courier New;font-size: small">height</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">).</span></b></span><span class="sc46"><span style="font-family: Courier New;font-size: small">width</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">(</span></b></span><span class="sc46"><span style="font-family: Courier New;font-size: small">width</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">);</span></b></span><span class="sc41">
<span style="font-family: Courier New;font-size: small">
</span></span><span class="sc43"><span style="color: #008000;font-family: Courier New;font-size: small">// Get a plugin</span></span><span class="sc41">
<span style="font-family: Courier New;font-size: small">        </span></span><span class="sc46"><span style="font-family: Courier New;font-size: small">visual</span></span> <span class="sc50"><b><span style="font-family: Courier New;font-size: small">=</span></b></span> <span class="sc46"><span style="font-family: Courier New;font-size: small">pluginService.getPlugin</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">(</span></b></span><span class="sc49"><span style="color: #808080;font-family: Courier New;font-size: small">'barChart'</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">).</span></b></span><span class="sc46"><span style="font-family: Courier New;font-size: small">create</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">();</span></b></span><span class="sc41">
<span style="font-family: Courier New;font-size: small">        </span></span><span class="sc46"><span style="font-family: Courier New;font-size: small">powerbi.visuals.DefaultVisualHostServices.initialize</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">();</span></b></span><span class="sc41"><span style="font-family: Courier New;font-size: small">
</span></span><span class="sc46"><span style="font-family: Courier New;font-size: small">visual.init</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">({</span></b></span><span class="sc41">
<span style="font-family: Courier New;font-size: small">            </span></span><span class="sc43"><span style="color: #008000;font-family: Courier New;font-size: small">// empty DOM element the visual should attach to.</span></span><span class="sc41">
<span style="font-family: Courier New;font-size: small">            </span></span><span class="sc46"><span style="font-family: Courier New;font-size: small">element</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">:</span></b></span> <span class="sc46"><span style="font-family: Courier New;font-size: small">element</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">,</span></b></span><span class="sc41">
<span style="font-family: Courier New;font-size: small">            </span></span><span class="sc43"><span style="color: #008000;font-family: Courier New;font-size: small">// host services</span></span><span class="sc41">
<span style="font-family: Courier New;font-size: small">            </span></span><span class="sc46"><span style="font-family: Courier New;font-size: small">host</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">:</span></b></span> <span class="sc46"><span style="font-family: Courier New;font-size: small">defaultVisualHostServices</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">,</span></b></span><span class="sc41">
<span style="font-family: Courier New;font-size: small">            </span></span><span class="sc46"><span style="font-family: Courier New;font-size: small">style</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">:</span></b></span> <span class="sc46"><span style="font-family: Courier New;font-size: small">createDefaultStyles</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">(),</span></b></span><span class="sc41">
<span style="font-family: Courier New;font-size: small">            </span></span><span class="sc46"><span style="font-family: Courier New;font-size: small">viewport</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">:</span></b></span> <span class="sc50"><b><span style="font-family: Courier New;font-size: small">{</span></b></span><span class="sc41">
<span style="font-family: Courier New;font-size: small">                </span></span><span class="sc46"><span style="font-family: Courier New;font-size: small">height</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">:</span></b></span><span class="sc46"><span style="font-family: Courier New;font-size: small">height</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">,</span></b></span><span class="sc41">
<span style="font-family: Courier New;font-size: small">                </span></span><span class="sc46"><span style="font-family: Courier New;font-size: small">width</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">:</span></b></span> <span class="sc46"><span style="font-family: Courier New;font-size: small">width</span></span><span class="sc41">
<span style="font-family: Courier New;font-size: small">            </span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">},</span></b></span><span class="sc41">
<span style="font-family: Courier New;font-size: small">            </span></span><span class="sc46"><span style="font-family: Courier New;font-size: small">settings</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">:</span></b></span> <span class="sc50"><b><span style="font-family: Courier New;font-size: small">{</span></b></span> <span class="sc46"><span style="font-family: Courier New;font-size: small">slicingEnabled</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">:</span></b></span> <span class="sc47"><b><i><span style="color: #000080;font-family: Courier New;font-size: small">true</span></i></b></span> <span class="sc50"><b><span style="font-family: Courier New;font-size: small">},</span></b></span><span class="sc41">
<span style="font-family: Courier New;font-size: small">            </span></span><span class="sc46"><span style="font-family: Courier New;font-size: small">interactivity</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">:</span></b></span> <span class="sc50"><b><span style="font-family: Courier New;font-size: small">{</span></b></span> <span class="sc46"><span style="font-family: Courier New;font-size: small">isInteractiveLegend</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">:</span></b></span> <span class="sc47"><i><span style="color: #000080;font-family: Courier New;font-size: small"><b>false</b></span></i></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">,</span></b></span> <span class="sc46"><span style="font-family: Courier New;font-size: small">selection</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">:</span></b></span> <span class="sc47"><b><i><span style="color: #000080;font-family: Courier New;font-size: small">false</span></i></b></span> <span class="sc50"><b><span style="font-family: Courier New;font-size: small">},</span></b></span><span class="sc41">
<span style="font-family: Courier New;font-size: small">            </span></span><span class="sc46"><span style="font-family: Courier New;font-size: small">animation</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">:</span></b></span> <span class="sc50"><b><span style="font-family: Courier New;font-size: small">{</span></b></span> <span class="sc46"><span style="font-family: Courier New;font-size: small">transitionImmediate</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">:</span></b></span> <span class="sc47"><b><i><span style="color: #000080;font-family: Courier New;font-size: small">true</span></i></b></span> <span class="sc50"><b><span style="font-family: Courier New;font-size: small">}</span></b></span><span class="sc41">
<span style="font-family: Courier New;font-size: small">        </span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">});</span></b></span><span class="sc41">
<span style="font-family: Courier New;font-size: small">        </span></span><span class="sc46"><span style="font-family: Courier New;font-size: small">updateVisual</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">();</span></b></span><span class="sc41">
<span style="font-family: Courier New;font-size: small">    </span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">}</span></b></span></div>
<div>In addition to this I have a timer that calls updateVisuals every few seconds which in turn uses ajax call to talk to our backend function supplying new data.</div>
<div>
<div><span class="sc46"><span style="font-family: Courier New;font-size: small">setInterval</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">(</span></b></span><span class="sc47"><i><span style="color: #000080;font-family: Courier New;font-size: small"><b>function</b></span></i></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">(){</span></b></span><span class="sc41">
<span style="font-family: Courier New;font-size: small">    </span></span><span class="sc46"><span style="font-family: Courier New;font-size: small">getData</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">();</span></b></span><span class="sc41">
</span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">},</span></b></span> <span class="sc45"><span style="color: #ff0000;font-family: Courier New;font-size: small">3000</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">);</span></b></span></div>
</div>
<div>
<div><span class="sc47"><b><i><span style="color: #000080;font-family: Courier New;font-size: small">function</span></i></b></span> <span class="sc46"><span style="font-family: Courier New;font-size: small">getData</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">()</span></b></span> <span class="sc50"><b><span style="font-family: Courier New;font-size: small">{</span></b></span><span class="sc41">
<span style="font-family: Courier New;font-size: small">    $</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">.</span></b></span><span class="sc46"><span style="font-family: Courier New;font-size: small">ajax</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">({</span></b></span><span class="sc41">
<span style="font-family: Courier New;font-size: small">        </span></span><span class="sc46"><span style="font-family: Courier New;font-size: small">url</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">:</span></b></span> <span class="sc49"><span style="color: #808080;font-family: Courier New;font-size: small">'/api/MyDashingBoard?code=MYCODE'</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">,
</span></b></span><span class="sc41"><span style="font-family: Courier New;font-size: small">        </span></span><span class="sc46"><span style="font-family: Courier New;font-size: small">type</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">:</span></b></span> <span class="sc49"><span style="color: #808080;font-family: Courier New;font-size: small">'GET'</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">,</span></b></span><span class="sc41">
<span style="font-family: Courier New;font-size: small">        </span></span><span class="sc46"><span style="font-family: Courier New;font-size: small">contentType</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">:</span></b></span> <span class="sc49"><span style="color: #808080;font-family: Courier New;font-size: small">'application/json'</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">,</span></b></span><span class="sc41">
<span style="font-family: Courier New;font-size: small">        </span></span><span class="sc46"><span style="font-family: Courier New;font-size: small">dataType</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">:</span></b></span> <span class="sc49"><span style="color: #808080;font-family: Courier New;font-size: small">'json'</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">,</span></b></span><span class="sc41">
<span style="font-family: Courier New;font-size: small">        </span></span><span class="sc46"><span style="font-family: Courier New;font-size: small">success</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">:</span></b></span> <span class="sc47"><i><span style="color: #000080;font-family: Courier New;font-size: small"><b>function</b></span></i></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">(</span></b></span><span class="sc46"><span style="font-family: Courier New;font-size: small">data</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">,</span></b></span><span class="sc46"><span style="font-family: Courier New;font-size: small">text</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">)</span></b></span> <span class="sc50"><b><span style="font-family: Courier New;font-size: small">{</span></b></span><span class="sc41">
<span style="font-family: Courier New;font-size: small">           </span></span><span class="sc46"><span style="font-family: Courier New;font-size: small">updateVisual</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">(</span></b></span><span class="sc46"><span style="font-family: Courier New;font-size: small">data.l1</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">,</span></b></span><span class="sc46"><span style="font-family: Courier New;font-size: small">data.l2</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">);</span></b></span><span class="sc41">
<span style="font-family: Courier New;font-size: small">        </span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">},</span></b></span><span class="sc41">
<span style="font-family: Courier New;font-size: small">        </span></span><span class="sc46"><span style="font-family: Courier New;font-size: small">error</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">:</span></b></span> <span class="sc47"><b><i><span style="color: #000080;font-family: Courier New;font-size: small">function</span></i></b></span> <span class="sc50"><b><span style="font-family: Courier New;font-size: small">(</span></b></span><span class="sc46"><span style="font-family: Courier New;font-size: small">request</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">,</span></b></span><span class="sc46"><span style="font-family: Courier New;font-size: small">status</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">,</span></b></span><span class="sc46"><span style="font-family: Courier New;font-size: small">error</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">)</span></b></span> <span class="sc50"><b><span style="font-family: Courier New;font-size: small">{</span></b></span><span class="sc41">
<span style="font-family: Courier New;font-size: small">            $</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">(</span></b></span><span class="sc48"><span style="color: #808080;font-family: Courier New;font-size: small">"#errormsg"</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">).</span></b></span><span class="sc46"><span style="font-family: Courier New;font-size: small">html</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">(</span></b></span><span class="sc46"><span style="font-family: Courier New;font-size: small">request.responseText</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">);</span></b></span><span class="sc41">
<span style="font-family: Courier New;font-size: small">            $</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">(</span></b></span><span class="sc48"><span style="color: #808080;font-family: Courier New;font-size: small">"#failureinfo"</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">).</span></b></span><span class="sc46"><span style="font-family: Courier New;font-size: small">removeClass</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">(</span></b></span><span class="sc48"><span style="color: #808080;font-family: Courier New;font-size: small">"hidden"</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">);</span></b></span><span class="sc41">
<span style="font-family: Courier New;font-size: small">            </span></span><span class="sc46"><span style="font-family: Courier New;font-size: small">console.log</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">(</span></b></span><span class="sc46"><span style="font-family: Courier New;font-size: small">request.responseText</span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">);</span></b></span><span class="sc41">
<span style="font-family: Courier New;font-size: small">        </span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">}</span></b></span><span class="sc41">
<span style="font-family: Courier New;font-size: small">    </span></span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">});</span></b></span><span class="sc41">
</span><span class="sc50"><b><span style="font-family: Courier New;font-size: small">}</span></b></span></div>
<div>And this code results to something like this on my dashboard:
<a href="https://msdnshared.blob.core.windows.net/media/2016/05/result.png"><img class="alignnone size-full wp-image-225" src="https://msdnshared.blob.core.windows.net/media/2016/05/result.png" alt="result" width="651" height="427" /></a></div>
Pretty neat , huh ?

</div>
<div></div>
<h3>Get the bits:</h3>
<div><a href="https://msdnshared.blob.core.windows.net/media/2016/05/pt3function.html_.txt">pt3function.html</a></div>
<div><a href="https://msdnshared.blob.core.windows.net/media/2016/05/pt3index.html_.txt">pt3index.html</a></div>
<div></div>
<div>You've probably noticed that I have used the location from Part I of this series for storing my static files.
In order to access those files You would have to fix the urls in html-files to reference your service instead of mine and change the ajax function to point to your newly created Azure Function located inside pt3function.html (add it to the same Function App as previous parts).</div>
<div></div>
<div>You would request the test page from the Part I fileservices with something like this:
https://petsaforms.azurewebsites.net/api/YOURPT1NAME?code=YOURPT1CODE&amp;op=file&amp;p1=forms/test.html</div>]]></content:encoded>
    </item>
    <item>
      <title>Serverless Azure Architecture pt II, Adding User Authentication</title>
      <link>https://docs.microsoft.com/archive/blogs/petsablog/serverless-azure-architecture-pt-ii-adding-user-authentication</link>
      <pubDate>Fri, 29 Apr 2016 13:43:40 GMT</pubDate>
      <dc:creator><![CDATA[petsablog]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/petsablog/?p=136</guid>
      <description><![CDATA[This is Part II of articles in series discussing Azure Functions, a serverless way to execute custom...]]></description>
      <content:encoded><![CDATA[This is Part II of articles in series discussing Azure Functions, a serverless way to execute custom logic on Azure.

<a title="Part I - SImple Forms" href="https://blogs.msdn.microsoft.com/petsablog/2016/04/25/serverless-azure-architecture-simple-forms/">Part I - Simple Forms</a>
<a title="Part II - Adding Authentication" href="https://blogs.msdn.microsoft.com/petsablog/2016/04/29/serverless-azure-architecture-pt-ii-adding-user-authentication/">Part II  - Adding Authentication</a>
<a title="Part III - POwer BI Dashboarding" href="https://blogs.msdn.microsoft.com/petsablog/2016/05/12/serverless-azure-architecture-pt-iii-realtime-power-bi-dashboards-for-free/">Part III - Power Bi Dashboarding</a>
<h1>Adding User Authentication</h1>
So we have our forms-solution up and running . Next we want to restrain the solution so that only my company's employees get access to the forms.
This happens on application level. In real every azure serverless function is being run on a server, of course, and behind the covers we are using Web Applications as the deployable unit to control and manage execution. This gives us some benefits since we already know that Web Apps can do a lot of nice things like talk to on-prem resources and implement proper security.

<a href="https://msdnshared.blob.core.windows.net/media/2016/04/auth.png"><img class="alignnone  wp-image-185" src="https://msdnshared.blob.core.windows.net/media/2016/04/auth.png" alt="auth" width="712" height="434" /></a>
<h2>Benefits of declarative Auth</h2>
So this time we get to reap the benefits of the security subsystem that Web Apps have had for some time. It is really close to sweet spot when being used with scripting like we are doing today. The infrastructure serving the our function (and the invisible Web App) has a configuration item for turning security on and setting the most important settings like the underlying identity provider (Azure Ad, Facebook, Google, Amazon ,...).

<a href="https://msdnshared.blob.core.windows.net/media/2016/04/settingspage.png"><img class="alignnone  wp-image-145" src="https://msdnshared.blob.core.windows.net/media/2016/04/settingspage.png" alt="settingspage" width="616" height="496" /></a>
<a href="https://msdnshared.blob.core.windows.net/media/2016/04/enable-auth.png"><img class="alignnone size-large wp-image-155" src="https://msdnshared.blob.core.windows.net/media/2016/04/enable-auth-1024x611.png" alt="enable auth" width="1024" height="611" /></a>
<a href="https://msdnshared.blob.core.windows.net/media/2016/04/enable-ad.png"><img class="alignnone size-large wp-image-165" src="https://msdnshared.blob.core.windows.net/media/2016/04/enable-ad-1024x773.png" alt="enable ad" width="1024" height="773" /></a>

So , after few clicks we have enabled the Authentication features of our Function and by using Azure Active Directory as the source we have effectively restricted the users into people that are in our AD, our employees that is.
<h1><a href="https://msdnshared.blob.core.windows.net/media/2016/04/login1.png"><img class="alignnone  wp-image-195" src="https://msdnshared.blob.core.windows.net/media/2016/04/login1.png" alt="login" width="672" height="375" /></a></h1>
<h2>Who's there</h2>
If You take a new inPrivate Browser session and try to reach Your function now You'll notice that You can't ... until You log in. After login things work just as they did before.
But very often our solution would like to know who the user is and use this information for something. Luckily that's easy.
Make new C# http Function and change the contents to something like this and try requesting it :
<a href="https://msdnshared.blob.core.windows.net/media/2016/04/testcode.png"><img class="alignnone size-large wp-image-175" src="https://msdnshared.blob.core.windows.net/media/2016/04/testcode-1024x277.png" alt="testcode" width="1024" height="277" /></a>

You'll notice that when You call the Url You will be getting Your own email back. Very simple. (did I say that I like simple ?).
You can use this information to add correct user info into database instead of relying on web form posts and such or by using some AD graph queries You can access more information about this logged-in user and use that info for various purposes.
Anywhere in Your app where You need to know the user name just refer request headers and dig the name up from there.
<h2>Summary</h2>
All this magic of course works since my three functions belong to the same underlying Web App and they share the same config ... another way around ... If You want to serve some functions to people outside Your own organization You would have to do that with an Service Function App that doesn't have the Auth enabled (by default it is off) and for Your internal audience You would enable the Auth just like we did.

So there You have it, adding proper enterprise-level auth on top of  Azure Functions is extremely easy and very useful tool in ones toolbelt.
Next time we will do some Power Bi Realtime Dashboarding and reporting with Azure Functions.]]></content:encoded>
    </item>
    <item>
      <title>Serverless Azure Architecture, Simple Forms</title>
      <link>https://docs.microsoft.com/archive/blogs/petsablog/serverless-azure-architecture-simple-forms</link>
      <pubDate>Mon, 25 Apr 2016 09:03:34 GMT</pubDate>
      <dc:creator><![CDATA[petsablog]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/petsablog/?p=76</guid>
      <description><![CDATA[Part I - Simple Forms
Part II  - Adding Authentication
Part III - Power Bi...]]></description>
      <content:encoded><![CDATA[<a title="Part I - SImple Forms" href="https://blogs.msdn.microsoft.com/petsablog/2016/04/25/serverless-azure-architecture-simple-forms/">Part I - Simple Forms</a>
<a title="Part II - Adding Authentication" href="https://blogs.msdn.microsoft.com/petsablog/2016/04/29/serverless-azure-architecture-pt-ii-adding-user-authentication/">Part II  - Adding Authentication</a>
<a title="Part III - POwer BI Dashboarding" href="https://blogs.msdn.microsoft.com/petsablog/2016/05/12/serverless-azure-architecture-pt-iii-realtime-power-bi-dashboards-for-free/">Part III - Power Bi Dashboarding</a>
<h1><span style="color: #2e74b5;font-family: Calibri Light;font-size: x-large">Serverless Azure Architecture, Simple Forms</span></h1>
<span style="color: #000000;font-family: Calibri">I hate complex software, not just out of laziness (definitely part of it) but I honestly do think that simple software is easier to maintain in the long run and usually better asset to software companies than complex software is.</span>

<span style="color: #000000;font-family: Calibri">Azure has just recently gotten a new service “Azure Functions” : </span><a href="https://azure.microsoft.com/en-us/documentation/articles/functions-overview/"><span style="color: #0563c1;font-family: Calibri">https://azure.microsoft.com/en-us/documentation/articles/functions-overview/</span></a><span style="color: #000000;font-family: Calibri"> which is a fine example of simple thing that can drive enormous business value. Basically it is a system which allows You to create a reasonably rich solution by simple scripting while allowing serverless execution.  This shifts the attention to application logic, not application infrastructure. Besides, scripting is fun … which is more important than one might think at first. </span>
<h2><span style="color: #2e74b5;font-family: Calibri Light;font-size: large">Scripting, not software development project</span></h2>
<span style="color: #000000;font-family: Calibri">So I took a closer look at the functions and decided to test with something that has some real value, something that implements an actual use case that my customers have.  This case is Simple Feedback Forms. Simple forms are basically forms that You might want to use when asking company’s employees whether they will participate to next field day and what employees thought of the services they’ve been getting from IT or customer feedback form … just to name a few usage scenarios.</span>

<a href="https://msdnshared.blob.core.windows.net/media/2016/04/form.png"><img class="alignnone size-large wp-image-106" src="https://msdnshared.blob.core.windows.net/media/2016/04/form-1024x488.png" alt="form" width="1024" height="488" /></a>

<span style="color: #000000;font-family: Times New Roman">
</span><span style="color: #000000;font-family: Calibri"> I decided to implement the actual forms in HTML5 so users could use whatever clients they happen to have handy. The backend would be Azure Sql database for easy reporting. Finally the little logic (the script) in the middle would be implemented in C# even I have been writing a lot about Node.js and other non-microsoft languages, this time I just felt like writing some C#. </span>

<span style="color: #000000;font-family: Times New Roman"><a href="https://msdnshared.blob.core.windows.net/media/2016/04/arch.png"><img class="alignnone size-full wp-image-95" src="https://msdnshared.blob.core.windows.net/media/2016/04/arch.png" alt="arch" width="692" height="282" /></a></span>

<span style="color: #000000;font-family: Calibri">1.</span><span style="font: 7.0pt 'Times New Roman'"><span style="color: #000000">       </span></span><span style="color: #000000;font-family: Calibri">The browser makes a request towards our published function
</span><span style="color: #000000;font-family: Calibri">2.</span><span style="font: 7.0pt 'Times New Roman'"><span style="color: #000000">       </span></span><span style="color: #000000;font-family: Calibri">The function fetches the correct form (just an HTML-file) from blobstorage and serves it to browser
</span><span style="color: #000000;font-family: Calibri">3.</span><span style="font: 7.0pt 'Times New Roman'"><span style="color: #000000">       </span></span><span style="color: #000000;font-family: Calibri">The user fills in the form and presses submit
</span><span style="color: #000000;font-family: Calibri">4.</span><span style="font: 7.0pt 'Times New Roman'"><span style="color: #000000">       </span></span><span style="color: #000000;font-family: Calibri">The function saves the data into Azure Sql Db for later processing
</span><span style="color: #000000;font-family: Calibri">5.</span><span style="font: 7.0pt 'Times New Roman'"><span style="color: #000000">       </span></span><span style="color: #000000;font-family: Calibri">Power Bi report shows a report based on the collected data</span>
<h2><span style="color: #2e74b5;font-family: Calibri Light;font-size: large">Serverless doesn’t mean free</span></h2>
<span style="color: #000000;font-family: Calibri">The cool thing is that we do not have to reserve any server capacity beforehand and we pay only for those seconds that our function does any processing. On top of this we have a cheap Sql Database and miniscule amount of storage on blob storage services.
We can use the database for various other usages and same goes for the storage. I could have used a TableStorage for storing the data (cheaper than sql) but my customer is very good with sql reporting tools so let’s do it this time like this. One interesting result of my Sql usage was that the script started requiring more memory to run, instead of the minimal 128 MB the script needed 256 MB to run properly , and that costs a tad more. </span>
<h2><span style="color: #2e74b5;font-family: Calibri Light;font-size: large">Some implementation notes</span></h2>
<span style="color: #000000;font-family: Calibri">The system was very easy to implement once I figured out the correct way to send and receive ajax requests since there was not much documentation available at the time of writing. Another big thing was the pattern of utility modules, i.e. having utility functions written in separate module so they would not clutter the main script logic. Overall a very enjoyable experience.</span>

<a href="https://msdnshared.blob.core.windows.net/media/2016/04/code.png"><img class="alignnone size-large wp-image-105" src="https://msdnshared.blob.core.windows.net/media/2016/04/code-1024x420.png" alt="code" width="1024" height="420" /></a>

<span style="color: #000000;font-family: Calibri">btw, the Url-format for getting images out of blob storage is like this :  api/YOURAPPNAME?code=YOURCODE&amp;op=file&amp;p1=img/microsoft-logo.jpg </span>
<h2><span style="color: #2e74b5;font-family: Calibri Light;font-size: large">Resources</span><span style="color: #2e74b5;font-family: Calibri Light;font-size: large"><img src="/Users/petsa/AppData/Local/Temp/msohtmlclip1/01/clip_image006.png" alt="" width="12" height="11" /></span></h2>
<span style="color: #000000;font-family: Calibri">I have stored all the solution files and step-by-step guide here :
</span>

<span style="color: #000000;font-family: Calibri"><a href="https://msdnshared.blob.core.windows.net/media/2016/04/AppUtils.cs_.txt">AppUtils.cs</a>
</span><a href="https://msdnshared.blob.core.windows.net/media/2016/04/App.cs_.txt">App.cs</a>
<a href="https://msdnshared.blob.core.windows.net/media/2016/04/index.html_.txt">index.html</a>

<span style="color: #000000;font-family: Calibri">1.</span><span style="font: 7.0pt 'Times New Roman'"><span style="color: #000000">       </span></span><span style="color: #000000;font-family: Calibri">In Azure portal go and provision a new Function App
</span><span style="font: 7.0pt 'Times New Roman'"><span style="color: #000000">       </span></span><span style="color: #000000;font-family: Calibri">Choose dynamic App Service plan so only actual usage gets billed
</span><span style="font: 7.0pt 'Times New Roman'"><span style="color: #000000">       </span></span><span style="color: #000000;font-family: Calibri">Name the resource group with apps name so You rememeber later what it is
</span><span style="font: 7.0pt 'Times New Roman'"><span style="color: #000000">       </span></span><span style="color: #000000;font-family: Calibri">Make note of the storage account name</span><span style="color: #000000;font-family: Calibri">d.
</span><span style="font: 7.0pt 'Times New Roman'"><span style="color: #000000">       </span></span><span style="color: #000000;font-family: Calibri">Change the memory allocation to 256 (for sql)</span>

<span style="color: #000000;font-family: Calibri">2.</span><span style="font: 7.0pt 'Times New Roman'"><span style="color: #000000">       </span></span><span style="color: #000000;font-family: Calibri">In that same resource group add
</span><span style="font: 7.0pt 'Times New Roman'"><span style="color: #000000">       </span></span><span style="color: #000000;font-family: Calibri">Database (if you don’t already have one somewhere)
</span><span style="font: 7.0pt 'Times New Roman'"><span style="color: #000000">       </span></span><span style="color: #000000;font-family: Calibri">In the storage account go and create a blob “apphelp” and make note of storage accounts primary access key</span>

<span style="color: #000000;font-family: Calibri">3.</span><span style="font: 7.0pt 'Times New Roman'"><span style="color: #000000">       </span></span><span style="color: #000000;font-family: Calibri">Install free “Azure explorer” from Cerebrata, configure the storage account
</span><span style="font: 7.0pt 'Times New Roman'"><span style="color: #000000">       </span></span><span style="color: #000000;font-family: Calibri">Use the explorer to create folders “forms” and “img” on apphelp-blob .
</span>

<span style="color: #000000;font-family: Calibri">4.</span><span style="font: 7.0pt 'Times New Roman'"><span style="color: #000000">       </span></span><span style="color: #000000;font-family: Calibri">On Your new “Azure Function”-service go and create new Function (top left), choose type “Empty – C#”, call it AppUtils and paste attached AppUtils.csx contents there and hit save.
</span><span style="font: 7.0pt 'Times New Roman'"><span style="color: #000000">       </span></span><span style="color: #000000;font-family: Calibri">fix your connection strings in getConnStr- function to point to Your resources, the storage and your database. Save again.</span>

<span style="color: #000000;font-family: Calibri">5.</span><span style="font: 7.0pt 'Times New Roman'"><span style="color: #000000">       </span></span><span style="color: #000000;font-family: Calibri">Create another function, call it your apps name, type “HttpTrigger – C#”.
</span><span style="font: 7.0pt 'Times New Roman'"><span style="color: #000000">       </span></span><span style="color: #000000;font-family: Calibri">Paste in the code from app.csx
</span><span style="font: 7.0pt 'Times New Roman'"><span style="color: #000000">       </span></span><span style="color: #000000;font-family: Calibri">Copy the “Function Url” above your code , this will be your apps index-page
</span><span style="font: 7.0pt 'Times New Roman'"><span style="color: #000000">       </span></span><span style="color: #000000;font-family: Calibri">Save and make note of the Url used to access Your function .</span>

!!!! IMPORTANT.  *************************
<span style="color: #000000;font-family: Calibri">     </span><span style="color: #000000;font-family: Calibri">Go and edit the attached index.html to include Your functions Url in the the SendData-function.
Format is like this: : '/api/YOURFUNCTIONNAME?code=YOURCODE&amp;op=method1&amp;fil=nop'</span>

<span style="color: #000000;font-family: Calibri">       Copy the attached index.html (rename from index.html.txt to index.html) to forms directory in the blob storage with the storage explorer
****************************************
</span>

<span style="color: #000000;font-family: Calibri">6.</span><span style="font: 7.0pt 'Times New Roman'"><span style="color: #000000">       </span></span><span style="color: #000000;font-family: Calibri">Use Visual Studio or the free Sql Server Management studio
</span><span style="font: 7.0pt 'Times New Roman'"><span style="color: #000000">       </span></span><a href="https://msdn.microsoft.com/en-us/library/mt238290.aspx"><span style="color: #0563c1;font-family: Calibri">https://msdn.microsoft.com/en-us/library/mt238290.aspx</span></a>

<span style="font: 7.0pt 'Times New Roman'"><span style="color: #000000">       </span></span><span style="color: #000000;font-family: Calibri">Create a table sort of like this :
CREATE TABLE [dbo].[qparty](
</span><span style="color: #000000;font-family: Calibri">              [changedtime] [datetime] NOT NULL,
</span><span style="color: #000000;font-family: Calibri">              [name] [varchar](50) NOT NULL,
</span><span style="color: #000000;font-family: Calibri">              [participating] [varchar](1) NULL,
</span><span style="color: #000000;font-family: Calibri">              [meal] [bigint] NULL,
</span><span style="color: #000000;font-family: Calibri">              [options] [varchar](50) NULL,
</span><span style="color: #000000;font-family: Calibri">              [notes] [varchar](256) NULL,
</span><span style="color: #000000;font-family: Calibri">              [id] [bigint] IDENTITY(1,1) NOT NULL,
</span><span style="color: #000000;font-family: Calibri"> CONSTRAINT [PK_qparty] PRIMARY KEY CLUSTERED ([id] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
)</span>

<span style="color: #000000;font-family: Calibri">7.</span><span style="font: 7.0pt 'Times New Roman'"><span style="color: #000000">       </span></span><span style="color: #000000;font-family: Calibri">You should be good to go … try the Url that You made a copy of in step 5, You should see the form. If You don’t, then most likely your connection string to Your storage isn’t quite right in AppUtils. Look at the console dumps from Your app functions to find out more.</span>
<h2><span style="color: #2e74b5;font-family: Calibri Light;font-size: large">Whats next ?</span></h2>
<span style="color: #000000;font-family: Calibri">Next time I will add user authentication to this solution so we can restrict it to company employees only and have some info prefilled from Azure AD. After that we’ll add some realtime dashboarding capabilities with Power Bi visualization libraries. </span>]]></content:encoded>
    </item>
    <item>
      <title>Arduino and Azure IOT, better together</title>
      <link>https://docs.microsoft.com/archive/blogs/petsablog/arduino-and-azure-iot-better-together</link>
      <pubDate>Thu, 09 Apr 2015 00:22:00 GMT</pubDate>
      <dc:creator><![CDATA[petsablog]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/petsablog/2015/04/09/arduino-and-azure-iot-better-together/</guid>
      <description><![CDATA[Thought I'd share this with You guys. Just in case You're wondering wether to do this kind of thing...]]></description>
      <content:encoded><![CDATA[<p>Thought I'd share this with You guys. Just in case You're wondering wether to do this kind of thing or not.</p>
<h2>Setup</h2>
<p>Sharp 2Y0A02 comes from a large family of sensors for distance measuring. There are several versions of the same thing optimized for different needs and use cases. I happened to have this partiular version lying in my junkbox so without too much thought thats what I'll be using for this project. It is optimized for distances between 10cm to 100Cm and it gives out the measurement results as an analog voltage. (Sharp GP2D02 does the same thing but You can use a digital protocol to talk to it just in case You are using some microcontroller that has no analog input pins like Raspberry).<br /><br />I also have a spare Arduino Leonardo from another experiment so I'll use that . Besides its very cheap and capable.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/arduinoiot/2352.arduino.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-arduinoiot/2352.arduino.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/arduinoiot/2352.arduino.jpg" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-arduinoiot/2352.arduino.jpg" alt="" border="0" /></a></p>
<h2>Connectivity</h2>
<p>As You can see from the picture I have USB cable attached my Arduino. It is primarily used to push compiled application to the oboard chip but it can also be utilized by my own software as a serial port.<br />So I'll be using that USB to talk to my PC-software which does the actual talking to Azure IOT infrastructure. Arduino just takes care of measuring and communicates result to pc.<br />There are other options :</p>
<ul>
<li>Wifi shields enable Arduino to have its own connection to internet and send data directly to Azure</li>
<ul>
<li><a href="http://arduino.cc/en/Main/ArduinoWiFiShield">http://arduino.cc/en/Main/ArduinoWiFiShield</a></li>
</ul>
<li>One could&nbsp;use wireless connection to PC instead of usb (software stays exactly the same since&nbsp;these boards usually pretend to be serial connections)</li>
<ul>
<li><a href="http://playground.arduino.cc/Learning/Tutorial01">http://playground.arduino.cc/Learning/Tutorial01</a></li>
</ul>
</ul>
<p>So in my case I decided to use USB since it also provides +5v to Arduino.&nbsp;</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/arduinoiot/3324.dataflow.PNG" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-arduinoiot/3324.dataflow.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/arduinoiot/3324.dataflow.PNG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-arduinoiot/3324.dataflow.PNG" alt="" border="0" /></a></p>
<h2>Arduino code&nbsp;</h2>
<p>The code reads the voltage from our sensor, linearizes it and sends it over serial line to PC. <em>(there will be a link in resources)</em><br />&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/arduinoiot/4201.arduinocode.PNG" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-arduinoiot/4201.arduinocode.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/arduinoiot/4201.arduinocode.PNG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-arduinoiot/4201.arduinocode.PNG" alt="" border="0" /></a></p>
<p>I am using a miniprotocol where I prepend the readings with&nbsp;sensorid, in this case "A", then separator ":"&nbsp;, then the actual value and finally a newline as terminator. This because I will attach more sensors&nbsp;later on.<br />Codewise there is really nothign spectacular going on here. Just plain old plain old.</p>
<h2>PC-code</h2>
<p>So the PC is listening to the Arduino and talking to Azure whenever it gets new values. I am also visualizing the&nbsp;received values&nbsp;with a progres bar.The most notable thing here is maybe the pattern of using Action to communicate between receiving thread and ui thread.The actual Azure communication bit is probably very familiar by now and we've been covering it in previous IOT postings in this blog.<br /><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/arduinoiot/0272.sender.PNG" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-arduinoiot/0272.sender.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/arduinoiot/0272.sender.PNG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-arduinoiot/0272.sender.PNG" alt="" border="0" /></a></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/arduinoiot/4214.sendcode.PNG" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-arduinoiot/4214.sendcode.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/arduinoiot/4214.sendcode.PNG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-arduinoiot/4214.sendcode.PNG" alt="" border="0" /></a></p>
<p>As You can see from the code we parse the lines received from Arduino and add the data to send Queue which will automagically sends the events to Azure.<br />Take a look at the actual file for more details on how to setup serial connection and so forth.</p>
<h2><br />Azure side</h2>
<p>On&nbsp;Azure&nbsp;I have setup a&nbsp;Azure Stream Analytics job which stores the received lines into TableStorage&nbsp;and in csv-file for later usage by HDInsight (MS version of Hadoop).<br />I have blogged earlier about how to setup the Azure infrastructure for capturing events, so take a look at them if You are unsure about these details.<br />When looking at the data with storage Explorer here is what we see.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/arduinoiot/4682.data.PNG" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-arduinoiot/4682.data.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/arduinoiot/4682.data.PNG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-arduinoiot/4682.data.PNG" alt="" border="0" /></a></p>
<h2>Conclusions ,resources and next steps</h2>
<p>This article&nbsp;is about&nbsp;data capture and storage which are&nbsp;definitely needed steps in every succesfull IOT solution but the business value usually doesn't lie here but more in the realm of data analysis and machine learning.<br />My next IOT-articles will concentrate more on&nbsp;the usage of the gathered data since we pretty much have proven that&nbsp;data capture and storage are very close to nobrainers when using Azure PaaS infrastructure.<br />&nbsp;</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/arduinoiot/0871.sharp_2Y0A02_test.ino" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-arduinoiot/0871.sharp_5F00_2Y0A02_5F00_test.ino">Arduino code file</a></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/arduinoiot/28432E00Form12E00cs" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-arduinoiot/2843_2E00_Form1_2E00_cs">C# code file</a></p>
<p>&nbsp;</p>]]></content:encoded>
    </item>
    <item>
      <title>IOT for mere mortals, Part II .</title>
      <link>https://docs.microsoft.com/archive/blogs/petsablog/iot-for-mere-mortals-part-ii</link>
      <pubDate>Tue, 17 Mar 2015 03:13:00 GMT</pubDate>
      <dc:creator><![CDATA[petsablog]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/petsablog/2015/03/17/iot-for-mere-mortals-part-ii/</guid>
      <description><![CDATA[IOT for mere mortals , Part II
Part I of this article describes IOT in general and Microsoft PaaS...]]></description>
      <content:encoded><![CDATA[<h1>IOT for mere mortals , Part II</h1>
<p>Part I of this article describes IOT in general and Microsoft PaaS offering around it in more general terms.<br />Take a look if You feel the need for some theory: <a title="Part I" href="http://blogs.msdn.com/b/petsablog/archive/2014/12/11/iot-for-mortals-part-i.aspx">Part I </a></p>
<p>Sorry it took me so long to get back to this, but&nbsp;time flies when youre having fun&nbsp;...<br />Anyways, we are here now.</p>
<p><strong>On the menu today :</strong></p>
<ul>
<li>Simulating events with nice gui and generating credible traffic</li>
<li>Designing your data so that it plays nicely with the storage infrastructure</li>
<li>Storing data in several places and forms at one go</li>
<li>Retrieving data from relational database (Azure Sql) to webApp and graphing it</li>
<li>Retrieving data from Azure Tablestore to webapp</li>
</ul>
<h2>Set up</h2>
<p>The basic structure of an IOT solution in "Azure PaaS"-land usually consists of following things:</p>
<ol>
<li>Someone who knows how to send event using either AMQP or REST over https</li>
<ol>
<li>Our simulator&nbsp;is using AMQP and threading for efficiency</li>
</ol>
<li>Provisioned PaaS infrastructure to catch the traffic</li>
<ol>
<li>Event Hub service in our Azure subscription</li>
</ol>
<li>Optional real-time analytics and processing</li>
<ol>
<li>Averaging the events in 30 second windows</li>
</ol>
<li>Permanent storage on one or more places</li>
<ol>
<li>Storing&nbsp;averaged events to Azure Sql and storing all (unsummed) event to Azure Blob Storage and Azure Tablestore</li>
</ol>
<li>Some sort of client to see the data</li>
<ol>
<li>Our web app which does rudimentary visualization of collected data</li>
</ol></ol>
<p>We are intentionally not doing any higher level analytics or Machine Learning here. We are leaving that for the possible sequel: "Part III"</p>
<h2>&nbsp;Sending events in - the simulator</h2>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/iot%20partII/8510.Simulator%20UI.PNG" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-iot+partII/8510.Simulator-UI.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/iot%20partII/8510.Simulator%20UI.PNG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-iot+partII/8510.Simulator-UI.PNG" alt="" border="0" /></a>&nbsp;</p>
<p>I&nbsp;programmed the simulator as a WebApi-project in VIsual Studio. I wrote a bunch of REST-Services and a HTML5/Jquery- interface on top of it.<br />You might prefer some other technologies for client but I do mine like this since I can whip them up pretty fast and they behave&nbsp;quite ok. (and i know HTML and Jquery very well)</p>
<p>Basically the whole program is a no-brainer but I'll go over some of the most interesting bits here.<br />First of all we need to have some structure that we are sending back and forth, here's mine:</p>
<p>public <span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;">class </span></span></span><span style="color: #2b91af; font-family: Consolas; font-size: x-small;"><span style="color: #2b91af; font-family: Consolas; font-size: x-small;"><span style="color: #2b91af; font-family: Consolas; font-size: x-small;">MeasurementEvent</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;"> : </span></span><span style="color: #2b91af; font-family: Consolas; font-size: x-small;"><span style="color: #2b91af; font-family: Consolas; font-size: x-small;"><span style="color: #2b91af; font-family: Consolas; font-size: x-small;">TableEntity<br /></span></span></span>&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [<span style="color: #2b91af; font-family: Consolas; font-size: x-small;"><span style="color: #2b91af; font-family: Consolas; font-size: x-small;"><span style="color: #2b91af; font-family: Consolas; font-size: x-small;">DataMember</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;">]<br /></span></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;">public </span></span></span><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;">long</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;"> deviceid { </span></span><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;">get</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;">; </span></span><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;">set</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;">; }</span></span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [<span style="color: #2b91af; font-family: Consolas; font-size: x-small;"><span style="color: #2b91af; font-family: Consolas; font-size: x-small;"><span style="color: #2b91af; font-family: Consolas; font-size: x-small;">DataMember</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;">]<br /></span></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;">public </span></span></span><span style="color: #2b91af; font-family: Consolas; font-size: x-small;"><span style="color: #2b91af; font-family: Consolas; font-size: x-small;"><span style="color: #2b91af; font-family: Consolas; font-size: x-small;">DateTime</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;"> arrivaltime { </span></span><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;">get</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;">; </span></span><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;">set</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;">; }</span></span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [<span style="color: #2b91af; font-family: Consolas; font-size: x-small;"><span style="color: #2b91af; font-family: Consolas; font-size: x-small;"><span style="color: #2b91af; font-family: Consolas; font-size: x-small;">DataMember</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;">]<br /></span></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;">public </span></span></span><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;">long</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;"> temperature { </span></span><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;">get</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;">; </span></span><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;">set</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;">; }</span></span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [<span style="color: #2b91af; font-family: Consolas; font-size: x-small;"><span style="color: #2b91af; font-family: Consolas; font-size: x-small;"><span style="color: #2b91af; font-family: Consolas; font-size: x-small;">DataMember</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;">]<br /></span></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;">public </span></span></span><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;">long</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;"> pressure { </span></span><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;">get</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;">; </span></span><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;">set</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;">; }</span></span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [<span style="color: #2b91af; font-family: Consolas; font-size: x-small;"><span style="color: #2b91af; font-family: Consolas; font-size: x-small;"><span style="color: #2b91af; font-family: Consolas; font-size: x-small;">DataMember</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;">]<br /></span></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;">public </span></span></span><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;">long</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;"> vibration { </span></span><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;">get</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;">; </span></span><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;">set</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;">; }</span></span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [<span style="color: #2b91af; font-family: Consolas; font-size: x-small;"><span style="color: #2b91af; font-family: Consolas; font-size: x-small;"><span style="color: #2b91af; font-family: Consolas; font-size: x-small;">DataMember</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;">]<br /></span></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;">public </span></span></span><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;">long</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;"> value { </span></span><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;">get</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;">; </span></span><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;">set</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;">; }</span></span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [<span style="color: #2b91af; font-family: Consolas; font-size: x-small;"><span style="color: #2b91af; font-family: Consolas; font-size: x-small;"><span style="color: #2b91af; font-family: Consolas; font-size: x-small;">DataMember</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;">]<br /></span></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;">public </span></span></span><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;">string</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;"> type { </span></span><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;">get</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;">; </span></span><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;">set</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;">; }</span></span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [<span style="color: #2b91af; font-family: Consolas; font-size: x-small;"><span style="color: #2b91af; font-family: Consolas; font-size: x-small;"><span style="color: #2b91af; font-family: Consolas; font-size: x-small;">DataMember</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;">]<br /></span></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;">public </span></span></span><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;">long</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;"> serial { </span></span><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;">get</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;">; </span></span><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;">set</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;">; }</span></span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;">public</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;"> MeasurementEvent()<br /></span></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;"><span style="color: #0000ff; font-family: Consolas; font-size: x-small;">this</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;">.serial = </span></span><span style="color: #2b91af; font-family: Consolas; font-size: x-small;"><span style="color: #2b91af; font-family: Consolas; font-size: x-small;"><span style="color: #2b91af; font-family: Consolas; font-size: x-small;">AppModel</span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas; font-size: x-small;">.getSerial();&nbsp;&nbsp;&nbsp;<br /></span></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; }</p>
<p>As You can see I'm using the same structure to carry all the event types in my demo. In real life You might be using few types instead.<br />The other notable thing is that the class is decendent from TableEntity, it doesn't have to be, but I'm doing it because I'm later on reusing this same class when querying the TableStore for events and LINQ wants it like this.</p>
<p>Here is my sender-function that is being called&nbsp;once&nbsp;a second when the simulator is active :</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/iot%20partII/1665.Senderfunc.PNG" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-iot+partII/1665.Senderfunc.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/iot%20partII/1665.Senderfunc.PNG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-iot+partII/1665.Senderfunc.PNG" alt="" border="0" /></a><br /><em>(sorry for including this as an image but the editing system screws my VS-pasted code blocks pretty good, I'll&nbsp;put the code in resources at the tail of this article)</em><br /><br />The SensorData is just a structure to convey the HTML-fields from the screen to the backend .So nothing special there. The randomizer is a simple block generating some randomly drifting values. The dice generates (-1,0,1) and the values are drifting accordingly:<br /><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/iot%20partII/8764.Randomizer.PNG" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-iot+partII/8764.Randomizer.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/iot%20partII/8764.Randomizer.PNG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-iot+partII/8764.Randomizer.PNG" alt="" border="0" /></a><br /><br />The timing is&nbsp;implemented by the client using good old window.setInterval since it doesn't have to be rock solid. Add some basic field checks and the simulator is pretty much a done deal.</p>
<h2>&nbsp;Catching the events</h2>
<p>For&nbsp;instruction on how to setup the infrastructure for Azure Stream Analytics please see<a title="Part I" href="http://blogs.msdn.com/b/petsablog/archive/2014/12/11/iot-for-mortals-part-i.aspx"> Part I of this article</a>. I'll show here only the most interesting bits <br /><br />Stream analytics dashboard:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/iot%20partII/0336.streamdash.PNG" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-iot+partII/0336.streamdash.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/iot%20partII/0336.streamdash.PNG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-iot+partII/0336.streamdash.PNG" alt="" border="0" /></a><br />Averaging query:<br /><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/iot%20partII/3716.sqlquery.PNG" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-iot+partII/3716.sqlquery.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/iot%20partII/3716.sqlquery.PNG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-iot+partII/3716.sqlquery.PNG" alt="" border="0" /></a></p>
<p>&nbsp;Basic query for storing into Blob storage:<br /><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/iot%20partII/6648.Query.PNG" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-iot+partII/6648.Query.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/iot%20partII/6648.Query.PNG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-iot+partII/6648.Query.PNG" alt="" width="331" height="145" border="0" /></a></p>
<p>So at runtime we have three active jobs consuming&nbsp;the same input. Pretty cool, it just works that way.<br />Maybe one thing&nbsp;worth noting in Tablestore output definition is that the fields "Partition Key" and "Row Key" are referring to column names in Your input, not values.</p>
<p>Here's a piece of data from blob storage:<br /><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/iot%20partII/8103.blobdata.PNG" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-iot+partII/8103.blobdata.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/iot%20partII/8103.blobdata.PNG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-iot+partII/8103.blobdata.PNG" alt="" border="0" /></a><br />After adding&nbsp;a terminating "]" this is basically a valid json file that can be used by tools like HDInsight (Hadoop) or Azure Machine Learning (we might look in to that in Part III).</p>
<p>TableStore looks like this:<br /><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/iot%20partII/0121.tabledata.PNG" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-iot+partII/0121.tabledata.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/iot%20partII/0121.tabledata.PNG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-iot+partII/0121.tabledata.PNG" alt="" border="0" /></a><br />This is a more traditional view of the same data.<br />Actually this is newer picture and there are a couple fields worth mentioning. I added a thing called avain (key in Finnish) which is a decending number since there is no "order by" when selecting rows from the TableStore which just gives You rows starting from the first one. So making the key decending turns the default sorting (PartitionKey,RowKey) upside down so that when I take only 40 lines I get the latest ones.<br />Other thing to note is that the PartitionKey is used as the datatype label. Very much like table name would be in relational world.</p>
<h2>Here's looking at You kid</h2>
<p>I wanted to view how my pumps and ekg-monitors are doing so I needed to build a little dashboard to show&nbsp;the latest values coming from the relational db. <br /><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/iot%20partII/8446.monitoring.PNG" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-iot+partII/8446.monitoring.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/iot%20partII/8446.monitoring.PNG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-iot+partII/8446.monitoring.PNG" alt="" border="0" /></a><br />Remember that it was averaged data&nbsp;in db&nbsp;so we are looking at trends here, not actual line data.</p>
<p>One can go totally crazy and build wild visualizations of this data using BI-tools or whatever. I'm using just&nbsp;HTML and flot here. There's a little REST-function on the backend that spits out lates monitoring data from tga db and jquery feeds it to&nbsp;flot diagrams. Easy as pie.</p>
<p>Another view of the same data comes from TableStore :<br /><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/iot%20partII/0638.Tablestoredata.PNG" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-iot+partII/0638.Tablestoredata.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/iot%20partII/0638.Tablestoredata.PNG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-iot+partII/0638.Tablestoredata.PNG" alt="" border="0" /></a></p>
<p>Here we are presenting all the latest rows unsummed which is a good starting point for later analysis.<br /><br />The TableStore is approached by this little code snippet:<br /><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/iot%20partII/0882.sensorquery.PNG" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-iot+partII/0882.sensorquery.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/iot%20partII/0882.sensorquery.PNG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-iot+partII/0882.sensorquery.PNG" alt="" border="0" /></a><br />&nbsp;Note the usage of the same MeasurementEvent-class we used sending data in Event Hub . (the full code is in resources)</p>
<h2>So there You have it !</h2>
<p>This is how You programmatically create events, send them , capture them, analyze them and finally show them in various forms.<br />What's missing is the business case here and the real value that comes from applying analysis to this data.<br />We'll probabply look into those tools in the next part of this article.</p>
<p><a title="Resources" href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/iot%20partII/2570.resources.txt" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-iot+partII/2570.resources.txt">Get&nbsp;the code&nbsp;resources to help Your typing.</a></p>
<p>&nbsp;</p>]]></content:encoded>
    </item>
    <item>
      <title>Authorization As a Service,the coolest thing for LOB</title>
      <link>https://docs.microsoft.com/archive/blogs/petsablog/authorization-as-a-servicethe-coolest-thing-for-lob</link>
      <pubDate>Fri, 06 Feb 2015 01:35:00 GMT</pubDate>
      <dc:creator><![CDATA[petsablog]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/petsablog/2015/02/06/authorization-as-a-servicethe-coolest-thing-for-lob/</guid>
      <description><![CDATA[World is getting better - definitely
If You are a lazy programmer like me this will blow Your...]]></description>
      <content:encoded><![CDATA[<h2>World is getting better - definitely</h2>
<p><br />If You are a lazy programmer like me this will blow Your mind&nbsp; .... <strong>I promise</strong>.</p>
<p>When developing software I'd like to write only the stuff that absolutely definitely needs to be written, nothing more.<br />So I have a long standing hate-hate relationship with those verbose xml-configs and convoluted frameworks since all they represent extra work that I need to do. In the worst case such work that has no value to the actual customer (<em>remember customer anyone ?</em>) , but work that just needs to be done to make the wheels go round.<br /><br /><strong>I hate writing boilerplate code/config/definition with a passion.</strong></p>
<p>So Imagine my smile when I found out that I can consume the services of a modern Authorization stack (including multi factor authentication) with a simple click of a button.<br />Doesn't sound like much does it ? Wait, let me show You ...</p>
<h2>Setting the scene</h2>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/auth/2500.Azure%20auth%201.PNG" original-url="http://blogs.msdn.com/cfs-filesystemfile.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-auth/2500.Azure-auth-1.PNG"><img style="max-width: 550px;" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/auth/2500.Azure%20auth%201.PNG" original-url="http://blogs.msdn.com/cfs-filesystemfile.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-auth/2500.Azure-auth-1.PNG" alt="" border="0" /></a><br />&nbsp;<br />I&rsquo;m writing this from the viewpoint of an LOB &ndash; developer. More specifically I want to write responsive HTML5 single page applications so I&rsquo;m using Bootstrap on the front end side and some jquery (optionally some knockout,angular,&hellip;) and some sort of backend to service my front ed app some REST JSON APIs. <br />Simple enough. <br /><br />In this scenario my backend needs to spit out some html but mostly serve my API calls. And when doing that the backend needs to know who the user is !<br /><br />The users can&rsquo;t be stored on the LOB-applications own database anymore (we all know that) so how about using some modern structure like oAuth and Azure Ad and so on &hellip; <strong>That&rsquo;s when everything starts<br />getting convoluted !<br /><br /></strong>The minute You start dabbling with authorization things slow down like in Matrix bullet-time and You lose all productivity and Your hair starts getting gray very rapidly.</p>
<p>But luckily there&rsquo;s a really nice rabbit hole to bypass oll this grief when operating with Azure websites:<br /><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/auth/5355.Azure%20auth%202.PNG" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-auth/5355.Azure-auth-2.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/auth/5355.Azure%20auth%202.PNG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-auth/5355.Azure-auth-2.PNG" alt="" border="0" /></a><br /><br />The red bar is the real superhero of this story. It intercepts all calls to my application, regardless if it is a page request or a REST call to one of my APIs It makes sure that only those people who have successfully logged in with my AD can pass. And when they do pass my application is being given a nice context describing the user &hellip; <br />And all this without writing any code. &hellip; well almost no code , since I need to write code to acces and use the userinfo I&rsquo;ve been so graciously given.</p>
<h2>Enough talk, show me the money !</h2>
<p>For the sake of simplicity I&rsquo;ll only present the skeleton portion of an LOB, next time well continue from that.<br /><br />Visual Studio 2013&nbsp; / New Project /&nbsp; Cloud / ASP.NET Web application / Web API / No Authentication :<br /><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/auth/7271.Azure%20auth%203.PNG" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-auth/7271.Azure-auth-3.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/auth/7271.Azure%20auth%203.PNG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-auth/7271.Azure-auth-3.PNG" alt="" border="0" /></a><br /><br />So now we have a nice skeleton. Lets tweak it just a little.<br /><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/auth/1108.Azure%20auth%204.PNG" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-auth/1108.Azure-auth-4.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/auth/1108.Azure%20auth%204.PNG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-auth/1108.Azure-auth-4.PNG" alt="" border="0" /></a></p>
<p>&nbsp;And hit run (F5) . Once it runs go to <a href="http://Your_app/api/values">http://Your_app/api/values</a>. Mine is: <a href="http://localhost:44752/api/values">http://localhost:44752/api/values</a><br /><br />You should get some JSON back. Opening mine : ["value1","value2",""] &ndash; Exactly as it should be<br /><br /><strong>So now we are done developing !!!</strong></p>
<p><strong>Header:<br /></strong></p>
<pre class="scroll"><code class="cplusplus"> using System.Security.Claims;<br /> using System.Threading;<br /> using System.Web.Configuration;</code></pre>
<p><strong>Code:</strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
<pre class="scroll"><code class="cplusplus"> public IEnumerable&lt;string&gt; Get()<br /> {<br /> String res = "";<br /> var claimsPrincipal = Thread.CurrentPrincipal as ClaimsPrincipal;<br /> if (claimsPrincipal != null &amp;&amp; claimsPrincipal.Identity.IsAuthenticated)<br /> {<br /> foreach (var claim in claimsPrincipal.Claims)<br /> {<br /> res += "&lt;div&gt;type:" + claim.Type + ":" + claim.Value + "&lt;/div&gt;";<br /> }<br /> res += "&lt;p&gt;Logout:" + WebConfigurationManager.AppSettings["WEBSITE_AUTH_LOGOUT_PATH"] + "&lt;/p&gt;";<br /> }<br /> return new string[] { "value1", "value2", res };<br /> }<br /> </code></pre>
<p>Let&rsquo;s deploy this to azure. <br /><br />If You didn&rsquo;t already create a publishing profile while creating the product do it now:</p>
<ol>
<li>Stop the debug, Right click Your project name and choose &ldquo;publish&rdquo;</li>
<li>As publish target choose &ldquo;Microsoft Azure Website&rdquo;</li>
<li>If You don&rsquo;t have existing websites choose new.</li>
<li>Either way now You have a website picked, Validate the connection</li>
<li>On File publish options choose : &ldquo;Remove additional files&rdquo; and hit publish</li>
<li>After few minutes Your site should come up. go to the same relative url &ldquo;/api/values&rdquo;</li>
<li>You should get the exact same response as when running locally</li>
</ol>
<p>Fine . Now for the magic &hellip;.. (drumroll ,please) &hellip;.</p>
<p>Goto to : manage.windowsazure.com/ , find Your website and go to configure and find this:</p>
<p>&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/auth/5238.Azure%20auth%205.PNG" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-auth/5238.Azure-auth-5.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/auth/5238.Azure%20auth%205.PNG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-auth/5238.Azure-auth-5.PNG" alt="" border="0" /></a></p>
<p>Choose Your directory and &ldquo;Add Application&rdquo;.<br /><strong><span style="font-size: large;">That&rsquo;s it. You&rsquo;re done .</span>&nbsp;<br /><br /><br /></strong>Next take a new browser or inPrivate browsing or whatever it is called in Your browser. The idea being that You should have a browser where You have no ongoing sessions to azure. <br />This time You are presented with a login screen and once You clear that you go to the same url <a href="http://yourapp/api/values">http://yourapp/api/values</a><br /><br /><strong>Notice that the returned JSON has all kinds of interesting claims now. Amongst them are your name , email and so on &hellip;</strong> <br /><br />Now You know that for every api or page request the caller is going to be identified against Your Azure AD (You can manage the AD as You wish) and You are being told who the caller is.<br />Isn't this wonderful.</p>
<h2>Adding Multi Facet login capabilities</h2>
<p>Let's get a little greedy and add some cool stuff while we're at it.<br />Take a look at here on how to setup Your AD to support multi facet logins : <a href="http://azure.microsoft.com/en-us/documentation/services/multi-factor-authentication/">http://azure.microsoft.com/en-us/documentation/services/multi-factor-authentication/</a><br />I have Azure AD premium so I just enabled the feature and made one of my users to require some additional authentication.<br /><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/auth/6746.Azure%20auth%206.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-auth/6746.Azure-auth-6.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/auth/6746.Azure%20auth%206.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-auth/6746.Azure-auth-6.png" alt="" border="0" /></a></p>
<p>Then I logged in with that user and was presented with a request to use my mobile app for extra credentials.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/auth/3146.Azure%20auth%207.PNG" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-auth/3146.Azure-auth-7.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/auth/3146.Azure%20auth%207.PNG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43-auth/3146.Azure-auth-7.PNG" alt="" border="0" /></a>&nbsp;</p>
<p><em>Sorry , this is in Finnish, but You probably can guess what is says.</em> <br /><br />So the application in my mobile came up and I chose &ldquo;verify&rdquo; and Boooom &hellip; I got in to my little sample application .<br />And sure enough, the returned JSON message from "/api/values" had my webusers details in it.</p>
<h2>Easy breezy multi-factor-authentication-implemented-with-no-code</h2>
<p>This is so cool . <br />Next time we&rsquo;ll start to implement the actual application itself since we now got this super cool authentication implemented in no time. <br />There are still things to wish for. Group-support is one of them but it is coming.<br /><br />Read more from here: <a href="http://azure.microsoft.com/blog/2014/11/13/azure-websites-authentication-authorization/">http://azure.microsoft.com/blog/2014/11/13/azure-websites-authentication-authorization/</a></p>
<p>Until next time &hellip;</p>]]></content:encoded>
    </item>
    <item>
      <title>IOT for mere mortals, Part I</title>
      <link>https://docs.microsoft.com/archive/blogs/petsablog/iot-for-mere-mortals-part-i</link>
      <pubDate>Thu, 11 Dec 2014 01:35:00 GMT</pubDate>
      <dc:creator><![CDATA[petsablog]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/petsablog/2014/12/11/iot-for-mere-mortals-part-i/</guid>
      <description><![CDATA[You must have heard the buzz about IOT.&nbsp; Internet of Things that is.It is supposed to fix the...]]></description>
      <content:encoded><![CDATA[<p>You must have heard the buzz about IOT.&nbsp;<strong> Internet of Things </strong>that is.<br />It is supposed to fix the european economy and cure cancer.&nbsp; The industy heavies are waiting the IOT to solve all our problems ...</p>
<p>Well, in the meantime us regular dudes can actually do something without spending huge amounts of time or cash to get our feet wet in IOT by utilizing ... You guessed it ... good old <strong>PaaS approach</strong>.</p>
<p>So today we are going to build an <strong>infinitely scalable&nbsp;input</strong> point and send in some random temperature readings.</p>
<p><br />Here's a picture of the overall architecture of a generic IOT solution running on Azure PaaS offering.<br /><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/1884.architecture.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43/1884.architecture.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/1884.architecture.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43/1884.architecture.png" alt="" border="0" /></a></p>
<p>We have our gadgets that produce events, optionally some gateways to aggregate&nbsp;messages or transform protocols, Event hubs to catch all the traffic, then some more or less realtime analysis and storage.<br /><strong>So what's new ? ... nothing really</strong>. <br />Other than the fact that now we can do this in an afternoon <strong>without building a costly infrastructure</strong> first. We do this&nbsp;by utlizing PaaS components and by doing so we get the benefit of world class <strong>scalability</strong> and <strong>security</strong> by design. But looking at this purely from a functional standpoint ... it's all stuff that we have been doing for a long ... long time.&nbsp;</p>
<p>Enough talk, let's actually do something...</p>
<ol>
<li>Create Service Bus namespace to contain our event hub</li>
<li>Create event hub to catch the message from field</li>
<li>Build a small Simulator to send in events</li>
<li>Create a Stream Processing Job to do some mild analysis</li>
<li>Store the data for Part II where we will try to do some reporting and analysis</li>
</ol>
<h4>Namespace</h4>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/4061.newnamespace.PNG" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43/4061.newnamespace.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/4061.newnamespace.PNG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43/4061.newnamespace.PNG" alt="" width="308" height="355" border="0" /></a></p>
<p>The namespace is a manageable unit that can house several different services like Queues,Topics and Event Hubs, which we will be using today. One interesting thing about the namespace is that it controls the scaling of&nbsp;the Services it contains. <br /><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/1602.scaling.PNG" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43/1602.scaling.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/1602.scaling.PNG" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43/1602.scaling.PNG" alt="" width="378" height="241" border="0" /></a></p>
<p>Namespace does this via Throughput Units. One TU can take in roughly <strong>1MB per second</strong>. Given a 12 hour day that makes about <strong>50GB per day</strong>. Not bad.<br />TU's are also a billable resource. One TU in standard mode cost about <strong>0.0224&euro; per hour</strong>, which&nbsp;totals about 17&euro; per month. SO cost isn't the thing keeping Your company from testing IOT.<br />Pay attention to this ! This is the point that decides how scalable Your solutions intake will be and how costly it will be to run. With this slider You can easily provision up to 20 TU's for running Your ingress.</p>
<h4>&nbsp;Event Hub</h4>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/0842.createeventhub.PNG" original-url="http://blogs.msdn.com/cfs-filesystemfile.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43/0842.createeventhub.PNG"><img style="max-width: 550px;" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/0842.createeventhub.PNG" original-url="http://blogs.msdn.com/cfs-filesystemfile.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43/0842.createeventhub.PNG" alt="" border="0" /></a><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/4048.configureeventhub.PNG" original-url="http://blogs.msdn.com/cfs-filesystemfile.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43/4048.configureeventhub.PNG"><img style="max-width: 550px;" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/4048.configureeventhub.PNG" original-url="http://blogs.msdn.com/cfs-filesystemfile.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43/4048.configureeventhub.PNG" alt="" border="0" /></a></p>
<p>An Event Hub is the actual endpoint to which all the gadgets send their events.You can use Partitions and parition keys in Your data to&nbsp;splice the data up, but if not used the&nbsp;partitions will be used evenly for all data.&nbsp;<br />Remember to configure Shared Access Policy for Your Event Hub or the Job will not be able find it later. I created a poly called "manage" and ticked&nbsp; all the boxes for access.</p>
<h4>&nbsp;Stream Analytics Job</h4>
<p>&nbsp;A Job is actually very simple thing connecting the ingreaa queue with long term storage and performing some optional analysis on the fly.<br /><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/5287.newjob.PNG" original-url="http://blogs.msdn.com/cfs-filesystemfile.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43/5287.newjob.PNG"><img style="max-width: 550px;" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/5287.newjob.PNG" original-url="http://blogs.msdn.com/cfs-filesystemfile.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43/5287.newjob.PNG" alt="" border="0" /></a></p>
<p>Jobs monitoring storage account should reside in same region as the job itself or You will be paying for the traffic.<br />A Job consists of three moving parts :<br /><strong>Input</strong>: Here You will reference Your Event Hub. <br /><strong>Output</strong>: The long-term storage can be various things I chose Sql Database in the same region that the Job is in. Remember to enable Access for other Azure Services in DB's config ot You will spend some time wondering why the Job is not running.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/4431.allow.PNG" original-url="http://blogs.msdn.com/cfs-filesystemfile.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43/4431.allow.PNG"><img style="max-width: 550px;" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/4431.allow.PNG" original-url="http://blogs.msdn.com/cfs-filesystemfile.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43/4431.allow.PNG" alt="" border="0" /></a></p>
<p>There needs to be a table in the&nbsp;Sql database that matches the structure that Your "query" produces and it needs to be named in the outputs-config, so here goes:<br />CREATE TABLE <span class="pun">[</span><span class="pln">dbo</span><span class="pun">].[</span><span class="typ">AvgReadings</span><span class="pun">]</span><span class="pun">(</span><span class="pln"><br />&nbsp;&nbsp;&nbsp; </span><span class="pun">[</span><span class="typ">WinStartTime</span><span class="pun">]</span><span class="pln">&nbsp;&nbsp; DATETIME2 </span><span class="pun">(</span><span class="lit">6</span><span class="pun">)</span><span class="pln"> NULL</span><span class="pun">,</span><span class="pln"><br />&nbsp;&nbsp;&nbsp; </span><span class="pun">[</span><span class="typ">WinEndTime</span><span class="pun">]</span><span class="pln">&nbsp;&nbsp;&nbsp;&nbsp; DATETIME2 </span><span class="pun">(</span><span class="lit">6</span><span class="pun">)</span><span class="pln"> NULL</span><span class="pun">,</span><span class="pln"><br />&nbsp;&nbsp;&nbsp; </span><span class="pun">[</span><span class="typ">DeviceId</span><span class="pun">]</span><span class="pln">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BIGINT NULL</span><span class="pun">,</span><span class="pln"><br />&nbsp;&nbsp;&nbsp; </span><span class="pun">[</span><span class="typ">AvgTemperature</span><span class="pun">]</span><span class="pln"> FLOAT </span><span class="pun">(</span><span class="lit">53</span><span class="pun">)</span><span class="pln">&nbsp;&nbsp;&nbsp; NULL</span><span class="pun">,</span><span class="pln"><br />&nbsp;&nbsp;&nbsp; </span><span class="pun">[</span><span class="typ">EventCount</span><span class="pun">]</span><span class="pln"> BIGINT </span><span class="kwd">null</span><span class="pln"><br /></span><span class="pun">);</span><span class="pln"><br />CREATE CLUSTERED INDEX </span><span class="pun">[</span><span class="typ">AvgReadings</span><span class="pun">]</span><span class="pln"> ON </span><span class="pun">[</span><span class="pln">dbo</span><span class="pun">].[</span><span class="typ">AvgReadings</span><span class="pun">]([</span><span class="typ">DeviceId</span><span class="pun">]</span><span class="pln"> ASC</span><span class="pun">);</span></p>
<p><strong>Query</strong>:&nbsp;This is where the realtime analysis and the overall definition of the data structure happens. Basically You create a query and whatever it produces will be the new datatype and it will be store in "output".<br />A simple query could be like this&nbsp;: "SELECT DeviceId, Temperature FROM input" - this would just store the values received into output-table for later usage. <br />If You want to do some aggregation or math with the data before it is written to storage You can use some clever sql:<a href="http://msdn.microsoft.com/en-us/library/azure/dn834998.aspx">http://msdn.microsoft.com/en-us/library/azure/dn834998.aspx</a><br /><br />In this case we will just average some values with 5-second window:<br />"SELECT DateAdd(second,-5,System.TimeStamp) as WinStartTime, system.TimeStamp as WinEndTime, DeviceId, Avg(Temperature) as AvgTemperature, Count(*) as EventCount&nbsp; FROM input GROUP BY TumblingWindow(second, 5), DeviceId"<br />Note that the "input" needs to refer to the alias-name that You gave when defining Your Job input !!!</p>
<p>Go to Your Jobs Dashboard and hit Start ... and our system should be ready to accept some input.</p>
<h4>Creating some events</h4>
<p>The most&nbsp;important things&nbsp;in our little Simulator client are:<br />NamespaceManager to connect to our namespace ,credentials stored in app.config.<br />EventHubClient for accessing the api<br />EventData to house our data structure.<br />EventHubCLient.SendAsyc for actually sending.<br /><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/5658.code.PNG" original-url="http://blogs.msdn.com/cfs-filesystemfile.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43/5658.code.PNG"><img style="max-width: 550px;" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/5658.code.PNG" original-url="http://blogs.msdn.com/cfs-filesystemfile.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43/5658.code.PNG" alt="" border="0" /></a><br />Don't worry there will be a link from where You can get the client code from.<br />Running this guy feeds some events in our pipeline.<br /><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/1881.running.PNG" original-url="http://blogs.msdn.com/cfs-filesystemfile.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43/1881.running.PNG"><img style="max-width: 550px;" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/1881.running.PNG" original-url="http://blogs.msdn.com/cfs-filesystemfile.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43/1881.running.PNG" alt="" border="0" /></a></p>
<p>Note that the second parameter needs to be the name of Your Event Hub inside Your namespace.</p>
<p>Querying tha database will show that we indeed get some events coming in and we are able to perform some light operations&nbsp;on it too.<br /><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/8662.query.PNG" original-url="http://blogs.msdn.com/cfs-filesystemfile.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43/8662.query.PNG"><img style="max-width: 550px;" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/68/43/8662.query.PNG" original-url="http://blogs.msdn.com/cfs-filesystemfile.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-68-43/8662.query.PNG" alt="" border="0" /></a>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h4>&nbsp;Conclusions and next steps</h4>
<p>So , IOT isn't that hard after all. <br />By using some PaaS Services we were able to make&nbsp;a solution that can ingest <strong>millions of &nbsp;messages per second</strong>. By using some good old SQL we were also able to enrich and analyze the incoming data stream.<br />Not bad.<br /><br />Next part of this article will elaborate on the client side, namely we will be sending events from scripting language, probabply from Python, We'll use a Raspberry pi as a client if all goes well . <br />We will also do some reporting and maybe some Machine Learning.<br />Stay tuned.<br /><br /><br />In case You have problems finding Your way around Azure management screens there is a more step-by-step oriented tutorial available here, it also has the source code for the client used:<br /><a href="http://azure.microsoft.com/en-us/documentation/articles/stream-analytics-get-started/">http://azure.microsoft.com/en-us/documentation/articles/stream-analytics-get-started/</a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>]]></content:encoded>
    </item>
  </channel>
</rss>