Sunday 27 December 2020

IBM Support Terminology

 APRR (defect)

a request / defect reported to IBM (authorized program analysis report)


TPAE (application architecture)

Tivoli's Process Automation Engine / Base Services

Core Java Classes that can be used to build Java applications. 

Benefit: The benefit of using TPAE architecture is that the core functionality of many Java applications DOES NOT need to be coded by the application. Each application relies on base classes for core functionality rather than to code in each.

base system core functionally, security tools for user, role, group management


Interim Fix (patch):

a patch to fix a confirmed product defect reported by clients from IBM technical developers reported. 

It contains 1 or more product defects/APARs. the most common patch that IBM delivers.


Fix Pack (Cumulative patches):

A cumulative collection of all patches/fixes since that last released FP. (usually every after 4 months)


Service Pack: (like windows sp1,2,3,4 and then new windows like from 98 to xp, 7, 8,10)

A new feature release


Delete a Person from a list of Person Groups (Dialog, Automation Script) | Maximo

A revised version of the existing post Delete a Person from Person Groups (LIST VIEW QUERY) using Automation Script | Maximo.

We are going to add a dialog box on the list view of Person Group Application to choose the Person to be deleted




1. New Non-Persistent Object with one attribute Personid

  • Object Name: NP_DELETE_PERSONID
  • Attribute:        NP_personid

Thursday 24 December 2020

Reassign Workflow Assignments in Bulk using Escalation | IBM Maximo

Sometimes you have the requirement of reassignment of 200-300 workflow assignments for users.

You can reassign the workflow assignments using an Escalation based on the WFAssignment object. In this example, we will reassign all of Umar's (personid=116524) WF Assignments for application to Qadeer. To do all of Umar's assignments, not just the specific application assignments, leave off the "app =" parameter used below. 

Condition:

WFID != 0 and assignstatus = 'ACTIVE' and assigncode = '116524' and app = 'SR'

Create escalation point bute Leave all the escalation point fields empty. Repeat is off

Create and Attach Action:

Create an action on the same object with set Value of replacement user's assigncode.

Wednesday 23 December 2020

Invoke/Call any dialog from Automation Script | Maximo

Question:
Can we invoke/call my custom dialog or any dialog from the automation script, like we usually can trigger it from the Push button or from Select Action of the application 

Answer:

Yes, you can in the latest version 7.6.1. 

1. Get the dialog name from the application designer 
2. using below mentioned automation script to call it. 

In my example, I created one object launch point automation on the work order application to trigger automation. 
Below is the body of the automation in which I called one of the standard change status dialogs. 


from psdi.server import MXServer
from psdi.mbo import MboConstants
from psdi.common.context import UIContext
from psdi.webclient.system.controller import SessionContext, Utility, WebClientEvent
mxServer = MXServer.getMXServer()
userInfo = mxServer.getUserInfo("maxadmin")
vmbo = mbo.getString("wonum")
if vmbo == '30352551':
    context = UIContext.getCurrentContext()
    if context:
        wcs = context.getWebClientSession()
        Utility().sendEvent(WebClientEvent("status", wcs.getCurrentPageId(), None, SessionContext(wcs)))
        #service.error("",str(abc))



To Close a dialog, either use "okdialog" or in the newer version in can be done with 1 line of code:

service.closeDialog() 

Tuesday 22 December 2020

Make Memo field mandatory on specific inputs in workflow | Maximo

 It's very simple by using just once Global data restriction based on conditions.


1. create an expression using Conditional expression Manager (copy this)

(
    :ACTIONID in (
        select
            distinct ACTIONID
          from
            WFACTION
         where
            1 = 1
            and PROCESSNAME = 'SR'
            and PROCESSREV='1'
    )
)

2. Create Global Data Restriction -> Attribute Restriction -> New Row

Object : INPUTWF
Attribute : MEMO
Application : SR
Type : QUALIFIED
Reevaluate ? y
Condition : myCondition (the one we created in step 1)

Sunday 20 December 2020

Workflow Handling from Automation Script | IBM Maximo

Initiate a workflow from Automation Script. 

from psdi.server import MXServer

mxs = MXServer.getMXServer()

wfstart = mxs.lookup('WORKFLOW')

wfstart.initiateWorkflow('CSPREIMB',mbo)

 

-------------------------

or define a function in your script and call it whenever needed as below:

Function Defination:

def startwf(a):
   actionSet = MXServer.getMXServer().getMboSet("action", a.getUserInfo());
   sqf = SqlFormat("action = :1")
   sqf.setObject(1, "action", "action", "STWFEUNRI")
   actionSet.setWhere(sqf.format())
   actionSet.reset()
   actionSet.getMbo(0).executeAction(a)

 

Function Call:

startwf(MboVariable)

 2. Stop an active workflow from Automation Script. 

from psdi.server import MXServer

mxs = MXServer.getMXServer().lookup('WORKFLOW') 

wfstop = mxs.getActiveInstances(mbo)

         wfstart.getMbo(0).stopWorkflow('Stopped')

 

Invoke Action from Automation Script | IBM Maximo

from psdi.common.action import Action, ActionRemote

from psdi.security import UserInfo

from psdi.server import MXServer


mxServer = MXServer.getMXServer()

userInfo = mbo.getUserInfo()


actionSet = mxServer.getMboSet("ACTION", userInfo)

actionSet.reset()

actionSet.setWhere("action = 'INV_RUN_REP'")


if(not actionSet.isEmpty()):

action = actionSet.getMbo(0)

action.executeAction(mbo)

actionSet.close()

Wednesday 2 December 2020

Modify Maximo URL's Context Root | Maximo

 Some times we need to change the default context root (/maximo) to something else, for example "/maximoprod"

http://localhost/maximo     ------->>>>        http://localhost/maximoprod

1. login to Websphere (https://maximo76.el.com:9043/ibm/console/) with wasadmin user

2. Applications > Enterprise Applications > MAXIMO > Context Root For Web Modules.

and modify the context root to "maximoprod" instead of "maximo" , as in my example. 


Restart Application server or Ripple start your cluster to login with new URL : 

http://maximo76.el.com/maximoprod


you are done :)

Sunday 29 November 2020

Refresh/Update Start Center for All Users in a specific Security Group | Maximo

 Create an automation script to delete the records from the respected table to refresh the start centers displayed on the user's screen

or delete the records from the tables using SQL.

Today we are going to make an automation script and attached it to a signature option on the toolbar. 

So that whenever the user clicks on this button on the security group application, all the respected records will be deleted, and the start center will try to create new records, which means our records will be updated. 


This:

1. Create an Action Launch Point Automation Script with a name like( STARTCENTER_REFRESH ).

Copy the below code in the script section, use jython as language. 

from psdi.server import MXServer

from psdi.mbo import MboConstants

from psdi.util.logging import MXLoggerFactory


logger = MXLoggerFactory.getLogger("maximo.maximodev")

logger.info("Entering MXD_RESETSC")


def deleteSc(objectName, where):

    scSet = MXServer.getMXServer().getMboSet(objectName, mbo.getUserInfo())

    scSet.setWhere(where)

    logger.debug("Deleting " + str(scSet.count()) + " rows from " + objectName)

    # disable logging of large fetch result set to avoid FetchResultLogLimit errors

    scSet.setLogLargFetchResultDisabled(True)

    scSet.deleteAll()

    scSet.save()

Saturday 28 November 2020

Copy WF Memo to Status Memo in View History of Status dialog | Maximo

Copy the Memo from the MANUAL INPUT of the workflow dialog into Memo field of CHANGE STATUS in View History Dialog of any application. 

Both Memos are different , one is coming from wftransaction, and the other one is in the xxstatus table. 

We were trying to cross over the memo from Wftrancation to status table's memo. 

here is the solution we developed using automation script in jyton. 
In my example i am using PR object and PRSTATUS table.

1. Make a relationship from WFTRANSACTION to PR
RelationShip Name: PR
Child Object: PR
Where Clause: prid = :ownerid and :ownertable = 'PR'

1. Object Launch Point 
Object : WFTRANSACTION
Events: SAVE, Add, After Save
wftmemo = mbo.getString("memo")
if (wftmemo!=''):
    prset = mbo.getMboSet("pr")
    pr = prset.moveFirst()
    if pr is not None:
        prstatusset = pr.getMboSet("prstatus")
        prstatus = prstatusset.moveLast()
        prstatus.setValue("memo",wftmemo,2L)
        #prstatusset.save()

 

Sunday 22 November 2020

Implicit Variables like Current Date and or Time to a Communications Template | Maximo

:DATETIME - to display the current Date and Time

:DATE - to display the current Date

:TIME - to display the current Time

:HOSTNAME - to display the hostname defined in System Properties 

Change Status method using Automation script | Maximo

from psdi.server import MXServer

 mbo.changeStatus("APPR", MXServer.getMXServer().getDate(), "heheh")



Wednesday 18 November 2020

Tax to be applied on Inventory Cost (Exclusive Tax) - Functional | Maximo

When a Purchase order is approved and tax is also charged to the vendor. In this case, Inventory costing will take the price of the unit cost inclusive tax, whereas the last price will be shown as pretax price. 

There is a configuration for in Tax Options of Organization - > Purchasing option. 

Tax Types: there are by default 5 types are available. 

Expand the tax type, let's say TAX1. Under the section "Add Tax 1 Amount to Vendor Price



For All Items:

Tuesday 17 November 2020

Delete a Person from Person Groups (LIST VIEW QUERY) using Automation Script | Maximo

Requirement # 1:

How can we delete all persons from a list of PersonGroups except Group Default at once?

Requirement #2:

 How can we delete a specific person from all the listed person groups?

Solution:






  1. Create an Action Launch Point Script (let's say. DEL_PGTEAM)
  2. Open PERSONGR in application designer: 
    1. Create a Signature Option: DEL_PGTEAM., and choose "This is an action that must be invoked by the user in the UI" in the advance section
    2. Create Action with type Option with the same name as the signature option in step 1.
  3. Grant newly created signature option for specific Security Group.

Monday 26 October 2020

Swagger - Maximo Restful API Categories

Maximo APIs are grouped into modules based on the functional aspect of the software they cater to. 

Here is the link to the list of all modules and then proceed with swagger to open one by one based on the need/requirements.

https://localhost/maximo/maximomodules.jsp


or use direct link to open selected API in swagger with actions =1 or 0 for no

https://localhost/maximo/oas3/api.html?module=PURCHASE&includeactions=0 

Thursday 22 October 2020

Service Specific to an Application/Object in Maximo - AppService | Maximo

These are wrapped with multiple capabilities as a service to support an Application/object within Maximo. 

for example, a service specifically for asset, another is for workflow, and so on. 

Also, some of the services work globally like Escalations service.

If we look into the log, we can see something like 

BMXAA6348I - The ASSET service is initializing.

BMXAA6348I - The WORKFLOW service is initializing.

 

So as mentioned above, there are 2 types of AppServices

1. App-related services

  • psdi.app.asset.AssetService
  • psdi.app.item.ItemService
  • psdi.app.pr.PRService
  • psdi.app.inventory.InventoryService
  • and so on.

Display Last Workflow Memo in Application field | Maximo

 Requirement

Is it possible to see the last workflow message when I open any record just beside/below the status field? 


Solution: 

Yes, It is possible with 2 different approaches. Let take this example and display the last memo in work order application.

A. Directly with the relationship, no need for a view also. 

B. Create a View to handle a query


A.  Start with easy way, just relationship and display the field

  1. add the following relationship to the workorder
    • Relationship: LAST_MEMO_VIEW
    • Where Clause: ownertable= 'WORKORDER' and ownerid= :workorderid and memo is not null and transid in (select max(transid) from wftransaction where ownerid= :workorderid and memo is not null)
    • Child Object: WFTRANSACTION
  2. Now in the application designer just add a new text field and put LAST_MEMO_VIEW.MEMO in attribute property and make it read-only also. 


Tuesday 20 October 2020

Object Lauch Point - Allow Objet Creation/Deletion (CanAdd/CanDelete) | Maximo

These 2 events fire immediate and do not even wait for the framework to save/insert the record.


Allow Object Creation - canAdd() method of mbo framework

Creation is bit tricky because it runs when there is no record. And because there is no record there is no mbo the implicit variable. In that case, we use "mboset" as 

if mboset.getOwner() is not None and mboset.getOwner().getName()=="PO" and mboset.getOwner().isNull("vendor"): 

   service.error("PO", "vendor is null") 


Allow Object Delete - canDelete() method of mbo framework

Deletion is simple if we throw an error, the system will prompt with an error and stop further processing, and the record will not be deleted.  


if mbo.getOwner() is not None and mbo.getOwner().getName()=="PO" and !mbo.getOwner().isNull("vendor"): 

   service.error("PO", "vendor is not null") 

Tuesday 29 September 2020

Change Status of Child Work Orders or Child Tasks from Parent Work Order using Automation Script || IBM Maximo

 This Automation Script will close all child Task work orders when the Parent work order is closed.

Based on Relationship, We can get Child Work orders or Tasks as we required.

When we are closing the work order if the child is complete. It will close the child WO or Tasks.

Launch Point: Attribute

Object: Workorder

Attribute: Status

Binding Variable: status

Body:

from psdi.server import MXServer

Thursday 17 September 2020

Do not Reinstate the PM Workorder if Cancel from Workflow | Maximo

One of the missing features we found is to NOT REINSTATE the work order generated from the PM.

Behavior:

1. Cancel from the Status Change Button:

If the user cancels a work order from the Change Status button, a Dialog box appears something like "do you want to reinstate " with Yes and No buttons. 

(you have the option to choose either Reinstate or Not)

2. Cancel from the Workflow Action

If the Assigned User of workflow wants to CANCEL the record. The system will cancel the workflow and with Reinstate option Yes. 

(No prompt/dialogs appear to ask for reinstating  Yes or No. )


Therefore below is the solution in Jython: 

Get PersonID of the Logged in User in Automation Script | Maximo

There are multiple ways  to get the person id in Automation script, one of the them is as below:

PersonSet = MXServer.getMXServer().getMboSet("MAXUSER", mbo.getUserInfo())

    PersonSet.setWhere("PERSONID=:&PERSONID&")

    vPerson = PersonSet.getMbo(0)

    service.error(user,vPerson.getString("personid"))

    PersonSet.save()

 

For Person ID: -                 :&PERSONID&

For Username  -                   :&USERNAME&

 

or we can also use the one of the implicit variable ( USER )fo the logged in user:

PersonSet = MXServer.getMXServer().getMboSet("MAXUSER", mbo.getUserInfo())

    PersonSet.setWhere("userID='" + user + "'");

    vPerson = PersonSet.getMbo(0)

    service.error(user,vPerson.getString("personid"))

    PersonSet.save()

Tuesday 15 September 2020

Automation for Restriction on Increasing PO Quantity for the PO Revision but Allow the Quantity Decrease || IBM Maximo

Recently we had a requirement of Increasing the PO quantity on the PO revision but allow the quantity increase. So, We used the automation script getPreviousValue() and getCurrentValue() functions in order to resolve this requirement.

Create Database Error Message on Database Config Application.

Object :         POLINE

Attribute:      ORDERQTY

Events:          Validate

Type:             Attribute Type Launch Point

Body:

Monday 14 September 2020

Extract web data using Free Web Scrapping Extension I used in Edge

Extract the data from the website easily with nocoding using https://webscraper.io/

Web Scraper - The #1 web scraping extension


Click here to Install and enable: 



1. open dev tools in any website, (f12), and click on WebScriping tab.

2. create sitemap, name: myWebsite, url: https://macc-fm.com/post_job.php

3. add selector: name: element-wrapper, type: element, select: shift + click 2 or 3 jobs. 

4. within the Element-wrapper, client child selector

a. name: title, type: text, select, click on job Title  > Done Selecting > Save selector.

  b. requirement, type:text ,select job requirement area > Done Selecting > Save selector.

c.expericne, type:text ,select job experience area > Done Selecting > Save selector.

d. degree, type:text > ,select degree area > Done Selecting > Save selector.

e. dept, type:text > ,select dept area > Done Selecting > Save selector.

f. job-desc,type:text > ,select description job > Done Selecting > Save selector.

Thursday 3 September 2020

How Maximo Populates Lead Attribute of Person Group on Work Order Application || IBM Maximo

  • Lead is inherited from PM if defined in PM.
  • Group Default Person in Person Group is selected based on person calendar availability between work order target start and complete dates of attached "Calendar/ Shift".
  • The alternate person will be populated if group default is not available.
  • if alternate is also not available, Lowest person  in the sequence of person group with calendar availability will be populated .
  • The Calendar and shifts should be properly applied.

Saturday 15 August 2020

Conditional Lookup Functionality for List View Search using Automation Script isZombie() Method || IBM Maximo

Recently we had a requirement of conditional lookup for Maximo list view search. We have a custom column called sub-work type which is based on the value selected on the main work type attribute. This functionality on the application was working fine using table domain but it wasn't working on the list view in Maximo.

SO we developed a solution using conditional lookup automation script in Maximo list view search fields. First, we got the where clause of the current APP from memory in wclause variable, and then we got the work type i.e. CM or PM value using the split function. Then by using the zombie() method we set the work type value for a list where clause.

Object

WORKORDER

Type

ATTRIBUTE LAUNCH POINT (Jython)

Attribute

WOSUBTYPE

Name

WOSUBTYPE

Body

from psdi.common.context import UIContext

appName = mbo.getThisMboSet().getParentApp()

if appName in ('PLUSPWO','PLUSPWOCMP'):

#Get Where clause for list view search

    wclause = service.webclientsession().getCurrentApp().getResultsBean().getMboSet().getUserAndQbeWhere() 

 #Search worktype value of list view

    if mbo.isZombie():

         clause=wclause.split("worktype")[1].split("'")[1]

         listWhere="worktype='"+clause+"'"

Saturday 8 August 2020

Find First Empty Column in a Row | Excel

If you want to find first EMPTY column in row, then use this formula into (column I) to find the index of the empty column (see column I). 

#N/A means there is no column , like row 3


 =MATCH(TRUE,INDEX(A3:G3="",0),0)

Thursday 23 July 2020

Question: A Lot expiry received from vendor. if I transfer it to another store/bin/lot, does the expiry will also transfer? | Maximo

Question: 
A Lot expiry received from vendor. if I transfer it to another store/bin/lot, does the expiry will also transfer? 

Answer:
It's better to keep the same lot number while transferring from one store to another, but even then the Expiry of Lot will not be transferred. 



Thursday 18 June 2020

Cancel a Work Order If Actual material Exists | Maximo

Question:
Can we cancel a workorder if there is material in Actuals?

Answer:
The product design team have confirmed that a user is able to cancel a Work Order as long as the Material has a zero cost associated to it.

To check the Cost, Goto > Select Action > View > Cost.

Sunday 14 June 2020

List of Items as Parameters of a Function, Map() | Python

Map isn't pythonic, use list instead. 

map(func, iterable)

func : It is a function to which map passes each element of given iterable.
iter : It is a list which is to be mapped( list of parameters to be passed to func).

lets say:
>>> func add(a):
>>>     return a+5;
>>> print add(2)    // 2 as parameter, it will return 2+5=77

//lets give a list of parameters instead of only 1 param

>>> myList = (2,6,7,1)

//first lets do the same with for loop.
>>> for i in number:
...     print add(i);...
96

// lets do the same with list.
func add(a):
    returnn a+5;
myList = (2,6,7,1);
// all items of list will be the parameter for the function add().
>>> print map(add, myList)
[610115]

Sunday 31 May 2020

Retrieve Saved Password from System Properties in Jython | Maximo

from psdi.server import MXServer

if mbo.getString("ASSETNUM") == '10002':

    service.error("cust",MXServer.getMXServer().getProperty("mxe.db.password"))


Original Post: http://vietmaximo.blogspot.com/2020/07/display-password-stored-in-system.html 

Thursday 21 May 2020

Maximo product configuration matrix | IBM Maximo


A configuration matrix for Maximo. New product versions are released and tested on an ongoing basis. So  below is the link for IBM Maximo configuration Matrix that can help build and configure environment in complicated environments.

Configuration Matrix will give you understanding of installation and configuration of IBM Maximo patches, hot fixes, add-ons and versions compatibility as well.



 https://www.ibm.com/support/pages/maximo-product-configuration-matrix

Thanks

Wednesday 20 May 2020

Usage of Discardable MBO sets to less utilize the JVM Memory.

The best approach for MboSets , is to make the MboSet "Discardable". This tells Maximo to not place data in the Cache, freeing up memory.


assetMboSet = mbo.getMboSet("ASSET")
assetMboSet.setFlag(MboConstants.DISCARDABLE, true)
curMbo = mbo.moveFirst()
while
        curMbo != None:

curMbo = mbo.moveNext().


You can see above it only take one line of code but can have a big impact on memory usage.

Note: "Discardable" MboSet is always read-only.

If you are struggling with JVM memory availability in your Maximo environment, this is an easy way to help free up some JVM memory.

Tuesday 19 May 2020

Enabling SAML SP-Initiated web single sign-on (SSO) | IBM Maximo

This task assumes that you have enabled your system to use the SAML web SSO feature. If you have not done this yet, see Enabling your system to use the SAML websingle sign-on (SSO) feature.

This task provides an example class and the steps to configure SP-initiated SSO.

Develop a SAML authentication request provider that implements the com.ibm.wsspi.security.web.saml.AuthnRequestProvider interface.

The com.ibm.wsspi.security.web.saml.AuthnRequestProvider class is found in the was_public.jar file in the (was_home)/dev directory.

The com.ibm.ws.wssecurity.saml.common.util.UTC class used in this sample can be found in the (was_home)/plugins directory.

The method getAuthnRequest(HttpServletRequest req, String errorMsg, String acsUrl, ArrayList<String> ssoUrls) must return a map that includes four entries with the following keys:

AuthnRequestProvider.SSO_URL

The SAML identity provider's Single-Sign-On URL.

AuthnRequestProvider.RELAY_STATE

The relayState as defined by the SAML Web Browser single-sign-on profile.

AuthnRequestProvider.REQUEST_ID

The value for this key must match the ID attribute's value in the AuthnRequest message.

AuthnRequestProvider.AUTHN_REQUEST

A Base64 encoded AuthnRequest message as defined in the spec. Your code is responsible for generating the AuthnRequest message.

You have to change your code as per your SSO URL you generated from Meta data.


import java.util.ArrayList;
                import java.util.HashMap;
                import javax.servlet.http.HttpServletRequest;
                import com.ibm.websphere.security.NotImplementedException;
                import com.ibm.ws.wssecurity.saml.common.util.UTC;
                import com.ibm.wsspi.security.web.saml.AuthnRequestProvider;
                .........

                public HashMap <String, String> getAuthnRequest(HttpServletRequest req, String errorMsg,
               String acsUrl, ArrayList<String> ssoUrls)
            throws NotImplementedException {
      
            //create map with following keys
            HashMap <String, String> map = new HashMap <String, String>();
          
            String ssoUrl = "https://example.com/saml20/Login";
            map.put(AuthnRequestProvider.SSO_URL, ssoUrl);

            String relayState = generateRandom();
            map.put(AuthnRequestProvider.RELAY_STATE, relayState);

            String requestId = generateRandom();
            map.put(AuthnRequestProvider.REQUEST_ID, requestId);
           
            //create AuthnRequest                       
            String authnMessage = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
                   +"<samlp:AuthnRequest xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\" "
                   +"ID=\""+requestID+"\" Version=\"2.0\" "
                   + "IssueInstant=\"" +UTC.format(new java.util.Date())+ "\" ForceAuthn=\"false\" IsPassive=\"false\""
                   + "ProtocolBinding=\"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST\" "
                   + "AssertionConsumerServiceURL=\"" +acs+"\" "
                   + "Destination=\"" +destination +"\"> "
                   + "<saml:Issuer xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\">"
                   + issuer
                   +"</saml:Issuer> <samlp:NameIDPolicy"
                   +"Format=\"urn:oasis:names:tc:SAML:2.0:nameid-format:transient\""
                   +"SPNameQualifier=\"mysp\""
                   +"AllowCreate=\"true\" /> <samlp:RequestedAuthnContext Comparison=\"exact\"> "
                   +"<saml:AuthnContextClassRef xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\">"
                     +"urn:oasis:names:tc:SAML:2.0:ac:classes:</samlp:RequestedAuthnContext> </samlp:AuthnRequest>";

            map.put(AuthnRequestProvider.AUTHN_REQUEST, authnMessage);
                return map;
            }
             private String generateRandom() {
             //implement code that generates a random alpha numeric String that is unique
             //each time it is invoked and cannot be easily predicted (like a counter)
             }


Put a jar file that contains your custom class in the (WAS_HOME)/lib/ext directory.

Configure the SAML web SSO to use your AuthnRequest message.

Log on to the WebSphere Application Server administrative console.
 
Click Security > Global security.
 
Expand Web and SIP security and click Trust association.
 
Click Interceptors.
 
Click com.ibm.ws.security.web.saml.ACSTrustAssociationInterceptor
 
For Custom properties,
click new, then complete the following custom property information,
where id is what you assigned to the SSO Service Provider (SP) for which you want this property to apply:

Name: sso_<id>.sp.login.error.page
Value: The class name of your custom AuthnRequestProvider implementation.


For More Info please visit : IBM Knowledge center 

SAML web single sign-on








Enabling and Configuring your Maximo system to use the SAML web single sign-on (SSO) | IBM Maximo

Install the SAML ACS application.
Choose one of the following approaches:

Using the administrative console, install the app_server_root/installableApps/WebSphereSamlSP.ear file to your application server or cluster.

Install the SAML ACS application by using the python script.
    
Navigate to the app_server_root/bin directory.
    
Run the installSamlACS.py script.

wsadmin -f installSamlACS.py install <nodeName> <serverName>
 or
wsadmin -f installSamlACS.py install <clusterName>

Copy where node Name is the node name of the target application server, server Name is the server name of the target application server, and cluster Name is the name of the application server cluster.

Enable SAML

You can enable SAML by using either the wsadmin command utility or the administrative console.

 Enable SAML using the wsadmin command utility.

Start the WebSphere Application Server.

Start the wsadmin command utility from the app_server_root/bin directory by entering the command:
wsadmin -lang jython.

At the wsadmin prompt, enter the following command: AdminTask.addSAMLTAISSO('-enable true -acsUrl https://<hostname>:<sslport>/samlsps/<any URI pattern string>')

where host name is the host name of the system where WebSphere Application is installed and SSL port is the web server SSL port number (WC_defaulthost_secure).

 Save the configuration by entering the following command: AdminConfig.save().

Exit the wsadmin command utility by entering the following command: quit.
    
Restart the WebSphere Application Server.

 Enable SAML using the administrative console.
    
Log on to the WebSphere Application Server administrative console.
    
Click SecurityGlobal security.
    
Expand Web and SIP security and click Trust association.
    
Under the General Properties heading, select the Enable trust association check box and click Interceptors.
   
Click New and enter com.ibm.ws.security.web.saml.ACSTrustAssociationInterceptor in the Interceptor class name field.

Under Custom properties, fill in the following custom property information:

Name: sso_1.sp.acsUrl and
Value: https://<hostname>:<sslport>/samlsps/<any URI pattern string>
where host name is the host name of the system where WebSphere Application is installed and sslport is the web server SSL port number (WC_defaulthost_secure).

Note: 
If you need to have multiple, similar entry points for your SAML workflows, you can specify a wildcard value instead of a specific URI pattern string at the end of the URL specified as the value of this property.
Specifying a wildcard as part of the value of this property eliminates the need to separately configure each of the similar entry points.
Following are some examples of valid ways to include a wildcard as part of the value for this property:
https://<server>/<context_root>/ep1/path1/p*
https://<server>/<context_root>/ep1/path1/*
https://<server>/<context_root>/ep1/*


Warning: 


If you are using metadata to configure your SSO, wildcards cannot be used in the acsUrl definition.

Click New and enter the following custom property information:
Name: sso_1.sp.idMap and Value: idAssertion.
Click OK.

Go back to SecurityGlobal security and click Custom properties.

Click New and define the following custom property information under General properties:
Name: com.ibm.websphere.security.DeferTAItoSSO and
Value: com.ibm.ws.security.web.saml.ACSTrustAssociationInterceptor.

Warning:

The property com.ibm.websphere.security.DeferTAItoSSO,
was previously used in the default configuration of all installed servers.
Now it is only used as part of the SAML configuration. Therefore, even if this property already exists in your system configuration,
you must change its value to com.ibm.ws.security.web.saml.ACSTrustAssociationInterceptor.

Multiple values, separated with commas, cannot be specified for this property. It must be set to a single SAML

Click New and define the following custom property information under General properties:
Name: com.ibm.websphere.security.InvokeTAIbeforeSSO and
Value: com.ibm.ws.security.web.saml.ACSTrustAssociationInterceptor.
Click OK.


Restart WebSphere Application Server.

The SAML is now enabled for WebSphere Application Server.


For Reference Please visit: IBM Knowledge center 

https://www.ibm.com/support/knowledgecenter/SS7K4U_9.0.5/com.ibm.websphere.zseries.doc/ae/twbs_enablesamlsso.html 








Exception Handling in Jython | IBM Maximo

from psdi.util.logging import MXLoggerFactory
from psdi.util.logging import MXLogger


try:
       
    log = MXLoggerFactory.getLogger("maximo.application.AUTOSCRIPT")
    scriptname="<script name>"
    log.info("******Entering Autoscript : " +scriptname +"******")
       
   
    log.debug("[DEBUG] script "+scriptname+" <Message>")
   
    log.info("******Existing Autoscript : " +scriptname +"******")   

Exceptions Handling

except Exception, e:
    print >> sys.stderr, "[ERROR] script "+scriptname+" failed: ",e.message
    print >> sys.stdout, "[ERROR] script "+scriptname+" failed: ",e.message
    log.error("[ERROR] script "+scriptname+" failed: " +e.message)

How to use Maximo Logger in Jython Script to capture Logs of script | IBM Maximo

Define libraries

from psdi.util.logging import MXLoggerFactory

from psdi.util.logging import MXLogger


call logs

   
log = MXLoggerFactory.getLogger("maximo.application.AUTOSCRIPT")
scriptname="<script_name>"
log.info("******Entering Autoscript : " +scriptname +"******")






<Script body>



log.info("******Exiting Autoscript : " +scriptname +"******")

Monday 18 May 2020

Utility to export Maximo Automation scripts to directory for backup and version control.

Utility will help extract the all scripts to directory for version control and for backup as well.


Download utility:

Maximo automataion script utility

Installation:
 

Extract the files and copy into <SMP Path>/maximo/tools/maximo/ path.
 

Running: 
Run the extract automation scripts_utility file.
It will take connection from maximo.properties file.
will create and update files in <SMP Path>/maximo/tools/maximo/automatioscripts folder.
 

Note: utility will work for Java 1.7 or above. Source file is available in same folder. You can recompile and use, if required in lower versions.



Windows: run extractAutomationScripts.bat

Linux or AIX run ./extractAutomationScripts.sh


Result: folder will create with automation scripts and create files with automation script name and description will copy top in text with comment.

Thanks

  



Sunday 17 May 2020

mboSet() in Automation Script, getMboSet() vs getThisMboSet() | Maximo

Most of the time automation script creates an implicit variable "mbo". It represents the current record on which the script was triggered. 

let say we open one workorder: 123. in this case, our mbo is 123. 

what If we want to get the MboSet of this mbo. (like we are going back to the list tab :)
here you go. 

mboSet = mbo.getThisMboSet()

2. Most common way to call an mboset is using famous method , which is
mbo.getMboSet("PR")
where PR is the Relation Name already exists in database configuration from this record. 

3. or we can create at run time a new relation with WhereClause, like this:
 woSet = mbo.getMboSet("woSet ", "WORKORDER", "status = 'APPR' and siteid = 'BEDFORD'")

4th and last is get any MBO from the system, which is the least recommended if the things can be handled with first 3 methods.  
If the "mbo" implicit variable is not exists then you need this:
woSet = MXServer.getMXServer().getMboSet("WORKORDER", userInfo)