Clarity

Expand all | Collapse all

CA PPM Tuesday Tip:  How To Launch a Process from a Gel Script

navzjoshi0004-15-2015 05:08 AM

  • 1.  CA PPM Tuesday Tip:  How To Launch a Process from a Gel Script

    Posted 04-14-2015 11:47 AM

    WHY

     

    I find myself pointing customers who use processes to this option over and over again.  It is particularly useful when a CA PPM (Clarity) administrator wants to save on licenses.

     

    Launching a process via a gel script will allow you to change who is running a process on-the-fly to someone else with more permissions.  It will also allow you to launch a secondary object-based process to modify an individual object instance using a system action while running a non-object-based process.


    For Example, if you want to have a process convert an idea or any other object to a project, most users won’t have sufficient rights to make the necessary changes.  You can create one user with sufficient rights to do whatever needs doing and when your user with fewer permissions does something that launches the process, you can simply have a gel script that launces a second process with the user who has sufficient rights to do everything specified as the process owner. When the second process is done, control is returned to the primary process.


    Let’s say you are running a non-object-based process as a job and you want to lock/unlock attributes before and after xogging in changes to a number of object instances.  Launching a secondary object-based process allows you to lock/unlock your attributes using a System Action instead of updating tables directly which means you are making these changes in a supported way. 


    I am sure there are many other applications for launching a process via a gel script that I am not mentioning here.

     

     

    HOW


    Use the bpm:startProcess tag (example attached). When you get to the point in your current process where you want to become someone else or make changes to a particular object instance that can’t be done via xog, do it cleanly. Call a GEL script that launches a brand new process as this new super-privileged user or a brand new object-based process for the particular object instance and exit your current one. This way there's no session mess, there's no special table to mess with that might break when the next revision of Clarity comes out and you are never updating tables directly which we all know is a big no-no.



    ***EXAMPLE:

    <gel:script xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:bpm="jelly:com.niku.bpm.gel.BPMTagLibrary"
    xmlns:core="jelly:core"
    xmlns:gel="jelly:com.niku.union.gel.GELTagLibrary"
    xmlns:sql="jelly:sql"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

    <gel:setDataSource dbId="niku"/>

    <!-- Take the target processCode as a parameter -->
    <gel:parameter var="processCode"/>

    <!-- we will launch this next process on the same object id this script is running on-->
    <core:set var="targetObjectId" value="${gel_objectInstanceId}"/>

    <!-- we will launch the next process as admin to avoid rights issues -->
    <core:set var="targetUserId" value="1"/>

    <core:choose>

    <!-- Make sure we've supplied the processCode parameter -->
    <core:when test="${processCode != null &amp;&amp; processCode.length() &gt; 0}">

    <sql:query var="results">
    SELECT
    bdpv.id process_version_id,
    bdo.object_name
    FROM
    bpm_def_processes bdp,
    bpm_def_process_versions bdpv,
    bpm_def_objects bdo
    WHERE bdpv.process_id = bdp.id
    and bdo.pk_id = bdpv.id
    and bdp.process_code = ?
    and (bdo.is_system = 0 or bdo.is_system is null)
    <sql:param value="${processCode}"/>
    </sql:query>

    <!-- Extract the process_version_id, targetObjectKey from the query -->
    <core:set var="targetProcessId" value="${results.rows[0].process_version_id}"/>
    <core:set var="targetObjectKey" value="${results.rows[0].object_name}"/>

    <core:choose>

    <!-- start the process if we've got a valid process_version_id -->
    <core:when test="${targetProcessId != null}">
    <bpm:startProcess processVersionId="${targetProcessId}" initObjectKey="${targetObjectKey}"
    initObjectId="${targetObjectId}" initUserId="${targetUserId}"/>
    </core:when>

    <core:otherwise>
    <gel:log level="ERROR">Cannot find process code '${processCode}' to launch. </gel:log>
    </core:otherwise>

    </core:choose>

    </core:when>

    <core:otherwise>
    <gel:log level="ERROR">processCode parameter has not been supplied</gel:log>
    </core:otherwise>

    </core:choose>

    </gel:script>

     

    *** Gel script written by Sean Harp

     

    NOTE:  If you are running a non-object-based process, you won’t be able to use the existing object id like this script is doing.  However, you will already have had to determine the object_instance_id in the gel script you have already created.  Just use that project id instead of the gel_objectInstanceId. Also, make sure you only launch your process(es) once per object instance so that you don’t get a separate process instance running for each change you make on a single object instance.

     

     

    TERMINOLOGY

     

    Object-based process:  An object has been selected on the Objects tab of the process definition.  Each process instance that is launched is designed to work on a single object instance.


    Non-Object-based process:  No object has been selected on the Objects tab of the process definition. These processes usually make similar changes to many object instances or they xog in data to many object instances. These processes can be launched from the Processes tab in the Organizer.  But, they are usually launched via a scheduled job.



  • 2.  Re: CA PPM Tuesday Tip:  How To Launch a Process from a Gel Script

    Posted 04-14-2015 12:50 PM

    Thanks for sharing this tip with the community Jeanne!

    Jeanne Gaskill wrote:

     

    WHY

     

    I find myself pointing customers who use processes to this option over and over again.  It is particularly useful when a CA PPM (Clarity) administrator wants to save on licenses.

     

    Launching a process via a gel script will allow you to change who is running a process on-the-fly to someone else with more permissions.  It will also allow you to launch a secondary object-based process to modify an individual object instance using a system action while running a non-object-based process.


    For Example, if you want to have a process convert an idea or any other object to a project, most users won’t have sufficient rights to make the necessary changes.  You can create one user with sufficient rights to do whatever needs doing and when your user with fewer permissions does something that launches the process, you can simply have a gel script that launces a second process with the user who has sufficient rights to do everything specified as the process owner. When the second process is done, control is returned to the primary process.


    Let’s say you are running a non-object-based process as a job and you want to lock/unlock attributes before and after xogging in changes to a number of object instances.  Launching a secondary object-based process allows you to lock/unlock your attributes using a System Action instead of updating tables directly which means you are making these changes in a supported way. 


    I am sure there are many other applications for launching a process via a gel script that I am not mentioning here.

     

     

    HOW


    Use the bpm:startProcess tag (example attached). When you get to the point in your current process where you want to become someone else or make changes to a particular object instance that can’t be done via xog, do it cleanly. Call a GEL script that launches a brand new process as this new super-privileged user or a brand new object-based process for the particular object instance and exit your current one. This way there's no session mess, there's no special table to mess with that might break when the next revision of Clarity comes out and you are never updating tables directly which we all know is a big no-no.



    ***EXAMPLE:

    <gel:script xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:bpm="jelly:com.niku.bpm.gel.BPMTagLibrary"
    xmlns:core="jelly:core"
    xmlns:gel="jelly:com.niku.union.gel.GELTagLibrary"
    xmlns:sql="jelly:sql"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

    <gel:setDataSource dbId="niku"/>

    <!-- Take the target processCode as a parameter -->
    <gel:parameter var="processCode"/>

    <!-- we will launch this next process on the same object id this script is running on-->
    <core:set var="targetObjectId" value="${gel_objectInstanceId}"/>

    <!-- we will launch the next process as admin to avoid rights issues -->
    <core:set var="targetUserId" value="1"/>

    <core:choose>

    <!-- Make sure we've supplied the processCode parameter -->
    <core:when test="${processCode != null &amp;&amp; processCode.length() &gt; 0}">

    <sql:query var="results">
    SELECT
    bdpv.id process_version_id,
    bdo.object_name
    FROM
    bpm_def_processes bdp,
    bpm_def_process_versions bdpv,
    bpm_def_objects bdo
    WHERE bdpv.process_id = bdp.id
    and bdo.pk_id = bdpv.id
    and bdp.process_code = ?
    and (bdo.is_system = 0 or bdo.is_system is null)
    <sql:param value="${processCode}"/>
    </sql:query>

    <!-- Extract the process_version_id, targetObjectKey from the query -->
    <core:set var="targetProcessId" value="${results.rows[0].process_version_id}"/>
    <core:set var="targetObjectKey" value="${results.rows[0].object_name}"/>

    <core:choose>

    <!-- start the process if we've got a valid process_version_id -->
    <core:when test="${targetProcessId != null}">
    <bpm:startProcess processVersionId="${targetProcessId}" initObjectKey="${targetObjectKey}"
    initObjectId="${targetObjectId}" initUserId="${targetUserId}"/>
    </core:when>

    <core:otherwise>
    <gel:log level="ERROR">Cannot find process code '${processCode}' to launch. </gel:log>
    </core:otherwise>

    </core:choose>

    </core:when>

    <core:otherwise>
    <gel:log level="ERROR">processCode parameter has not been supplied</gel:log>
    </core:otherwise>

    </core:choose>

    </gel:script>

     

    *** Gel script written by Sean Harp

     

    NOTE:  If you are running a non-object-based process, you won’t be able to use the existing object id like this script is doing.  However, you will already have had to determine the object_instance_id in the gel script you have already created.  Just use that project id instead of the gel_objectInstanceId. Also, make sure you only launch your process(es) once per object instance so that you don’t get a separate process instance running for each change you make on a single object instance.

     

     

    TERMINOLOGY

     

    Object-based process:  An object has been selected on the Objects tab of the process definition.  Each process instance that is launched is designed to work on a single object instance.


    Non-Object-based process:  No object has been selected on the Objects tab of the process definition. These processes usually make similar changes to many object instances or they xog in data to many object instances. These processes can be launched from the Processes tab in the Organizer.  But, they are usually launched via a scheduled job.



  • 3.  Re: CA PPM Tuesday Tip:  How To Launch a Process from a Gel Script

    Posted 04-15-2015 05:08 AM

    A big thanks, Jeanne, and Sean Harp

     

    NJ



  • 4.  Re: CA PPM Tuesday Tip:  How To Launch a Process from a Gel Script

     
    Posted 04-16-2015 03:31 AM

    "When the second process is done, control is returned to the primary process" - I'm not sure this statement is true. This would imply that the bpm:startProcess tag has enough 'smarts' to stall the current GEL thread until the called process is complete. My experience of this tag suggests this is not the case.



  • 5.  Re: CA PPM Tuesday Tip:  How To Launch a Process from a Gel Script

    Posted 04-16-2015 10:35 AM

    Hi Stuart,

     

    When you add a gel script to a process you have two options right above the box where you input the gel script:

     

     

     

     

     

     

     

     



  • 6.  Re: CA PPM Tuesday Tip:  How To Launch a Process from a Gel Script

    Posted 04-16-2015 12:16 PM

    I would agree with Stuart on this point that it is true that the main process can complete whilst the steps/scripts of the sub process (or any other actions) are still executing.  It is not even required for the sub process to start when the <bpm:startProcess> tag is called, only that the event will be fired to ask the process engine to start it, but the handling of that process instance will be asynchronous to this process instance (regardless and independently of the step synch settings in each of them).

     

     

    These processes were each set to run a single script with 'synchronous' set for their step settings.

     

    master_process gel:

     

    <gel:script
    xmlns:core="jelly:core"
    xmlns:gel="jelly:com.niku.union.gel.GELTagLibrary"
    xmlns:sql="jelly:sql"
    xmlns:util="jelly:util"
    xmlns:bpm="jelly:com.niku.bpm.gel.BPMTagLibrary"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

    <gel:out>master process script starting</gel:out>

    <gel:setDataSource dbId="niku"/>

    <sql:query var="results">
      SELECT bdpv.id process_version_id
      FROM bpm_def_processes bdp,
           bpm_def_process_versions bdpv
      WHERE bdpv.process_id = bdp.id
      AND bdp.process_code = 'slave_process'
    </sql:query>
    <core:set var="targetProcessId" value="${results.rows[0].process_version_id}"/>

    <bpm:startProcess processVersionId="${targetProcessId}" initUserId="1"/>

    <gel:out>master process script finishing</gel:out>

    </gel:script>

     

    slave_process gel:

    <gel:script
    xmlns:gel="jelly:com.niku.union.gel.GELTagLibrary"
    xmlns:util="jelly:util"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

    <gel:out>slave process script starting</gel:out>
    <util:sleep millis="30000" />
    <gel:out>slave process script finishing</gel:out>

    </gel:script>

     

    Contents of my bg-system.log:

     

    C:\Clarity\virtual\logs>tail -6 bg-system.log
    2015/04/16 10:48:57.012 | Clarity Background 13.3.0.286 ready.
    2015/04/16 11:06:39.702 | master process script starting
    2015/04/16 11:08:03.713 | master process script starting
    2015/04/16 11:08:03.824 | master process script finishing
    2015/04/16 11:08:04.025 | slave process script starting
    2015/04/16 11:08:34.050 | slave process script finishing

    C:\Clarity\virtual\logs>

     

    This shows that the master process finished before the slave one even started (in separate threads), but the timing of the slave processes isn't absolute; maybe it will start before the master completes, maybe it will not, it all depends on various factors.

     

    (Note the master process started 'twice' apparently, because I had a gel script error to fix and retried it again, so it was actually only one instance of the script/step, with a retry).



  • 7.  Re: CA PPM Tuesday Tip:  How To Launch a Process from a Gel Script

    Posted 05-20-2015 08:35 PM

    Jeanne, is there a way to start processes that have implied objects with bpm:startProcess?

     

    For example:

     

    I have two processes,

    Process 1, Idea as its main object, has a step containing your indicated gel script.

    Process 2, Idea as its main object and Project as Implied Object. It has a step that performs idea conversion to project.

    2015-05-20_20-51-54.jpg

     

    The problem: when the gel script step of Process 1 will create the Process 2, this is not made, is released error: "BPM-0513: Internal Process Engine Error. Contact your site administrator (The following object(s) are not initialized: 'thisIdeia')."

    2015-05-20_21-31-24.jpg

    2015-05-20_21-32-59.jpg

     

    If I modify Process 2 removing the Project implied Object, there is no error, and Process 2 runs fine. But that way Process 2 isn't able to make changes to project attributes, because it doesn't have Project implied object.



  • 8.  Re: CA PPM Tuesday Tip:  How To Launch a Process from a Gel Script

    Posted 05-21-2015 02:54 PM

    The tag only has support for a single linked object identifier via the single attribute.

     

    The tag was originally intended and implemented in order to satisfy the needs of some add-ins / connectors to other products, so for internal only purposes, and so the scope of what the tag can do is limited accordingly.

     

    This could be a situation that calls for an Idea to be created to have this capability added.



  • 9.  Re: CA PPM Tuesday Tip:  How To Launch a Process from a Gel Script

    Posted 03-11-2016 04:06 AM

    Same thing.. it does not work when I have a linked object:

     



  • 10.  RE: Re: CA PPM Tuesday Tip:  How To Launch a Process from a Gel Script

    Posted 07-31-2019 05:00 PM
    Revisiting this after some time, it can be possible getting this to work with linked objects, but there are bugs in the original queries that may prevent it from doing so.

    There needs to be conditions on the joins to bpm_def_objects that include type_code = 'BPM_POT_PRIMARY' and src_table_name = 'BPM_DEF_PROCESS_VERSIONS'

    Otherwise the query can return multiple rows and you can end up injecting the wrong object type into the call.  The query should only return 1 row, and it should be for the primary object of the process definition.


  • 11.  Re: CA PPM Tuesday Tip:  How To Launch a Process from a Gel Script

    Posted 04-29-2017 08:36 AM

    Based on the this discussion i have made a single process which locks the start date of multiple projects via system actions. Please review the below code and let me know if it causes any issue on system. Process is running fine without any issue.

     

    <gel:script xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:bpm="jelly:com.niku.bpm.gel.BPMTagLibrary"
    xmlns:core="jelly:core"
    xmlns:gel="jelly:com.niku.union.gel.GELTagLibrary"
    xmlns:sql="jelly:sql"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

    <gel:setDataSource dbId="niku"/>

    <!-- Take the target processCode as a parameter -->
    <gel:parameter var="processCode"/> <!-- Object based process which having a system action to lock Start date -->

    <!-- we will launch the next process as admin to avoid rights issues -->
    <core:set var="targetUserId" value="1"/>

    <core:choose>

    <!-- Make sure we've supplied the processCode parameter -->
    <core:when test="${processCode != null &amp;&amp; processCode.length() &gt; 0}">

    <sql:query var="results">
    SELECT
    bdpv.id process_version_id,
    bdo.object_name
    FROM
    bpm_def_processes bdp,
    bpm_def_process_versions bdpv,
    bpm_def_objects bdo
    WHERE bdpv.process_id = bdp.id
    and bdo.pk_id = bdpv.id
    and bdp.process_code = ?
    and (bdo.is_system = 0 or bdo.is_system is null)
    <sql:param value="${processCode}"/>
    </sql:query>

    <!-- Extract the process_version_id, targetObjectKey from the query -->
    <core:set var="targetProcessId" value="${results.rows[0].process_version_id}"/>
    <core:set var="targetObjectKey" value="${results.rows[0].object_name}"/>

    <core:choose>

    <sql:query var="Project_id">
    Select id from inv_investments where...<!--Here i am using query to get project DB instance id where start date needs to be lock-->
    </sql:query>

    <core:forEach items=project_id.rowbyindex var="result">
    <core:set var="ProjectId" value="${result.rows[0]}"/>

    <!-- Here i am running a proess which locks the start date of a project -->
    <core:when test="${targetProcessId != null}">
    <bpm:startProcess processVersionId="${targetProcessId}" initObjectKey="${targetObjectKey}" initObjectId="${ProjectId}" initUserId="${targetUserId}"/>
    </core:when>

    </core:forEach>

    <core:otherwise>
    <gel:log level="ERROR">Cannot find process code '${processCode}' to launch. </gel:log>
    </core:otherwise>

    </core:choose>

    </core:when>

    <core:otherwise>
    <gel:log level="ERROR">processCode parameter has not been supplied</gel:log>
    </core:otherwise>

    </core:choose>

    </gel:script>



  • 12.  Re: CA PPM Tuesday Tip:  How To Launch a Process from a Gel Script

    Posted 09-22-2018 07:16 AM

    Hi,

     

    Can anyone let me know how to make the process asynchronous?

     

    If by default it is synchronous then what do you define in tag to make it async?

     

    Regards,

    Mamta 



  • 13.  Re: CA PPM Tuesday Tip:  How To Launch a Process from a Gel Script

    Posted 09-22-2018 03:08 PM

    It's already going to be asynchronous if you use the bpm:startProcess tag.  There isn't a choice or parameter for setting this.

     

    It wasn't created as a general purpose tag or to have the functionality of the sub-process (it's not a sub process but a new standalone process).  The process may never even start and your current process that launches it may complete before it does.

     

    The tag was created originally for some internal-only usage for integrating with a 3rd party system; since then it has been accepted in the documentation for others to use, but the code and functionality remains the same as previous.



  • 14.  RE: CA PPM Tuesday Tip:  How To Launch a Process from a Gel Script

    Posted 10-15-2019 07:38 AM
    Hello @Jeanne Gaskill@Jeanne_Gaskill_CA_Clarity_Support@Jeanne Gaskill

    Is there any way to launch a System action i.e. Baseline Investment in gel script like here launching process in gel script?​


  • 15.  RE: CA PPM Tuesday Tip:  How To Launch a Process from a Gel Script

    Posted 10-15-2019 10:00 AM
    If you had a second process for the project object with that system action defined in it, then the gel of one process could use this technique from the tip in order to execute/run it.

    Just bare in mind that it's still going to execute asynchronously also per the prior discussions.

    There isn't a direct/supported way to execute the system actions otherwise.


  • 16.  RE: CA PPM Tuesday Tip:  How To Launch a Process from a Gel Script

    Posted 10-15-2019 11:02 AM
    Hello Nick,
    Thanks for your response.

    I would like to run System action i.e. Baseline Investment for multiple investments and can give parameters on run time like baseline name and code. If i use system action in normal way then i can't pass parameters on run time like we are able to do while launching process in gel script.

    i hope you got my point.