Search code examples
cazurearduinoazure-eventhubarduino-esp8266

Sending batch events to Azure event hub using REST


I am able to send events to event hub using NodeMCU. I use the following code

https://www.hackster.io/stepanb/proof-of-concept-nodemcu-arduino-and-azure-event-hub-a33043

But I want to send batch events. I referred this page for that

https://learn.microsoft.com/en-us/rest/api/eventhub/send-batch-events

Here's a snapshot of serial monitor of NodeMCU sending single event

single event

As per the link we have to change the "content type" to

Content-Type: application/vnd.microsoft.servicebus.json

and the payload in the format

data= "[{'Temperature':25.25 , 'Deviceid':esp3} , {'Temperature':30.30 , 'Deviceid':esp3}]";

Here's a snapshot of serial monitor for batch events

batch events

Am I missing something? For receiving batch events do I need to do any change in the stream analytics. I am new to Azure and StackOverflow.

here's the code for sending single events

#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <String.h>
#include "sha256.h"
#include "Base64.h"

// START: Azure Evet Hub settings
const char* KEY = "dhGE6MbbRLe6IPZs6dOHd3byQlEJ8YzqnW+uBAT7T/Q=";   // main event hub key 
const char* KEY_NAME = "RootManageSharedAccessKey";                 //  key name
const char* HOST = "rishieventhub2.servicebus.windows.net";         //  event hub name
const char* END_POINT = "/rishidata/messages";                      // name of eventhub created inside event hub
// END: Azure Evet Hub settings

// START: WiFi settings
const char* SSID = "Nokia";
const char* PASSWORD = "rishikesh";
// END: WiFi settings
String request;
String data;
String fullSas;
 WiFiClientSecure client;
void setup() {
  Serial.begin(115200);
  Serial.println();
  Serial.println();

  // START: Naive URL Encode
  String url = "https://" + (String)HOST + (String)END_POINT;
  url.replace(":", "%3A");
  url.replace("/", "%2F");
  Serial.println(url);
  // END: Naive URL Encode

  // START: Create SAS
  // https://azure.microsoft.com/en-us/documentation/articles/service-bus-sas-overview/
  // Where to get secods since the epoch: local service, SNTP, RTC
  int expire = 1711104241;
  String stringToSign = url + "\n" + expire;

  // START: Create signature
  Sha256.initHmac((const uint8_t*)KEY, 44);
  Sha256.print(stringToSign);
  char* sign = (char*) Sha256.resultHmac();
  int signLen = 32;
  // END: Create signature

  // START: Get base64 of signature
  int encodedSignLen = base64_enc_len(signLen);
  char encodedSign[encodedSignLen];
  base64_encode(encodedSign, sign, signLen); 
  String encodedSas = (String) encodedSign;
  // Naive URL encode
  encodedSas.replace("=", "%3D");
  Serial.println(encodedSas);
  // END: Get base64 of signature

  // SharedAccessSignature
   fullSas = "sr=" + url + "&sig="+ encodedSas + "&se=" + expire +"&skn=" + KEY_NAME;
  // END: create SAS

  // START: Wifi connection
  Serial.print("connecting to ");
  Serial.println(SSID);

  WiFi.begin(SSID, PASSWORD);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  // END: Wifi connection

}
int temp=15;
void loop() {
   WiFiClientSecure client;
  if (!client.connect(HOST, 443)) {
    Serial.println("connection failed");
    return;
  }

  //data= "[{'Temperature':25.25 , 'Deviceid':'esp3'} , {'Temperature':30.30 , 'Deviceid':'esp3'}]";  // for batch events  
   data = "{'Temperature':25.25 , 'Deviceid':'esp3'}"; // for single events 
   request = String("POST ")+"https://rishieventhub2.servicebus.windows.net" + END_POINT + "?timeout=60&api-version=2014-01" + " HTTP/1.1\r\n" +
               "Host: " + HOST + "\r\n" +
               "Authorization: SharedAccessSignature " + fullSas + "\r\n" +                
               "Content-Type: application/atom+xml;type=entry;charset=utf-8\r\n" + 
               "Content-Length: " + data.length() + "\r\n\r\n" +
               data;
    Serial.println(request);
    client.print(request);

 delay(100);

The code for sending single events works and i am able to store the values in table storage and i can see using azure table storage. here's the code which i am trying to send batch events

#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <String.h>
#include "sha256.h"
#include "Base64.h"

// START: Azure Evet Hub settings
const char* KEY = "dhGE6MbbRLe6IPZs6dOHd3byQlEJ8YzqnW+uBAT7T/Q=";   // main event hub key 
const char* KEY_NAME = "RootManageSharedAccessKey";                 //  key name
const char* HOST = "rishieventhub2.servicebus.windows.net";         //  event hub name
const char* END_POINT = "/rishidata/messages";                      // name of eventhub created inside event hub
// END: Azure Evet Hub settings

// START: WiFi settings
const char* SSID = "Nokia";
const char* PASSWORD = "rishikesh";
// END: WiFi settings
String request;
String data;
String fullSas;
 WiFiClientSecure client;
void setup() {
  Serial.begin(115200);
  Serial.println();
  Serial.println();

  // START: Naive URL Encode
  String url = "https://" + (String)HOST + (String)END_POINT;
  url.replace(":", "%3A");
  url.replace("/", "%2F");
  Serial.println(url);
  // END: Naive URL Encode

  // START: Create SAS
  // https://azure.microsoft.com/en-us/documentation/articles/service-bus-sas-overview/
  // Where to get secods since the epoch: local service, SNTP, RTC
  int expire = 1711104241;
  String stringToSign = url + "\n" + expire;

  // START: Create signature
  Sha256.initHmac((const uint8_t*)KEY, 44);
  Sha256.print(stringToSign);
  char* sign = (char*) Sha256.resultHmac();
  int signLen = 32;
  // END: Create signature

  // START: Get base64 of signature
  int encodedSignLen = base64_enc_len(signLen);
  char encodedSign[encodedSignLen];
  base64_encode(encodedSign, sign, signLen); 
  String encodedSas = (String) encodedSign;
  // Naive URL encode
  encodedSas.replace("=", "%3D");
  Serial.println(encodedSas);
  // END: Get base64 of signature

  // SharedAccessSignature
   fullSas = "sr=" + url + "&sig="+ encodedSas + "&se=" + expire +"&skn=" + KEY_NAME;
  // END: create SAS

  // START: Wifi connection
  Serial.print("connecting to ");
  Serial.println(SSID);

  WiFi.begin(SSID, PASSWORD);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  // END: Wifi connection

}
int temp=15;
void loop() {
   WiFiClientSecure client;
  if (!client.connect(HOST, 443)) {
    Serial.println("connection failed");
    return;
  }

   data= "[{'Temperature':25.25 , 'Deviceid':'esp3'} , {'Temperature':30.30 , 'Deviceid':'esp3'}]";  // for batch events  
  // data = "{'Temperature':25.25 , 'Deviceid':'esp3'}"; // for single events 
   request = String("POST ")+"https://rishieventhub2.servicebus.windows.net" + END_POINT + "?timeout=60&api-version=2014-01" + " HTTP/1.1\r\n" +
               "Host: " + HOST + "\r\n" +
               "Authorization: SharedAccessSignature " + fullSas + "\r\n" +                
               "Content-Type: application/vnd.microsoft.servicebus.json" +"\r\n" + 
               "Content-Length: " + data.length() + "\r\n\r\n" +
               data;
    Serial.println(request);
    client.print(request);

 delay(100);

}

Solution

  • The above code works for sending batch events. one thing to change is that in the stream analytic we need different key for partition key and row key for output(table storage). where as for sending single events the partition and row key can be same.