Maximo Open Forum

 View Only
  • 1.  Automation Script - arg can't be coerced

    Posted 12-04-2023 09:20

    I have an automation script that I want to call up another script after it has  and obtained data from an external system API. I am getting an error TypeError: invokeScript(): 2nd arg can't be coerced to String in <script> at line number 107. 

    Line 107 is  service.invokeScript("NEWSCRIPT",map1,targObj.serialize())

    below is the script.

    from java.util import Date
    from java.util import Calendar
    from psdi.server import MXServer
    from java.text import SimpleDateFormat 
    from psdi.iface.router import Router
    from java.util import HashMap
    from java.lang import String
    import sys
    from java.lang import Exception
    from com.ibm.json.java import JSONObject
    from com.ibm.json.java import JSONArray
    from com.ibm.json.java import JSON

    logger = service.getLogger("maximo.script")

    def invokeExtEndpoint(handler,map):
        logger.debug("Inside invokeExtEndpoint.")
        success = False
        errorMessage=""
        response = ""
        respStatusCode = ""
        try:
            responseBytes = handler.invoke(map,None)
            response = String(responseBytes,"utf-8")
            respStatusCode = responseHeader.get("RESPONSE_STATUS")
            if int(respStatusCode)<400:
                success = True
            else:
                errorMessage=str(sys.exc_info()[1])
                logger.error("Inside Try/Else block, Error Message: "+errorMessage)
        except Exception, e:
            logger.error(e)
            respStatusCode = responseHeader.get("RESPONSE_STATUS")
            errorMessage=str(e.getMessage())
            logger.error("Inside Exception block, Error Message: "+errorMessage)
        return success, errorMessage, response, respStatusCode

    # Calculating the date - it will be passed as a changedate parameter value
    currentDate = MXServer.getMXServer().getDate()
    cal = Calendar.getInstance()
    cal.setTime(currentDate)
    cal.add(Calendar.DATE, -1)
    sdf = SimpleDateFormat("yyyy-MM-dd")
    queryDate = sdf.format(cal.getTime())
    logger.debug("Query Date is: "+str(queryDate))

    # Loops through the set of  to fetch and process the applicable 
    for q in queryDate:
        logger.debug("Inside for loop: Last Update Date - "+queryDate)
        map = HashMap()
        urlmap = HashMap()
        urlnew = str()
        responseHeader = HashMap()
        
     
        
        # String variables 
        urlnew = str("LastUpdateDate" + ' ' + 'ge' + ' ' + queryDate);

       

        urlmap.put("$filter",urlnew)

        
        map.put("GETURLPROPS",urlmap)
        map.put("RESPONSE_HEADERS",responseHeader)
        
        # Fetching the endpoint details and calling invokeExtEndpoint function to invoke API
        handler = Router.getHandler("APIEP")
        extServResp = invokeExtEndpoint(handler,map)

        logger.debug("External Service response is:: ")
        logger.debug(extServResp)

        emailTo = "Admin@network.com"
        emailFrom = "Admin@network.com"
        subject = "Sync Failed!"
        emailContent = ""

     if(extServResp[0] == True):
            logger.debug("Success Response!!! Invoking Maximo Enterprise Service.")
            logger.debug(extServResp[2])
            map1 = HashMap()
            
            jsonobj = JSONObject.parse(extServResp[2])
            # Load json string file into a variable
            logger.debug("Size of Json Object Is: ")
            logger.debug(str(jsonobj.size()))

            
            gmrSvcErrFlag = False
            errorMessage1 = ""
            

            try:
            for row in jsonobj.get("value"):
                   targObj = JSONArray()
                   targObj.add(row)
                   logger.debug(targObj.serialize())
                   service.invokeScript("NEWSCRIPT",map1,targObj.serialize())


    #Customizations
    #Integrations

    ------------------------------
    Michael Odera
    n/a
    ------------------------------


  • 2.  RE: Automation Script - arg can't be coerced

    Posted 12-05-2023 13:33

    Look at our library script documentation: https://ibm-maximo-dev.github.io/maximo-autoscript-documentation/coreconcepts/libraryscripts

    We have 3 different invokeScript options on service (ScriptService), two of which are the legacy approaches. The first legacy approach is just passing in the script name. The second is passing the script name & a HashMap. In this scenario, you would setup any variables in the HashMap (like mbo) that you need to be available for your script and after it is done, you can retrieve any variables that were set from the HashMap.

    In 7.6.1 we enhanced the automation scripts to support invoking functions in the automation scripts. You need to set the "Allow Invoking Script Functions" flag on the automation script which can only be set during script creation. 

    When you do that, you can call out a specific function and pass in any parameters that are required for the function. In that scenario the first argument is the script, the second argument is the function name (which is where that string error is coming from), and then the third is any arguments you need to pass in like [map1,targObj.serialize()]



    ------------------------------
    Steven Shull
    IBM
    ------------------------------



  • 3.  RE: Automation Script - arg can't be coerced

    Posted 12-06-2023 09:10

    Michael, 

    In addition to Steven's comments, note that the HashMap not only allows you to pass in variables, but also is the representation of the script invoked. So the functions from the invoked script are added to the HashMap and can be invoked from there.  I wrote a blog post on this a while back:

    https://www.sharptree.io/blog/2021/2021-11-29-js-invoke-library/

    You can also just fully inline another script into your current script with something like this:

    // Import the ScriptCache Java class.
    ScriptCache = Java.type('com.ibm.tivoli.maximo.script.ScriptCache');
    
    // Load the Excel library inline with the current script.
    load({ script: ScriptCache.getInstance().getScriptInfo('SHARPTREE.EXCEL').getScriptSource(), name: 'SHARPTREE.EXCEL' });

    This will load effectively insert your loaded script into the current script at the point you invoke it. I pulled this example from here, https://github.com/sharptree/autoscript-library/tree/main/excel if you want to see the context of how it can be used.

    - Jason



    ------------------------------
    Jason VenHuizen
    Sharptree
    ------------------------------