question

CasperRubaek avatar image
0 Votes"
CasperRubaek asked ·

How to route traffic to servicebus service via api management and also retain session information for return call

I would like to get help in routing traffic to servicebus through api management.

I am able to send a message to a queue on servicebus through its REST API endpoint: POST https://<mynamespace>.servicebus.windows.net/personqueue/messages, but when I try to route traffic from an API endpoint for example: POST https://<apiname>.azure-api.net/servicebus/personqueue/messages, I am unable to do so.

I have tried setting this up accordingly to this article, but that does not work:
https://www.serverlessnotes.com/docs/expose-service-bus-queue-through-api-management

Can you walk me through the steps required to accomplish this?


In addition when I have processed from the queue I need to send back a REST API response from one of my services behind the servicebus and I am not sure how to get the response call associated with the existing client session.

Can you walk me through this as well?

Here is the topology and the topic flow I am using

56263-image.png


56333-image.png




Please ask me any questions if you are unsure what the question is about :)

azure-functionsazure-api-managementazure-service-bus
image.png (54.3 KiB)
image.png (113.1 KiB)
· 2
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

If you have any feedback, please share it :)

0 Votes 0 ·

I have figured out the solution for reading a service bus queue in order to send the reply message back to the user, however exposing servicebus though API management still does not work.

0 Votes 0 ·
ChaitanyaNaykodiMSFT-9638 avatar image
0 Votes"
ChaitanyaNaykodiMSFT-9638 answered ·

Hello @CasperR-1809, my sincere apologies for the delay. To expose Service Bus through API management you can follow this Microsoft Build Event demo (skip to 40:54) . The policy snippet used here is as bellow.

 <policies>
  <inbound>
  <base />
  <set-header name="Content-Type" exists-action="override">
  <value>vnd.microsoft.servicebus.yml</value>
  </set-header>
  <set-header name="Authorization" exists-action="override">
  <value>{
                 {orders-queue-key}}</value>
  </set-header>
  <set-header name="BrokerProperties" exists-action="override">
  <value>@{
                     var json = new JObject();
                     json.Add("MessageId", context.RequestId);
                     json.Add("Label", "New-Order");
                     return json.ToString(Newtonsoft.Json.Formatting.None);                    
  }</value>
  </set-header>
  <set-backend-service base-url="{
                 {orders-sb-namespace}}" />
  <rewrite-uri template="{
                 {orders-queue}}" />
  </inbound>
  <backend>
  <base />
  </backend>
  <outbound>
  <base />
  <choose>
  <when condition="@(context.Response.StatusCode == 201)">
  <set-header name="Content-Type" exists-action="override">
  <value>application/json</value>
  </set-header>
  <set-body>@{
                         var json = new JObject() {
                 {"Order", context.RequestId}} ;
                         return json.ToString(Newtonsoft.Json.Formatting.None);     
  }</set-body>
  </when>
  </choose>
  </outbound>
  <on-error>
  <base />
  </on-error>
 </policies>


You can follow this documentation for adding named values in API management. Please let me know if there are any additional concerns.


· 3 ·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Thank you for the provided example.

Is it also possible to either send a servicebus message back to API management or a seperate Rest API request for which it can fetch the data and send it back to the original Rest API client that requested a screenshot?

If this is not possible with API management I would need to implement this with a seperate application that would work as an API management gateway and would listen for a reply message on a specific session. However I want to use API management instead so is this possible for scenarios where the client expects a reply? As depicted on my diagrams.

0 Votes 0 ·

I am still not able to make it work. Always I am getting response like below but the message is not sent to the queue. Am I missing something? Please help.

HTTP/1.1 200 OK

content-length: 0
date: Wed, 03 Feb 2021 14:26:52 GMT
ocp-apim-trace-location: https://apimstmdwdvjnoanqrdeslgn.blob.core.windows.net/apiinspectorcontainer/vtsgUbjZYUr93i9Qw2-32?sv=2019-07-07&sr=b&sig=OC%2Bl0akakZbsGFRL1pekJYjMysqFLd%2BDniYgHIVwszk%3D&se=2021-02-04T14%3A26%3A53Z&sp=r&traceId=e1168633d204491c86e10effc16bf2f5
vary: Origin

0 Votes 0 ·
CasperRubaek avatar image CasperRubaek ArnabBhowmick-9385 ·

You have exposed the SAS connection string, you should hide the ?sv= ... part of the string, since this is the connection string.

Regarding your issue. You probably created/modified the queue it self like this:
https://docs.microsoft.com/en-us/rest/api/servicebus/stable/queues/createorupdate

What you need to be doing is creating the message: https://docs.microsoft.com/en-us/rest/api/servicebus/send-message-to-queue
Response code for message creation is : HTTP/1.1 201 Created



0 Votes 0 ·
ChaitanyaNaykodiMSFT-9638 avatar image
0 Votes"
ChaitanyaNaykodiMSFT-9638 answered ·

(Posting this as an answer due to character limits in Comments section).
Hello @CasperR-1809, Based on my understanding of the architecture given. The requirement is -> Upon Single request from the client, the following operations should take place within Azure API Management.

  1. Add a message to Service Bus Topic 1.

  2. This message added above will trigger a Function App which will generate some data and add it to Service Bus Topic 2.

  3. Perform a Peek-Lock Message (Non-Destructive Read) OR Receive and Delete Message (Destructive Read) to receive the message from Service Bus Topic 2.

This message(content) from Service Bus Topic 2 should be sent back to same Client. Please correct me if my understanding is wrong.

Based on my understanding of the architecture, I do not think this is possible just using API Management, I think you might have to use a Function App before your Azure Service Bus to maintain the same client session.
If it helps I could think of below mentioned APIM policy which can do multiple calls in the backend.

 <policies>
  <inbound>
         <!-- Sending a message to Azure Service Bus -->
  <send-request ignore-error="true" timeout="30" mode="new" response-variable-name="responseState">
  <set-url>http{s}://{serviceNamespace}.servicebus.windows.net/{queuePath&#124;topicPath}/messages</set-url>
  <set-method>POST</set-method>
  <set-header name="Content-Type" exists-action="override">
  <value>vnd.microsoft.servicebus.yml</value>
  </set-header>
  <set-header name="Authorization" exists-action="override">
  <value>{<!-- -->{orders-queue-key}}</value>
  </set-header>
  <set-header name="BrokerProperties" exists-action="override">
  <value>@{
                                 var json = new JObject();
                                 json.Add("MessageId", context.RequestId);
                                 json.Add("Label", "New-Order22");
                                 return json.ToString(Newtonsoft.Json.Formatting.None);                    
             }</value>
  </set-header>
  </send-request>
  <choose>
  <when condition="@(((IResponse)context.Variables["responseState"]).StatusCode != 201)">
  <return-response>
  <set-status code="401" reason="ASB POST message failed" />
  </return-response>
  </when>
  </choose>
         <!-- Receiving a message from Azure Service Bus -->
  <set-method>POST</set-method>
  <set-header name="Content-Type" exists-action="override">
  <value>vnd.microsoft.servicebus.yml</value>
  </set-header>
  <set-header name="Authorization" exists-action="override">
  <value>{<!-- -->{orders-queue-key}}</value>
  </set-header>
  <set-backend-service base-url="http{s}://{serviceNamespace}.servicebus.windows.net/{topicPath}/subscriptions/{subscriptionName}/messages/head" />
  <rewrite-uri template="\" />
  <base />
  </inbound>
  <backend>
  <base />
  </backend>
  <outbound>
  <base />
  </outbound>
  <on-error>
  <base />
  </on-error>
 </policies>


Here are some some limitation about "timeout" mentioned in the policy above which should be taken under considertaion.

Also based on my understanding, can you please let me know how you are planning to handle concurrency in your architecture? (Multiple Clients performing API request concurrently).

Please let me know if there are any concerns, I will be glad to continue with our discussion. Thank you!


· 1 ·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Your understanding of the question is correct.

I also came to the conclusion that API management does not support waiting for message in servicebus queue or topic and hence I have implemented an azure function app to act as a proxy to do the handling of servicebus messages and the API management calls this function app, as you suggested.

Concurrency I have not tested yet, so I cant answer this.

If you came to another conclusion or if you come to knowledge of any alternative solution, please contact me again.

Also is it correct that sessions (for reply message) does not work with topics?

0 Votes 0 ·
GuilhermeMarianoMunis-0480 avatar image
0 Votes"
GuilhermeMarianoMunis-0480 answered ·

Hello @CasperR-1809 , how are you?
I am new to Azure development.
I got to this topic because I have a task.
I need to send a payload received from a webhook to two queues of the type servicebusqueuetrigger.
Can you help me with this?

· 1 ·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hi.

I am good thanks, how about you?

To answer your question.
You can either send the webhook call to Azure function App, azure API Management or azure logic app and then add the payload to a queue from there.

I would recommend to use API management and send the traffic to function app and have the function app add the payload to the queue.

You are welcome to contact me directly on my LinkedIn profile if you have any other questions or if you would like to network: https://www.linkedin.com/in/casper-rub%C3%A6k/

Here is a diagram of how this works:

80284-image.png


1 Vote 1 ·
image.png (46.7 KiB)