I am using channel adapter along with the Mux for routing message from client to destination server. However when it reaches to query remote host (using mux and channel adapter) it is routing back to the client rather than to the destination server as set in config files.
Please find the class used:
#Component
public class MyRequestListner implements ISORequestListener,Configurable {
private static final Logger logger = LoggerFactory.getLogger(MyRequestListner.class);
protected String queueName;
protected Space sp;
protected String destinationMux;
public static final String REQUEST = "REQUEST";
public static final String ISOSOURCE = "ISOSOURCE";
#Override
public void setConfiguration(Configuration cfg) throws ConfigurationException {
queueName = cfg.get("queue");
destinationMux = cfg.get("destination-mux");
sp = SpaceFactory.getSpace(cfg.get("space"));
}
public boolean process (ISOSource source, ISOMsg m) {
try{
logger.info("INSIDE MY REQUEST LISTNER PROCESS : " + queueName + " : "+ destinationMux);
Context ctx = new Context ();
ctx.put (REQUEST, m);
ctx.put (ISOSOURCE, source);
sp.out (queueName, ctx);
}catch(Exception ex){
System.out.println("MY REQUEST LISTNER ERROR : "+ex);
}
return true;
}
}
package np.com.fonepay.isoswitch.iso;
import java.io.Serializable;
import org.jpos.iso.ISOMsg;
import org.jpos.iso.ISOSource;
import org.jpos.iso.ISOUtil;
import org.jpos.iso.MUX;
import org.jpos.q2.iso.QMUX;
import org.jpos.transaction.Context;
import org.jpos.transaction.TransactionParticipant;
import org.jpos.util.NameRegistrar;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class QueryRemoteHost implements TransactionParticipant {
private static final Logger logger = LoggerFactory.getLogger(QueryRemoteHost.class);
#Override
public int prepare(long id, Serializable context) {
logger.info("INSIDE QUERYREMOTEHOST PREPARE");
Context ctx = (Context) context;
try {
ISOSource source = (ISOSource) ctx.get("ISOSOURCE");
ISOMsg queryRemote = (ISOMsg) ctx.get("REQUEST");
// -- forward msg to destination host
MUX remoteMux = (QMUX) NameRegistrar.getIfExists("mux.visamux");
System.out.println("===Outgoing Message To Remote Server: ");
System.out.println(ISOUtil.hexdump(queryRemote.pack()));
queryRemote = remoteMux.request(queryRemote, 30000);
System.out.println("===Incoming Message From Remote Server: ");
logger.info("Incoming Message From Remote Server: " + queryRemote);
if (queryRemote == null) {
ctx.put("CHKCARDRESP", "911");
} else {
// Modify the response message to client (if required)
ctx.put("PROCESSRESPONSE", queryRemote);
return PREPARED;
}
queryRemote.setResponseMTI();
source.send(queryRemote);
return PREPARED | NO_JOIN | READONLY;
} catch (Exception ex) {
logger.error("Query Remote Host | error | " + ex);
ex.printStackTrace();
}
return 0;
}
#Override
public void abort(long id, Serializable context) {
logger.info("INSIDE QUERYREMOTEHOST ABORT");
Context ctx = (Context) context;
try {
ISOSource source = (ISOSource) ctx.get("ISOSOURCE");
ISOMsg responseabort = (ISOMsg) ctx.get("REQUEST");
responseabort.setResponseMTI();
responseabort.set(38, "MWS000");
responseabort.set(39, "99");
source.send(responseabort);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Here are the required config files:
10_server_config.xml
<server name="MARIA_SERVER_12201" class="org.jpos.q2.iso.QServer" logger="Q2" >
<attr name="port" type="java.lang.Integer">12201</attr>
<attr name="minSessions" type="java.lang.Integer">20</attr>
<attr name="maxSessions" type="java.lang.Integer">250</attr>
<channel class="org.jpos.iso.channel.ASCIIChannel"
logger="Q2" packager="org.jpos.iso.packager.GenericPackager">
<property name="packager-config" value="cfg/packager_ebl.xml" />
</channel>
<request-listener class="np.com.fonepay.isoswitch.iso.MyRequestListner" logger="Q2">
<property name="space" value="tspace:default" />
<property name="queue" value="MyVisaTxnQueue" />
<property name="destination-mux" value="mux.visamux" />
<property name="timeout" value="30000"/>
</request-listener>
<in>VISA_IN</in>
<out>VISA_OUT</out>
</server>
15_channeladapter.xml
<channel-adaptor name='visaca' class="org.jpos.q2.iso.ChannelAdaptor" logger="Q2">
<channel class="org.jpos.iso.channel.ASCIIChannel" logger="Q2" packager="org.jpos.iso.packager.GenericPackager">
<property name="host" value="localhost" />
<property name="port" value="13301" />
<property name="packager-config" value="cfg/packager_ebl.xml" />
<property name="timeout" value="300000" />
<property name="keep-alive" value="true" />
</channel>
<in>VISA_IN</in>
<out>VISA_OUT</out>
<reconnect-delay>10000</reconnect-delay>
</channel-adaptor>
18_qserver_mux.xml
<?xml version="1.0" ?>
<mux class="np.com.fonepay.isoswitch.iso.EblMux" logger="Q2" name="visamux">
<in>VISA_OUT</in>
<out>VISA_IN</out>
<ready>visaca.ready</ready>
<key>41,11</key>
<unhandled>visaca-unhandled</unhandled>
</mux>
20_txnmanager_config.xml
<?xml version="1.0" ?>
<txnmgr name="txnmgrvisa" logger="Q2" class="org.jpos.transaction.TransactionManager">
<property name="space" value="tspace:default" />
<property name="queue" value="MyVisaTxnQueue" />
<property name="sessions" value="5" />
<participant class="np.com.fonepay.isoswitch.iso.QueryRemoteHost" logger="Q2" realm="visatxn"/>
</txnmgr>
We can see from System Output that the first it reaches to MyRequestListner and then RemoteHostQuery (Process) and instantly forward/reply message to client IP and Port whereas it has to forward it to remote host as defined in channel adapter. Since it is not able to get response(obvious) ABORT method is invoked:
<log realm="channel/127.0.0.1:64352" at="2019-09-12T12:10:40.690" lifespan="190293ms">
<receive>
<isomsg direction="incoming">
<!-- org.jpos.iso.packager.GenericPackager[cfg/packager_ebl.xml] -->
<field id="0" value="1804"/>
<field id="11" value="000000000001"/>
<field id="12" value="20190912121040"/>
<field id="24" value="831"/>
<field id="32" value="627765"/>
<field id="41" value="00627765"/>
<field id="59" value="EBLECHO"/>
<field id="93" value="627765"/>
<field id="94" value="627766DC"/>
<field id="123" value="DC"/>
</isomsg>
</receive>
</log>
2019-09-12 12:10:40.693 INFO 30136 --- [hread-2-running] n.c.f.isoswitch.iso.MyRequestListner : INSIDE MY REQUEST LISTNER PROCESS : MyVisaTxnQueue : mux.visamux
2019-09-12 12:10:40.694 INFO 30136 --- [12T12:10:40.694] n.c.f.isoswitch.iso.QueryRemoteHost : INSIDE QUERYREMOTEHOST PREPARE
===Outgoing Message To Remote Server:
<log realm="channel/127.0.0.1:64352" at="2019-09-12T12:10:40.702" lifespan="5ms">
<send>
<isomsg direction="outgoing">
<!-- org.jpos.iso.packager.GenericPackager[cfg/packager_ebl.xml] -->
<field id="0" value="1804"/>
<field id="11" value="000000000001"/>
<field id="12" value="20190912121040"/>
<field id="24" value="831"/>
<field id="32" value="627765"/>
<field id="41" value="00627765"/>
<field id="59" value="EBLECHO"/>
<field id="93" value="627765"/>
<field id="94" value="627766DC"/>
<field id="123" value="DC"/>
</isomsg>
</send>
</log>
===Incoming Message From Remote Server: java.lang.NullPointerException
at np.com.fonepay.isoswitch.iso.QueryRemoteHost.prepare(QueryRemoteHost.java:54)
at org.jpos.transaction.TransactionManager.prepare(TransactionManager.java:549)
at org.jpos.transaction.TransactionManager.prepare(TransactionManager.java:615)
at org.jpos.transaction.TransactionManager.run(TransactionManager.java:291)
at java.lang.Thread.run(Thread.java:748)
2019-09-12 12:11:10.708 INFO 30136 --- [12T12:10:40.694] n.c.f.isoswitch.iso.QueryRemoteHost : Incoming Message From Remote Server: null
2019-09-12 12:11:10.709 ERROR 30136 --- [12T12:10:40.694] n.c.f.isoswitch.iso.QueryRemoteHost : Query Remote Host | error | java.lang.NullPointerException
2019-09-12 12:11:10.711 INFO 30136 --- [12T12:11:10.710] n.c.f.isoswitch.iso.QueryRemoteHost : INSIDE QUERYREMOTEHOST ABORT
<log realm="channel/127.0.0.1:64352" at="2019-09-12T12:11:10.711">
<send>
<isomsg direction="outgoing">
<!-- org.jpos.iso.packager.GenericPackager[cfg/packager_ebl.xml] -->
<field id="0" value="1814"/>
<field id="11" value="000000000001"/>
<field id="12" value="20190912121040"/>
<field id="24" value="831"/>
<field id="32" value="627765"/>
<field id="38" value="MWS000"/>
<field id="39" value="99"/>
<field id="41" value="00627765"/>
<field id="59" value="EBLECHO"/>
<field id="93" value="627765"/>
<field id="94" value="627766DC"/>
<field id="123" value="DC"/>
</isomsg>
</send>
</log>
<log realm="org.jpos.transaction.TransactionManager" at="2019-09-12T12:11:10.715" lifespan="30021ms">
<abort>
txnmgrvisa-0:idle:2
<context>
REQUEST:
<isomsg direction="outgoing">
<!-- org.jpos.iso.packager.GenericPackager[cfg/packager_ebl.xml] -->
<field id="0" value="1814"/>
<field id="11" value="000000000001"/>
<field id="12" value="20190912121040"/>
<field id="24" value="831"/>
<field id="32" value="627765"/>
<field id="38" value="MWS000"/>
<field id="39" value="99"/>
<field id="41" value="00627765"/>
<field id="59" value="EBLECHO"/>
<field id="93" value="627765"/>
<field id="94" value="627766DC"/>
<field id="123" value="DC"/>
</isomsg>
ISOSOURCE: org.jpos.iso.channel.ASCIIChannel#4533bed0
CHKCARDRESP: 911
</context>
prepare: np.com.fonepay.isoswitch.iso.QueryRemoteHost ABORTED
abort: np.com.fonepay.isoswitch.iso.QueryRemoteHost
in-transit=0, head=3, tail=3, paused=0, outstanding=0, active-sessions=5/5, tps=0, peak=1, avg=0.00, elapsed=30020ms
<profiler>
prepare: np.com.fonepay.isoswitch.iso.QueryRemoteHost [30015.2/30015.2]
abort: np.com.fonepay.isoswitch.iso.QueryRemoteHost [4.7/30020.0]
end [0.9/30021.0]
</profiler>
</abort>
</log>
Your problem is here:
<server name="MARIA_SERVER_12201" class="org.jpos.q2.iso.QServer" logger="Q2" >
<attr name="port" type="java.lang.Integer">12201</attr>
<attr name="minSessions" type="java.lang.Integer">20</attr>
<attr name="maxSessions" type="java.lang.Integer">250</attr>
<channel class="org.jpos.iso.channel.ASCIIChannel"
logger="Q2" packager="org.jpos.iso.packager.GenericPackager">
<property name="packager-config" value="cfg/packager_ebl.xml" />
</channel>
<request-listener class="np.com.fonepay.isoswitch.iso.MyRequestListner" logger="Q2">
<property name="space" value="tspace:default" />
<property name="queue" value="MyVisaTxnQueue" />
<property name="destination-mux" value="mux.visamux" />
<property name="timeout" value="30000"/>
</request-listener>
<!--you need to delete the following two lines -->
<in>VISA_IN</in> <!--here-->
<out>VISA_OUT</out> <!-- and here-->
</server>
As mentioned in the comments:
unless your server (the one receiving requests from your client, for which you didn't share the deploy file) has an in queue named "VISA_IN"
You have the in and out queues defined in the server, with the same names of the channel, so the server is competing with the channel for the messages put in those queues, messages that goes to the in queue of the server are sent to it's client, you need to remove them, since you are not using the queues to communicate to the client connected to the server but calling send() from a transaction participant
Related
I am working on a new Jaspert Report. It should print all data of a xml text.
The xml text looks like this:
<?xml version="1.0" encoding="ISO-8859-1"?>
<invoice:invoiceMessage>
<invoice>
<invoiceIdentification></invoiceIdentification>
<seller>
<address>
<name></name>
<city></city>
<cityCode></cityCode>
</address>
</seller>
</invoice>
</invoice:invoiceMessage>
And the Jasper Report looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Jaspersoft Studio version 7.1.0.final using JasperReports Library version 6.4.3 -->
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="main_report_xml1" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="24a4119c-6e8f-4411-bbb5-c069ab379330">
<property name="com.jaspersoft.studio.data.sql.tables" value=""/>
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="Sample DB"/>
<property name="ireport.jasperserver.url" value="http://10.100.10.236/jasperserver-pro/"/>
<property name="ireport.jasperserver.user" value="reko"/>
<property name="ireport.jasperserver.reportUnit" value="/Reko/main_report_xml1"/>
<subDataset name="pageHeader" uuid="cf87fcbb-cbcd-4c3b-bf87-3cf147854adb">
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="Sample DB"/>
<queryString language="xPath">
<![CDATA[//seller/address]]]>
</queryString>
<field name="name" class="java.lang.String">
<property name="net.sf.jasperreports.xpath.field.expression" value="name"/>
<fieldDescription><![CDATA[name]]></fieldDescription>
</field>
<field name="streetAdressOne" class="java.lang.String">
<property name="net.sf.jasperreports.xpath.field.expression" value="streetAdressOne"/>
<fieldDescription><![CDATA[streetAdressOne]]></fieldDescription>
</field>
<field name="cityCode" class="java.lang.String">
<property name="net.sf.jasperreports.xpath.field.expression" value="cityCode"/>
<fieldDescription><![CDATA[cityCode]]></fieldDescription>
</field>
<field name="city" class="java.lang.String">
<property name="net.sf.jasperreports.xpath.field.expression" value="city"/>
<fieldDescription><![CDATA[city]]></fieldDescription>
</field>
</subDataset>
<parameter name="xmlString" class="java.lang.String" isForPrompting="false">
<defaultValueExpression><![CDATA[xmlText]]></defaultValueExpression>
</parameter>
<parameter name="XML_INPUT_STREAM" class="java.io.InputStream">
<defaultValueExpression><![CDATA[new java.io.ByteArrayInputStream($P{xmlString}.getBytes("ISO-8859-1"))]]></defaultValueExpression>
</parameter>
<queryString language="xPath">
<![CDATA[/invoiceMessage/invoice[invoiceIdentification/entityIdentification=9000009029]]]>
</queryString>
<field name="value" class="java.lang.String">
<fieldDescription><![CDATA[creationDateTime]]></fieldDescription>
</field>
<pageHeader>
<band height="38"/>
</pageHeader>
<columnHeader>
<band height="31" splitType="Stretch"/>
</columnHeader>
<detail>
<band height="488" splitType="Stretch">
<componentElement>
<reportElement positionType="Float" stretchType="RelativeToTallestObject" x="0" y="21" width="552" height="30" isRemoveLineWhenBlank="true" uuid="fc7d22c7-8c60-4ecb-974f-c842becc4bf7"/>
<jr:list xmlns:jr="http://jasperreports.sourceforge.net/jasperreports/components" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports/components http://jasperreports.sourceforge.net/xsd/components.xsd" printOrder="Vertical">
<datasetRun subDataset="pageHeader" uuid="1e20fa2b-bb3a-475f-b721-5a13d3c374eb">
<datasetParameter name="XML_DATE_PATTERN">
<datasetParameterExpression><![CDATA[$P{XML_DATE_PATTERN}]]></datasetParameterExpression>
</datasetParameter>
<datasetParameter name="XML_NUMBER_PATTERN">
<datasetParameterExpression><![CDATA[$P{XML_NUMBER_PATTERN}]]></datasetParameterExpression>
</datasetParameter>
<datasetParameter name="XML_LOCALE">
<datasetParameterExpression><![CDATA[$P{XML_LOCALE}]]></datasetParameterExpression>
</datasetParameter>
<datasetParameter name="XML_TIME_ZONE">
<datasetParameterExpression><![CDATA[$P{XML_TIME_ZONE}]]></datasetParameterExpression>
</datasetParameter>
<dataSourceExpression><![CDATA[((net.sf.jasperreports.engine.data.JRXmlDataSource)$P{REPORT_DATA_SOURCE}).subDataSource("//*[entityIdentification=9000009029]/parent::*/seller")]]></dataSourceExpression>
</datasetRun>
<jr:listContents height="30">
<textField isStretchWithOverflow="true">
<reportElement stretchType="RelativeToTallestObject" x="0" y="0" width="552" height="15" uuid="eac696b9-e20f-48a3-b70d-b186f5e649d6"/>
<textFieldExpression><![CDATA[$F{name}]]></textFieldExpression>
</textField>
</jr:listContents>
</jr:list>
</componentElement>
</band>
</detail>
</jasperReport>
My question is:
What should my dataSourceExpression in the componentElement be, so I can get the data out of it?
I also have some data in the invoice node that I need to show and thats why i set it like this in the query string. And I need to filter by the parameter that is stored inside of invoiceIdentification node.
I am new to jpos. trying to use jpos-2_1_3 out of the box. I can see the message forwarded to remote host and response back but the response message is not delivered to the requested client.Getting the below error
[HOST_UNREACHABLE] o.j.t.p.QueryHost.expired:111 'mux.rsc' does not respond
I checked the client status which is connected and waiting for the response
My config files are as below
50_server.xml
<server class="org.jpos.q2.iso.QServer" logger="Q2" name="bnet-server-7003" realm="bnet-server-8000">
<attr name="port" type="java.lang.Integer">6003</attr>
<channel class="org.jpos.iso.channel.NACChannel"
packager="org.jpos.iso.packager.GenericPackager"
type="server"
logger="Q2"
header="6000000000"
>
<property name="packager-config" value="cfg/packager/CISebcdic.xml" debug="True" />
<property name="timeout" value="18000"/>
</channel>
<request-listener class="org.jpos.iso.IncomingListener" logger="Q2" realm="incoming-request-listener">
<property name="space" value="tspace:default" />
<property name="queue" value="RSCTXNMGR" />
<property name="ctx.DESTINATION" value="rsc" />
</request-listener>
</server>
10_channel.xml
<?xml version="1.0" ?>
<channel-adaptor name='rsc-channel' class="org.jpos.q2.iso.ChannelAdaptor" logger="Q2">
<channel class="org.jpos.iso.channel.BCDChannel"
packager="org.jpos.iso.packager.GenericPackager" header="6000000000" logger="Q2" >
<property name="packager-config" value="cfg/packager/CISascii.xml" debug="True" />
<property name="host" value="127.0.0.1" />
<property name="port" value="9000" />
<property name="keep-alive" value="true" />
</channel>
<in>rscbnet-send</in>
<out>rscbnet-receive</out>
<reconnect-delay>10000</reconnect-delay>
</channel-adaptor>
20_mux.xml
<?xml version="1.0" ?>
<mux class="org.jpos.q2.iso.QMUX" logger="Q2" name="rsc">
<in>rscbnet-receive</in>
<out>rscbnet-send</out>
<ready>rsc-channel.ready</ready>
<key>41,11</key>
<unhandled>rsc-channel-unhandled</unhandled>
</mux>
30_txnmgr.xml
<?xml version='1.0'?>
<txnmgr class="org.jpos.transaction.TransactionManager" logger="Q2">
<property name="queue" value="RSCTXNMGR"/>
<property name="sessions" value="10"/>
<property name="max-sessions" value="128"/>
<property name="debug" value="true"/>
<participant class="org.jpos.transaction.participant.QueryHost" logger="Q2"/>
<participant class="org.jpos.transaction.participant.SendResponse" logger="Q2" />
</txnmgr>
in the log i can see message is send to the remote host and response is received
<log realm="channel/127.0.0.1:9000" at="2020-02-22T17:11:39.114">
<send>
<isomsg direction="outgoing">
<!-- org.jpos.iso.packager.GenericPackager[cfg/packager/CISascii.xml] -->
<header>6000000000</header>
<field id="0" value="0400"/>
<field id="2" value="4113550001234586"/>
<field id="3" value="003000"/>
<field id="4" value="000000005000"/>
<field id="7" value="0218135108"/>
<field id="11" value="570164"/>
<field id="12" value="005106"/>
<field id="13" value="0219"/>
<field id="14" value="1906"/>
<field id="18" value="7399"/>
<field id="22" value="812"/>
<field id="32" value="001529"/>
<field id="33" value="004601"/>
<field id="37" value="702011961044"/>
<field id="39" value="00"/>
<field id="41" value="W1Q99999"/>
<field id="42" value="25233065 "/>
<field id="43" value="Apple NZ GCS Sydney AU"/>
<field id="48" value="543432303730313033323130363331355649533237333634353032313920203230303153" type="binary"/>
<field id="49" value="036"/>
<field id="61" value="10251040066000362000"/>
<field id="90" value="010057016402181351080000000152900000004601"/>
</isomsg>
</send>
</log>
<log realm="channel/127.0.0.1:9000" at="2020-02-22T17:11:39.115" lifespan="179071ms">
<receive>
<isomsg direction="incoming">
<!-- org.jpos.iso.packager.GenericPackager[cfg/packager/CISascii.xml] -->
<header>6000000000</header>
<field id="0" value="0410"/>
<field id="2" value="4113550001234586"/>
<field id="3" value="003000"/>
<field id="4" value="000000005000"/>
<field id="7" value="0221223852"/>
<field id="11" value="620156"/>
<field id="12" value="093850"/>
<field id="13" value="0222"/>
<field id="14" value="1906"/>
<field id="18" value="7399"/>
<field id="22" value="812"/>
<field id="32" value="001529"/>
<field id="33" value="004601"/>
<field id="37" value="702011079220"/>
<field id="39" value="00"/>
<field id="41" value="W1Q99999"/>
<field id="42" value="25233065 "/>
<field id="43" value="Apple NZ GCS Sydney AU"/>
<field id="48" value="543432303730313033323130363331353030303030303030303030303020203230303153" type="binary"/>
<field id="49" value="036"/>
<field id="61" value="10251040066000362000"/>
<field id="90" value="010062015602212238520000000152900000004601"/>
</isomsg>
</receive>
</log>
<log realm="org.jpos.transaction.TransactionManager" at="2020-02-22T17:12:09.115" lifespan="30001ms">
<abort>
txnmgr-9:idle:2
<context>
TIMESTAMP: Sat Feb 22 17:11:39 AEDT 2020
SOURCE: org.jpos.iso.channel.NACChannel#795c411
REQUEST:
<isomsg direction="outgoing">
<!-- org.jpos.iso.packager.GenericPackager[cfg/packager/CISascii.xml] -->
<header>6000000000</header>
<field id="0" value="0400"/>
<field id="2" value="4113550001234586"/>
<field id="3" value="003000"/>
<field id="4" value="000000005000"/>
<field id="7" value="0218135108"/>
<field id="11" value="570164"/>
<field id="12" value="005106"/>
<field id="13" value="0219"/>
<field id="14" value="1906"/>
<field id="18" value="7399"/>
<field id="22" value="812"/>
<field id="32" value="001529"/>
<field id="33" value="004601"/>
<field id="37" value="702011961044"/>
<field id="39" value="00"/>
<field id="41" value="W1Q99999"/>
<field id="42" value="25233065 "/>
<field id="43" value="Apple NZ GCS Sydney AU"/>
<field id="48" value="543432303730313033323130363331355649533237333634353032313920203230303153" type="binary"/>
<field id="49" value="036"/>
<field id="61" value="10251040066000362000"/>
<field id="90" value="010057016402181351080000000152900000004601"/>
</isomsg>
DESTINATION: rsc
**RESULT:
<result>
<fail>
[HOST_UNREACHABLE] o.j.t.p.QueryHost.expired:111 'mux.rsc' does not respond
</fail>
</result>**
:paused_transaction:
id: 2
</context>
prepare: o.j.t.p.QueryHost PREPARED PAUSE READONLY NO_JOIN
prepare: o.j.t.p.SendResponse ABORTED READONLY NO_JOIN
in-transit=0, head=3, tail=3, paused=0, outstanding=0, active-sessions=10/128, tps=0, peak=1, avg=0.00, elapsed=30001ms
<profiler>
prepare: o.j.t.p.QueryHost [0.3/0.3]
resume [30000.5/30000.8]
prepare: o.j.t.p.SendResponse [0.1/30001.0]
end [1.1/30002.2]
</profiler>
</abort>
</log>
<log realm="Q2.system" at="2020-02-22T17:12:43.242">
it will be great if i get some help to solve this issue.thanks in advance.
To summarize in an answer what was explained in comments, problem was field 11 not being matched by response. Because of that the mux didn't know that the incoming message was a response for the request.
You can see default fields used to match responses to requests by QMUX, and learn how to configure a different set of keys in jPOS programmers guide section 8.3.2
I am trying to unmarshall an XML to Object using Castor OXM Unmarshalling in Spring.
XML:
<LevelA>
<LevelB>
<item name="itemA">value</item>
<item name="itemB">value</item>
<item name="itemC">value</item>
<item name="itemD">value</item>
<item name="itemE">value</item>
</LevelB>
</LevelA>
Object:
Class LevelA {
LevelB objLevelB;
//getter and setter
}
Class LevelB {
List<Items> item = new ArrayList<Items>();
//getter and setter
}
Class Items {
String Name;
String Value;
//getter and setter
}
Castor Mapping:
<mapping>
<class name="LevelA">
<map-to xml="LevelA" />
<field name="objLevelB" type="LevelB">
<bind-xml name="LevelB" />
<class name="LevelB">
<field name="item" type="Items" collection="arraylist">
<bind-xml name="item" node="element" />
<class name="Items">
<field name="Name" type="string">
<bind-xml name="name" node="attribute" />
</field>
<field name="Value" type="string">
<bind-xml node="text" />
</field>
</class>
</field>
</class>
</field>
</class>
</mapping>
I am getting the following error:
org.xml.sax.SAXException: unable to find FieldDescriptor for 'item' in ClassDescriptor of LevelB
I have tried several ways and spent enough time that I need some help from you all now.
Any help would be useful.
Figured out the way myself, here is the mapping that worked for me. I am sharing the answer to help others, in the same situation.
<?xml version="1.0" encoding="UTF-8"?>
<mapping>
<description> Provides Mapping to Convert Document to POJO</description>
<class name="LevelAClass">
<map-to xml="LevelA" />
<field name="objLevelB" type="LevelBClass">
<bind-xml name="LevelB" />
</field>
</class>
<class name="LevelBClass">
<field name="item" type="LevelCClass"
collection="arraylist">
<bind-xml name="item" />
</field>
</class>
<class name="LevelCClass">
<field name="Name">
<bind-xml name="name" node="attribute" />
</field>
<field name="Value">
<bind-xml name="item" node="text" />
</field>
</class>
</mapping>
I am trying to integrate BeanIO with spring batch. Using BeanIO I am reading a fixed length stream file. I have tested and verified the code to read the flat file using a standalone class and it works seamlessly but when I tried to integrate it with Spring Batch the doRead() method of BeanIOFlatFileItemReader is not getting invoked and some how directly the RedemptionEventCustomProcessor written by me is getting invoked.
I get below stacktrace on console.:
:::::::::::::In Processor::::::::::::::::
Exit Status : FAILED job Id 0 [java.lang.NullPointerException]
Done
Please find the dependencies used below:
spring-batch-core version 2.1.9.RELEASE
spring-batch-infrastructure 2.1.9.RELEASE
beanio-2.1.0.M2
Please find below the resources files as mentioned below:
earn-api-batch - spring batch xml file
earn-api-batch-context - spring batch context xml file
earn-api-mapping.xml - BeanIO mapping xml file
earn-api-batch.xml:
<import resource="classpath:earn-api-batch-context.xml" />
<batch:job id="processEventJob">
<batch:step id="step">
<batch:tasklet>
<batch:chunk reader="RedemptionFileReader" writer="RedemptionEventCustomWriter" processor="RedemptionEventCustomProcessor" commit-interval="1"></batch:chunk>
</batch:tasklet>
</batch:step>
</batch:job>
<bean id="RedemptionFileReader" class="org.beanio.spring.BeanIOFlatFileItemReader">
<property name="streamMapping" value="classpath:/earn-api-mapping.xml" />
<property name="streamName" value="redemptionFile" />
<property name="resource" value="classpath:/RedemptionTest" />
</bean>
<bean id="RedemptionEventCustomWriter" class="org.beanio.spring.BeanIOFlatFileItemWriter">
<property name="streamMapping" value="classpath:/earn-api-mapping.xml" />
<property name="streamName" value="redemptionFile" />
<property name="resource" value="file:Redemption.txt" />
</bean>
earn-api-batch-context:
<context:component-scan base-package="com.aexp.earn.api.batch" />
<bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository" />
</bean>
<bean id="jobRepository" class="org.springframework.batch.core.repository.support.SimpleJobRepository">
<constructor-arg>
<bean class="org.springframework.batch.core.repository.dao.MapJobInstanceDao"/>
</constructor-arg>
<constructor-arg>
<bean class="org.springframework.batch.core.repository.dao.MapJobExecutionDao" />
</constructor-arg>
<constructor-arg>
<bean class="org.springframework.batch.core.repository.dao.MapStepExecutionDao"/>
</constructor-arg>
<constructor-arg>
<bean class="org.springframework.batch.core.repository.dao.MapExecutionContextDao"/>
</constructor-arg>
</bean>
<bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" />
earn-api-mapping.xml:
<beanio xmlns="http://www.beanio.org/2012/03"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.beanio.org/2012/03 http://www.beanio.org /2012/03/mapping.xsd">
<stream name="redemptionFile" format="fixedlength">
<!-- 'class' binds the header record to a java.util.HashMap -->
<record name="header" class="map">
<!-- 'rid' indicates this field is used to identify the record -->
<field name="recordType" length="1" rid="true" literal="1" />
<field name="fileSeqNo" length="10" padding=" " justify="right" />
<!-- 'format' can be used to provide Date and Number formats -->
<field name="fileDate" length="8" type="date" format="yyyyMMdd" />
</record>
<record name="nar" class="com.aexp.earn.api.batch.vo.NonAirline">
<field name="recordType" length="1" ignore="true" />
<field name="redeemType" rid="true" literal="1" length="1" />
<field name="mmNo" length="10" />
<field name="cmNo" length="19" padding=" " justify="right" />
<field name="rewardProgCode" length="2" padding="0" justify="right" />
<field name="certNo" length="10"/>
<field name="certFaceValue" length="13" padding=" " justify="right" />
<field name="redeemTimeStamp" length="26" />
<field name="statusCode" length="2" />
<field name="statusTimeStamp" length="26" />
<field name="rewardCode" length="4" />
<field name="rewardSubCode" length="4" />
<field name="transId" length="15" />
<field name="transSrcId" length="3" />
<field name="narRequestId" length="14" />
<field name="narRequestLnId" length="5" padding=" " justify="right" />
</record>
<record name="ar" class="com.aexp.earn.api.batch.vo.Airline">
<field name="recordType" length="1" ignore="true" />
<field name="redeemType" rid="true" literal="2" length="1" />
<field name="partnerTransferType" length="1" />
<field name="mmNo" length="10" />
<field name="cmNo" length="19" padding=" " justify="right" />
<field name="rewardProgCode" length="2" />
<field name="frequentFlyerNo" length="15" />
<field name="partnerCode" length="2"/>
<field name="redeemTimeStamp" length="26" />
<field name="transferedMiles" length="12" padding=" " justify="right" />
<field name="transferedStatus" length="1" />
<field name="statusTimeStamp" length="26" />
<field name="originSourceCode" length="3" />
<field name="transId" length="15" />
<field name="transSrcId" length="3" />
<field name="arRequestId" length="14" />
<field name="arRequestLnId" length="5" padding=" " justify="right" />
</record>
<record name="pwp" class="com.aexp.earn.api.batch.vo.PWP">
<field name="recordType" length="1" ignore="true" />
<field name="redeemType" rid="true" literal="3" length="1" />
<field name="mmNo" length="10" />
<field name="cmNo" length="19" padding=" " justify="right" />
<field name="rewardProgCode" length="2" />
<field name="redeemTimeStamp" length="26" />
<field name="adjustMiles" length="12" />
<field name="adjustCD" length="4" />
<field name="transId" length="15" />
<field name="transSrcId" length="3" />
<field name="pwpRequestId" length="14" padding=" " justify="right" />
<field name="pwpRequestLnId" length="5" />
</record>
<record name="pap" class="com.aexp.earn.api.batch.vo.PAP">
<field name="recordType" length="1" ignore="true" />
<field name="redeemType" rid="true" literal="4" length="1" />
<field name="mmNo" length="10" />
<field name="cmNo" length="19" padding=" " justify="right" />
<field name="rewardProgCode" length="2" />
<field name="redeemTimeStamp" length="26" />
<field name="chnlPtnrId" length="5" />
<field name="orderId" length="32" />
<field name="partnerReserId" length="32" />
<field name="confirmId" length="16" padding=" " justify="right" />
<field name="actPtCnt" length="12" />
<field name="rewdActTypeCd" length="3" />
<field name="seqNo" length="5" />
</record>
<!-- 'target' binds the trailer record to the Integer record count field -->
<record name="trailer" target="recordCount">
<!-- 'literal' is used to define constant values -->
<field name="recordType" rid="true" literal="9" length="2" />
<!-- 'type' can be declared where bean introspection is not possible -->
<field name="recordCount" length="7" type="int" />
</record>
</stream>
</beanio>
Find below the classes:
Main class:
public class EventStart {
#SuppressWarnings("resource")
public static void main(String[] args) {
String[] springConfig =
{
"earn-api-batch.xml"
};
ClassPathXmlApplicationContext appContext = null;
appContext = new ClassPathXmlApplicationContext(springConfig);
JobLauncher jobLauncher = (JobLauncher) appContext.getBean("jobLauncher");
Job job = (Job) appContext.getBean("processEventJob");
try {
JobExecution execution = jobLauncher.run(job, new JobParameters());
System.out.println("Exit Status : " + execution.getStatus() + " job Id " + execution.getJobId() + " " + execution.getAllFailureExceptions());
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Done");
}
}
Reader Class:
#Component(value = "RedemptionFileReader")
#Scope("step")
public class RedemptionFileReader extends BeanIOFlatFileItemReader<Map<String,Object>>{
/* #Value("#{batchProps['redemption.server.file.path']}")
private Resource resource;*/
Map<String,Object> map = new HashMap<String,Object>();
/*#Override
public String read() throws Exception, UnexpectedInputException,
ParseException, NonTransientResourceException {
System.out.println("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
// TODO Auto-generated method stub
return null;
}*/
#Override
public Map<String,Object> doRead() throws Exception, UnexpectedInputException,
ParseException, NonTransientResourceException {
System.out.println("HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH");
/*if (null != recordsCount) {
return null;
}*/
map = identifyRecord();
return map;
}
private Map<String,Object> identifyRecord() throws FileNotFoundException {
Map<String,Object> map=new HashMap<String,Object>();
ArrayList<NonAirline> narList = new ArrayList<NonAirline>();
ArrayList<Airline> arList = new ArrayList<Airline>();
ArrayList<PWP> pwpList = new ArrayList<PWP>();
ArrayList<PAP> papList = new ArrayList<PAP>();
// create a StreamFactory
StreamFactory factory = StreamFactory.newInstance();
// load the mapping file
factory.load("src/main/resources/earn-api-mapping.xml");
// use a StreamFactory to create a BeanReader
BeanReader in = factory.createReader("redemptionFile", new File("src/main/resources/RedemptionTest"));
Object record = null;
String recordCount = "";
while ((record = in.read()) != null) {
if ("header".equals(in.getRecordName())) {
//Map<String,Object> header = (Map<String,Object>) record;
//System.out.println(header.get("fileDate"));
System.out.println("Header");
}
else if ("nar".equals(in.getRecordName())) {
NonAirline nar = (NonAirline) record;
System.out.println("NAR Redeem Type: " + nar.getRedeemType());
System.out.println("NAR MM No.: " + nar.getMmNo());
System.out.println("NAR CM No.: " + nar.getCmNo());
narList.add(nar);
}
else if ("ar".equals(in.getRecordName())) {
Airline ar = (Airline) record;
System.out.println("AR Redeem Type: " + ar.getRedeemType());
System.out.println("AR MM No.: " + ar.getMmNo());
System.out.println("AR CM No.: " + ar.getCmNo());
arList.add(ar);
}
else if ("pwp".equals(in.getRecordName())) {
PWP pwp = (PWP) record;
System.out.println("PWP Redeem Type: " + pwp.getRedeemType());
System.out.println("PWP MM No.: " + pwp.getMmNo());
System.out.println("PWP CM No.: " + pwp.getCmNo());
pwpList.add(pwp);
}
else if ("pap".equals(in.getRecordName())) {
PAP pap = (PAP) record;
System.out.println("PAP Redeem Type: " + pap.getRedeemType());
System.out.println("PAP MM No.: " + pap.getMmNo());
System.out.println("PAP CM No.: " + pap.getCmNo());
papList.add(pap);
}
else if ("trailer".equals(in.getRecordName())) {
recordCount = (String) record;
System.out.println("Trailer");
System.out.println(recordCount + " contacts processed");
}
}
map.put("NAR", narList);
map.put("AR", arList);
map.put("PWP", pwpList);
map.put("PAP", papList);
in.close();
return map;
}
}
Processor Class:
#Component(value = "RedemptionEventCustomProcessor")
public class RedemptionEventCustomProcessor implements ItemProcessor<Map<String,Object>, Map<String,Object>> {
ArrayList<NonAirline> narList = new ArrayList<NonAirline>();
ArrayList<Airline> arList = new ArrayList<Airline>();
ArrayList<PWP> pwpList = new ArrayList<PWP>();
ArrayList<PAP> papList = new ArrayList<PAP>();
#SuppressWarnings("unchecked")
#Override
public Map<String,Object> process(Map<String,Object> map) throws Exception {
System.out.println(":::::::::::::In Processor::::::::::::::::");
narList = (ArrayList<NonAirline>) map.get("NAR");
for(int i=0; i <= narList.size(); i++)
{
NonAirline nar = narList.get(i);
System.out.println("CM No. " + nar.getCmNo());
}
return map;
}
}
Please let me know if any other information is required. Any help will be really appreciated, please consider I am new to both BeanIO and spring as well.
If anyone could share a working example of BeanIO using Spring Batch that should also help.
Thank You in advance.
I too am using beanio with spring batch. The error you are getting is perhaps for the version issue. Here is my xsd config from job xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:batch="http://www.springframework.org/schema/batch" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
I have a SOAP request
<Register>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" >
<soap:Header/><soap:Body>
<Register>
<identifiers>?</identifiers>
<userId></userId>
<password pwct="?">?</password>
<locale>?</locale>
</Register>
Fully Formed Request that works is
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Header/>
<soap:Body>
<Register>
<identifiers>
<DIdentifiers>
<Section name="IDENTIFIERS">
<Property name="Type" value="Support" />
<Property name="Version" value="3.80 Jan 03 2013" />
<Property name="Timestamp" value="2015/06/08 11:57:48 GMT" />
<Property name="SerialNumber" value="00004" />
<Property name="Hostname" value="gmail.com" />
<Property name="ProductNumber" value="C00004" />
</Section><Section name="INTERFACE_IDENTIFIERS">
<Property name="InterfaceAddress" value="45.34.54.6"/>
<Property name="InterfaceMacAddress" value="00579FGHslkf"/>
</Section>
</DIdentifiers>
</identifiers>
<userId> <userId>
<password pwct="TRUE">shirl123</reg:password>
<locale>en_US</locale>
<Register>
</soap:Body>
</soap:Envelope>
I have added
WSDL client = Savon::client(wsdl: " ")
And calling method
client.call(:Register, message: { })
How can I send the above parameters in Ruby? Could not figure out the correct way to pass parameters
I'm passing
DeviceIdentifiers: {
:Section=> {
{ :Property => nil,
:attributes! => { :Property => { "name" => Type, "value" =>Support} }
}
}
But this doesnot work..
I referred to this
http://savonrb.com/version1/executing-soap-requests.html