DataPower

DataPower

Join this online group to communicate across IBM product users and experts by sharing advice and best practices with peers and staying up to date regarding product enhancements.

 View Only
  • 1.  How do I extract the JSON array using for each in Gateway script ?

    Posted Tue September 29, 2020 12:48 PM

    Hi ,

    I have below request payload , and I want to extract the empId from each list and after that , need to make a side call with each empId thru the loop ?

    Could you please share how to achieve this in Gatewayscript ?

    Request Payload

    {

    "FinalEmpList": {

    "shiftsLst": {

    "empID": [

    "1111",

    "2222"

    ]

    },

    "unAssignedLst": {

    "empID": [

    "55555",

    "66666",

    "77777"

    ]

    },

    "supervisorLst": {

    "empID": [

    "12345",

    "12345",

    "12345"

    ]

    }

    }

    }

    JS : Need to pass the each empId from above json payload to the below url and need to collect the response for each empId call.

    var uri = url + 'test/' +empID;

    Could you please help me in this.

    Thank you

    SK



    #DataPower
    #Support
    #SupportMigration


  • 2.  RE: How do I extract the JSON array using for each in Gateway script ?

    Posted Sat October 03, 2020 02:16 PM

    Hi,

    In the GatewayScript, as you know the urlopen is async, we can't rely on the timing of the callback function to process the response. However I strongly feel this can be achieved quite easily using the Transform action which is Synchronous by default and easy to aggregate the response from the sub service calls. If you are ok to consider XSLT I can post some details here.

    Hope that helps

    Regards,

    Vijay



    #DataPower
    #Support
    #SupportMigration


  • 3.  RE: How do I extract the JSON array using for each in Gateway script ?

    Posted Tue October 06, 2020 03:44 PM

    For the solutioning purpose I created one XML Firewall with three matching rules LoadEmployees (this is the main service), GetEmployee (is being called to get the details of each employee), JSON2XML (being called to convert JSON to XML as GetEmployee service returns JSON).

    Here is the XSLT that was used in LoadEmployees to call GetEmployee for each occurrence of the empId and then aggregate the response

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:dp="http://www.datapower.com/extensions" xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx" extension-element-prefixes="dp"> <xsl:template match="/"> <dp:set-local-variable name="'isBeginning'" value="'Y'" /> <xsl:variable name="port" select="substring-after(dp:variable('var://service/local-service-address'),':')"/> <xsl:for-each select="//json:array[='empID']"> <xsl:for-each select="json:string"> <xsl:variable name="getEmpResponse"> <dp:url-open target="{concat('http://localhost:',$port,'/GetEmployee?id=',.)}" timeout="100" response="responsecode-binary" http-method="get"/> </xsl:variable> <xsl:variable name="JSONContent" select="dp:decode(dp:binary-encode($getEmpResponse/result/binary/node()),'base-64')"/> <xsl:variable name="getEmpXMLResponse"> <dp:url-open target="{concat('http://localhost:',$port,'/JSON2X')}" timeout="100" http-method="post"> <xsl:value-of select="$JSONContent"/> </dp:url-open> </xsl:variable> <xsl:variable name="empName" select="$getEmpXMLResponse//json:string[='Name']"/> <xsl:choose> <xsl:when test="dp:local-variable('isBeginning')= 'Y'"> <dp:set-local-variable name="'isBeginning'" value="'N'" /> <dp:set-variable name="'var://context/scratch/aggResp'" value="concat('{&quot;Employees&quot;:[&quot;', $empName, '&quot;')"/> </xsl:when> <xsl:otherwise> <dp:set-variable name="'var://context/scratch/aggResp'" value="concat(dp:variable('var://context/scratch/aggResp'), ',', '&quot;', $empName, '&quot;')"/> </xsl:otherwise> </xsl:choose> </xsl:for-each> </xsl:for-each> <xsl:copy-of select="concat(dp:variable('var://context/scratch/aggResp'), ']}')"/> </xsl:template> </xsl:stylesheet>

    Request



    #DataPower
    #Support
    #SupportMigration


  • 4.  RE: How do I extract the JSON array using for each in Gateway script ?

    Posted Tue October 06, 2020 04:07 PM

    Request:

    {

    "FinalEmpList": {

    "shiftsLst": {"empID": ["1","2"]},

    "unAssignedLst": {"empID": ["3","4","5"]},

    "supervisorLst": {"empID": ["6","7","8"]}

    }

    }

    Response:

    {

      "Employees":[

       "Employee One",

       "Employee Two",

       "Employee Three",

       "Employee Four",

       "Employee Five",

       "Employee Six",

       "Employee Seven",

       "Employee Eight"

      ]

    }



    #DataPower
    #Support
    #SupportMigration


  • 5.  RE: How do I extract the JSON array using for each in Gateway script ?

    Posted Wed October 07, 2020 05:08 AM

    Hi Vijay,


    Thanks a lot for the quick response.


    But my requirement is I have to make multiple URL calls based on the success responses.Each side call is dependent on previous call and for every call with multiple empid's.

    If one of the empId gets fail, we have to throw error with corresponding empId in the logs, continue with next empid.

    Here is the sample code which I am expecting and in this I have GET,PATCH,POST calls.

    But in xslt we can't make the PATCH call using url-open and all are json messages.


    var url1resp= urlvalues+/+test1


    if(url1resp==200) {

    var Response = JSON.parse(responseData);

    response=url1resp.statuscode;

    var UserIDs = JSON.parse(responseData).userID;

    ctx.setVariable("UserIDsvalue", UserIDs);

    var url2= urlvalues+/+test2;

    if(url2==200){

      // If this call success

      var url3= urlvalues+/+test3;

      if(url3==200){

    loger.error("url3 call fail");

      }

      

    } else {

    loger.error("url2 call fail");

    }

    }else { 

    loger.error("url call fail");

    }



    Thank you

    SK




    #DataPower
    #Support
    #SupportMigration


  • 6.  RE: How do I extract the JSON array using for each in Gateway script ?

    Posted Wed October 07, 2020 06:15 AM

    Hi SK,

    If DataPower supports the HTTP method PATCH, please refer to https://www.ibm.com/support/knowledgecenter/SS9H2Y_7.7.0/com.ibm.dp.doc/urlopen_js.html


    The url-open in the above XSL is called for each empId, after making the first side call using <dp:url-open/> you can check whether the side call has returned HTTP 200 or not by using the XPATH as below. For failures log an error and for success you call another rule on the same service (JSON2XML) to get it converted to XML (as shown in my XSLT piece of code)

    <xsl:message dp:priority="info">

    Side call Response Code: <xsl:value-of select="$getEmpResponse/result/responsecode"/>

    </xsl:message>


    As you know the GatewayScript (Node.js) executes callbacks in asynchronous manner, there is no guaranty on the sequence


    Also a note of caution, it appears there are multiple side calls, which might potentially hold up the DataPower transaction for much longer duration which may be an antipattern from DataPower usage/performance perspective.


    Hope that helps.


    Regards,

    Vijay




    #DataPower
    #Support
    #SupportMigration


  • 7.  RE: How do I extract the JSON array using for each in Gateway script ?

    Posted Wed October 14, 2020 09:03 AM

    Hi,


    If you want to use GatewayScript you have to use Promise. This has been discussed in a couple of threads on this site, here is one example: https://www.ibm.com/mysupport/s/question/0D50z00006AAykL/gatewayscript-es6-asyncawait-and-urlopen?


    That said, I have to agree with Vijay. I don't recommend making a lot of url-open calls from one GW script/XSLT transform.


    --Hermanni



    #DataPower
    #Support
    #SupportMigration