Exposing Azure Service Bus through APIM, generating a SAS Token
On one of my recent projects, a client
application was required to place a message onto an Azure Service Bus by using
a HTTP endpoint rather than using the Service Bus SDK and with the following
constraints.
·
The client is unable to generate the Service
Bus SAS token.
·
Service Bus Session Id needs to be set to the
customer number found in the message to ensure ordered delivery by the
consumer.
·
Custom HTTP Request Headers may be used.
I decided upon a solution that uses Azure APIM
to expose the Service Bus endpoint.
1.
The first step of this solution is to
create an Azure Service Bus with a queue called ‘apimqueue’.
Please refer below screen shot.
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpfXp2pjz8D8rHxiuD_HaJFrfWOxwG7UGcTyV4A_TRL4kqVMPHdvRgS9O0r6abNlgc6Gsj_Ff66N9Dejqny5igbMebMttg83y5chRuOuw63aCsIRwcVJXI2q4kYouc2n3rIxk-uaFp7C0/w583-h159/image.png)
2. Next click on created queue and navigate
Shared access policy and added ‘apimqueuesend’
which has only Send claims.
3. Click on created shared access policies and copy
primary key for further use.
4. Next is to create an API using the ‘Blank API’
template similar to what I have done below. Note the ‘Web service URL’ value is
the base address of the Service Bus topic URL.
5. Enter the Name and give web service URL of
your service bus and click on create.
6.
Next Add operation based on your request like
Post, Get Methods.
Refer below screen after crated operation.
7.
Next step to added polices in added operation.
<policies>
<inbound>
<base />
<cache-lookup-value key="apimqueuesend" variable-name="apimqueuesend" />
<choose>
<when condition="@(context.Variables.GetValueOrDefault<string>("apimqueuesend") == null)">
<cache-store-value key="crmsbsas" value="@{
string resourceUri = "https://dwproject.servicebus.windows.net/apimqueue";
string keyName = "apimqueuesend";
string key = "saskey";
TimeSpan sinceEpoch =
DateTime.UtcNow - new DateTime(1970, 1, 1);
var expiry =
Convert.ToString((int)sinceEpoch.TotalSeconds + 120);
string stringToSign =
System.Uri.EscapeDataString(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("SharedAccessSignature
sr={0}&sig={1}&se={2}&skn={3}",
System.Uri.EscapeDataString(resourceUri),
System.Uri.EscapeDataString(signature), expiry, keyName);
return sasToken;
}" duration="10" />
<cache-lookup-value key="apimqueuesend" variable-name="apimqueuesend" />
</when>
</choose>
<set-backend-service base-url="https://dwproject.servicebus.windows.net" />
<rewrite-uri template="apimqueue/messages" />
<set-header name="Content-Type" exists-action="override">
<value>vnd.microsoft.servicebus.yml</value>
</set-header>
<set-header name="Authorization" exists-action="override">
<value>{{apimqueuesend}}</value>
</set-header>
<set-header name="BrokerProperties" exists-action="override">
<value>@{
var json = new JObject();
json.Add("MessageId", context.RequestId);
return
json.ToString(Newtonsoft.Json.Formatting.None);
}</value>
</set-header>
<set-body>@{
JObject json =
context.Request.Body.As<JObject>(preserveContent: true);
return JsonConvert.SerializeObject(json);
}</set-body>
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
<return-response>
<set-status code="200" reason="OK" />
</return-response>
</on-error>
</policies>
10.
Finally Navigate to our queue and check whether
message have received.
Reference
Link:
https://www.serverlessnotes.com/docs/expose-service-bus-queue-through-api-management
Comments
Post a Comment