Using Queues on Azure for message relay

Setting up queues and a messaging relay is a bit more complimicated

Published on Saturday, 21 August 2021

Overview

  1. Create a service bus queue
  2. Create a logic app to respond to queue messages
  3. Create the workflow to pop the message off queue and send an email (parsing json along the way)
  4. Post a message to queue via .Net

Create a service bus name space

  1. In Azure Portal, select All resources and then create a service bus namespace (or use an existing one, if you have it already)
  2. Select an Azure subscription
  3. Select or create an Azure resource group
  4. Pick a unique name
  5. Pick a region for functions api (close to home)
  6. Pick a pricing plan (Basic is good if all you need is queue, Standard is good if you need subscriptions, Premium is too spendy)
  7. Review + Create

Create a service bus queue

  1. In Azure Portal, select All resources and then select the namespace already created
  2. Select an Queues from the context menu
  3. Click + Queue
  4. Pick a unique name
  5. Customize settings (defaults are good)
  6. Review + Create

Create a logic app

  1. In Azure Portal, select All resources and then create a logic app
  2. Only one workflow per logic app apparently
  3. Select an Azure subscription
  4. Select or create an Azure resource group
  5. Pick a type (consumption is good unless you want more control, are using multiple subscriptions or want your own docker container)
  6. Pick a unique name
  7. Pick a region (close to home)
  8. Review + Create
  9. Go to Resource

Configure Workflow

  1. In Azure Portal, select All resources and then select the logic app
  2. Only one workflow per logic app apparently
  3. Select the logic app designer
  4. Select a trigger (When message received in service bus queue)
  5. Pick the subscription, service bus namespace, access key (you may have to look these up if the portal does not provide drop downs like it should)
  6. Pick queue name, queue type (main or dead), polling interval etc.
  7. If parsing JSON, you'll need a Parse JSON operation (don't forget the decodebase64 in order to parse the message: add dynamic content, choose expression and enter: decodebase64(triggerbody()?['ContentData']))
  8. Add schema if parsing JSON ({ propterties: { message: { type: "string" }, subject: {type: "string"}}, type: "object" })
  9. Next operation
  10. Add outlook.com "send email"
  11. Add creds
  12. Configure email
  13. Save

Configure .net

        static public void SendMessagestring subject, string body) {
 
            string queueUrl = "https://servicename.servicebus.windows.net/queuename";
            string token = GetSasToken(queueUrl, "sharedaccesspolicyname", "0jDE9SyjGkpg--replace with actual key--ycFk+8E0SkgWGQ=", TimeSpan.FromDays(1));
            try {
                using (var wc = new WebClient()) {
                    wc.Headers[HttpRequestHeader.Authorization] = token;
                    wc.Headers[HttpRequestHeader.ContentType] = "application/json";
                    wc.UploadString(queueUrl + "/messages", "{ \"subject\": \"" + subject + "\", \"message\": \"" + body.Replace("\\","\\\\") +"\" }");
                }
            } catch (Exception ex) {
                Console.WriteLine(ex.Message);
                Console.WriteLine("failed to send queue message: " + subject + ": " + body);
            }
        }
 
        public static string GetSasToken(string resourceUri, string keyName, string key, TimeSpan ttl) {
 
            var expiry = GetExpiry(ttl);
            string stringToSign = HttpUtility.UrlEncode(resourceUri) + "\n" + expiry;
            HMACSHA256 hmac = new HMACSHA256(Encoding.UTF8.GetBytes(key));
            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(resourceUri), HttpUtility.UrlEncode(signature), expiry, keyName);
 
            return sasToken;
        }
 
        private static string GetExpiry(TimeSpan ttl) {
            TimeSpan expirySinceEpoch = DateTime.UtcNow - new DateTime(1970, 1, 1) + ttl;
            return Convert.ToString((int)expirySinceEpoch.TotalSeconds);
        }

Save, build, deploy and enjoy!!

comments powered by Disqus