Background
A common requirement amongst many Siebel customers, is to have the ability to run an asynchronous workflow under the real
user's login.
This issue is highlighted in the following Oracle support web document, and is representative of the problems faced by many
customers.
NOTE:494815.1
Setting CREATED_BY to the user that invoked the workflow process asynchronously
The customer stated that they have an asynchronous workflow, and wanted to know if it was possible to set the creator login
of a server request. The solution offered by the support personnel was to run the work flow in synchronous mode.
Asynchronous workflows are used in Siebel to offload work from the user session to perform background processing, however
that leaves an undesired effect of stamping the record with SADMIN. This behavior obscures information about the creator,
updater, and prevents audit trail from being utilized.
Workflows can be run synchronously as suggested in the Oracle support web document above, but it has the rather
unwanted effect of blocking the UI.
Fortunately, for customers who can't accept running background tasks synchronously, there is a viable solution, but it
requires a little bit of effort.
Requirement
To re-affirm the requirement, we are going to walk through a solution that allows any workflow or business service in
Siebel to be run asynchronously, under the actual users credentials, and without actually supplying the password!
If we step back, and look at the problem from an architectural perspective, we know that when the user logs into the
Application and executes any type of code such as eScript, or workflow, it will run synchronously
under the users application object manager, and it will operate under the users own credentials.
The only supported method to run code and avoid blocking the UI, is to run code under a background process, however any
code that is run in the background will operate under SADMIN by default.
The first challenge is to find a supported method to execute code in a background session under the current users
credentials. Experienced Siebel Integrators in the audience can probably guess, that we can achieve this with any Siebel API that
supports SSO, or utilize the inbuilt impersonation capability of certain Siebel components.
The two most suitable choices are:
1. Siebel WS
2. Siebel JDB
I've highlighted these particular interfaces, because both provide APIs that can be invoked from a background session,
and has the potential to allow arbitrary code to be dispatched, and run under a different set of credentials. As an added
benefit, both of these APIs can be built to support load balancing for high availability.
With a suitable SSO API identified, we have the necessary key piece required to solve the above problem.
Solution Overview
The diagram below shows an overview of this proposed solution.
1. The user triggers an asynchronous task from the current user session, and is allowed to continue with their work in the
application
2. In the background, A WFProcMgr component on the server executes the process, and calls a bespoke service called
"JLE Session Transport Service" that acts as a wrapper for the transport.
3. A synchronous call is invoked over the transport, using the Siebel API identified above
4. The Siebel API instantiates a new session on behalf of the real user, executes the destination business service, and
returns the results back to the background process.
Siebel API
An important implementation aspect worth considering upfront, is designing a
transport agnostic API for the Siebel developer. The developer should be able to specify the desired subsystem, and the service
should abstract the low level transport requirements, and perform the necessary acrobatics to make the call.
The following diagram shows how a facade is used for invoking the actual SSO interface.
A standard Siebel business service is defined, so it can be substituted in any existing workflow, or hooked into any
existing Siebel trigger. The designer now has to implement the adapter code, and build the interface to communicate with the
relevant SSO interface.
The implementation of interfaces to these Siebel APIs are out of scope of this article, as it requires different spectrum's of design,
involve advanced integration, and require environment dependencies to exist, but the key considerations are provided below for customers who are interested in building this capability.
Depending on which SSO API is chosen, you may require an Integration specialist to implement a WS/BS dispatch wrapper, or a
Siebel EAI/Java specialist to implement the Siebel-JDB bridge.
Please consult with your Siebel Integration Architect for more localized implementation advice.
Input Arguments
To support a plug and play design, I propose that all input arguments and child properties passed into this service would
be dispatched to the remote business, in the same way as any other business service in Siebel including workflows.
This design allows us to go into tools, and retrofit this capability to any business service, without redevelopment effort.
It is also deliberately designed to avoid hierarchy changes required for the correct invocation of the destination business
service.
To control the dispatch, lets define a custom child hierarchy, which contains 3 key elements.
1. The user login to impersonate
2. The destination business service to dispatch to
3. The destination business method name
The diagram below illustrates the property set structure, with the required information to dispatch the call
This special PropertySet can sit at any index, however it should be removed before it is dispatched to the remote
business service, in-case there is logic that is sensitive to property sets with specific indexes.
PropertySet Serialization
PropertySets are a Siebel proprietary representation of objects that only exist in memory. In order to send a PropertySet
out of Siebel, and receive it back in, it has to be serialized, de-serialized, and potentially encoded to match transport
constraints.
XML is usually used to transfer data between different systems, and Siebel provides methods to convert the PropertySet to
XML, and back, however a more efficient method is to utilize Siebel's own PropertySet to text encoding format, or a utilise a
custom JSON parsing engine in eScript. This minimizes the size of the message, results in less IO, and ensures that request is
sent as efficiently as possible.
Error Handling
This is the most critical aspect of the design, as every component in the design has to be proactive in handling, and
bubbling errors back up the chain.
The caller is effectively making a synchronous request/response call between two sessions. Errors at the end of the chain
in the impersonated session, has to be propagated through the transport, to the calling session, which has the responsibility to
handle and log any errors.
It is imperative that each component have guards in place to handle environmental, transport, and general unhanded
exception scenarios, which could cause the call to fail.
This can happen for a variety of reasons including
Component is offline
Component Maxed Task
Connection timeouts
Failed authentication
Out of resource
The Siebel JDB interface has OOTB capability with extra options for configuring, settings such as retry, and timeouts, to
counter some of the above issues. Customers choosing the Siebel WS API will have to consider implementing the appropriate
mechanisms to guard against transient errors.
Load Testing
Both the Siebel WS, Siebel JDB options can be configured for load balancing through virtual server definitions. This
capability allows this solution to scale easily. In practice this only works natively for the WS option, the JDB interface seems to only
get load balanced if sessions are spawned from the thread. An as alternative, the load balancing responsibility for the JDB interface can be offloaded to the SRProc component.
Its important to understand the current expected load, and forecast the expected number of tasks that are needed.
Every invocation can potentially spawn a new session, which could effectively double the amount of threads that the system has to
spawn, along with the increased resource utilization, so it would prudent to involve your performance test team, and environment specialists to ensure that the
application is tuned to handle the extra load.
Maintaining Impersonation
One last consideration in this design, is that once the user dispatches the work flow to be picked up in the background, no
part of the invocation chain is allowed dispatch to another server process.
The impact is that the developer needs to ensure that all work flows are run inside the impersonated object manager. If a
server request is initiated, that would then dispatch to a server thread, breaking the impersonation for that particular thread.
Conclusion
The above capability was designed and delivered for a customer who needed to meet regulatory audit requirements, to capture
the identity of the users when they performed bulk CRUD operations across the application.
In the past customers who needed to meet this requirement would have chosen to take a hit in performance, and kill
the user experience, while expensive background operations are forced to run in the foreground, or resort to creating extra columns across
entities in the application to separately capture the identity of the user.
With a little bit of effort, Siebel customers now
have the option of creating a custom impersonation component, that can run asynchronous tasks under a real user.