Azure Service Bus

  • 4 minutes to read

Azure Service Bus is een online dienst waarmee berichten kunnen uitgewisseld worden tussen applicaties.
Voordelen van gebruik van deze dienst:

  • asynchroon. Er kunnen berichten uitgewisseld worden, zelfs als een applicatie niet actief is.
  • gebruik van de Azure Message Bus kan ook pieken in communicatie opvangen. Frequentie waarop berichten worden opgehaald is onder eigen controle.

Codeunit CFL Azure Service Bus Mgt.

Deze codeunit is een implementatie van de Azure Service Bus REST API.

Meer info vind je ook terug op de officiële documentatie

procedure CFLSetConnection

procedure CFLSetConnection(pServiceBus: Text; pQueue: Text; pAccessPolicyName: Text; pAccessKey: Text)

Het beheer van één of meerdere wachtrijen valt buiten de scope van deze codeunit en is vaak afhankelijk van het individuele project. Het is een best-practice om per type bericht een aparte wachtrij te gebruiken. Via deze functie wordt de connectie met de wachtrij opgezet. Je hoeft dit slechts éénmalig te doen per instantie van de codeunit.

procedure CFLSend

procedure CFLSend(Content: Text)

Functie voor het plaatsen van een bericht op de wachtrij met als parameter de inhoud van het bericht. Deze inhoud is typisch in de vorm van een JSON-bericht met een af te spreken formaat.

procedure CFLSend

procedure CFLSend(Content: Text; UserProperties: Dictionary of [Text, Text])

Functie voor het plaatsen van een bericht op de wachtrij waarbij naast de inhoud ook bijkomende eigenschappen als header bij het bericht worden toegevoegd. Deze bijkomende eigenschappen bevatten in paar een naam en waarde van de eigenschap.

procedure CFLSendBatch

procedure CFLSendBatch(Content: JsonArray)

Omwille van performantie kunnen we meerdere berichten ineens doorsturen. De berichten worden als JsonArray doorgestuurd. BrokerProperties bevatten eigenschappen van het platform, UserProperties bevatten bijkomende eigenschappen. Bv.

[  
  {  
    "Body":"This is the first message",  
    "BrokerProperties":{"Label":"M1","TimeToLiveTimeSpan":"0.00:00:40"}  
  },  
  {  
    "Body":"This is the second message",  
    "BrokerProperties":{"Label":"M2"},  
    "UserProperties":{"Priority":"Low"}  
  },  
  {  
    "Body":"This is the third message",  
    "BrokerProperties":{"Label":"M3"},  
    "UserProperties":{"Priority":"Medium","Customer":"ABC"}  
  }  
]  

procedure CFLReceiveDelete

procedure CFLReceiveDelete() HttpMessage : Record "CFL HttpMessage"

Functie om het eerstvolgende bericht van de wachtrij te lezen. Deze lees-instructie verwijdert ook onmiddelijk het bericht van de wachtrij. Eventuele andere partijen kunnen dit bericht ook niet meer lezen. De inhoud van het bericht wordt geplaatst in een HttpMessage voor verdere verwerking. Zie ook voorbeelden.

Specifieke eigenschappen (BrokerProperties) van het bericht worden ook opgehaald in de Response Headers van het bericht.

procedure CFLReceiveDeleteAll

procedure CFLReceiveDeleteAll() 

Functie om alle berichten van de wachtrij te lezen (en te verwijderen). Deze functie wordt typisch in een taakwachtrijpost geplaatst en periodiek uitgevoerd.

procedure CFLPeekLock

procedure CFLPeekLock() HttpMessage : Record "CFL HttpMessage"

Functie om het eerstvolgende bericht van de wachtrij te lezen. Het bericht blijft wel staan op de wachtrij zodat eventuele andere partijen kunnen dit bericht ook kunnen lezen.

Bij het lezen wordt het bericht even geblokkeerd. Na een aantal pogingen wordt het bericht ook verplaatst naar dead-letter queue. Deze instellingen worden op de servicebus binnen Azure beheerd.

procedure CFLPeekLock

procedure CFLPeekLockAll()

Functie om alle berichten van de wachtrij te lezen (zonder te verwijderen).

procedure CFLUnLock

procedure CFLUnLock(MessageId: Text; LockToken: Text) HttpMessage : Record "CFL HttpMessage"

Functie om bericht na een Peek (met Lock) versneld te ontgrendelen.

procedure CFLRenewLock

procedure CFLRenewLock(MessageId: Text; LockToken: Text) HttpMessage : Record "CFL HttpMessage"

Functie om bericht na een Peek (met Lock) langer te vergrendelen.

procedure CFLDelete

procedure CFLDelete(MessageId: Text; LockToken: Text) HttpMessage : Record "CFL HttpMessage"

Functie om bericht na een Peek (met Lock) te verwijderen.

Voorbeelden

Bericht plaatsen op de wachtrij valkyrie van host bc18bus.servicebus.windows.net met als inhoud van het bericht 'Hello World!'. We gebruiken een Shared Access Policy Dynamics met zijn behorende Key om onszelf te authenticeren (user/password).

procedure SendMessage()
var
    ASB: Codeunit "CFL Azure Service Bus Mgt.";
    Props: Dictionary of [Text, Text];
begin
    ASB.CFLSetConnection('bc18bus', 'valkyrie', 'Dynamics', '******E7ZQcbb3YL9d6WA+N8hIPU6Z72Bn6mSmx6Lp8=');
    ASB.CFLSend(StrSubstNo('Hello %1!', UserId));

Er kunnen bijkomende Custom Properties worden toegevoegd aan de bericht-headers (name en value pair zijn hier bv. de bedrijfsnaam). Deze kunnen door de tegenpartij gebruikt/ontleed worden, naast de inhoud van het bericht zelf.

procedure SendMessageWithHeader()
var
    ASB: Codeunit "CFL Azure Service Bus Mgt.";
    Props: Dictionary of [Text, Text];
begin
    ASB.CFLSetConnection('bc18bus', 'valkyrie', 'Dynamics', '******E7ZQcbb3YL9d6WA+N8hIPU6Z72Bn6mSmx6Lp8=');
    Props.Add('CompanyName', CompanyName());
    ASB.CFLSend(StrSubstNo('Hello %1!', UserId), Props);
end;

Omwille van performantie kunnen we meerdere berichten ineens doorsturen in. Onderstaand voorbeeld stuurt alle openstaande klanten door.

procedure SendOpenCustomers()
var
    ASB: Codeunit "CFL Azure Service Bus Mgt.";
    HttpMessage: record "CFL HttpMessage";
    JsonArray: JsonArray;
    JsonObject, JsonObjectProps : JsonObject;
    Customer: Record Customer;
begin
    Customer.SetFilter("Balance (LCY)", '>0');
    if Customer.FindFirst() then
        repeat
            Customer.CalcFields("Balance (LCY)");
            JsonObject.ReadFrom('{}');
            JsonObjectProps.ReadFrom('{}');
            JsonObjectProps.Add('CompanyName', CompanyName());
            JsonObject.Add('UserProperties', JsonObjectProps);
            JsonObject.Add('Body', StrSubstNo('Customer %1 has Balance Due (LCY) of %2.', Customer.Name, Customer."Balance (LCY)"));
            JsonArray.Add(JsonObject);
        until Customer.Next() = 0;
    ASB.CFLSetConnection('bc18bus', 'valkyrie', 'Dynamics', '******E7ZQcbb3YL9d6WA+N8hIPU6Z72Bn6mSmx6Lp8=');
    ASB.CFLSendBatch(JsonArray);
end;

Code die periodiek wordt uitgevoerd om de ganse wachtrij uit te lezen, bv. via taakwachtrijpost.

codeunit 50000 ReceiveDeleteAll
{
    trigger OnRun()
    var
        ASB: Codeunit "CFL Azure Service Bus Mgt.";  
        HttpMessage : record "CFL HttpMessage"; 
        JsonObject: JsonObject;
        Bus, Queue : Text; 
    begin
        Bus := 'bc18bus';
        Queue := 'valkyrie';
        ASB.CFLSetConnection(Bus, Queue, 'Dynamics', '******E7ZQcbb3YL9d6WA+N8hIPU6Z72Bn6mSmx6Lp8=');
        repeat
            HttpMessage := ASB.CFLReceiveDelete();
            if (HttpMessage."CFL Method" = 'DELETE')
                and (HttpMessage."CFL Uri" = StrSubstNo('https://%1.servicebus.windows.net/%2/messages/head', Bus, Queue))
                and (HttpMessage."CFL Http Status Code" = 200) then begin
                    if JsonObject.ReadFrom(HttpMessage.CFLGetResponse()) then begin
                        //DO STUFF
                    end;
                end;
        until HttpMessage."CFL Http Status Code" <> 200
    end;
}

Voorbeeld om bericht na een Peek te verwijderen.

trigger OnAction()
var
    ASB: Codeunit "CFL Azure Service Bus Mgt.";
    MessageId: Record "CFL HttpMessage Header";
    LockToken: Record "CFL HttpMessage Header";
    HttpHeaderType: Enum "CFL HttpHeaderType";
begin
    ASB.CFLSetConnection('bc18bus', 'valkyrie', 'Dynamics', '******E7ZQcbb3YL9d6WA+N8hIPU6Z72Bn6mSmx6Lp8=');
    MessageId.Get("CFL Entry No.", HttpHeaderType::"CFL Response", 'MessageId');
    LockToken.Get("CFL Entry No.", HttpHeaderType::"CFL Response", 'LockToken');
    ASB.CFLDelete(MessageId."CFL Value", LockToken."CFL Value");
end;