Skip to main content
1-Visitor
August 4, 2015
Question

Create a Thing that accepts XML

  • August 4, 2015
  • 4 replies
  • 8168 views

To work with a third party system I'd like to implement a Thing that allow XML to be POSTed to a service that I define

For example id like the URL to be .../Thingworx/Things/workGateway/Services/workOrder

And to be able to call the service using  the content loader


var request = <request>

    <workorder>

      <WOEXTID>123</WOEXTID>

    </workorder>

</request>;

   

var params = {

    url: '.../Thingworx/Things/workGateway/Services/workOrder' /* STRING */,

  content: request /* XML */

};

var responce = Resources["ContentLoaderFunctions"].PostXML(params);

result = responce..*::status;

Now I could implement this as:


.../Thingworx/Things/workGateway/Services/workOrder?method=POST&value= <request><workorder><WOEXTID>123</WOEXTID></workorder></request>

And this superficially works for the trivial case above if I use the actual XML from the third party system then I get a 400 Bad Request error when creating a URL in chrome or the PostMan REST plugin for chrome.

XML Request2.PNG

If does work however if I use the Thingworks built in test function.  I have tried Linarizing the XML and appling HTML escaping the XML

XML Request.PNG

Does anyone have any suggestions on how the call the method using a non-trivial amount of XML (the actual XML is >6kloc) or how to accept a XML content.

Message was edited by: Graham Allan  Changed 400 Bad Gateway to 400 Bad Request - The correct message

4 replies

1-Visitor
August 4, 2015

Set the Input parameter to String first and see what Thingworx thinks it is receiving.

grahamall1-VisitorAuthor
1-Visitor
August 5, 2015

I'm still getting the same Bad Request (400) error for the non trivial case and the simple case still works provided I remove the internal processing from the method.

With the internal processing intact the code fails as I'm using XMLPath to process the data and I can find a function to parse/convert XML into a string

grahamall1-VisitorAuthor
1-Visitor
August 5, 2015

Here is an anonymised example of the XML that I need to pass as a parameter (with SOAP envelope removed):


<hj:operations xmlns:hj="http://example.com/hjrkOrdersType" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://example.com/hjrkOrdersType EXM-XXX-IN-hj-Core_1.7.xsd ">


  <hj:request type="INSERT">


  <hj:hjrkorder>


  <hj:hjEXTID>123</hj:hjEXTID>


  <hj:MODEL_ID>XXX_WERF</hj:MODEL_ID>


  <hj:SUBJECT>Short description of the hjrk order</hj:SUBJECT>


  <hj:DESCRIPTION>Long description of the hjrk order</hj:DESCRIPTION>


  <hj:DOMAIN>PLANT</hj:DOMAIN>


  <hj:CATEGORY>Custom category</hj:CATEGORY>


  <hj:hjRKORDERTYPE>Custom type</hj:hjRKORDERTYPE>


  <hj:hjRKTYPE>Custom hjrk type</hj:hjRKTYPE>


  <hj:SUBTYPE>Custom hjrk subtype</hj:SUBTYPE>


  <hj:FAILURE>Custom failure code</hj:FAILURE>


  <hj:PRIORITY>Custom priority level</hj:PRIORITY>


  <hj:STATUS>APPR</hj:STATUS>


  <hj:JOBPLAN>Custom job plan code</hj:JOBPLAN>


  <hj:CREATIONDATE>2001-12-31T12:00:00</hj:CREATIONDATE>


  <hj:CREATIONTYPE>USER</hj:CREATIONTYPE>


  <hj:CREATEDBY>qsiraut</hj:CREATEDBY>


  <hj:TARGETSTARTDATE>2001-12-31T12:00:00</hj:TARGETSTARTDATE>


  <hj:TARGETENDDATE>2001-12-31T12:00:00</hj:TARGETENDDATE>


  <hj:ACTSTARTDATE>2001-12-31T12:00:00</hj:ACTSTARTDATE>


  <hj:ACTENDDATE>2001-12-31T12:00:00</hj:ACTENDDATE>


  <hj:LASTUPDATEDTS>2001-12-31T12:00:00</hj:LASTUPDATEDTS>


  <hj:ZONE>Zone identifier (will be filled by MOR)</hj:ZONE>


  <hj:LOCATION>POINT(4.836371863811936 45.76751923066087)</hj:LOCATION>


  <hj:EXThjRKEQUIPMENTID>2333 (WERF ID)</hj:EXThjRKEQUIPMENTID>


  <hj:EXThjRKEQUIPMENTTYPE>wWashout (MOR type)</hj:EXThjRKEQUIPMENTTYPE>


  <hj:UPDATEDBY>qsiraut</hj:UPDATEDBY>


  <hj:LEAD>qsiraut</hj:LEAD>


  <hj:NEThjRK>WATER</hj:NEThjRK>


  <hj:ADDRESS>Address</hj:ADDRESS>


  <hj:PERFORMEDBY>qsiraut</hj:PERFORMEDBY>


  <hj:LOCOWNERID>qsiraut</hj:LOCOWNERID>


  <hj:LOCOWNERDETAILS>Phone, email details</hj:LOCOWNERDETAILS>


  <hj:LOCCONTACTID>qsiraut</hj:LOCCONTACTID>


  <hj:LOCCONTACTDETAILS>Phone, email details</hj:LOCCONTACTDETAILS>


  <hj:REPORT>The result of the hjrk order</hj:REPORT>


  <hj:SRCEVENTLIST>


  <hj:SRCEVENT>


  <hj:SRCEVTCATEGORY>ALERT</hj:SRCEVTCATEGORY>


  <hj:SRCEVTTYPE>BACKFLOW (MOR alert/event type)</hj:SRCEVTTYPE>


  <hj:SRCEVTID>BF001 (WERF ID)</hj:SRCEVTID>


  <hj:SRCEVTDATE>2001-12-31T12:00:00</hj:SRCEVTDATE>


  <hj:SRCEVTCURRVALUE/>


  <hj:SRCEVTORIGVALUE/>


  <hj:SRCEVTCOMMENT/>


  <hj:SOPREFERENCE/>


  </hj:SRCEVENT>


  </hj:SRCEVENTLIST>


  </hj:hjrkorder>


  <hj:hjrkorder>


  <hj:hjEXTID>124</hj:hjEXTID>


  <hj:MODEL_ID>XXX_WERF</hj:MODEL_ID>


  <hj:SUBJECT>Short description of another hjrk order</hj:SUBJECT>


  <hj:DESCRIPTION>Long description of another hjrk order</hj:DESCRIPTION>


  <hj:DOMAIN>CUSTOMER</hj:DOMAIN>


  <hj:CATEGORY>Custom category</hj:CATEGORY>


  <hj:hjRKORDERTYPE>Custom type</hj:hjRKORDERTYPE>


  <hj:hjRKTYPE>Custom hjrk type</hj:hjRKTYPE>


  <hj:SUBTYPE>Custom hjrk subtype</hj:SUBTYPE>


  <hj:FAILURE>Custom failure code</hj:FAILURE>


  <hj:PRIORITY>Custom priority level</hj:PRIORITY>


  <hj:STATUS>APPR</hj:STATUS>


  <hj:JOBPLAN>Custom job plan code</hj:JOBPLAN>


  <hj:CREATIONDATE>2001-12-31T12:00:00</hj:CREATIONDATE>


  <hj:CREATIONTYPE>USER</hj:CREATIONTYPE>


  <hj:CREATEDBY>qsiraut</hj:CREATEDBY>


  <hj:TARGETSTARTDATE>2001-12-31T12:00:00</hj:TARGETSTARTDATE>


  <hj:TARGETENDDATE>2001-12-31T12:00:00</hj:TARGETENDDATE>


  <hj:ACTSTARTDATE>2001-12-31T12:00:00</hj:ACTSTARTDATE>


  <hj:ACTENDDATE>2001-12-31T12:00:00</hj:ACTENDDATE>


  <hj:LASTUPDATEDTS>2001-12-31T12:00:00</hj:LASTUPDATEDTS>


  <hj:ZONE>Zone identifier (will be filled by MOR)</hj:ZONE>


  <hj:LOCATION>POINT(4.836371863811936 45.76751923066087)</hj:LOCATION>


  <hj:EXThjRKEQUIPMENTID>2333 (WERF ID)</hj:EXThjRKEQUIPMENTID>


  <hj:EXThjRKEQUIPMENTTYPE>wWashout (MOR type)</hj:EXThjRKEQUIPMENTTYPE>


  <hj:UPDATEDBY>qsiraut</hj:UPDATEDBY>


  <hj:LEAD>qsiraut</hj:LEAD>


  <hj:NEThjRK>WATER</hj:NEThjRK>


  <hj:ADDRESS>Address</hj:ADDRESS>


  <hj:PERFORMEDBY>qsiraut</hj:PERFORMEDBY>


  <hj:LOCOWNERID>qsiraut</hj:LOCOWNERID>


  <hj:LOCOWNERDETAILS>Phone, email details</hj:LOCOWNERDETAILS>


  <hj:LOCCONTACTID>qsiraut</hj:LOCCONTACTID>


  <hj:LOCCONTACTDETAILS>Phone, email details</hj:LOCCONTACTDETAILS>


  <hj:REPORT>The result of the hjrk order</hj:REPORT>


  <hj:SRCEVENTLIST>


  <hj:SRCEVENT>


  <hj:SRCEVTCATEGORY>READINGTHRESHOLD</hj:SRCEVTCATEGORY>


  <hj:SRCEVTTYPE>FLOW</hj:SRCEVTTYPE>


  <hj:SRCEVTID/>


  <hj:SRCEVTDATE>2001-12-31T12:00:00</hj:SRCEVTDATE>


  <hj:SRCEVTCURRVALUE>34.0</hj:SRCEVTCURRVALUE>


  <hj:SRCEVTORIGVALUE>32.0</hj:SRCEVTORIGVALUE>


  <hj:SRCEVTCOMMENT>Threshold is set to 30.0</hj:SRCEVTCOMMENT>


  <hj:SOPREFERENCE/>


  </hj:SRCEVENT>


  </hj:SRCEVENTLIST>


  </hj:hjrkorder>


  </hj:request>


  <hj:request type="UPDATE">


  <hj:hjrkorder>


  <hj:hjEXTID>125</hj:hjEXTID>


  <hj:MODEL_ID>XXX_WERF</hj:MODEL_ID>


  <hj:SUBJECT>New Short description of the hjrk order</hj:SUBJECT>


  <hj:DESCRIPTION>New Long description of the hjrk order</hj:DESCRIPTION>


  <hj:DOMAIN>PLANT</hj:DOMAIN>


  <hj:CATEGORY>Custom category</hj:CATEGORY>


  <hj:hjRKORDERTYPE>Custom type</hj:hjRKORDERTYPE>


  <hj:hjRKTYPE>Custom hjrk type</hj:hjRKTYPE>


  <hj:SUBTYPE>Custom hjrk subtype</hj:SUBTYPE>


  <hj:FAILURE>Custom failure code</hj:FAILURE>


  <hj:PRIORITY>Custom priority level</hj:PRIORITY>


  <hj:STATUS>APPR</hj:STATUS>


  <hj:JOBPLAN>Custom job plan code</hj:JOBPLAN>


  <hj:CREATIONDATE>2001-12-31T12:00:00</hj:CREATIONDATE>


  <hj:CREATIONTYPE>USER</hj:CREATIONTYPE>


  <hj:CREATEDBY>qsiraut</hj:CREATEDBY>


  <hj:TARGETSTARTDATE>2001-12-31T12:00:00</hj:TARGETSTARTDATE>


  <hj:TARGETENDDATE>2001-12-31T12:00:00</hj:TARGETENDDATE>


  <hj:ACTSTARTDATE>2001-12-31T12:00:00</hj:ACTSTARTDATE>


  <hj:ACTENDDATE>2001-12-31T12:00:00</hj:ACTENDDATE>


  <hj:LASTUPDATEDTS>2001-12-31T12:00:00</hj:LASTUPDATEDTS>


  <hj:ZONE>Zone identifier (will be filled by MOR)</hj:ZONE>


  <hj:LOCATION>POINT(4.836371863811936 45.76751923066087)</hj:LOCATION>


  <hj:EXThjRKEQUIPMENTID>2333 (WERF ID)</hj:EXThjRKEQUIPMENTID>


  <hj:EXThjRKEQUIPMENTTYPE>wWashout (MOR type)</hj:EXThjRKEQUIPMENTTYPE>


  <hj:UPDATEDBY>qsiraut</hj:UPDATEDBY>


  <hj:LEAD>qsiraut</hj:LEAD>


  <hj:NEThjRK>WATER</hj:NEThjRK>


  <hj:ADDRESS>Address</hj:ADDRESS>


  <hj:PERFORMEDBY>qsiraut</hj:PERFORMEDBY>


  <hj:LOCOWNERID>qsiraut</hj:LOCOWNERID>


  <hj:LOCOWNERDETAILS>Phone, email details</hj:LOCOWNERDETAILS>


  <hj:LOCCONTACTID>qsiraut</hj:LOCCONTACTID>


  <hj:LOCCONTACTDETAILS>Phone, email details</hj:LOCCONTACTDETAILS>


  <hj:REPORT>The result of the hjrk order</hj:REPORT>


  <hj:SRCEVENTLIST>


  <hj:SRCEVENT>


  <hj:SRCEVTCATEGORY>ALERT</hj:SRCEVTCATEGORY>


  <hj:SRCEVTTYPE>BACKFLOW (MOR alert/event type)</hj:SRCEVTTYPE>


  <hj:SRCEVTID>BF001 (WERF ID)</hj:SRCEVTID>


  <hj:SRCEVTDATE>2001-12-31T12:00:00</hj:SRCEVTDATE>


  <hj:SRCEVTCURRVALUE/>


  <hj:SRCEVTORIGVALUE/>


  <hj:SRCEVTCOMMENT/>


  <hj:SOPREFERENCE/>


  </hj:SRCEVENT>


  </hj:SRCEVENTLIST>


  </hj:hjrkorder>


  </hj:request>


</hj:operations>


1-Visitor
August 5, 2015

Have you tried your same method with just passing a regular string first? ie try passing in "This is my test string" and seeing if you get the same error? If you do, then maybe you have a permission issue, with the system not having permissions to call your function. You may have to set up a user who can run the function, and possible create an appkey for that user that gets passed in with your request call in order to have the proper permissions. Just a thought.

grahamall1-VisitorAuthor
1-Visitor
August 5, 2015

I have tried all the above bar using a string but as the simple XML works without and the complex form doesn't I don't thing that its an auth problem - It seems to be caused by the use of a namespace e.g. <ab:tag> rather than <tag>

5-Regular Member
August 5, 2015

So the big thing you are missing here is the "postParameter" parameter that you need to specify on the end of the URL. This is how the content will know where it needs to go. For example,

var request = <request>

    <workorder>

      <WOEXTID>123</WOEXTID>

    </workorder>

</request>;


if you are trying to post that var request xml above, you can keep content:request but you will need to modify the url to url:'../Thingworx/Things/workGateway/Services/workOrder?postParameter=parameter_name_in_service'

var params = {

    url: '.../Thingworx/Things/workGateway/Services/workOrder?postParameter=parameter_name_in_service' /* STRING */,

  content: request /* XML */

};

var responce = Resources["ContentLoaderFunctions"].PostXML(params);

result = responce..*::status;


Where it says parameter_name_in_service you will want to change that to the XML parameter name you have defined in that workOrder service.

Hopefully this helps.

grahamall1-VisitorAuthor
1-Visitor
August 7, 2015

Sorry, I was not clear in my original question, I'm using this URL

server/Thingworx/Things/IOWWorkOrderGateway/Services/workOrder?method=post&value=<xml>...  ...</xml>

And it works fine provided that the xml is not to long

What I'd like to do is the equivalent of this

2015-08-07_09-08-21.png

Where the XML is submitted as the body of the request rather than as a parameter as I thing that Thingworx is struggling with the length of the XML I'm using.

5-Regular Member
August 10, 2015

For you to pass the body defined in Postman to your service you need to provide the postParameter=name_of_input_parameter_to_service segment to the URL; this will tell the REST call that you want the body you are providing to be posted to the input parameter of the service you are calling.

What you have in that screen shot is fine, just add that segment I bolded above (where name_of_input_parameter_to_service is your predefined input parameter)

Do you have an input parameter to your service of base type XML? If not you need to add one to accept the XML content.