cancel
Showing results for 
Search instead for 
Did you mean: 

Sequence of event tasks

joachimvanpraet
Active Participant
0 Kudos

Hi All,

I defined 2 different tasks on change and modify event of the attribute MXREF_MX_PRIVILEGE to change the group assignments in Active directory.

When I change the value of MXREF_MX_PRIVILEGE from "<mskeyvalue_priv1>|<mskeyvalue_priv4>" to "<mskeyvalue_priv1>|<mskeyvalue_priv2>|<mskeyvalue_priv3>", sometimes priv1 is assigned in AD and sometimes not, because the adding event is finished before the delete event.

How do I know the deleting event for priv1 is finished before the modify event?

thanks,

Joachim

Accepted Solutions (0)

Answers (2)

Answers (2)

former_member192665
Participant
0 Kudos

Hi Joachim,

I read your question again. I think there is a way to prevent one job to start before another has finished.

Did I get you right that you first handle the add event for

<mskeyvalue_priv1>|<mskeyvalue_priv4>

and then the modify event for

<mskeyvalue_priv1>|<mskeyvalue_priv2>|<mskeyvalue_priv3>

sometimes the delete handler finishes faster than the add handler?

If so, then I can perhaps answer the question. What you can do is to check in table mxp_provision whether an instance of the event handler is still running. Let's say the event handler is an ordered task group with id 100 and the mskey of the person is 200 then the statement to check whether something is currently being processed is:

select count(mskey) from mxp_provision where mskey=200 and parentid=100

If the result is 0 then nothing is in the queue.

Another question is how you make the other operations wait. Here I have 2 approaches, one is simple, one is complex:

1) you code the query above in a conditional task and if result is >0 then you wait some minutes and try again then. If it doesn't succeed after several retries then make the entire thing fail.

2) You make the event handler run into an approval task. This way the execution is stopped until the approval is approved. This is a kind of semaphore mechanism: If somebody else has the lock then I wait until the lock is released. The lock holder must run a query when done in order to determine which other tasks are waiting in an approval and approve the one which waits the longest. All this can be done with a little scripting. But I wouldn't like to implement this, it's a pretty tedious.

Cheers,

Kai

-

http://kaidentity.blogspot.com/

joachimvanpraet
Active Participant
0 Kudos

Hi Kai,

I'm testing your solution (starting with the easy way to do it ).

So I created a conditional task that checks if there are other tasks running.

If there are no other task, I start the provisioning job. If there are other tasks, I wait for 20 seconds before I check again.

What is the best way to implement this loop?

Is ther a way to define a loop?

or do I have to define it like this:


Ordered Goup: Assing Privilege
- Conditional task: Other provisioning jobs for this MSKEY?
- - True
- - - Wait 20 seconds Conditional task: Other provisioning jobs for this MSKEY? 
- - - - True
- - - - - Wait 20 seconds Conditional task: Other provisioning jobs for this MSKEY? 
- - - - - -True
- - - - - - - Log error
- - - - - - False
- - - - - - - run proviisoning job
- - - - False
- - - - - run provisioning job
- - False
- - - run provisioning job

kr,

Joachim

former_member192665
Participant
0 Kudos

Hi Joachim,

what you can do is in the true clause of your first conditional you write a task that is started with 20 seconds delay and calls the first conditional again with the uProvision function. This is the kind of loop you are looking for.


Ordered Group: Assign Privilege
-- 189 / Conditional: Other provisioning jobs for this MSKEY?
----true
------uProvision(mskey, 189, %$SAP_MASTER_IDS_ID%, 0, 0, 0)   => goes back 2 lines above
----false
------do the real work here

Cheers,

Kai

-


http://kaidentity.blogspot.com/

joachimvanpraet
Active Participant
0 Kudos

Thanks Kai!

It works ... the third parameter of the uProvision-function needs to be the ID of the current repository and not the IDS.

I also copied the field userid of the current task to the new task.


  var mskey = Par.get("MSKEY");
  var task  = Par.get("TASKNUMBER"); 
  
  //get current audit ID
  var auditID = UserFunc.uGetAuditID();
  var userid =  UserFunc.uSelect("SELECT userid FROM mxp_audit WHERE auditid = " + auditID + " ");
  
  //start new provisioning task.
  uProvision(mskey, task, 0, uGetRepositoryID(), userid, 20);

Thanks for your help.

kr,

Joachim

Former Member
0 Kudos

Hi!

One aspect of the problem seems to be the replace directive . Replace is pretty straight forward in what it does:

1. delete all existing values (triggering deprovisioning tasks)

2. add all new values (triggering provisioning tasks)

This means: Deprovisioning and provisioning tasks are also called for privilege assignments which do not change. This is unnecessary, causes the race conditon you describe, and puts additional load on the IdM and target systems.

My suggestion would be to implement a script for a "smart replace" which analyses the existing values (their MSKEYVALUEs respectvely) and computes the adds and deletes only. Then only the following modification would be performed:

<mskeyvalue_priv4>|<mskeyvalue_priv2>|<mskeyvalue_priv3>

This gets rid of the nasty race condition, because <mskeyvalue_priv1> is never deleted.

Cheers

Andreas

former_member192665
Participant
0 Kudos

Hi Joachim,

I can't reply directly to the question but have you considered using the MX_PROVISIONTASK/MX_DEPROVISIONTASK/MX_MODIFYTASK hooks to provision stuff to the directory instead of using event tasks? I would consider this the normal way of doing it.

Cheers,

Kai

-

http://kaidentity.blogspot.com/