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.  HTTP requests to backend servers from Gatewayscript

    Posted Tue December 22, 2020 12:04 AM

    Hi All,

    I've been asked to pull together a program that reads in a bunch of really non-standardly formatted data, performs several dozen transformations on it and then places the result on a message queue.

    The reading in and message queue portions is straightforward. The transforms are giving me a lot of grief as I have to do several HTTP queries per request to various back end systems to populate additional data. XSLT isn't at all suited to the message model, so I'm using Gatewayscript.

    Does anyone know a way to do a synchronous request from within Gatewayscript? I've spent a couple of days on this without any luck.

    Thanks,

    Roman



    #DataPower
    #Support
    #SupportMigration


  • 2.  RE: HTTP requests to backend servers from Gatewayscript

    Posted Tue December 22, 2020 09:31 AM

    > Does anyone know a way to do a synchronous request from within Gatewayscript? I've spent a couple of days on this without any luck.

    >

    You can just nest the urlopen calls, that ensures sequential execution. But this gets ugly quickly with more than 3 urlopens.

    The other option is to "await" a "Promise".

    Here is a simple synchronous wait example:

    $ cat sync_wait.js async function wait(ms) { return new Promise(resolve => { setTimeout(resolve, ms); }); } session.input.readAsJSON(async function(error,json){ var t0 = new Date().getTime(); await wait(json); var t1 = new Date().getTime(); session.output.write((t1-t0)+"ms"); }); $



    #DataPower
    #Support
    #SupportMigration


  • 3.  RE: HTTP requests to backend servers from Gatewayscript

    Posted Wed December 23, 2020 07:09 PM

    Thanks - doesn't seem to work for me - I've got the following test script:

    function dlog(s) { console.error('urlopen promise test: ' + s); } const sleep = function ( millis ) { dlog( "sleep waiting for " + millis + " mSec" ) ; return new Promise(resolve => { setTimeout(resolve, millis) } ); } dlog('ENTER'); var urlopen = require('urlopen'); const SUCCESS = "success" ; const FAILED = "failed" ; const STATUS = "status" ; const RESULT = "result" ; const PENDING = "pending" ; let result = [] ; function doUrlOpen(backendUrl) { dlog('START doUrlOpen'); return new Promise((resolve, reject) => { result[ STATUS ] = PENDING ; dlog('PROMISE doUrlOpen'); var options = { target: backendUrl, method: 'get', timeout: 30 }; urlopen.open(options, (error, response) => { if (error) { result[ STATUS ] = FAILED ; dlog('REJECT urlOpen'); return reject(error); } result[ STATUS ] = SUCCESS ; dlog('RESOLVE urlOpen'); return resolve(response); }); }); }; dlog('START'); doUrlOpen( 'http://ipinfo.io' ).then( (response) => { dlog('AFTER GOOD urlOpen'); dlog( "Final Result " + response ) ; }) .catch((error) => { dlog('AFTER BAD urlOpen'); }); dlog( "WAITING" ) ; sleep( 10000 ) ; dlog( "Status " + result[ STATUS ] ) ; dlog("FINIS " + result[ RESULT ] );

    Regretfully, the urlopen does not return until after FINIS ...

    12:24:37 PM gatewayscript-user error 136608 response 172.17.0.1 0x8580005c mpgw (dp-test): do_request urlopen.open result: 12:24:37 PM gatewayscript-user error 136608 response 172.17.0.1 0x8580005c mpgw (dp-test): do_request urlopen.open start 12:24:37 PM gatewayscript-user error 136608 response 172.17.0.1 0x8580005c mpgw (dp-test): do_request - done 12:24:37 PM gatewayscript-user error 136608 response 172.17.0.1 0x8580005c mpgw (dp-test): FINIS 12:24:37 PM gatewayscript-user error 136608 response 172.17.0.1 0x8580005c mpgw (dp-test): 12:24:37 PM gatewayscript-user error 136608 response 172.17.0.1 0x8580005c mpgw (dp-test): do_request request 12:24:37 PM gatewayscript-user error 136608 response 172.17.0.1 0x8580005c mpgw (dp-test): START

    What am I doing wrong?

    Thx

    Roman



    #DataPower
    #Support
    #SupportMigration


  • 4.  RE: HTTP requests to backend servers from Gatewayscript

    Posted Thu December 24, 2020 11:47 AM

    Regretfully, I've got a variable number calls (probably on the order of 10+), REST, DB and MQ to make per transaction, depending on input.

    Looking like datapower is just not going to be able to do what I need it to.



    #DataPower
    #Support
    #SupportMigration


  • 5.  RE: HTTP requests to backend servers from Gatewayscript

    Posted Thu December 24, 2020 11:57 AM

    sample code I provided uses Promise - looks like this is a non-starter on on datapower.



    #DataPower
    #Support
    #SupportMigration


  • 6.  RE: HTTP requests to backend servers from Gatewayscript

    Posted Mon December 28, 2020 07:16 AM

    Regarding Promise not working on DataPower, wait.js works, just test it. So Promises do work.


    I cannot tell what is wrong with your code.


    But I did once write a GatewayScript that did asynchronous calls using urlopen. I did it without Promises I think, cannot find the code. The idea was to increment a global counter variable for each urlopen, and decrement it when urlopen completed. Main code joust uses wait counter to become 0 loop with sleeping.


    I will try to find the code, but the idea is not difficult to implement freshly (code was GatewayScript equivalent to event sink action).



    #DataPower
    #Support
    #SupportMigration


  • 7.  RE: HTTP requests to backend servers from Gatewayscript

    Posted Mon January 18, 2021 03:29 PM

    Hi,

    The solution is using callbacks,

    httpCall1( (a,b) => { .... httpCall2( (a,b) => { .... }) })

    as you can imagine it would be quite difficult to read when getting bigger, so Promises come in to help us manage the flow of messages, the inner functions won´t be triggered until the previous one get the jobs done.

    Example:

    const promiseA = new Promise(myExecutorFunc); const promiseB = promiseA.then(handleFulfilled1, handleRejected1); const promiseC = promiseA.then(handleFulfilled2, handleRejected2);

    MDN Docs



    #DataPower
    #Support
    #SupportMigration