Thursday, October 24, 2019

The template language expression 'xxx' cannot be evaluated because property 'xxx' doesn't exist. Property selection is not supported on content of type 'application/xml'

I tried to use the orderID node's value in the subject of the send email action from the triggerBody(),the message to trigger logic app is as below
<purchaseOrder>
    <orderID>PO0029</orderID>
    <orderDate>2019-10-20</orderDate>
    <description>Discount applied on the Order</description>
    <shipTo>
        <name>Mike Taylor</name>
        <street>MG Road</street>
        <city>Pune</city>
        <state>MH</state>
        <pin>411001</pin>
        <country>India</country>
    </shipTo>
    <billTo>
        <name>Mike Taylor</name>
        <street>MG Road</street>
        <city>Pune</city>
        <state>MH</state>
        <pin>411001</pin>
        <country>India</country>     
        <emailID>maheshkumar.tiwari@emtecinc.com</emailID>
    </billTo>
</purchaseOrder>

However I was encountered with an error
property doesn't exist


InvalidTemplate. Unable to process template language expressions in action 'Send_email' inputs at line '1' and column '1607': 'The template language expression 'triggerBody().purchaseOrder.orderID' cannot be evaluated because property 'purchaseOrder' doesn't exist. Property selection is not supported on content of type 'application/xml'. Please see https://aka.ms/logicexpressions for usage details.'.


Why it happened




It is clear from error that the Logic App runtime was not able to find purchaseOrder property although the node purchaseOrder is present and another thing it’s pointing out is that property selection is not supported on content of type ‘application/xml’.



And what I was doing is sending xml as message body, content type as ‘application/xml’ and  with 'triggerBody().purchaseOrder.orderID' expression I was asking logic app runtime to fetch the value of orderID under purchaseOrder of triggerBody() with assumption that triggerBody() always returns JSON upon which property selection can be done  – And this assumption was wrong.

triggerBody() is an Azure Workflow built-in FUNCTION, which is used to access the output of trigger(shorthand for trigger().outputs.body) and it’s return type is String. But when you trigger a logic app with content type as ‘application/JSON’ , the logic app runtime implicitly applies the JSON parsing on it and thus the triggerBody() returns JSON document as output.

To get the entire body you just use triggerBody() and with the property suffix added to it , value of that field is returned.

So if I had to pass following JSON message
{
   "orderID": "PO0029",
   "orderDate": "2019-10-20",
   "description": "Discount applied on the Order",
   "shipTo": {
      "name": "Mike Taylor",
      "street": "MG Road",
      "city": "Pune",
      "state": "MH",
      "pin": "411001",
      "country": "India"
   },
   "billTo": {
      "name": "Mike Taylor",
      "street": "MG Road",
      "city": "Pune",
      "state": "MH",
      "pin": "411001",
      "country": "India",
      "emailID": "maheshkumar.tiwari@emtecinc.com"
   }

}

then  triggerBody() would  give me above whole json whereas 'triggerBody().billTo.emailID' would give me value as maheshkumar.tiwari@emtecinc.com

In my case , here the content passed on was XML and therefore no JSON parsing was applied and thus leading to error.


What to do


Logic app is very well equipped to process XML message apart from JSON, however if any expressions(functions) are to be applied on it then it has to be explicitly handled either by casting it to JSON using xml based functions.

Here, I need to get value of  orderID node thus the message has to be casted to JSON and then access the property (property is JSON = node in XML) by following expression
                          json(xml(triggerBody())).purchaseOrder.orderID

In the above expression first triggerBody() (which is string) is casted in XML using xml() function and then casted it  in JSON using json() function. And it worked absolutely fine.

However with understanding that json function is used to convert xml then it can do it directly , thus directly passed on triggerBody to it and it works too.
json(triggerBody()).purchaseOrder.orderID

Note : First triggerBody is converted to JSON by using  json(triggerBody()) and then using dot operator particular property is accessed

Out of curiosity, the another syntax which can be used

json(triggerBody())['purchaseOrder']['orderID']


  



Monday, October 21, 2019

Getting Started with Logic Apps - What happened to the Request?

What happened to the request  or what happened to the order with Order No #xyz or why the particular order is not processed etc etc – I am sure most of us have faced or atleast heard of it and it is most common thing if you are working in Integration domain 😊 .


Offcourse it is well known situation and way to handle it is to identify the key business entities and have them logged in database/monitoring application and run query against it to do the findings. If custom Integration application is build then it should be definitely considered  while designing.

If you are to use someone one else’s product or services  then do check if there is provision for tracking or any out of box monitoring capability available and you can search or query on that tracked data based on the needs.  If you know BizTalk, then you know that there is out of box feature available i.e. Business Activity Monitoring (BAM) .

Now let’s get to the topic of blog post, tracking key business entities in logic app. We do have provision in Logic App wherein the run history of each logic app is maintained and the happenings around each action can be seen (inputs and outputs) – I personally think this is very powerful and helps a lot in troubleshooting the issues but does this solve the above mentioned issue “What happened to the order with Order No #xyz”.

Upto certain extent yes it is helpful, say if you know the time when request was processed then you traversed down to that request processed time or near to it and check few logic apps one by one. Now what if there are hundreds or thousands of requests processed during same time?  - Still it can be done by going through them one by one but the amount of time needed would be too much and the frustration too 😏.

Logic App Product team should really consider this and add a search capability on top of run history.

I am sure down the line in the near future it will be provisioned, but how do we cater the situation now?

For now we can have a function written to log the details to either custom database or application insights and call that function from the logic app and we can search/query the database/application Insight thus saving lot of time and efforts. But note we are to put efforts to write code and efforts in managing (code and database).

So is there a better Way


Yes, there is and it is with the help of Log Analytics service, it is azure monitor log service which collects  Log data (from any Azure resources or any external resource) and  stores it in a Log Analytics workspace (which can be further analyzed by the Log Analytics service through the Log analytics portal).

And provision to integrate Logic App with Log Analytics workspace is through linking them while creating logic app instance and mentioning the properties to track wile developing logic App. In our Logic App, we can add tracked properties onto different actions to track our custom data(e.g, OrderID or MsgID etc)
in diagnostics data.

Let's see how to do it 

1.Create your Log Analytics Workspace


create log Analytics Workspace


 In Azure Portal-->All services -->Monitor and select Log Analytics workspace

configure log analytics workspace

Give the desired Name,select resource group or create new, select subscription and location. Pricing tier - I would suggest to use Free one as the data is retained for 7 days and it's good enough to  get started .  If you need more days of data retention then choose accordingly 

Note: The first 5 GB of data ingested per customer to the Azure Log Analytics service every month is offered free


2.Create your Logic App



Order Processing Logic App


While creating instance of Logic App, switch On the Log Analytics and then select from drop down list the workspace created in above step.

When you do this you are telling Logic App runtime engine that it should now start sending Diagnostics Logs to the selected Log Analytics workspace. Details such as status, execution time , Start/end of each run, Start/end for each action, resubmission status,Run ids, Resource group, resource name  and correlation IDs.

Behind the scene , all the above data is added to AzureDiagnostics Table. 


For the sake of simplicity, a simple logic app is created here which will accept Purchase Order (xml) and will send email to the Bill to contact person

Order Process Logic App Design


Next step is to add Tracked Properties, and to add those select the action (not supported in trigger Action) where you want tracking to happened. 


action settings

You can either edit Logic app in code view and add tracked properties or you can use designer to do by clicking on ellipsis of action and selecting the Settings



Add Tracked Properties in Logic App

Give the name of property being tracked and provide the expression to extract the value, here I want to track only orderID of the purchase Order thus below expression

                  json(xml(triggerBody())).purchaseOrder.orderID

                                          

But you can add more than one property if needed. And below is how it looks in code view


logic App code view



What happens when we add Tracked Properties 

When you add tracked properties, a column trackedProperties_Propertyname_s gets added to AzureDiagnostics table of the workspace you created and at runtime only after the particular action on which tracked properties are added is executed then entry is made in this column. So here if SendEmail action is executed then only orderID will be added else nothing will be seen in that column.



Testing 


To test you can use tool like Postman, ARC etc. I have used ARC 

ARC

And following XML as message body

<purchaseOrder>
    <orderID>PO0025</orderID>
<orderDate>2019-10-20</orderDate>
<description>Discount applied on the Order</description>
    <shipTo>
        <name>Mike Taylor</name>
        <street>MG Road</street>
        <city>Pune</city>
        <state>MH</state>
        <pin>411001</pin>
<country>India</country>
    </shipTo>
    <billTo>
        <name>Mike Taylor</name>
        <street>MG Road</street>
        <city>Pune</city>
        <state>MH</state>
        <pin>411001</pin>
<country>India</country>
<emailID>maheshkumar.tiwari@emtecinc.com</emailID>
    </billTo>
    <items>
        <item>
    <productID>ABC123</productID>
            <productName>ABC product</productName>
            <quantity>1</quantity>
            <price>148.95</price>
    <shipDate>2019-10-21</shipDate>
            <comment>Confirm this is electric</comment>
        </item>
        <item>
    <productID>XYZ123</productID>
            <productName>XYZ product</productName>
            <quantity>1</quantity>
            <price>39.98</price>
            <shipDate>2019-10-22</shipDate>
        </item>
    </items>
</purchaseOrder>

Check the logs

checking Logic App tracked properties in logs

Now to check if all went as desired go to Log Workpace created and click on logs and run query on AzureDiagnostics Table. Say to check about all the orders having orderID having PO002 in it ,following query is fired 

AzureDiagnostics
| where trackedProperties_OrderID__s contains "PO002"


Microsoft is on its way to provide Logic App management solutions on top of AzureDiagnostics.It is still in preview but looks promising 

logic app monitoring solution

Click on configure monitoring solutions and you should see all details presented to you as below

Logic App Monitoring Solution

Apart from grouping the requests, there is feature to apply filters and narrow down the search based on our requirement and another very good feature is the abiltiy to  Resubmit one or more logic apps runs that failed, succeeded, or are still running, like in Biztalk we have ESB Portal.

Conclusion


So if I have to search any Order say having OrderId as PO0031 then I have two options


1. Query the Diagnostics log

In Query tab fire following query

AzureDiagnostics
| where trackedProperties_OrderID__s == "PO0031"

And the result would be as below

result1


2. Search it in Logic App management solution

Click on Logic App runs tile and apply filter on Tracked Properties column

filter on tracked properties

 And the result would be as below

result


Note : It takes time for the tracked data to get synched in Log Analytics. I experienced around 5-10 minutes lag.



If you know any better way then do share !!!




Related Post