Custom Request Processor

Does anyone have experience with building a custom Request Processor/Scheduler or customizing the out-of-the-box one (sailpoint.request.RequestProcessor)? The OOTB meets the needs of my organization except for a couple of areas:

  • Serial execution: We want to group requests by their targets (e.g., identities) and execute those groups of requests sequentially. This would be to avoid simultaneously processing multiple requests for the same target and objectAlreadyLockedExceptions.
  • Ordered execution: We want to process eligible/ready requests in the order of our choosing, e.g., by creation date. In other words, we want to treat the requests queue as a first-in-first-out queue.

What would it take to do this? At a mininmum, it looks to me like we’d need to write a class that extends sailpoint.request.RequestProcessor and overrides its processRequests() method.

Hi David,

Possibly you would need to change the “Request” ServiceDefinition to reference a custom executor, which would use your extended RequestProcessor.

Thanks for the reply, Paul. And, yes, I agree with you about altering the Request serviceDef.

I was hoping to avoid writing a custom RequestProcessor.processRequests() method because mimicking the OOTB one seems relatively complex. Based on trace logs (see below), the OOTB one calls multiple substantial private methods (i.e., initialize, isAllowed, and processRequest). So I would have to guess at what four RequestProcessor methods do and then reassess this for each (major) new IdentityIQ release. Does this seem like an accurate assessment? Or am I missing something?

Trace logs from RequestProcessor.processRequests():

2025-12-24T10:38:06,033 TRACE RequestProcessor sailpoint.request.RequestProcessor:138 - Entering processRequests()
2025-12-24T10:38:06,033 TRACE RequestProcessor sailpoint.request.RequestProcessor:138 - Entering initialize(context = sailpoint.server.InternalContext@49cfa46c)
2025-12-24T10:38:06,034 TRACE RequestProcessor sailpoint.request.RequestProcessor:150 - Exiting initialize = null
2025-12-24T10:38:06,034 TRACE RequestProcessor sailpoint.request.RequestProcessor:138 - Entering createRequestsFilter()
2025-12-24T10:38:06,034 TRACE RequestProcessor sailpoint.request.RequestProcessor:150 - Exiting createRequestsFilter = ((completed.isNull() || completed == “”) && (nextLaunch <= DATE$1766590686034 || nextLaunch.isNull()) && (launched.isNull() || launched == “”))
2025-12-24T10:38:06,045 INFO RequestProcessor sailpoint.request.RequestProcessor:762 - Cycle 258 [385e48199b5019cc819b51029b8d0043:Acme Update Identity - JDOE]
2025-12-24T10:38:06,046 TRACE RequestProcessor sailpoint.request.RequestProcessor:138 - Entering logInfo(msg = Considering 385e48199b5019cc819b51029b8d0043:Acme Update Identity - JDOE)
2025-12-24T10:38:06,046 TRACE RequestProcessor sailpoint.request.RequestProcessor:138 - Entering getLogMessage(msg = Considering 385e48199b5019cc819b51029b8d0043:Acme Update Identity - JDOE)
2025-12-24T10:38:06,046 TRACE RequestProcessor sailpoint.request.RequestProcessor:150 - Exiting getLogMessage = Host:Server123: Considering 385e48199b5019cc819b51029b8d0043:Acme Update Identity - JDOE
2025-12-24T10:38:06,046 INFO RequestProcessor sailpoint.request.RequestProcessor:254 - Host:Server123: Considering 385e48199b5019cc819b51029b8d0043:Acme Update Identity - JDOE
2025-12-24T10:38:06,046 TRACE RequestProcessor sailpoint.request.RequestProcessor:150 - Exiting logInfo = null
2025-12-24T10:38:06,046 TRACE RequestProcessor sailpoint.request.RequestProcessor:138 - Entering isAllowed(context = sailpoint.server.InternalContext@49cfa46c, id = 385e48199b5019cc819b51029b8d0043, pool = sailpoint.request.RequestProcessor$ThreadPool@2081287e, host = null, phase = 0, dependentPhase = 0)
2025-12-24T10:38:06,046 TRACE RequestProcessor sailpoint.request.RequestProcessor:138 - Entering getRunningThreads()
2025-12-24T10:38:06,046 TRACE RequestProcessor sailpoint.request.RequestProcessor:150 - Exiting getRunningThreads = 0
2025-12-24T10:38:06,046 TRACE RequestProcessor sailpoint.request.RequestProcessor:150 - Exiting isAllowed = true
2025-12-24T10:38:06,046 TRACE RequestProcessor sailpoint.request.RequestProcessor:138 - Entering processRequest(context = sailpoint.server.InternalContext@49cfa46c, pool = sailpoint.request.RequestProcessor$ThreadPool@2081287e, id = 385e48199b5019cc819b51029b8d0043)
2025-12-24T10:38:06,061 TRACE RequestProcessor sailpoint.request.RequestProcessor:138 - Entering logInfo(req = sailpoint.object.Request@65a86dc[id=385e48199b5019cc819b51029b8d0043,name=Acme Update Identity - JDOE], msg = Obtained transaction lock)
2025-12-24T10:38:06,061 TRACE RequestProcessor sailpoint.request.RequestProcessor:138 - Entering getLogMessage(req = sailpoint.object.Request@65a86dc[id=385e48199b5019cc819b51029b8d0043,name=Acme Update Identity - JDOE], msg = Obtained transaction lock)
2025-12-24T10:38:06,062 TRACE RequestProcessor sailpoint.request.RequestProcessor:150 - Exiting getLogMessage = Host: Server123, Request 385e48199b5019cc819b51029b8d0043:Acme Update Identity - JDOE: Obtained transaction lock
2025-12-24T10:38:06,062 INFO RequestProcessor sailpoint.request.RequestProcessor:292 - Host: Server123, Request 385e48199b5019cc819b51029b8d0043:Acme Update Identity - JDOE: Obtained transaction lock
2025-12-24T10:38:06,062 TRACE RequestProcessor sailpoint.request.RequestProcessor:150 - Exiting logInfo = null
2025-12-24T10:38:06,062 TRACE RequestProcessor sailpoint.request.RequestProcessor:138 - Entering logInfo(req = sailpoint.object.Request@65a86dc[id=385e48199b5019cc819b51029b8d0043,name=Acme Update Identity - JDOE], msg = Processing)
2025-12-24T10:38:06,062 TRACE RequestProcessor sailpoint.request.RequestProcessor:138 - Entering getLogMessage(req = sailpoint.object.Request@65a86dc[id=385e48199b5019cc819b51029b8d0043,name=Acme Update Identity - JDOE], msg = Processing)
2025-12-24T10:38:06,063 TRACE RequestProcessor sailpoint.request.RequestProcessor:150 - Exiting getLogMessage = Host: Server123, Request 385e48199b5019cc819b51029b8d0043:Acme Update Identity - JDOE: Processing
2025-12-24T10:38:06,063 INFO RequestProcessor sailpoint.request.RequestProcessor:292 - Host: Server123, Request 385e48199b5019cc819b51029b8d0043:Acme Update Identity - JDOE: Processing
2025-12-24T10:38:06,063 TRACE RequestProcessor sailpoint.request.RequestProcessor:150 - Exiting logInfo = null
2025-12-24T10:38:06,073 TRACE RequestProcessor sailpoint.request.RequestProcessor:150 - Exiting processRequest = null
2025-12-24T10:38:06,074 TRACE RequestProcessor sailpoint.request.RequestProcessor:150 - Exiting processRequests = null

Hi David,

Writing a custom processRequests method does look to be difficult.

A cheesy solution is to override processRequests() with a method that would:

  • Check the requests for any that are eligible to run, but you don’t want to run yet, and
  • set a nextLaunch date in future on them.
  • Then calls the real processRequests() method.

Hi Paul, yes, that is cheesy :slightly_smiling_face:, but it could work. I’ll take that into consideration. Thank you.