skip to Main Content

I am trying to use Azure Pipeline to build my API Management infrastructure automatically and have successfully added the API and API Operation but having trouble defining the Operation specific Policy.

I have this policy that I based on a very useful article https://www.serverlessnotes.com/docs/expose-service-bus-queue-through-api-management

<policies>
    <inbound>
        <base />
        <set-variable name="sasToken" value="@{            
            return "bob";
        }" />
        <set-header name="Authorization" exists-action="override">
            <value>@(context.Variables.GetValueOrDefault<string>("sasToken"))</value>
        </set-header>
        <set-header name="Content-type" exists-action="override">
            <value>application/json</value>
        </set-header>
        <set-header name="Ocp-Apim-Subscription-Key" exists-action="delete" />
        <set-header name="BrokerProperties" exists-action="override">
            <value>@{                
                return string.Format("{{"SessionId":"{0}"}}", "bob");
            }</value>
        </set-header>
        <set-backend-service base-url="https://i365intfnapidevtbcoresb.servicebus.windows.net/i365intfnapidevtbcoresbqueue" />
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>

There is actually more code in the value bits, but for illustration I’ve removed them.

However if I put this in a separate file (or even an inline variable) and run the Azure Powershell command

Set-AzApiManagementPolicy -Context $apim_context -ApiId $apiId -OperationId addmessage -PolicyFilePath <path to policy xml file>

Where the $ values are variables I declared previously.

I get the error

Error Details:
        [Code= ValidationError, Message= 'bob' is an unexpected token. Expecting white space. Line 5, position 21., Target=
representation]

Basically, I cant work out how to format the function thats in the value attribute or value elements. The bit starting with @{}.

I can enter the policy via the Azure API Management screen no problem, but cant do it via the Set-AzApiManagementPolicy command.

Any ideas on how to format it.

Thanks.

2

Answers


  1. Chosen as BEST ANSWER

    Solved it in the end, You have to encode some of the characters to make it work. For example @quot; instead of "

    So I have in my Azure Powershell script:

      $policyString = '
                <policies>
                    <inbound>
                        <base />
                        <set-variable name="sasToken" value="@{
                            string resourceUri = &quot;$(azure.servicebusqueueendpoint)&quot;;
                            string keyName = &quot;$(azure.servicebusaccesspolicykey)&quot;;
                            string key = &quot;$(azure.servicebusaccesspolicyvalue)&quot;;
                            TimeSpan sinceEpoch = DateTime.UtcNow - new DateTime(1970, 1, 1);
                            var expiry = Convert.ToString((int)sinceEpoch.TotalSeconds + 120);
                            string stringToSign = System.Uri.EscapeDataString(resourceUri) + &quot;n&quot; + expiry;
                            HMACSHA256 hmac = new HMACSHA256(Encoding.UTF8.GetBytes(key));
                            var signature = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));
                            var sasToken = String.Format(&quot;SharedAccessSignature sr={0}&amp;sig={1}&amp;se={2}&amp;skn={3}&quot;, 
                                            System.Uri.EscapeDataString(resourceUri),
                                            System.Uri.EscapeDataString(signature), expiry, keyName);
                            return sasToken;
                        }" />
                        <set-header name="Authorization" exists-action="override">
                            <value>@((string)context.Variables.GetValueOrDefault("sasToken"))</value>
                        </set-header>
                        <set-header name="Content-type" exists-action="override">
                            <value>application/json</value>
                        </set-header>
                        <set-header name="Ocp-Apim-Subscription-Key" exists-action="delete" />
                        <set-header name="BrokerProperties" exists-action="override">
                            <value>@{
                              return string.Format("{{"SessionId":"{0}"}}", "1");
                            }</value>
                        </set-header>
                        <set-backend-service base-url="$(azure.servicebusqueueendpoint)" />
                    </inbound>
                    <backend>
                        <base />
                    </backend>
                    <outbound>
                        <base />
                    </outbound>
                    <on-error>
                        <base />
                    </on-error>
                </policies>
              '
    
    Set-AzApiManagementPolicy -Context $apim_context -ApiId $apiId -OperationId addmessage -Policy $policyString
    

    and this now seems to do the trick.

    You would probably also need to do the same for c# things like:

    context.Variables.GetValueOrDefault<string> 
    

    would be

    context.Variables.GetValueOrDefault&lt;string&gt;
    

    to make it work otherwise it conflicts with the xml

    Thanks mclayton for pointing me in the right direction.


  2. It will escape it for you if you use the Format parameter.

    Set-AzApiManagementPolicy -Context $apim_context -Format "application/vnd.ms-azure-apim.policy.raw+xml" -ApiId $apiId -OperationId addmessage -Policy $policyString
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search