Shared Access Signature para conectar con EventHub

En casi todas las soluciones de IoT, Big Data o Business Inteligence se trata con una gran cantidad de datos que hay que recoger de alguna manera antes de procesar, y para ello uno de los servicios más utilizados es Azure Event Hub. Este servicio nos permite encolar gran cantidad de mensajes y poder enviarlos luego a otros servicios que hagan el procesamiento de estos datos  prácticamente en tiempo real, con posibilidad de configurar el escalado de estas colas, un buffer de mensajes basado en tiempo, etc.

Para enviar mensajes a este bus de datos que es EventHub podemos trabajar con dos protocolos:

  • AMQP (Advanced Message Queuing Protocol) un protocolo orientado a mensajes, encolamiento ("queuing") y enrutamiento (tanto punto-a-punto como publicación-subscripción), y cuyas características más descriptivas serían la exactitud y la seguridad.
  • HTTP, teniendo que hacernos cargo de la capa de seguridad nosotros mismos manejando la autorización de las peticiones usando una Shared Access Signature.

Para ello, necesitaremos tener creado nuestro Event Hub, que se organiza bajo un Service Bus que tiene un namespace bajo el que se ubicará nuestro Event Hub. Crearemos a nivel de Service Bus una política que nos permita enviar mensajes a nuestro servicio, y necesitaremos tanto el nombre de la política como el valor de su clave primaria para crear nuestro token SAS.

sas-policy-0

El siguiente código nos muestra cómo crear nuestra Shared Access Signature en C#:

 var _eventHubUri = "https://<<namespace-name>>.servicebus.windows.net/<<event-hub-name>>";
var _policyName = "sb-policy-name";
var _primaryKeyValue = "policy-primary-key-value";

TimeSpan sinceEpoch = DateTime.UtcNow - new DateTime(1970, 1, 1);
var expiry = Convert.ToString((int)sinceEpoch.TotalSeconds + 3600); //EXPIRES in 1h 
string stringToSign = HttpUtility.UrlEncode(_eventHubUri) + "\n" + expiry;
HMACSHA256 hmac = new HMACSHA256(Encoding.UTF8.GetBytes(_primaryKeyValue));

var signature = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));
var sasToken = String.Format(CultureInfo.InvariantCulture, 
"SharedAccessSignature sr={0}&sig={1}&se={2}&skn={3}",
HttpUtility.UrlEncode(_eventHubUri),
HttpUtility.UrlEncode(signature), 
expiry, _policyName);

Para usar este token SAS tendremos que ponerlo dentro de la cabecera de "Authorization" de nuestra petición REST, algo que por ejemplo en una aplicación de Xamarin vamos a necesitar puesto que no tenemos disponibles ciertos mecanismos del SDK de .NET. Por suerte, nuestra comunidad lo tuvo en cuenta y tenemos un cliente que nos ayuda a comunicarnos mediante peticiones HTTP a nuestros Event Hubs. Se trata de Com.Xamtastic.Patterns.Azure.EventHub y podéis encontrarlo en el gestor de paquetes NuGet. Un ejemplo de cómo podríamos enviar un mensaje a un Event Hub usando este componente sería el siguiente:

 private readonly string _sas = "<<sas-token-value>>";
private readonly string _serviceNamespace = "<<service-bus-namespace-name>>";
private readonly string _hubName = "<<event-hub-name>>";
private readonly string _deviceKey = "<<device-id>>"; // Cualquier valor con el que diferenciemos el dispositivo

private EventHubSasClient _sasClient = new EventHubSasClient (_sas, _serviceNamespace, _hubName, "_deviceKey"); 
HttpResponseMessage httpResponseMessage = await _sasClient.SendMessageAsync(JSONmessage);

Un saludo,

Gorka Madariaga – Technical Evangelist – @Gk_8