Maximo

 View Only
Expand all | Collapse all

MAS 9 to Manage user synchronization

  • 1.  MAS 9 to Manage user synchronization

    Posted Thu January 30, 2025 12:15 AM

    Hello,

    For the several years, we follow below mentioned conventions for users and persons in MAXIMO 7.6. There is absolutely no possibility for the business to change to the best practises in this connection.

    Person id: A numeric number e.g. 999999

    Email Id: JoneDoe@company.com

    User Id: JoneDoe

    SAMLID: JoneDoe

    Our custom integration programs populate the details of PERSON, EMAIL and PHONE MBOs. This happens much earlier before the new employee is introduced in MAS 9. For example, a new employee with person id 555555, Email id: JamesBond@company.com is joined the organization. His details in PERSON, EMAIL and PHONE MBOs are synchronised in Manage.

    Now, he is introduced to the Facilities dept and the system administrator adds his details in MAS 9 having details such as Useid: JamesBond,  Email id=JamesBond@company.com,  SAMLId= JamesBond

    The cron task that syncs MAS 9 to Manage will create additional person and possibly the related MBOs (e.g. email, phone etc) records in manage which we don't want. 

    To address this, I am trying to do the following:

    Develop an automation script OSIN.MASPERUSER (integration script that intercepts the message for MAXUSER MBO) that does the following:

     

    1. Get the value of the email address from the external record (ER).

    2. Read the "EMAIL" mbo with the following condition:

                 email.emailaddress=<email address from ER>

    1. If the record does not exist then, raise the exception with the error message suggesting "email/person details do not exist in Manage for the user xxxxxx" and skip processing that row and go to the next row.

    2. If the record exists in "EMAIL" mbo, then, get the value of "email.personid" into the variable "personid".

    3. Map the value of "personid" to "maxuser.personid".

    4. Lastly, skip processing the information in "person", "email" and "phone" MBOs by executing the method titled "skipMbo". This way, it will not insert/update the records into "email","person" and "phone" mbos.

    if (ctx.getMosDetailInfo().getObjectName() == "EMAIL" or

            ctx.getMosDetailInfo().getObjectName() == "PERSON" or

            ctx.getMosDetailInfo().getObjectName() == "PHONE"):

       

            ctx.skipMbo() 

    My challenge is how to access the ER record? What API call (any example?) will allow me getting email address from ER?

     

     Please help.

    Thanks



    ------------------------------
    Pankaj Bhide
    ------------------------------


  • 2.  RE: MAS 9 to Manage user synchronization

    Posted Fri January 31, 2025 05:47 AM
    Edited by Andrzej Więcław Tue February 11, 2025 03:23 PM

    Hi Pankaj,

    this sounds just like the process at one of my customers :-) 

    There are probably other ways to do it but I would recommend creating Object Structure integration processing automation script for MASPERUSER object structure which may look as follows.

    Script Name: OSIN.MASPERUSER

    Script Source:

    from psdi.mbo import SqlFormat
    
    def mboRules(ctx):
        table = ctx.getProcessTable()
        if table == "PERSON":   
            data = ctx.getData()
            # Mark the character casing - for parent/child navigation you need to use upper-case names
            emails = data.getChildrenData("EMAIL")
            # Find primary e-mail - example code below looks for a first found primary e-mail
            # Mark the character casing - you need to use lower-case to access JSON attributes
            primaryEmail = next((e.getCurrentData("emailaddress") for e in emails if e.getCurrentDataAsBoolean("isprimary")), None)
            # Find PERSON record with given e-mail
            mboSet = ctx.getMboSet()
            # Reset QBE initialized by the integration framework
            mboSet.resetQbe()
            sqf = SqlFormat(ctx.getUserInfo(), "exists(select 1 from email where email.personid = person.personid and email.emailaddress = :1)")
            sqf.setObject(1, "EMAIL", "EMAILADDRESS", primaryEmail)
            mboSet.setWhere(sqf.format())
            mbo = mboSet.moveFirst()
            if mbo:
                # Inject identified person MBO into the integration processing pipeline. 
                # The rule is that if mboRules function returns MBO (through the ctx) then 
                # the integration logic does not look for one on its own using standard rules.
                # The other way to do this would be to simply override "personid" column value
                # in the inbound JSON structure data but passing back MBO you save one
                # SQL query as the object to be processed has already been identified.
                ctx.setMbo(mbo)
            else:
                # Raise exception
                ctx.error("<msggrp>", "<msgkey>", [ "param1" ])
        elif table in ["EMAIL", "PHONE"]:
            # Skip updates to the EMAIL and PHONE tables
            ctx.skipMbo()
    #end def

    MASPERUSER object structure, used by MAS Core to Manage synchronization, uses PERSON record at the top level and you cannot really skip this one as you would not let the integration logic create corresponding child level MAXUSER record (PERSON/MAXUSER). If you do not want MAS Core to update person's details (display name, title, etc.) then you can do that by enabling Inbound Setting Restrictions for the attributes you're interested in. 



    ------------------------------
    Andrzej Więcław
    Maximo Technical Consultant
    AFRY
    Wrocław, Poland
    ------------------------------



  • 3.  RE: MAS 9 to Manage user synchronization

    Posted Sun February 02, 2025 10:10 AM

    Hello,

    Thank you for sharing the code and information. I will surely study them and let you know if I need more clarifications.

    Thanks again.



    ------------------------------
    Pankaj Bhide
    ------------------------------



  • 4.  RE: MAS 9 to Manage user synchronization

    Posted Tue February 04, 2025 01:40 PM

    You are a genius!



    ------------------------------
    Günter Metzner
    ------------------------------



  • 5.  RE: MAS 9 to Manage user synchronization

    Posted Wed February 05, 2025 09:45 AM

    Hello,

    Thanks for your advice and help. I was able to follow the script. 

    Any clue how to map the value person id to "maxuser.personid"? 

    Thanks again.



    ------------------------------
    Pankaj Bhide
    ------------------------------



  • 6.  RE: MAS 9 to Manage user synchronization

    Posted Wed February 05, 2025 12:59 PM

    Hi Pankaj,

    I'm not sure what do you mean... Could you please elaborate a bit more what is it that is not working?
    Basically when the script finds a PERSON record by e-mail, then it injects it into the integration pipeline and MAXUSER record gets created for given PERSON, therefore MAXUSER.PERSONID gets set to PERSON.PERSONID.



    ------------------------------
    Andrzej Więcław
    Maximo Technical Consultant
    AFRY
    Wrocław, Poland
    ------------------------------



  • 7.  RE: MAS 9 to Manage user synchronization

    Posted Wed February 05, 2025 07:52 PM

    Hello,

    Thank you for your patience. The concept of " it injects it into the integration pipeline and MAXUSER record gets created for given PERSON (the code line 

    ctx.setMbo(mbo)

      is relatively new to me).  I was therefore confused. I will try the same and get back to you.

    Regards

    Pankaj Bhide



    ------------------------------
    Pankaj Bhide
    ------------------------------



  • 8.  RE: MAS 9 to Manage user synchronization

    Posted Tue February 11, 2025 03:29 PM

    Hi Pankaj,

    I've just realised that my original automation script was missing following lines:

            # Reset QBE initialized by the integration framework
            mboSet.resetQbe()
    

    With this change you'll get MAXUSER record created properly for an existing PERSON record.



    ------------------------------
    Andrzej Więcław
    Maximo Technical Consultant
    AFRY
    Wrocław, Poland
    ------------------------------



  • 9.  RE: MAS 9 to Manage user synchronization

    Posted Thu February 06, 2025 07:37 AM

    Sorry for the inconvenience.

    The run of the script gives the following log

    06 Feb 2025 09:28:27:218 [INFO] [MXServer] [CID-CRON-288590] [pool-4-thread-12] Correlation started, correlation data added:  TaskName:AsyncImmediateJobCron
    06 Feb 2025 09:28:27:218 [INFO] [MXServer] [CID-CRON-288590] [pool-4-thread-12] Correlation started, correlation data added:  InstanceName:AsyncImmediate TaskName:AsyncImmediateJobCron
    06 Feb 2025 09:28:27:218 [INFO] [MXServer] [CID-CRON-288590] [pool-4-thread-12] Correlation started, correlation data added:  InstanceName:AsyncImmediate TaskName:AsyncImmediateJobCron Activity:ACTION
    06 Feb 2025 09:28:27:251 [DEBUG] [MXServer] [] [maximo-ReportCancelStatusUpdateThread] ReportCancelStatusUpdateThread getting cancelled reports from database
    06 Feb 2025 09:28:27:356 [INFO] [MXServer] [CID-CRON-288590] [pool-4-thread-12] Correlated data: BEGIN InstanceName:AsyncImmediate TaskName:AsyncImmediateJobCron Activity:ACTION ElapsedTime:138 ms  END
    06 Feb 2025 09:28:28:387 [WARN] [MXServer] [] [Default Executor-thread-10440] BMXAA7785W - Property mxe.defaultgroups.manage.admin does not exist.
    06 Feb 2025 09:28:28:387 [WARN] [MXServer] [] [Default Executor-thread-10440] BMXAA7785W - Property mxe.defaultgroups.hputilities.admin does not exist.
    06 Feb 2025 09:28:28:387 [WARN] [MXServer] [] [Default Executor-thread-10440] BMXAA7785W - Property mxe.defaultgroups.hputilities.user does not exist.
    06 Feb 2025 09:28:28:387 [WARN] [MXServer] [] [Default Executor-thread-10440] BMXAA7785W - Property mxe.defaultgroups.predict.admin does not exist.
    06 Feb 2025 09:28:28:387 [WARN] [MXServer] [] [Default Executor-thread-10440] BMXAA7785W - Property mxe.defaultgroups.predict.user does not exist.
    06 Feb 2025 09:28:28:387 [WARN] [MXServer] [] [Default Executor-thread-10440] BMXAA7785W - Property mxe.defaultgroups.health.admin does not exist.
    06 Feb 2025 09:28:28:387 [WARN] [MXServer] [] [Default Executor-thread-10440] BMXAA7785W - Property mxe.defaultgroups.health.user does not exist.
    06 Feb 2025 09:28:28:409 [ERROR] [MXServer] [] [Default Executor-thread-10440] Error from script OSIN.MASPERUSER launchPointName: null
    06 Feb 2025 09:28:28:410 [ERROR] [MXServer] [] [Default Executor-thread-10440] Die Verarbeitung für MASPERUSER ist fehlgeschlagen. Die Objekt ist 1. Das primäre Objekt ist PERSON. Der Schlüssel ist TTTMIBH.<msggrp>#<msgkey>
    06 Feb 2025 09:28:28:411 [ERROR] [MXServer] [] [Default Executor-thread-10440] Error while processing the incoming transaction
    psdi.util.MXApplicationException: <msggrp>#<msgkey>
    at com.ibm.tivoli.maximo.script.ScriptService.error(ScriptService.java:455) ~[businessobjects.jar:?]
    at jdk.internal.reflect.GeneratedMethodAccessor642.invoke(Unknown Source) ~[?:?]
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
    at java.lang.reflect.Method.invoke(Method.java:572) ~[?:?]
    at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:190) ~[jython.jar:2.7.3]
    at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:208) ~[jython.jar:2.7.3]
    at org.python.core.PyObject.__call__(PyObject.java:512) ~[jython.jar:2.7.3]
    at org.python.core.PyObject.__call__(PyObject.java:517) ~[jython.jar:2.7.3]
    at org.python.core.PyMethod.__call__(PyMethod.java:171) ~[jython.jar:2.7.3]
    at org.python.pycode._pyx181.mboRules$1(<script>:31) ~[?:?]
    at org.python.pycode._pyx181.call_function(<script>) ~[?:?]
    at org.python.core.PyTableCode.call(PyTableCode.java:173) ~[jython.jar:2.7.3]
    at org.python.core.PyBaseCode.call(PyBaseCode.java:306) ~[jython.jar:2.7.3]
    at org.python.core.PyFunction.function___call__(PyFunction.java:474) ~[jython.jar:2.7.3]
    at org.python.core.PyFunction.__call__(PyFunction.java:469) ~[jython.jar:2.7.3]
    at org.python.core.PyFunction.__call__(PyFunction.java:459) ~[jython.jar:2.7.3]
    at org.python.core.PyFunction.__call__(PyFunction.java:454) ~[jython.jar:2.7.3]
    at org.python.jsr223.PyScriptEngine.invokeFunction(PyScriptEngine.java:145) ~[jython.jar:2.7.3]
    at com.ibm.tivoli.maximo.script.JSR223ScriptDriver.evalScript(JSR223ScriptDriver.java:270) ~[businessobjects.jar:?]
    at com.ibm.tivoli.maximo.script.AbstractScriptDriver.runScript(AbstractScriptDriver.java:155) ~[businessobjects.jar:?]
    at psdi.iface.mos.MosProcessImpl.scriptMboRules(MosProcessImpl.java:630) ~[businessobjects.jar:?]
    at psdi.iface.mos.MosProcessImpl.setMainMaximoTable(MosProcessImpl.java:1114) ~[businessobjects.jar:?]
    at psdi.iface.mos.MosProcessImpl.fillMaximoTables(MosProcessImpl.java:807) ~[businessobjects.jar:?]
    at psdi.iface.mos.MosProcessImpl.processExternalData(MosProcessImpl.java:345) ~[businessobjects.jar:?]
    at psdi.iface.mic.MicSetIn.processExternalData(MicSetIn.java:149) ~[businessobjects.jar:?]
    at psdi.iface.mic.EntMicService.processDataIn(EntMicService.java:1750) ~[businessobjects.jar:?]
    at psdi.iface.mic.EntMicService.processExternalData(EntMicService.java:1646) ~[businessobjects.jar:?]
    at psdi.iface.mic.EntMicService.processExternalData(EntMicService.java:1474) ~[businessobjects.jar:?]
    at com.ibm.tivoli.maximo.intservice.EnterpriseService.secureProcessExternalDataSyncInternal(EnterpriseService.java:169) ~[businessobjects.jar:?]
    at com.ibm.tivoli.maximo.intservice.EnterpriseService.maxAPIKeySecureProcessExternalDataSync(EnterpriseService.java:122) ~[businessobjects.jar:?]
    at psdi.iface.util.WebUtil.invokeEnterpriseEJB(WebUtil.java:247) ~[meaweb.war:?]
    at psdi.iface.servlet.MEAServlet.invokeEJB(MEAServlet.java:538) ~[meaweb.war:?]
    at psdi.iface.servlet.MEAServlet.doPost(MEAServlet.java:359) [meaweb.war:?]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:706) [com.ibm.websphere.javaee.servlet.4.0_1.0.95.jar:?]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:791) [com.ibm.websphere.javaee.servlet.4.0_1.0.95.jar:?]
    at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1266) [com.ibm.ws.webcontainer_1.1.95.jar:?]
    at [internal classes]
    at com.ibm.tivoli.maximo.filter.UnSupportedMethodBlockFilter.doFilter(UnSupportedMethodBlockFilter.java:60) [commonweb.jar:?]
    at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:203) [com.ibm.ws.webcontainer_1.1.95.jar:?]
    at [internal classes]
    at com.ibm.tivoli.maximo.filter.MTIntegrationFilter.doFilter(MTIntegrationFilter.java:68) [meaweb.war:?]
    at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:203) [com.ibm.ws.webcontainer_1.1.95.jar:?]
    at [internal classes]
    [com.ibm.ws.channelfw_1.0.95.jar:?]
    at com.ibm.ws.tcpchannel.internal.WorkQueueManager.attemptIO(WorkQueueManager.java:586) [com.ibm.ws.channelfw_1.0.95.jar:?]
    at [internal classes]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?]
    at java.lang.Thread.run(Thread.java:839) [?:?]






    ------------------------------
    Günter Metzner
    ------------------------------



  • 10.  RE: MAS 9 to Manage user synchronization

    Posted Thu February 06, 2025 07:47 AM

    Perhaps, I should clarify it a little more. 

    We moving from 7.6 to 9 and the users have already been moved.

    If we go to core and change something within an user (e.g. the name) than the change is saved, but the sync fails because of the following error

    java.sql.SQLIntegrityConstraintViolationException: ORA-00001: unique constraint (OurDATABASE.EMAIL_NDX2) violated 

    This index EMAIL_NDX2 is on Object EMAIL and makes sure, that the Email only occours one time in the table (which makes sense)
    The problem is, that it seems that sync thinks it has to be added in this case. But it should update it.
    If we create a new user in CORE, than sync works perfecty, even if we change something afterwards. But already having the user within the tables and just want to change something leed to the error.



    ------------------------------
    Günter Metzner
    ------------------------------



  • 11.  RE: MAS 9 to Manage user synchronization

    Posted Wed February 05, 2025 10:32 AM

    Hi Andrzej,

    thank you for this hint.
    We tried it, but the problem seems to be, that we only can add it to manage and not to core. So it has no effect, becuase the table only exists in Core.

    How do we add it to core? Do you have a manual?

    Thanks in advance

    Kind regards



    ------------------------------
    Günter Metzner
    ------------------------------



  • 12.  RE: MAS 9 to Manage user synchronization

    Posted Wed February 05, 2025 01:05 PM

    Hi Gunter,

    I get the feeling that we're mixing up here different use cases. What I helped Pankaj with was the scenario where he creates user record in MAS Core which needs to be further quite specifically handled when synching MAS Core to MAS Manage.

    Could you please describe your use case? Are you still somehow trying to add user to MAS Manage and hoping that it gets synched to MAS Core?



    ------------------------------
    Andrzej Więcław
    Maximo Technical Consultant
    AFRY
    Wrocław, Poland
    ------------------------------



  • 13.  RE: MAS 9 to Manage user synchronization

    Posted Fri February 07, 2025 10:01 AM

    Hey guys.

    Unless I misunderstood, the database was upgraded, which means all Users are linked to the correct Person records, except these don't exist in MAS Core Mongo users.

    You can still sync Manage to MAS core with MASUSERSYNC Cron job. MAXUSER table has a new field MASISUER which is empty after upgrade. 

    In the Cron MASUSERSYNC configure the parameters:

    ISSUER = local

    OWNER = local

    Save the cron and Activate.  When the Cron instance runs, it will deactivate itself and it will trigger the User synch from Manage to MAS Core.

    Hope this Helps

    David G.



    ------------------------------
    DAVID GUTIERREZ
    ------------------------------