I have multiple participants in my transaction manager config as below. I want to switch between UAT
and LOCAL
participants based on the object property that the current context holds (like if specific fields have specific values). How can I achieve this without having to change Java code and just modify the XML config? I am not sure if org.jpos.transaction.participant.JSParticipant
is the way to go.
NOTE: I am simply using jpos-template project but not the Jpos-EE
<txnmgr class="org.jpos.transaction.TransactionManager" logger="Q2">
<property name="queue" value="TXNMGR"/>
<property name="sessions" value="10"/>
<property name="max-sessions" value="100"/>
<participant name="LOCAL" class="com.sanjok.qbean.RestParticipant">
<property name="server-signature-public-key"
value="***"/>
<property name="server-encryption-public-key"
value="***"/>
<property name="base64-client-signature-private-key"
value="***"/>
<property name="base64-client-encryption-private-key"
value="***"/>
</participant>
<participant name="UAT" class="com.sanjok.qbean.RestParticipant">
<property name="server-signature-public-key"
value="***"/>
<property name="server-encryption-public-key"
value="***"/>
<property name="base64-client-signature-private-key"
value="***"/>
<property name="base64-client-encryption-private-key"
value="***"/>
</participant>
<participant class="org.jpos.transaction.participant.SendResponse">
</participant>
</txnmgr>
You can use a Switch
transaction participant with transaction groups like this:
<txnmgr class="org.jpos.transaction.TransactionManager" logger="Q2">
<property name="queue" value="TXNMGR"/>
<property name="sessions" value="10"/>
<property name="max-sessions" value="100"/>
<participant class="org.jpos.transaction.participant.Switch"
logger="Q2" realm="Switch">
<property name="txnname" value="<CONTEXT_KEY_TO_SWITCH_ON>"/> <!--1-->
<property name="<LOCAL_VALUE>" value="LOCAL"/> <!--2-->
<property name="<UAT_VALUE>" value="UAT"/> <!--3-->
<property name="unknown" value="<DEFAULT_ENDPOINT_OR_ERROR_GROUP>"/> <!--4-->
</participant>
<group name="LOCAL">
<participant name="LOCAL" class="com.sanjok.qbean.RestParticipant">
...
</participant>
</group>
<group name="UAT">
<participant name="UAT" class="com.sanjok.qbean.RestParticipant">
...
</participant>
</group>
<participant class="org.jpos.transaction.participant.SendResponse">
</participant>
</txnmgr>
<CONTEXT_KEY_TO_SWITCH_ON>
is the context key that contains the value based on which you want to select the destiny.<LOCAL_VALUE>
is the value of that key that should make the transaction go to local<UAT_VALUE>
is the value of that key that should make the transaction go to UAT.<DEFAULT_ENDPOINT_OR_ERROR_GROUP>
is the endpoint (or an error group, if you want to handle it like that) where you want to go if none of the previous match. Like the default
on a java switch
statement.The Switch
transaction participant is documented in the jPOS Programmer's Guide section 9.8.1.
Basically, we are saying that if the key matches <LOCAL_VALUE>
run group LOCAL
, if it matches <UAT_VALUE>
run group UAT
, else run whatever group you define there. Participants in each group get executed right after the Switch
participant, and before the next one.
The OP asked in a comment to be able to select the endpoint based on a field of the request. For this we need to use code, it can be in a scripted participant.
Best option would be to use GroovyParticipant
since it enables to precompile the script, but since the OP is not using jPOS-EE, not clear if he doesn't want to, or just isn't but willing to do.
BSHGroupSelector
.The simplest option is to use BSHGroupSelector
since we just need to modify the Switch
participant for this xml:
<participant class="org.jpos.transaction.participant.BSHGroupSelector">
<select>
import org.jpos.iso.*;
ISOMsg m = context.get("REQUEST");
String de3 = m.getString(3);
result = (/*condition on DE3 for selecting UAT*/) ? "UAT" : "LOCAL";
</select>
</participant>
result
is the variable used by GroupSelector
to determine the result of the select
method, i.e., get the group to run.
JSParticipant
There is no way to write a GroupSelector
with JSParticipant
that I know of. However, we can use a JSParticipant
to extract field 3 to a context key. We would need to add this participant, previous to the Switch
participant:
<participant class="org.jpos.transaction.participant.JSParticipant"
logger="Q2" realm="js" src='cfg/extract-de3.js' />
</participant>
Where cfg/extract-de3.js
has the following content:
var K = Java.type("org.jpos.transaction.TransactionConstants");
var prepare = function(id, ctx) {
//put de 3 in context under de3 key. ctx.put("de3",
ctx.get("REQUEST").getString(3);
return K.PREPARED;
}
The Switch
participant definition would be as follows:
<participant class="org.jpos.transaction.participant.Switch"
logger="Q2" realm="Switch">
<property name="txnname" value="de3"/>
<property name="<LOCAL_VALUE>" value="LOCAL"/>
<property name="<UAT_VALUE>" value="UAT"/>
<property name="unknown" value="<DEFAULT_ENDPOINT_OR_ERROR_GROUP>"/>
</participant>