EKL HTTPClient
In previous posts I have shown how to create REST end points in AWS and AZURE, but how can we now use that data and connect it into CATIA. Using the Knowledgeware licenses you can create Actions, Reactions and Rules my preference is to break my code up into Actions and then call that action from a higher level object like a Rule or Reaction.
Once you have tested your REST end point in Postman or another end point testing application (I preferer Postman), you should have the end point URL and hopefully the API key (Your end point should be protected).
In CATIA we can now create an Action, first we will create variables for the URI and HTTPClient and initialize both of those, the URI with the End Point URL, and then constructing the HTTPClient with the default constructor.
Notice I’m also adding a request header for the REST API key, “x-fucntions-key” is specific to Azure other providers may use differing names for the keypair.
// Defines URI Let ioUri ( String ) ioUri = "https://mjeeves-catiawidgets-function.azurewebsites.net/api/v1/DoSomething" // Creates an HTTP client Let ioClient ( HTTPClient ) ioClient = CreateHTTPClient() ioClient->AddRequestHeaders("x-functions-key: BlahBlahBlahBlahBlahBlahBlahBlahBlahBlahBlah==")
Next, we need to cerate a Buffer for the raw reply, and a Data Tree Node for the JSON or XML structure, which is built from the buffered data. Then we can use the verb GET on the HTTPClient object to request the data from the end point. Based on the return code, hopefully Zero we can then do something.
// Defines output buffer Let ioBuffer ( string ) // Defines output DataTreeNode Let ioDataTreeNode ( DataTreeNode ) ioBuffer = ioClient.Get(ioUri, ioDataTreeNode) if (ioClient.ReturnCode == 0) { Notify("#","Success") } else { Notify("Request return code is #", ioClient.ReturnCode) }
For now lets assume that the end point just returns a List of values, we can handle this very simply. First remove the leading and trailing curly brackets, and then split the string by a comma into a list. We can then apply this list as the authorized values of a parameter essentially creating a multi-valued parameter.
Let ioList ( List ) ioBuffer = ioBuffer->Extract(1,ioBuffer->Length()-2) ioList = SplitString( ioBuffer , ",", False) String.1.AuthorizedValues = ioList
If we have something a little more complex then we can use the DataTreeNode object which is a DataTreeNodes of DataTreeNodes. The DataTreenode object has methods .Real, .String, .Integer. If the DataTreeNode is a value key pair within the JSON structure. For Example if the returned JSON is an object which is essentially a list of Key, Value pairs.
You can see in this case i have to cast each child to a DataTreeNode, so if one of the children is an object we can then get its children and then apply the same pattern.
Let ioJSOnChildren ( List ) ioJSOnChildren = ioDataTreeNode.Children String.1 = ((ioJSOnChildren[1]):DataTreeNode).String Real.1 = ((ioJSOnChildren[2]):DataTreeNode).Real Integer.1 = ((ioJSOnChildren[3]):DataTreeNode).Integer Length.1 = (((ioJSOnChildren[4]):DataTreeNode).Real)*1mm Angle.1 = (((ioJSOnChildren[5]):DataTreeNode).Real)*1deg Mass.1 = (((ioJSOnChildren[6]):DataTreeNode).Real)*1Kg Let ioSubTree ( DataTreeNode ) ioSubTree = (ioJSOnChildren[7]):DataTreeNode Let ioSubTreeList ( List ) ioSubTreeList = ioSubTree.Children String.1 = ((ioSubTreeList[1]):DataTreeNode).String Real.1 = ((ioSubTreeList[2]):DataTreeNode).Real Integer.1 = ((ioSubTreeList[3]):DataTreeNode).Integer Length.1 = (((ioSubTreeList[4]):DataTreeNode).Real)*1mm Angle.1 = (((ioSubTreeList[5]):DataTreeNode).Real)*1deg Mass.1 = (((ioSubTreeList[6]):DataTreeNode).Real)*1Kg
We could easily write a recursive script by checking if each DataTreeNode has Children and if it does then pass the List back into the Action, so we can recurse down the structure. Additionally Find, and Query also works. I will add additional details shortly.
Let QueryDataTreeNode ( DataTreeNode ) QueryDataTreeNode = (ioJSOnChildren->Query("DataTreeNode", "x.Name==\"JSONKEY\""))[1] Notify("#", QueryDataTreeNode.String)