CosmosDB – Build 2017 Recap Vienna

AzureCosmosDBViennaSpeakerAuf der Veranstaltung //BUILD on Tour gestern bei Microsoft Österreich durfte ich einen Vortrag zum Thema “CosmosDB” halten.

Die Slides zu meinem CosmosDB Vortrag könnt ihr hier herunterladen. Auf GitHub findet ihr meinen Source Code zum CosmosDB Vortrag und hier das Azure CosmosDB Graph Explorer Beispiel.

Hier auch die Gremlin Queries für das Beispiel aus The Hobbit.

Aja, nachdem es für einige Verwirrung gesorgt hat. In CosmosDB gibt es nur Request Units (RU) pro Sekunde/Minute und keine Orks Smile. Obwohl es hätte was.

Bester Sager eines Teilnehmers in dem Vortrag zu den UWP Apps: “Helene Fischer? Naja ohne Ton gehts” *haha*

Viel Spaß

AndiP

Global Azure Bootcamp 2017 Nachlese

 

Wissensturm in Linz 2017 (c) by Andreas PollakWie jedes Jahr fand auch heuer das Global Azure Bootcamp  für Österreich im Linzer Wissensturm statt. Wie immer , dank Rainer Stropek und Karin Huber, ausgezeichnet organisiert und mit spannenden Vorträgen versehen.

Diesmal durfte ich gleich zwei Vorträge zu den Themen “Azure API Management” und “Azure DocumentDB” beisteuern.

Speaker Foto (c) by Rainer StropekUnterhalb findet ihr die Verweise zu den Vortragsslides. Dort könnt ihr auch die Codebeispiele von GitHub herunterladen.

 

Slidedecks & Source

Viel Spaß und bis demnächst

AndiP

Direct Methods and MQTT Box in action

This is to anyone who wants to connect MQTT-Box to Azure IOT-Hub. In my last post I was changing the Microsoft.Azure.Devices.Client implementation to enable Direct Methods. In this article I am showing how to setup MQTT-Box to be able to receive Direct Messages there.

First and foremost you need to create a new IoT-Hub instance with “DeviceManagmentPreview” enabled. If you struggle with this have a look at this post.  To create the shared access signatures we use Device Explorer which you can get here. After you have set up IOT-Hub and downloaded MQTT-Box and Device Explorer start up those tools.

Copy the connection string from the IOT-Hub SAS-policy “iothubowner” to the connection info in Device Explorer:

image

Switch to Management-Tab and click “Create…” to create a new Device. Lets name it “myDeviceId”. Leave the suggested keys and click “Create”.   Click button “SAS Token…”. Select your device, set the time to live (TTL) to 1 and click “Generate”.

image

Copy the value of the SharedAccessSignature (everything after “SharedAccessSignature=”). The result should look like this

SharedAccessSignature sr=<yourIOTHubName>.azure-devices.net%2Fdevices%2F<yourDeviceId>&sig=<signature>&se=<se>

Then start MQTT-Box and create a new MQTT Client

image

Copy the SAS into the password field. Set the following fields and settings:

MQTT Client Name = Something
MQTT Client Id = <your Device ID>
Append timestamp to MQTT client Id? = NO
Protocol = mqtts / tsl
Host = <yourIOTHubName>.azuredevices.net:8883
UserName = <yourIOTHubName>.azure-devices.net/<your Device ID>/DeviceClientType=azure-iot-device%2F1.1.0-dtpreview&api-version=2016-09-30-preview

Click “Save” – You should get a green “Connected”-Button

image

Finally to receive the messages set the “Topic to subscribe” in the yellow box to:

  • $iothub/methods/POST/#

Then hit the “Subscribe”-Button. Now you need to start the node sample from this article to send a direct message to your device on your IOT-Hub. As a result you will receive the message in you MQTT-Box.
image

Of course, since we do not reply here the node client writes out a timeout error after a while. If you want however to send a successful response have a look at the “Topics to publish” section in MQTT Box

Prepare the “Topic to publish”: $iothub/methods/res/200/?$rid=
Payload Type: Strings /JSON / XML /Characters
Payload: “Hello”

Now use the node client to send a direct message again. Have a look at the results in the orange box and quickly copy the number after “$rid=”. After the second call it should be “2”. In the image above it is “1”.

Add this RID-Number to your Topic to publish. In this case: $iothub/methods/res/200/?$rid=2

Hit “Publish”. The message should pop up below:
image

In your node window you will get the result:
image

Enjoy
AndiP

Enable IOT Hub DeviceManagement Preview

imageI do not know if it is just my portal which is missing the “Enable Device Management PREVIEW” – Checkbox when creating a new IOT-Hub. It is still described in the article “Tutorial: Get started with device management” from Juan Perez .

You still can create it with an ARM Template by setting the “Feature”-Field to “DeviceManagement”.

I have written an ARM Template for an IOT-Hub with Device Management which you can download here. Be aware though, that this only works in certain regions like NorthEurope (but now WestEurope).

Enjoy
AndiP

Direct Methods with IOTHub in C#

There is a new preview in town. With this you can invoke a direct method on a device. Currently only MQTT devices are supported in this scenario. There is a nice article with some NodeJS samples. When Roman Kiss posted on the Azure Forum that he would like to write his simulated device in C# I thought this might be an nice opportunity to figure out why this does not work.

Well the answer is pretty simple: It is not yet implemented in the C# SDK.

But being me I decided to make the “impossible” possible (for the fun sake of it). First I did pull the complete preview of the Azure IOT Sdks  from github. Then I spend some time in figuring out what the NodeJS implementation does. I love debugging JavaScript *sigh*.

And then I quickly modded (aka hacked) the Microsoft.Azure.Devices.Client (Be aware that this is not an optimal solution Smile). These are the changes I made:

Microsoft.Azure.Devices.Client – MqttIotHubAdapter

sealed class MqttIotHubAdapter : ChannelHandlerAdapter
...
const string TelemetryTopicFormat = "devices/{0}/messages/events/";
// ADDED =>
const string MethodTopicFilterFormat = "$iothub/methods/POST/#";
const string MethodTopicFormat = "$iothub/methods/res/{0}/?$rid={1}";

Microsoft.Azure.Devices.Client – MqttIotHubAdapter – Connect Function

This was the most difficult to find out, because I did not expect this “hack”. Expect the unexpectable!
async void Connect(IChannelHandlerContext context)
{
...
var connectPacket = new ConnectPacket
{
ClientId = this.deviceId,
HasUsername = true,
// CHANGED => You need to add this weird suffix to make it work!
Username = this.iotHubHostName + "/" + this.deviceId + "/DeviceClientType=azure-iot-device%2F1.1.0-dtpreview&api-version=2016-09-30-preview",
HasPassword = !string.IsNullOrEmpty(this.password),

Microsoft.Azure.Devices.Client – MqttIotHubAdapter – SubscribeAsync Function
Here I added the method topic subscription!

async Task SubscribeAsync(IChannelHandlerContext context)
{
if (this.IsInState(StateFlags.Receiving) || this.IsInState(StateFlags.Subscribing))
{
return;
}

this.stateFlags |= StateFlags.Subscribing;

this.subscribeCompletion = new TaskCompletionSource();
string topicFilter = CommandTopicFilterFormat.FormatInvariant(this.deviceId);
var subscribePacket = new SubscribePacket(Util.GetNextPacketId(), new SubscriptionRequest(topicFilter, this.mqttTransportSettings.ReceivingQoS));
System.Diagnostics.Debug.WriteLine($"Topic filter: {topicFilter}");
await Util.WriteMessageAsync(context, subscribePacket, ShutdownOnWriteErrorHandler);
await this.subscribeCompletion.Task;

// ADDED => WE are using the const I decleared earlier to construct the topicFilter
this.subscribeCompletion = new TaskCompletionSource();
topicFilter = MethodTopicFilterFormat.FormatInvariant(this.deviceId);
System.Diagnostics.Debug.WriteLine($"Topic filter: {topicFilter}");
subscribePacket = new SubscribePacket(Util.GetNextPacketId(), new SubscriptionRequest(topicFilter, this.mqttTransportSettings.ReceivingQoS/*QualityOfService.AtMostOnce*/));
await Util.WriteMessageAsync(context, subscribePacket, ShutdownOnWriteErrorHandler);
await this.subscribeCompletion.Task;
// <= ADDED

}
Microsoft.Azure.Devices.Client – MqttIotHubAdapter –SendMessageAsync Function
Since we do want to acknowledge the arrival of the method we need to modify this too:
async Task SendMessageAsync(IChannelHandlerContext context, Message message)
{
// CHANGED => For our publish message we need to send to a different topic
string topicName = null;
if (message.Properties.ContainsKey("methodName"))
topicName = string.Format(MethodTopicFormat, message.Properties["status"], message.Properties["requestID"]);
else
topicName = string.Format(TelemetryTopicFormat, this.deviceId);
// <= CHANGED

PublishPacket packet = await Util.ComposePublishPacketAsync(context, message, this.mqttTransportSettings.PublishToServerQoS, topicName);
...
Microsoft.Azure.Devices.Client – MqttTransportHandler – ReceiveAsync Function
Since we do not get a lockToken with the Methodcall, we should not enqueue the Null in our completionQueue
public override async Task<Message> ReceiveAsync(TimeSpan timeout)
{
...
Message message;
lock (this.syncRoot)
{
this.messageQueue.TryDequeue(out message);
message.LockToken = message.LockToken;
// Changed line below to exclude LockTokens that are null #HACK better check if it is a Method message
if ((message.LockToken != null)&&(this.qos == QualityOfService.AtLeastOnce) )
{
this.completionQueue.Enqueue(message.LockToken);
}
...
Microsoft.Azure.Devices.Client – Util– ComposePublishPacketAsync
A little change here to prevent that this method “destroys” our carefully constructed topic name earlier.
public static async Task<PublishPacket> ComposePublishPacketAsync(IChannelHandlerContext context, Message message, QualityOfService qos, string topicName)
{
var packet = new PublishPacket(qos, false, false);

// MODIFIED ==>
if (message.Properties.ContainsKey("methodName"))
packet.TopicName = topicName; // Make sure to keep our Topic Name
else
packet.TopicName = PopulateMessagePropertiesFromMessage(topicName, message);
// <== MODIFIED
...

Microsoft.Azure.Devices.Client – Util– PopulateMessagePropertiesFromPacket
And finally we need to populate our method Messages with properties like our requestID, methodName,…
public static void PopulateMessagePropertiesFromPacket(Message message, PublishPacket publish)
{
message.LockToken = publish.QualityOfService == QualityOfService.AtLeastOnce ? publish.PacketId.ToString() : null;

// MODIFIED ==>
Dictionary<string, string> properties = null;
if (publish.TopicName.StartsWith("$iothub/methods"))
{
var segments = publish.TopicName.Split('/');
properties = UrlEncodedDictionarySerializer.Deserialize(segments[4].Replace("?$rid", "requestID"), 0);
properties.Add("methodName", segments[3]);
properties.Add("verb", segments[2]);
}
else
properties = UrlEncodedDictionarySerializer.Deserialize(publish.TopicName, publish.TopicName.NthIndexOf('/', 0, 4) + 1);
// <== MODIFIED

foreach (KeyValuePair<string, string> property in properties)
{
...

Building the simulated device with the modded Microsoft.Azure.Devices.Client SDK
Just create a new Console application and reference the modded SDK
 
using Microsoft.Azure.Devices.Client;
using System;
using System.Collections.Generic;
using System.Text;

namespace DeviceClientCS
{
class Program
{
private static async void ReceiveCloudToDeviceMessageAsync(DeviceClient client,
string theDeviceID)
{
Console.WriteLine($"Receiving messages from Cloud for device {theDeviceID}");
while (true)
{
Message receivedMessage = await client.ReceiveAsync();
if (receivedMessage == null) continue;

Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine($"Received method ({receivedMessage.Properties["methodName"]}): {Encoding.ASCII.GetString(receivedMessage.GetBytes())} for device {theDeviceID} - Verb: {receivedMessage.Properties["verb"]}");
Console.ResetColor();

// ACKNOWLEDGE the method call
byte[] msg = Encoding.ASCII.GetBytes("Input was written to log.");
Message respondMethodMessage = new Message();
foreach (KeyValuePair<string, string> kv in receivedMessage.Properties)
respondMethodMessage.Properties.Add(kv.Key, kv.Value);
respondMethodMessage.Properties.Add("status", "200");
await client.SendEventAsync(respondMethodMessage);
}
}


static void Main(string[] args)
{
string deviceID= "myDeviceId";
string connectionString = "<Your device connection string goes here>";

DeviceClient client = DeviceClient.CreateFromConnectionString(connectionString, deviceID, TransportType.Mqtt);
ReceiveCloudToDeviceMessageAsync(client, deviceID);
Console.ReadLine();
}
}
}
 
And here is a final screen shot of my results:
Result
Cheers
AndiP

 
 
 
 

Ubuntu with Visual Studio Code ARM Template

 

Setup the new cross-platform ASP.NET Core with Visual Studio Code on a Linux machine quickly? It’s a bit tedious to do all the required installation bits, not to mention to figure out the little issues.

DeployToAzure

imageUsing our new ARM-Template you can setup such Box on Microsoft Azure with a single click on the Deploy-Button (if you have an Azure Account already, if not get one here)! 

Then fill the parameters with values

  • Credentials
  • DNS-Name
  • Run full Ubuntu-Desktop? (installation will take much longer, but you can play Mahjong)
  • Resource-Group Name

and click “Create”.

The ARM Template installs:

  • Docker (from Docker Extension)
  • Ubuntu Desktop with XRDP and xfce4 (Full or Minimal)
  • Visual Studio Code
  • .NET Core SDK
  • NodeJS and NPM v6
  • Yeoman with ASP.NET Generator
  • C# Extension for Visual Studio Code in Visual Studio Code

RDPLoginLater use Remote Desktop Connection to connect to your machine! Computer:<DNS-Name>.<Location of Resource Group>.cloudapp.azure.com. Enter your credentials in the xrdp login dialog. Make sure “sesman-Xvnc” is selected!

 

VSCodeMenuYou find Visual Studio Code under Development. Or you can start it from the shell with “code .”. You also may use Yeoman with the preinstalled ASP.NET Generator.

Read more about the ASP.NET Generator at the blog of Scott Hanselman.

Enjoy playing with .NET Core and Visual Studio Code running in Windows Azure

YOGeneratorAndiP