Maximo

Maximo

Come for answers, stay for best practices. All we're missing is you.

 View Only
Expand all | Collapse all

Open a External Website with Params from Maximo

  • 1.  Open a External Website with Params from Maximo

    Posted Thu June 18, 2020 05:23 PM
    Hi All,
       I am relatively new to Maximo Development. My requirement is to invoke a non maximo website (another non IBM  application that is accessed via a URL).I have been scouring over IBM sites as well as the most popular sites (Bruno Portaluri, Chon Neth,Viet Tran)
    This article looks promising to me so I went and followed everything according to the letter,but my hyperlink is visible in Work Order Tracking application if I do not put the signature options. For  sake of snity I went to the two groups MAXADMIN and 
    IBM Launch In Context





    The forum members hopefully can see where I placed the Hyperlink in the work order application


    After I save and go back and close my browser and come back as maxadmin I do not see the hyperlink so if i go to application designer and remove the signature in the advanced section of hyperlink and come back  the hyperlink will be there but when i click i get a BMX error you are not authorized.

    If this is not how to pass a external website can someone comment actually all I want to do is create a tab(Done) when the user moves to my tab I want it to pass the Asset(or any other id MBO) to my external application and show its representation in that application, in other words like the IFRAME examples of yesteryear like 2013 and so on . The Iframe options are throwing cross-site problems et al.

    Some simple example of a script if anyone has done similar stuff.I am not afraid of doing java but again there is no quality java examples that say here is how you do it.I know by clicking on the presentation of application I see this psdi.webclient.beans.workorder.WorkorderAppBean but what I am wondering is how would one know what to extend/change in that IBM class ?surely I wouldnt probably need to do that but I just jotted it just so that I know where teh class is...

    Whty is IBM Developer site bereft of any real snippets,full examples most of it will lead to IBM Community which has been retired?

    ------------------------------
    Appu Nair
    ------------------------------



    #MaximoIntegrationandScripting
    #AssetandFacilitiesManagement
    #Maximo


  • 2.  RE: Open a External Website with Params from Maximo

    Posted Fri June 19, 2020 07:50 AM

    Launch in context is definitely the way to go when you want to open a new browser tab to a different application and have some data on the record you need to use. The fact that the hyperlink isn't visible when the signature option is associated implies that the security change hasn't taken effect. Maximo security changes can be painful, because if that user has more than one session logging out and logging back in won't address the issue.

    The signature option is critical in launch in context, because it's how the launch in context is associated to the button/hyperlink. You didn't attach a screenshot but I assume you configured that when you created your signature option. 



    ------------------------------
    Steven Shull
    Director of Development
    Projetech Inc
    Cincinnati OH
    ------------------------------



  • 3.  RE: Open a External Website with Params from Maximo

    Posted Fri June 19, 2020 07:57 AM
    First I created Signature option , second  I associated the control hyperlink to the Launch in Context signature option in step 1, third I went to everyone and max admin group found the application work order tracking and from about 99 selections in the bottom most selection found the launch in context test and checked it.

    Closed browser restarted everything tried it?

    Is there a table entry it makes which I could spoof ?

    Best
    Appu






  • 4.  RE: Open a External Website with Params from Maximo

    Posted Fri June 19, 2020 08:11 AM
    Assuming your user is in the MAXADMIN group the database side is fine. Permissions are maintained in a cache, and if there are other user sessions for your user your permission won't take effect. You didn't explicitly mention logging out, but you do need to log out of ALL your sessions in that environment. 

    There sometimes are weird results with other user sessions in that same group that got the permission added (in this case, MAXADMIN). I would ensure that everyone in MAXADMIN group is logged out (have them log out, don't do the system administration to log them out) and then log back in and see what happens. Also make sure that you don't have any stale sessions in the MAXSESSION table where it thinks you have an active session.

    ------------------------------
    Steven Shull
    Director of Development
    Projetech Inc
    Cincinnati OH
    ------------------------------



  • 5.  RE: Open a External Website with Params from Maximo

    Posted Fri June 19, 2020 08:40 AM
    @Steven Shull  You were right on the money this was classic rookie mistake, I logged in as maxadmin logged out Lo & Behold my hyperlink was there!

    For posterity anyone following the IBM hyperlink, it is imperative that you "Log Out" for the signature options to work restart or closing browsers will not 
    make your experience as the official article says :)

    ------------------------------
    Appu Nair
    ------------------------------



  • 6.  RE: Open a External Website with Params from Maximo

    Posted Fri June 19, 2020 08:20 AM
    Hi 
    You can try this solution - 
    1. create a button in the place where you want the user to click to launch the other web site
    2. back the button up using an action - which you can script (automation script app - action launch point)
    3. a sample "action launch point" automation script (1 line) for this would be below
    service.openUrl(url,True)

    Now you will need to manipulate the url - using the "mbo" implicit var - so that you can add the id etc to the url.
    As per the security group for the sigoption for the button - make sure MAXADMIN group has access for test purpose and then let it get driven by your business requirements as to who all need to have access.


    ------------------------------
    Anamitra Bhattacharyya
    IBM
    Littleton MA
    ------------------------------



  • 7.  RE: Open a External Website with Params from Maximo

    Posted Fri June 19, 2020 08:53 AM
    @Anamitra Bhattacharyya  That is definitely what I need to do in reality this is what needs to happen.
    1. The website where I am passing the parameter is protected using its own rest api mechanisms like a REST Header which I can craft through Postman. Postman actually shows me code for several programming languages. The line you have in the sample what language is that scripting. I see maximo supports several? 
    2. What would I need to do if the requirement is say one is on the Asset Tab and clicks the custom tab,not a hyperlink or button, could I possibly intercept the custom tab click in some way so that a "automation script" can be run.
    3. In this link the author says associate the code snippet with your button? https://maximomize.wordpress.com/2018/03/16/open-application-and-open-its-record-using-a-button/   or this link where the author talks about adding code https://maximonews.wordpress.com/2011/05/15/redirect-from-one-app-in-maximo-to-another/  is it part of a java class or  scripting ?


    ------------------------------
    Appu Nair
    ------------------------------



  • 8.  RE: Open a External Website with Params from Maximo

    Posted Mon June 22, 2020 04:39 PM
      |   view attached

    @Anamitra Bhattacharyya @Steven Shull

    can one of you look and tell me if I am doing the suggestion correct.I have print with a label in my script


    ------------------------------
    Appu Nair
    ------------------------------

    Attachment(s)

    docx
    Anamitra Solution.docx   156 KB 1 version


  • 9.  RE: Open a External Website with Params from Maximo

    Posted Tue June 23, 2020 08:10 AM
    Are you trying to just make a REST API request? Since you did your testing in Postman I assume the answer is yes. The launch in context is really intended for when a user needs to interactively go to a separate application. If you just want to make a REST API request to another system, you really want to utilize end points in Maximo. If you setup an end point in the end points application with the HTTP handler, you'll be able to provide headers, URL, method (POST/GET), etc. If something is dynamic (IE you need to set it in the automation script, such as headers or the URL) then you would want to check the "Allow Override" checkbox. If you don't check the checkbox, it will be ignored if you try to provide it in the overrides.

    In your script, you setup any overrides in a HashMap. Ex below (you would replace NEWURL with the URL, such as https://google.com):
    from java.util import HashMap
    map = HashMap()
    map.put("URL","NEWURL")

    Then you invoke the endpoint using:
    service.invokeEndpoint("endpointname",map,body)

    map corresponds to the hashmap of overrides that I talked about above. If none are required, you can provide a blank hashmap by declaring HashMap(). Body corresponds to a string of the message body that you want to send (assuming you have one to provide). Depending on the system, this could be JSON or XML or NULL entirely if not required for the request. 


    I've never executed code on a tab change, so I'm not sure what is possible there. I would personally recommend using an action (either in the Select Action/More Actions menu or via a push button). Tabs aren't an indicator in Maximo of an action occurring and actions should be explicit as possible. For example, what would occur if someone accidently clicked the wrong tab? Or what happens if you have a read-only account that needs to be able to see data on that tab? 


    Your two examples are both java examples, but could be adjusted to work with an automation script action launch point. Based on what I think you're trying to do though, this isn't what you want. These queue up events inside of the Maximo framework (IE go from Asset to Location application for example). They're not going to help you interact with an external system.

    ------------------------------
    Steven Shull
    Director of Development
    Projetech Inc
    Cincinnati OH
    ------------------------------



  • 10.  RE: Open a External Website with Params from Maximo

    Posted Tue June 23, 2020 09:32 AM
    @Steven Shull @Anamitra Bhattacharyya

    1. Action Launch Point Script called Launch2 created Language Jython in Automation Script Tab, No Variables in Variables Tab, Launch Points has Launch Point Type like this 
     ​​
    1. I created a Tab in Asset Application , I added a Section, Inside there I added a "Push Button" .in the Push Button properties in Advanced I have a signature created called Launch2. Going by that in its General I have the Label as Launch2 and Event as LAUNCH2.I do not know what Default Button is so I clicked it and tried without clicking it.
    2. I went and added Launch2 as possible for maxadmin group as this is a pre production system and I only have this user.Logged out.
    3. An HTTP endpoint called APPUHTTP with URL of google made in the Integration Application 
    4. in my Automation script that I am caling Launch2 here is the code in jython  
    from java.util import HashMap
    map = HashMap()
    map.put("URL","https://www.google.com/")
    service.invokeEndpoint("APPUHTTP",map,"appu")


    I open up an asset record. My Pushbutton shows . Clicking it produces no difference I see no messages of error 
    Nothing to say any script was called. The script is set to DEBUG as well.

    ------------------------------
    Appu Nair
    ------------------------------



  • 11.  RE: Open a External Website with Params from Maximo

    Posted Tue June 23, 2020 09:48 AM
    When you create the signature option for a push button automation script, it's slightly different than a launch in context. In the Advanced Signature Options, ensure that you have the radio selected for "This is an action that must be invoked by user in the UI". 

    Beyond that, invoking an endpoint won't record anything when it is successful. You would need to do that yourself if you need to indicate that to the user. If it failed for some reason (such as connection refused, certificate issue, etc.) an error would be thrown (assuming the script is firing). If you want to be sure that a request was invoked you can turn the integration logger to debug (inside of the logging application, ensuring that it is also checked as active) and it will show the details of the endpoint being invoked.

    ------------------------------
    Steven Shull
    Director of Development
    Projetech Inc
    Cincinnati OH
    ------------------------------



  • 12.  RE: Open a External Website with Params from Maximo

    Posted Tue June 23, 2020 07:45 PM
    @Steven Shull That piece of advice was very good. Currently, I am able to call my external REST API ​through my automation script :)
    I was able to do many things in this blog https://bportaluri.com/2018/08/maximo-call-external-rest-api-sms.html but far from out of the woods
    I have not found a way to trap the RESPONSE which comes like this from my logger
    [6/23/20 23:28:03:267 UTC] 000006d5 SystemOut O 23 Jun 2020 23:28:03:267 [DEBUG] [MAXIMO] [] nSending 'POST' request to URL : MASKED
    [6/23/20 23:28:03:267 UTC] 000006d5 SystemOut O 23 Jun 2020 23:28:03:267 [DEBUG] [MAXIMO] [] Post Data : {"userName":"MASKED","password":"MASKED"}
    [6/23/20 23:28:03:267 UTC] 000006d5 SystemOut O 23 Jun 2020 23:28:03:267 [DEBUG] [MAXIMO] [] Response Code :
    [6/23/20 23:28:03:267 UTC] 000006d5 SystemOut O 23 Jun 2020 23:28:03:267 [DEBUG] [MAXIMO] [] 200
    [6/23/20 23:28:03:267 UTC] 000006d5 SystemOut O 23 Jun 2020 23:28:03:267 [DEBUG] [MAXIMO] [] {"token":"6F7464735F73657373696F6E5F6B6579",
    "userId":"MASKED",
    "ticket":"*RFA",
    "resourceID":null,"failureReason":null,"passwordExpirationTime":0,"continuation":false,"continuationContext":null,"continuationData":null}

    My intention is to find the individual tuples in the TEXT that is being logged out. In POSTman it comes as JSON I am printing that lines

    br = BufferedReader(InputStreamReader(conn.getInputStream()))  (I belive I took this from Bruno's site)
    authResp = br.readLine()
    the authResp is what I am printing in my logger

    Hopefully, the IBM Maximo JSON API has easy ways to extract them 



    ------------------------------
    Appu Nair
    ------------------------------



  • 13.  RE: Open a External Website with Params from Maximo

    Posted Wed June 24, 2020 08:09 AM

    I don't often do this, but I have to disagree with Bruno's approach here. Maximo end points provide a well tested framework for making API requests to external systems and should be utilized unless there's a reason that prevents it. For example, if your HTTP header has a value that contains a comma (such as an OAuth 1 Authorization header), then it won't work as they use a comma separator between headers. End points can help you to abstract your code from some of the configuration data to minimize what you have in the script and greatly reduces the amount of code while still ensuring things like connections are properly closed. 

    Since you need to get the response, the service.invokeEndpoint example I showed you above returns a String of the response if it exists. So if you had something like:

    response=service.invokeEndpoint("APPUHTTP",map,"appu")

    response would contain a string of the response. Since you said it's returning it as JSON, I would then use the JSONObject class to parse it like:

    responseObject=JSONObject.parse(response)

    From there you can responseObject.get("token") for example if you were trying to retrieve token from the response. 


    ------------------------------
    Steven Shull
    Director of Development
    Projetech Inc
    Cincinnati OH
    ------------------------------



  • 14.  RE: Open a External Website with Params from Maximo

    Posted Wed June 24, 2020 12:13 PM
      |   view attached
    Hi Appu,

    Adding to Steven's last comment, Maximo has a number of ways and options to call external applications and you should try and use them.
    One other way it that you can also setup a json mapping to send a json data outside without writing a single line of code. 
    Create publish channel and map the publish channel data into a json string using json mapping application. Maximo can send data in json format to an external system.
    You can also fetch data from an external system using's invokeEndpoint method and process data and call a publish channel from script. The publish channel can be json mapped to send data in json format. So, you can basically create a logic to send and receive data from maximo.
    Maximo has all the possible ways to integrate with external system.
    I have attached a script for you to refer. It runs a logic to get multiassetloci data and send a message out of maximo for each assetloci. It is not perfect but a good example to send ,receive and process data.

    ------------------------------
    Biplab Choudhury
    Maximo Consultant
    Tata Consultancy Services
    Melbourne
    ------------------------------

    Attachment(s)



  • 15.  RE: Open a External Website with Params from Maximo

    Posted Thu June 25, 2020 12:15 PM
    Thanks Very much, guys. I am seeing light at the end of the tunnel. Unfortunately with no domain knowledge and with almost every example that one looks yielding to a broken IBM Community(Don't worry I come from another Enterprise App who are notorious for doing the same thing) link it is harder.
    Your knowledge and timely help are much appreciated . I will keep pinging when I am stuck in a particular aspect.

    Just like an example that shows how the MXPERSON Object using JMS Queues get dumped to a file system(That too if you didn't know how to set maximo properties you are stuck), it might be worth IBM Maximo people's time to show an example of using an HTTPHandler, a JAX handler and so on using perhaps a non-ibm system ( I wouldn't go as far as the REST example). Essentially if the reader knows how to use SOAPUI how do you take it from there.

    In my case, I struggled many days until I learned that the SOAPUI Body message is all I could deliver with the End Point. True for experienced people it would be a piece of cake as you say but how do you stuff a header.IBM trouble ticket people said I would have to code :)

    ------------------------------
    Appu Nair
    ------------------------------



  • 16.  RE: Open a External Website with Params from Maximo

    Posted Fri June 26, 2020 09:22 AM
    I'm not sure what the last part of your message means about you can only deliver the body with an end point. With end points you can (and almost always have to) control headers and/or the URL. If it's static you would define it on the end point to remove it from the code otherwise you would just put it in the override map before calling the end point. Something like:

    map.put("HEADERS","Authorization:basicAuthHeader,Header2:header2value")

    That would add 2 headers to your request (Authorization & Header2) with the values that follow provided that you set it up on the end point to allow overrides. 


    I definitely agree that end points aren't well documented aside from utilizing as a publish channel which isn't always a viable option. And any time you end up at the code stage (automation script or java) IBM support isn't allowed to assist. I personally hope to create more content (blogs, webinars, video recordings, etc.) as I know the feeling when you know something is possible but can't figure out how. I've worked exclusively with Maximo for 10 years in a rather unique role and I'm still constantly learn new things, especially from others in the industry. What sometimes is lacking in official documentation, you'll often be able to find people inside of the Maximo communities willing to help outside of their "day job".

    ------------------------------
    Steven Shull
    Director of Development
    Projetech Inc
    Cincinnati OH
    ------------------------------



  • 17.  RE: Open a External Website with Params from Maximo

    Posted Wed September 23, 2020 02:53 PM
    "If it's static you would define it on the end point to remove it from the code otherwise you would just put it in the override map before calling the end point."

    I am struggling with the part about calling the end point. Doesn't this happen automatically in many cases? In my scenario, I have an event listener that automatically calls my publish channel which is associated with my external system / end point. How do I interject myself in that flow and override anything by code? I don't call the endpoint, the event does.

    ------------------------------
    Daniel Gruszka
    ------------------------------



  • 18.  RE: Open a External Website with Params from Maximo

    Posted Wed September 23, 2020 03:08 PM
    I created an endpoint modeling the jax-ws handler. In my case the publish channel tied to my external system is wired to 
    this custom endpoint. With this, I am able to manipulate the soap header effectively as I did not totally understand what  all the 
    guru's mentioned.I also am constrained to not want an automation script.

    The soap structure I have to work with has an element that looks like sorry SOAPUI shown for ease of understanding
    <soapenv:Envelope>
        <soapenv:Header>
        -- The endpoint would never have this structure or that jax-ws client thing that you get in reprocessing
          --stuff in here s used by the other service as the token to understand a user in that system
       </soapenv:Header>
    <soapenv:Body>
      -- In the reprocessing queue one would see the body of the message
    --this is the wsdl I configure in the endpoint jax and that is the only thing i had control
    --to manipulate not the header.I did not know how to do this other than custom code. 
    </soapenv:Body>
    </soapenv:Envelope>

    If at all this design looks suspicious it is because I had to get something to be done
    and IBM regular support told me that they do not support authenticated soap or something like that
    and the other vendor also does not support that.

    Any time the event is triggered the publish channel tells the external system I have something for you. At that point, the external system will
    look at the endpoint,in my case my custom end point.


    ------------------------------
    Appu Nair
    ------------------------------



  • 19.  RE: Open a External Website with Params from Maximo

    Posted Wed September 23, 2020 05:13 PM

    Correct, if you're using a publish channel the publish channel invokes the endpoint. There are some use cases where it makes sense to invoke an endpoint from an automation script instead of utilizing a publish channel. Publish channels queue up messages and then try to send to the external system (the user isn't aware of success or failure). This can be a plus, but other times it's critical that the integration occurs immediately or the transaction inside of Maximo fails (change status is rolled back, labor transaction isn't saved, etc.). That's not possible with a publish channel. Less importantly, other systems can't process a Maximo message, so you have to transform the XML/JSON message into a format the other can consume and it's sometimes easier to build it directly as you need in a script instead of transforming. 

    I want to preface this with I haven't done this, but this is something we are planning to look at doing to improve some of our integrations.

    HTTP endpoints have a HTTPEXIT property that allows you to set a Java class (typically). What most people aren't aware of is you are supposed to be able to set it to script:SCRIPTNAME (replacing SCRIPTNAME with your automation script name) and that will invoke your script.

    I have never seen this fully documented on how to do it end to end, but there is some info such as how to declare your script that can be found here: HTTP handler (ibm.com)

    First things first, your script needs to be set to "Allow invoking methods" or else it won't work. Secondly inside your script you need to declare a function that matches what they're looking for. For example, if you wanted to control the header and were using python, you should have something like this:
    def headerProps():
        # Your logic here

    Depending on your function will determine what gets stored in an invokeArgs implicit variable (that is an object array). For the header it looks like Maximo declares a ScriptHTTPReq class that it puts in an object array that gets stored in the invokeArgs that you can reference in your script. Once you get that ScriptHTTPReq class you can call methods such as addHeader(name,value) with the appropriate header name and value that you want to add to the HTTP request and it should modify it.

    If you haven't gotten comfortable with it, I would recommend using a java decompiler as it's easier to understand what's possible and what's going on in situations like this that aren't very well documented.



    ------------------------------
    Steven Shull
    Director of Development
    Projetech Inc
    Cincinnati OH
    ------------------------------



  • 20.  RE: Open a External Website with Params from Maximo

    Posted Thu September 24, 2020 09:35 AM
    Hi
    just wanted to share my 2 cents in this discussion - there is a feature in Maximo publish channel integration that allows one to dynamically override endpoints or even the endpoint properties.
     
    To override an endpoint ie dynamically setting the endpoint 
    -----------------------------------------------------------------------------
    Assuming you are writing a java user exit or a script user exit - you can just use the following line of code to override an end point in publish channel
         
    from psdi.iface.mic import MetaDataProperties
    from psdi.iface.mic import IntegrationContext
     
    IntegrationContext.getCurrentContext().setProperty(MetaDataProperties.ENDPOINT, "my endpoint name")
     
    Now of course you can make it smart by checking some sdata (StructureData) content -wrapping the above statement using if else etc etc
    Note that this pretty much gets flowed through the queue - to the MIF endpoint framework - which checks this property and override the default endpoint set as part of the external system setup. 
    Note also that - this setting is "sticky" => if ur pub channel is going to multiple External systems - you are going to end up overriding all those by this same endpoint. Effectively till 7610 there was no way to scope this change to a specific external system for that pub channel. However we enhanced that in 7611 to support that scoping. Basically you can set a  java Map object instead of "my endpoint name" - key in the map is the external system name and the value is the endpoint name => effectively allowing one to control the override per external system. Note that this is only needed if ur pub channel is associated with >1 External system
     
    To override endpoint properties in pub channel exit
    -----------------------------------------------------------------------------
    In this model - instead of overriding the full endpoint - you can selectively override some of the properties of that endpoint. Note that for this thing to work - you need to make sure that your endpoint properties are marked as "overridable" .
     
    Assuming you are writing a java user exit or a script user exit - you can just use the following line of code to override an end point in publish channel
         
    from psdi.iface.mic import MetaDataProperties
    from psdi.iface.mic import IntegrationContext
     
    map = //create a java Map here
    //put property name/override value pairs in that map
    IntegrationContext.getCurrentContext().setProperty(MetaDataProperties.ENDPOINTPROPS, map)
     
    This one though does not have any scoping to external systems. 
     
    These features are used internally by location services/Esri integration.
     
    thanks
    Anamitra Bhattacharyya
    STSM, Maximo, IoT
    IBM Master Inventor
     






  • 21.  RE: Open a External Website with Params from Maximo

    Posted Thu September 24, 2020 02:03 PM

    Thank you so much @Anamitra Bhattacharyya and @Steven Shull! Both suggestions provoked a lot of ideas and lead me to a solution that is 98% there. A few follow ups:

    1) I used Anamitra's suggestion to dynamically update the endpoint properties on Publish Channel exit. This worked wonderfully for OAUTH2.0.

    # Grab OAUTH Access Token
    map = HashMap()
    body='client_id=MYIDHERE&client_secret=MYSECRETHERE&resource=https://blahblah.dynamics.com&grant_type=client_credentials'
    response=service.invokeEndpoint("365OAUTH",map,body)
    responseObject=JSONObject.parse(response)
    tkn=responseObject.get("access_token")

    I then use that token string to dynamically build my header for my HTTP endpoint.

    mapPOST = HashMap()
    mapPOST.put("HEADERS","Content-Type:application/json,OData-MaxVersion:4.0,OData-Version:4.0,Authorization:Bearer "+tkn)
    IntegrationContext.getCurrentContext().setProperty(MetaDataProperties.ENDPOINTPROPS, mapPOST)

    This works great! Only issue is if the message fails. It is great that it ends up in message reprocessing (exactly what I wanted) but it appears that reprocessing doesn't trigger my publish channel script again so reprocessing will always fail because the token is obviously missing from the header on my HTTP endpoint.

    My first thought was I could just update the actual endpoint properties to include the header+token and save it to the MBO. However, I'm not sure if it can actually save the entire token? When trying to manually paste the token into the headers via the UI, the field wasn't big enough to hold all that text. Would I run into that problem if I tried to save this token value via code? It obviously works dynamically, guessing the same size restriction doesn't exist when doing it entirely in code.

    My next thought is I may have to move this dynamic endpoint property code down a level from Publish Channel exit to endpoint? That is the only way I think it would work when the message fails and is stuck in message reprocessing?
    ​​



    ------------------------------
    Daniel Gruszka
    ------------------------------



  • 22.  RE: Open a External Website with Params from Maximo

    Posted Thu September 24, 2020 05:29 PM
    I wanted to add on to my post above. I decided to try doing an HTTP Exit script. I have spent all afternoon experimenting with the script that is being passed in the HTTPEXIT property like "script:D365EXIT".

    My script is super simple:

    def headerProps():
       print "TESTING 123"

    No matter what I do, this code will not execute. It seems to call that D365EXIT script in the logs but it won't execute anything within that function. I think those first 4 lines are the ones actually calling and executing for the headerProps but it doesn't seem to do anything within the function.

    24 Sep 2020 16:04:36:615 [DEBUG] loading script D365EXIT
    24 Sep 2020 16:04:36:615 [DEBUG] done loading script D365EXIT
    24 Sep 2020 16:04:43:678 [DEBUG] about to execute the cached compiled script for D365EXIT for launch point null
    24 Sep 2020 16:04:43:678 [DEBUG] The total time taken to execute the D365EXIT script for the null launch point is +0 ms.
    24 Sep 2020 16:04:43:678 [DEBUG] context params vals====service=com.ibm.tivoli.maximo.script.ScriptService@4b9d7f08,invokeStatus=false,invokeFunction=getUrl,invokeArgs=[Ljava.lang.Object;@ef6ca1e,
    24 Sep 2020 16:04:43:678 [DEBUG] context cloned params vals====invokeFunction=getUrl,service=com.ibm.tivoli.maximo.script.ScriptService@4b9d7f08,invokeArgs=[Ljava.lang.Object;@ef6ca1e,
    24 Sep 2020 16:04:43:678 [DEBUG] about to execute the cached compiled script for D365EXIT for launch point null
    24 Sep 2020 16:04:43:678 [DEBUG] The total time taken to execute the D365EXIT script for the null launch point is +0 ms.
    24 Sep 2020 16:04:43:678 [DEBUG] context params vals====service=com.ibm.tivoli.maximo.script.ScriptService@85cf8104,invokeStatus=false,invokeFunction=urlProps,invokeArgs=[Ljava.lang.Object;@fddc7bd6,
    24 Sep 2020 16:04:43:678 [DEBUG] context cloned params vals====invokeFunction=urlProps,service=com.ibm.tivoli.maximo.script.ScriptService@85cf8104,invokeArgs=[Ljava.lang.Object;@fddc7bd6,

    I also don't understand how I would utilize those invokeArgs within the headerProps definition? Do I return them or I can just access them? Not sure how I am actually changing the header.

    ------------------------------
    Daniel Gruszka
    ------------------------------



  • 23.  RE: Open a External Website with Params from Maximo

    Posted Thu September 24, 2020 06:10 PM
    Go through some of my experiences where @Steven Shull and others all walked me through rookie mistakes. What I learned is sigoptions were​ used one had to logout manually and I think to close the browser. Also, the launch point setup screens have 2 or 3 different options but if you are seeing your echo statement my thought tells me that it is running script thinks it is executing a launch point null .



    ------------------------------
    Appu Nair
    ------------------------------



  • 24.  RE: Open a External Website with Params from Maximo

    Posted Thu September 24, 2020 06:22 PM
    Make sure you have the checkbox "Allow Invoking Script Functions" checked on your script. This is documented as a requirement on the script and is NOT checked by default (and can't be changed after). 


    My guess is that is your issue. As for the invokeArgs, I believe you should just be able to get the java class using something like:


    scriptReq=invokeArgs[0]

    And then call the function (such as adding a header) like:

    scriptReq.addHeader(name,value)

    If that still doesn't work let me know and I'll try and build a similar test in our demo apps.



    ------------------------------
    Steven Shull
    Director of Development
    Projetech Inc
    Cincinnati OH
    ------------------------------



  • 25.  RE: Open a External Website with Params from Maximo

    Posted Fri September 25, 2020 08:54 AM
    Hey Steven, yeah I doubled checked everything a million times. The Invoking box is indeed checked.

    Apu brought up a good point that I thought about too:
    24 Sep 2020 16:04:43:678 [DEBUG] about to execute the cached compiled script for D365EXIT for launch point null
    24 Sep 2020 16:04:43:678 [DEBUG] The total time taken to execute the D365EXIT script for the null launch point is +0 ms.

    I wonder if it is somehow expecting a launchpoint? I wouldn't think so, integration scripts usually never need them. When you reference scripts via cron jobs, publish channels, obj structures etc. It is always just creating the script.

    Maybe it always says null launchpoint though when it executes a script that has no launch point. I did try putting some bogus code in the headerprops definition and that caused an exception during runtime saying it couldn't compile the script (when Maximo tried to call the exit). So we know it is looking at it, Maximo just doesn't seem to be calling the function properly.

    ------------------------------
    Daniel Gruszka
    ------------------------------



  • 26.  RE: Open a External Website with Params from Maximo

    Posted Thu October 01, 2020 12:53 PM
    Just wanted to update everyone, in light of the HTTP Exit scripting not working. I developed an alternate solution that works well. I think this is similar to what @Steven Shull suggested previously.

    I created a library function to call the OAUTH Http Endpoint. It will get the token and then save it to the headers on my Publish Channel HTTP Endpoint. This required me changing the size of the VALUE field of MAXENDPOINTDTL. Out of the box it is only 1000 len but these tokens are pretty big. I changed that to 2000. This allowed me to save the token directly to the database. I use the CHANGEDATE on that field to determine how old the token is. When I subsequently call my library function, I check if the CHANGEDATE is over 55 minutes old, if so I grab a new token and save it back to the headers of that HTTP endpoint in the database.

    The very important piece of code was this:
    MXServer.getMXServer().reloadMaximoCache('MAXENDPOINT',True)

    Endpoints get cached by Maximo so updating them in the database will not help your integration. If you change their data during script execution, you need to call this after so that the rest of the chain will flow correctly. Shout out to Kelly Nimmo for the tip here:
    https://a3jgroup.com/updating-end-points-and-reloading-cache-in-automation-script/

    I still want to figure out why the HTTP exit script won't work but in the meantime, this gets the job done.


    ------------------------------
    Daniel Gruszka
    ------------------------------



  • 27.  RE: Open a External Website with Params from Maximo

    Posted Fri April 09, 2021 02:09 PM
    Hi Daniel,

    I hope you were able to make this solution working. We are also having a requirement to integrate with an external system using OAUTH2 authentication. Just wanted to clarify that you have effectively defined 2 different HTTP endpoints? (The 365OAUTH endpoint which you have defined is an HTTP endpoint?). First endpoint is to get the token from the external system. Using this token in the second HTTP endpoint, you access the resource in the external system by updating the token in the HEADER property.

    What are the values for the other properties like URL and HTTPMETHOD?

    Would appreciate if you could shed some more light and if possible can you share the ASCRIPT code for the same?

    Regards,
    Priyaranjandas

    ------------------------------
    Priyaranjandas Kolambkar
    ------------------------------



  • 28.  RE: Open a External Website with Params from Maximo

    Posted Mon April 12, 2021 09:21 AM
    Hello Priyaranjandas,

    Yes, I defined 2 different HTTP endpoints.
    1) OAUTH Endpoint
    I store the CLIENTID in the USERNAME field and store the CLIENTSECRET in the PASSWORD field. Maximo doesn't do anything with these automatically, it is just a way for me to store those login values. The HEADERS must be set to
    "Content-Type:application/x-www-form-urlencoded"


    I then wrote a library script which calls this endpoint and returns the token. This library script is called within my publish channel automation script: PUBLISH.MYSCRIPT.EXTEXIT.OUT
    This script will fire on the outbound event for our publish channel. The library script was just a way to encapsulate all the logic for calling the OAUTH endpoint, parsing and getting the token etc. We also check how recently the token was last updated.

    Here is the call to the library script:
    # Call OAUTH endpoint, this will update token on our HTTP call to D365 if needed
    omap = HashMap()
    omap.put('oauthEnd', 'D365_OAUTH')
    omap.put('httpEnd','D365_HTTP')
    service.invokeScript('LIB_OAUTH', omap)

    2) To understand how the library script works, first you need to understand the HTTP endpoint for our actual integration. Again, the endpoint above is just a way to store the data used to get the token. I only access that endpoint manually via scripting. This next endpoint is the actual HTTP endpoint that lives on our Publish Channel:

    The URL property is the resource you are connecting to including the data entity (This is probably D365 specific), in my example "MyDataEntity".
    https://myenvironment.dynamics.com/data/MyDataEntity

    The real trick to making this work was allowing override on the HEADERS and also updating the database field size on MAXENDPOINTDTL.VALUE. This is because our library script will call the OAUTH endpoint and grab the token and then SAVE it to the headers on this endpoint. That way Maximo can then just do it's normal integration routine and the whole process will work without any involvement. Here is a snippet from the OAUTH library script. I am taking the header and appending the token that was just received from the OAUTH endpoint call. I then save that updated header (that is why allow override is required). I also realized Maximo caches endpoint data so you must do that MXServer call to reload cache.

    # Full Header, Update HTTP Endpoint
    fullheader = "Content-Type:application/json,OData-MaxVersion:4.0,OData-Version:4.0,Authorization:Bearer "+token
    endpHeader.setValue('value',fullheader)
    endpHeadSet.save()
    MXServer.getMXServer().reloadMaximoCache('MAXENDPOINT',True)

    Once you get that token and add it to the header on your HTTP Endpoint, then Maximo can format the integration message and send it.

    One other issue we had was that Maximo formatted JSON different than D365 required so I had to manipulate that manually in our publish channel script. I create a blank JSON object (to store my new message) and then get the existing JSON message that Maximo created. I then go through the existing message, format fields and data accordingly and add it into my new JSON object.

    #Create new Json
    jsnObj = JSONObject()

    # Get existing integration message in JSON map
    jsonIR = JSONObject.parse(irData.getDataAsString())

    Once I finish all that logic, I can take the new JSON record I created with all the updated data and assign it back to the irData. This means that Maximo can then use it in the rest of the integration flow just as if this was an out of the box message. It has no idea that we manipulated it. This also allows Message Reprocessing to still work.

    # Assign our new JSON object to the integration message, this will replace it with our new JSON we created above
    irData = StructureData(StringUtil.toBytes(jsnObj.serialize(True)))

    Hope that helps, this is pretty complex, took us a few months to get finished with all the troubleshooting. This should save you a ton of time though.
    -Dan

    ------------------------------
    Daniel Gruszka
    ------------------------------



  • 29.  RE: Open a External Website with Params from Maximo

    Posted Mon April 12, 2021 09:26 AM
    One other thing that was tricky was adding the certificates to WebSphere for both the microsoftonline website to grab the token and our D365 systems. Otherwise we got these weird security errors in Maximo. Also above, I forgot to mention, I updated MAXENDPOINTDTL.VALUE to 2000. This is because out of the box the field size was 1000 and it couldn't fit the token. Those tokens are pretty long, hundreds of characters. Updating the field to 2000 allowed us to save the token on the endpoint.

    ------------------------------
    Daniel Gruszka
    ------------------------------



  • 30.  RE: Open a External Website with Params from Maximo

    Posted Mon April 12, 2021 10:00 AM
    Hi Daniel,

    Really good solution. Learnt a lot.

    Just 1 thing I would have done differently is the creation of custom json format using custom autoscript.
    In place of auto script , you can use JSON Mapping application to map maximo data into the D365 format json. Very simple and useful solution without coding. Hope it will be useful  in future integrations.

    Thanks,
    Biplab

    ------------------------------
    Biplab Choudhury
    Maximo Consultant
    Tata Consultancy Services
    Melbourne
    ------------------------------



  • 31.  RE: Open a External Website with Params from Maximo

    Posted Mon April 12, 2021 10:07 AM
    Hey Biplab,

    Thank you! Funny enough I did end up using the JSON Mapping application but not automatically with Maximo. I stored the properties and data in there so that I could dynamically format JSON and even dig multiple levels deep with nested hierarchies. Here is what it looks like:

    My code looks at that source attribute and can return the correct data if it is a constant, attribute or relationship.

    If i remember correctly, I chose to manually utilize this structure rather than let Maximo do it out of the box because there were some formatting problems with how Maximo wanted to structure nested objects versus what D365 was expecting. My publish channel code basically loops through this mapping above and uses it to pull the data dynamically:

    while (jsMapProp is not None):
    jsPropName = jsMapProp.getString('propertyname') # Property that D365 Expects in JSON
    mxAttrName = jsMapProp.getString('attributename') # Property or Relationship in Maximo
    mxAttrType = jsMapProp.getString('type') # Maximo Data Type of Attribute

    I did have to write a recursive library function to handle the multiple layers of nesting in a relationship. I.e. PO.COMPANIES.COMPANY

    service.invokeScript('LIB_GETNESTEDJSONPROP',nestJs)

    Thanks!
    -Dan

    ------------------------------
    Daniel Gruszka
    ------------------------------



  • 32.  RE: Open a External Website with Params from Maximo

    Posted Mon April 12, 2021 10:10 AM
    One other thing I think was also an issue, was that Maximo wanted to convert property names to lower case once it converted the mapping to JSON ultimately. I had to control that because D365 expects camel case for all property names.

    ------------------------------
    Daniel Gruszka
    ------------------------------



  • 33.  RE: Open a External Website with Params from Maximo

    Posted Thu March 20, 2025 09:31 AM

    Hi Biplab,

    I have joined this forum newly and its very good. 

    From the below invoke endpoint, I want to know the status code for successfull or Unsuccessfull connection. Based on the status code need to send an email for notification. 

    service.invokeEndpoint("endpointname",map,body)

    Appreciate your support here.

    Thanks and Regards,

    Nandisha



    ------------------------------
    Nandisha MS
    ------------------------------



  • 34.  RE: Open a External Website with Params from Maximo

    Posted Thu March 20, 2025 09:32 AM

    Hello Biplab,

    I am using to call endpoint which is configured Oauth authorization as below

    response = service.invokeEndpoint(httpendpoint_name, map, jsonBody)

    Here, i am facing problem, i e if connection is successful to source will get data else if connection is failed, How we can identify? any solution to get the status code  like 200 is success and other is Unsuccess.

    why because,  if my connection is failed with source then i need to send an email notification to take appropriate action to re-request.

    Note: expectation is to get the status code of my request.

    Appreciate your response. Thanks 



    ------------------------------
    Nandisha MS
    ------------------------------



  • 35.  RE: Open a External Website with Params from Maximo

    Posted Thu March 20, 2025 09:39 AM

    The map that you pass into the invoke  call will get update with an entry with the key of RESPONSE_HEADERS, which is itself another Map object that has a key of RESPONSE_STATUS that is the HTTP status code from the response.  There is also a key of RESPONSE_STATUS_TEXT that contains the response text as well.

    Hope that is what you are looking for.

    - Jason



    ------------------------------
    Jason VenHuizen
    Sharptree
    https://sharptree.io
    https://opqo.io
    ------------------------------



  • 36.  RE: Open a External Website with Params from Maximo

    Posted 14 days ago
    Edited by Nandisha MS 13 days ago

    Hello Jason, 

    Thanks for your response,

    This is my sample code here

        map = HashMap()
        response = service.invokeEndpoint(endpointname, map, jsonBody)

        success = False   

        errorResponse = HashMap()
        errorMessage=""
        map.put("ERRORONSTATUS",False)
        map.put("RESPONSE_HEADERS",errorResponse)
        errorResponse.get("RESPONSE_STATUS") is producing None value.

    Please help me if anything wrong in my code or any other configuration is missing

    Thanks in advance!!



    ------------------------------
    Nandisha MS
    ------------------------------



  • 37.  RE: Open a External Website with Params from Maximo

    Posted Thu March 20, 2025 09:46 AM

    Jason has provided the exact details. 

    this below web page is very handy:

    https://www.ibm.com/docs/en/masv-and-l/maximo-manage/continuous-delivery?topic=concepts-service-object



    ------------------------------
    Biplab Choudhury
    IBM Champion 2022
    Solutions Consultant
    Valueztech Pty Ltd
    Melbourne VIC
    ------------------------------



  • 38.  RE: Open a External Website with Params from Maximo

    Posted Mon April 12, 2021 10:29 AM
    Hi Dan,

    Thanks for the detailed post as well as your subsequent posts. Should be of immense help.

    Will definitely let you know how it goes.

    -Priyaranjandas

    ------------------------------
    Priyaranjandas Kolambkar
    ------------------------------