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)


Invoke/Call a Publish Channel Conditionally - Automation Script | Maximo


Normally trigger point for the Publish channels is Event Listener, which is save/update any record. 

Question: Can we send the data using publish channel with a custom trigger point /condition ??

Answer: Yes you can. by using Maximo Automation Script. 
Below is the simple tricks to call a publish channel 

server = MXServer.getMXServer()
userInfo = mbo.getUserInfo()
whereClause = <CONDITION>
server.lookup("MIC").exportData("<Publish Channel Name>", "<External System Name>", whereClause, userInfo, 1000)
---------------------------------
Another example:
micSrv = MXServer.getMXServer().lookup("MIC")
server.lookup("MIC").exportData("MXPO", "LegecyApp", " ponum='"+vPONum+"' and revisionnum="+vREVNUM , micSrv.getNewUserInfo() , 1)


Note:

Mic is old service name for MIF, but still the same name


Sunday 10 May 2020

Creation of Yes / No User Input Dialog Validation for Custom Status using Automation Script || IBM Maximo

Today we are going to show you the creation of user user input dialog box for the custom status field. We have a custom application which has the custom status field, it changes the status of work order tasks based on this custom status. The requirement came when there was no validation when the user changed the status. We will show you how created validation dialog box using automation script.


1. Go to Database Configuration and create a message for user input

      Message Group:  os_taskstatus

      Message Key:      os_taskstatus

      Value:                Do you really want to change the status?

      Buttons:              Yes, No


2. Create Automation Script:

      Launch Point:    Attribute

      Events:          Validate

      Object:               WOACTIVITY

      Attribute:            ZZOSACTIVITYSTATUS

      Script:                  Jython

Wednesday 6 May 2020

Maximo Cluster deployment Assigning names to JVMs as Generic JVM arguments.

In WebSphere you can set the mxe.name property directly on the JVM. This is done in the Generic JVM arguments for each individual JVM. This prevents each cluster from starting up with a random name e.g. mxserverc1. This way we can specify the cron tasks do not run properties at the instance level for each JVM in the database.

1. In your WebSphere Console, expand 'Server Types' and click on 'WebSphere Application Servers'. From here click on maximo_ui01.

2. Under 'Server Infrastructure'  expand 'Java and Process Management' and click on 'Process Definition'. Under 'Additional Properties' click on 'Java Virtual Machine'.

3. There will be a box that says 'Generic JVM arguments' in here we want to enter -Dmxe.name=maximo_ui01 as seen below.

-Dsun.rmi.dgc.ackTimeout=10000 
-Djava.net.preferIPv4Stack=true 
-Dmxe.name=maximo_ui01 

4- Repeat the above steps for your remaining JVM's.  For example Dmxe.name=maximo_ui02,Dmxe.name=maximo_mif01,Dmxe.name=maximo_rep01 and Dmxe.name=maximo_cron01.

 This should be done before deploying Maximo applications on cluster and then start you cluster.

Checking physical & Logical volumes or LPARS in AIX 7.1

To check Physical Volumes run below commands
lspv

To obtain a list of all the physical volumes known to a node and to find out the volume groups to which they belong, use the lspv command. If you do not specify the name of a volume group as an argument, the lspv command displays every known
physical volume in the system.

lspv hdisk2


To check Logical Volumes run below commands
 
To check the state of logical volumes defined on the physical volumes, use the lspv -l command and specify the logical name of the disk to be checked.

As shown in the following example, you can use this command to determine the names of the logical volumes defined on a physical volume.

lspv -l hdisk2




Thanks

for more details https://www.ibm.com/support/knowledgecenter/en/SSPHQG_7.2/trouble/ha_trgd_check_log.html

Restart Maximo JVMS,Nodes and DMGR (Nodes,DMGR,Syncnode)

Goto WAS ,Login from Wasadmin user, Stop all the JVMS (Maximo_u01,02,03,04, Cron01,Cron02,Rep01,Rep02,Mif01,Mif02)

Go to System administartion stop all Nodes.

------------------Stop Nodes--------------------------------------


Now access server and run following commands from both servers.

server01  , server02

path:server01

/app/IBM/WebSphere/AppServer/profiles/AppSrv01/bin/

./stopNode.sh -username wasadmin -password <password>

path:server02

/app/IBM/WebSphere/AppServer/profiles/AppSrv01/bin/

./stopNode.sh -username wasadmin -password <password>



------------------Stop DMGR------------------------------------------

Goto wasadmin DMGR Path

path:server01

/app/IBM/WebSphere/AppServer/profiles/Dmgr01/bin/

./stopManager.sh -username wasadmin -password <password>


------------------Start DMGR-----------------------------------------

Goto wasadmin DMGR Path

path:mdrcqeamsapp01.qterminals.local

/app/IBM/WebSphere/AppServer/profiles/Dmgr01/bin/

./startManager.sh -username wasadmin -password <password>




-----------------Sync Nodes---------------------------------------------
path:server01

/app/IBM/WebSphere/AppServer/profiles/AppSrv01/bin/

./syncNode.sh <DMGR HOSTNAME> 8879 -username wasadmin -password <password>


path:server02

/app/IBM/WebSphere/AppServer/profiles/AppSrv01/bin/

./syncNode.sh <DMGR HOSTNAME> 8879 -username wasadmin -password <password>

-----------------Start Nodes--------------------------------------------
path:server01

/app/IBM/WebSphere/AppServer/profiles/AppSrv01/bin/

./startNode.sh -username wasadmin -password <password>   (Password is needed to start Nodes)

path:server02

/app/IBM/WebSphere/AppServer/profiles/AppSrv01/bin/

./stopNode.sh -username wasadmin -password <password> (Password is needed to start Nodes)


-----------------Start All JVMS--------------------------------------- 
Once Nodes syncing is done, Go to JVMS and start all the JVMS.



 

Jacl script to Deploy Maximo application Manually using virtual Host.


Applications having build size more then 1 GB need to be deployed from wsadmin using JACL or Python script.
Below example is how to deploy Maximo Application using Jacl commands in DMGR.

Once Application build is done 
In my case I have four applications all with separate functionality.
maximo_ui , maximo_mif, maximo_rep, maximo_cron

after EAR built you will have ear file in default folder.
/app/IBM/SMP/maximo/deployment/default/
First Copy ear file (maximo_ui.ear).
Navigate to the WAS bin folder.
/app/IBM/WebSphere/AppServer/bin/
Paste maximo_ui.ear file within bin folder.

from terminal window (putty,mobaxterm,VNC)

Navigate to the
/app/IBM/WebSphere/AppServer/bin/

Run ./wsadmin.sh -username wasadmin -password wasadmin
DMGR will be login automatically.

wsadmin>

Now if application are already installed /deployed in WAS then you have to uninstall them.
Below are the commands to do it.

wsadmin>$AdminApp uninstall MAXIMO_UI
once uninstall done.
wsadmin>$AdminConfig save.

for REDEPLOY OR INSTALLING again.

wsadmin>$AdminApp install maximo_ui.ear { -usedefaultbindings -defaultbinding.virtual.host maximoui_host }


Make sure Virtual host is defined in Environment of WAS.

$AdminApp install maximo_mif.ear { -usedefaultbindings -defaultbinding.virtual.host maximomif_host }

$AdminApp install maximo_cron.ear { -usedefaultbindings -defaultbinding.virtual.host maximocron_host }

$AdminApp install maximo_rep.ear { -usedefaultbindings -defaultbinding.virtual.host maximorep_host }

Dont forget to issue save command at the end of installation finish.
wsadmin>$AdminConfig save.

 wsadmin>quit. 

Once done goto WAS.
Login from wasadmin.
Navigate to the deployed application (MAXIMO_UI) in Enterprise Applications.
Open Application and click on manage modules. to merge  application on cluster.
Also click on Virtual host to assign all the virtual hosts as well.

once Finish,Restart Nodes and DMGR.
Start JVMS.

For more Info visit below IBM tech Note:
https://www.ibm.com/support/pages/manually-completing-product-deployment




Friday 1 May 2020

Refresh a Record by clicking the Button | Maximo

Sometimes data is  updated and we need to navigate back to the list view and re-open the record to see the updates,
or we copy the record id into the search field and hit search button to refresh. 

But with this trick, we can add Push Button we can refresh the record.

1. Refresh the Record, For Instance PR application

Drag Push button control and set these properties as below:

Label: Refresh PR 
Event: reset 
Target id: results_showlist



2. Refresh Child Record, For Instance PR Line Tab