Thursday 11 July 2013

OSB Adapter Framework : Execution Boundaries


Consider the following scenario where OSB projects use the same WM (WorkManager)
This WM has been defined with a max-threads-constraint of  <count>1</count>.

Customer has 2 AQ projects , however the second project fails to start up with exception:
<BEA-002936> <maximum thread constraint test.MaxThreadsConstraint is reached>

The customer's expectation is for both the projects to use individual WM threads.

The above expectation is incorrect.To understand the behavior , we should understand
the execution boundaries of  Adapter Framework:

PHASE 1: executed only once
The first execution comes into play only once , when the first Adapter proxy is activated.
During this phase , a conditional check is performed to confirm the state of the Adapter.
If the state is not "STARTED"(i.e) no previous proxy with AQAdapter  has been activated, the Adapter is initialized
with a BootStrap WorkManager and its state is updated to "STARTED".

This BootStrap WorkManager is then used by all AQ proxy services during dequeue activation.


PHASE 2: executed for each AQ proxy service
Following phase 1 , the second phase is executed wherein , the dequeue agent is activated using the WM from the first phase.
When the next AQ Adapter proxy is activated , the first phase is skipped since state is "STARTED" and the
execution enters the second phase where the dequeue agent is activated using the same WM (from the first phase)

As we can see , the adapter framework uses the same WorkManager for all the dequeue agents.


I've performed multiple tests to prove the above theory :
CASE 1:
Create 2 WM's - Project1.WorkManager & Project2.WorkManager
Create 2 MaxThreadConstraints - Project1.MaxThreadConstraint & Project2.MaxThreadConstraints
Associate
    Project1.MaxThreadConstraints to Project1.WorkManager
    Project2.MaxThreadConstraints to Project2.WorkManager

Create 2 Proxy Services - Project1.ProxyServices & Project2.ProxyServices
Associate
  Project1.ProxyServices with Project1.WorkManager
  Project2.ProxyServices with Project2.WorkManager

Enable Project1.ProxyServices , we should observe that the dequeue agent is activated
Enable Project2.ProxyServices , we should observe that the dequeue agent is not activated , and
the following WARNING message appears in the log
<BEA-002936> <maximum thread constraint Project1.MaxThreadConstraint is reached>


As we can see, the constraint being mentioned is Project1.MaxThreadConstraint
(i.e) the constraint belonging to the WM which was loaded first.

Without restarting the server deactivate Project2.ProxyServices
Modify the WM to point to "default"
Reactivate the proxy.
We will still observe that the dequeue agent is not activated 
      - this is because the WM used by the adapter is still Project1.WorkManager.
      - this also confirms that the runtime WM change to the proxy service has no effect
        on the underlying Adapter layer.

CASE 2:
Following CASE 1,deactivate both the proxies and  restart the server.
Activate Project2.ProxyServices (which uses the default WM)
Activate Project1.ProxyServices (which uses Project1.WorkManager)
Observe that both the dequeue agents are activated.

This is because , the first WM to be associted to the Adapter is "default" which does not have an MaxThreadConstraint set.
Even though Project1 refers to a custom WM , the Adapter would still end up using the  "default" WM.

POSSIBLE SOLUTION:
-----------------
Since we cannot rely on the order of proxy service (and hence the associated
WM) startup ,we should
create one custom WM with suitable MaxThreadConstraints value.
Associating all the proxies with the same custom WM should resolve the issue.

Email response from SOA Adapter base development :
yes , only one workmanager is handed down to the JCA framework as per design.

1 comment: