英文:
conditionally skip transaction participant in my Jpos-template project
问题
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>
英文:
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>
答案1
得分: 1
以下是您要翻译的内容:
你可以在事务组中像这样使用 Switch
事务参与者:
<CONTEXT_KEY_TO_SWITCH_ON>
是包含您想要选择目标的值的上下文键。<LOCAL_VALUE>
是应该使事务进入本地的该键的值。<UAT_VALUE>
是应该使事务进入UAT的该键的值。<DEFAULT_ENDPOINT_OR_ERROR_GROUP>
是如果前面的匹配项都不匹配时要前往的端点(或错误组,如果您想这样处理),类似于Java中的switch
语句的default
。
Switch
事务参与者在 jPOS程序员指南 第9.8.1节中有文档记录。
基本上,我们是这样说的,如果键匹配 <LOCAL_VALUE>
,则运行 LOCAL
组,如果匹配 <UAT_VALUE>
,则运行 UAT
组,否则运行您在那里定义的任何组。每个组中的参与者在 Switch
参与者之后以及下一个参与者之前执行。
根据上下文对象的属性选择端点。
OP 在评论中要求能够根据请求的字段选择端点。为此,我们需要使用代码,它可以在脚本化的参与者中进行。
最好的选择是使用 GroovyParticipant
,因为它可以预编译脚本,但由于OP未使用jPOS-EE,不清楚他是否不想使用,还是只是尚未使用但愿意尝试。
使用 BSHGroupSelector
。
最简单的选项是使用 BSHGroupSelector
,因为我们只需要修改此XML中的 Switch
参与者:
<participant class="org.jpos.transaction.participant.BSHGroupSelector">
<select>
import org.jpos.iso.*;
ISOMsg m = context.get("REQUEST");
String de3 = m.getString(3);
result = (/*根据DE3选择UAT的条件*/) ? "UAT" : "LOCAL";
</select>
</participant>
result
是由 GroupSelector
用于确定 select
方法的结果,即要运行的组。
使用 JSParticipant
我不知道如何编写具有 JSParticipant
的 GroupSelector
。但是,我们可以使用 JSParticipant
将字段3提取到上下文键中。我们需要在 Switch
参与者之前添加此参与者:
<participant class="org.jpos.transaction.participant.JSParticipant"
logger="Q2" realm="js" src='cfg/extract-de3.js' />
其中 cfg/extract-de3.js
具有以下内容:
var K = Java.type("org.jpos.transaction.TransactionConstants");
var prepare = function(id, ctx) {
// 将DE 3放入上下文的de3键下。 ctx.put("de3",
ctx.get("REQUEST").getString(3);
return K.PREPARED;
}
Switch
参与者的定义如下:
<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>
英文:
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 thedefault
on a javaswitch
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.
Select endpoint based on a property of a context object.
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.
Using 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.
Using 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>
答案2
得分: 0
你可以利用jPOS环境变量并添加enabled
属性。
你可以拥有一对环境变量,即uat.enabled
和local.enabled
,可以像这样配置:
<participant name="LOCAL" class="com.sanjok.qbean.RestParticipant" enabled="${local.enabled}">
...
...
</participant>
<participant name="UAT" class="com.sanjok.qbean.RestParticipant" enabled-"${uat.enabled}">
...
...
</participant>
然后,你可以使用YAML配置或仅使用环境变量(LOCAL_ENABLED
和UAT_ENABLED
)。
这在jPOS程序员指南的3.3节中有文档记录。
英文:
You can take advantage of jPOS environment variables and add the enabled
attribute.
You can have a couple of environment variables, i.e:uat.enabled
and local.enabled
that you can configure like this:
<participant name="LOCAL" class="com.sanjok.qbean.RestParticipant" enabled="${local.enabled}">
...
...
</participant>
<participant name="UAT" class="com.sanjok.qbean.RestParticipant" enabled-"${uat.enabled}">
...
...
</participant>
The you can either use YAML configurations or just environment variables (LOCAL_ENABLED
and UAT_ENABLED
).
This is documented in jPOS Programmer's Guide section 3.3.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论