jpos : is it possible to have different header for incoming and outgoing message in the same channel - jpos

jpos : how to handle messages with different headers with different length for incoming request and response
I have a below custom channel - the intentions is to handle different header of different length
package org.jpos.iso.channel;
import org.jpos.iso.ISOException;
import org.jpos.iso.ISOMsg;
import org.jpos.iso.ISOPackager;
import org.jpos.iso.packager.GenericPackager;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Arrays;
public class GWMipChannel extends NACChannel {
byte[] madaHeader = {(byte) 0x00, (byte) 0x18, (byte) 0xd6, (byte) 0xf3, (byte) 0xf6, (byte) 0xf8, (byte) 0xf7};
byte[] nitmxHeader = {(byte) 0x00, (byte) 0x18, (byte) 0xd6, (byte) 0xf3, (byte) 0xf7, (byte) 0xf3, (byte) 0xf2};
byte[] response_mada_header = {(byte) 0x00, (byte) 0x18, (byte) 0xc9, (byte) 0xf3, (byte) 0xf6, (byte) 0xf8, (byte) 0xf7};
protected byte[] readHeader(int hLen) throws IOException {
byte[] header = new byte[25];
serverIn.readFully(header, 0, 25);
boolean mada_header = ByteBuffer.wrap(header, 0, 7).equals(ByteBuffer.wrap(madaHeader));
boolean nitmx_header = ByteBuffer.wrap(header, 0, 7).equals(ByteBuffer.wrap(nitmxHeader));
boolean rsp_mada_header = ByteBuffer.wrap(header, 0, 7).equals(ByteBuffer.wrap(response_mada_header, 0, 7));
if (mada_header) {
return header;
} else if (nitmx_header) {
header = Arrays.copyOf(header, 47);
serverIn.readFully(header, 25, 22);
return header;
} else if (rsp_mada_header) {
//serverIn.readFully(header, 0, 50);
header = Arrays.copyOf(header, 50);
serverIn.readFully(header, 0, 50);
return header;
}
return header;
}
protected void sendMessageHeader(ISOMsg m, int len) throws IOException {
byte[] header = m.getHeader();
//assume header is the one to send, and already has 22 or 44 length
//or you can check
serverOut.write(header);
}
}
in the q2 log I can see the messages are parsed correctly as per to the headers
<log realm="org.jpos.transaction.TransactionManager" at="2020-04-16T18:37:55.662" lifespan="555ms">
<commit>
gwmip-1:idle:1
<context>
TIMESTAMP: Thu Apr 16 18:37:55 AEST 2020
SOURCE: org.jpos.iso.channel.X9AChannel#102579c0
REQUEST:
<isomsg direction="outgoing">
<!-- org.jpos.iso.packager.GenericPackager[cfg/packager/iso87ascii-backup.xml] -->
<header>0018D6F3F6F8F7000000000000000000000000000000000002</header>
<field id="0" value="0200"/>
<field id="2" value="5000100100700010"/>
<field id="3" value="000000"/>
<field id="4" value="002167959991"/>
<field id="7" value="0416083755"/>
<field id="11" value="199682"/>
<field id="12" value="183753"/>
<field id="13" value="0416"/>
<field id="14" value="1612"/>
<field id="18" value="4900"/>
<field id="22" value="812"/>
<field id="32" value="588850"/>
<field id="33" value="004601"/>
<field id="37" value="123451234512"/>
<field id="41" value="UTIS2I25"/>
<field id="42" value="EUREKAAIR "/>
<field id="43" value="01007/S2M_txn_base.mat rix_/ Parel M XYZ"/>
<field id="48" value="54363130353030303031393230333132333432303730313033323132343332386A48796E2B3759466931455541524541414141764E5565364876383D" type="binary"/>
<field id="49" value="356"/>
<field id="61" value="10251000066003560000000000"/>
<field id="63" value="MC2J2G6P8"/>
</isomsg>
DESTINATION: gwmip-AUTORESPONDER
RESULT:
<result/>
:paused_transaction:
id: 1
RESPONSE:
<isomsg direction="outgoing">
<!-- org.jpos.iso.packager.GenericPackager[cfg/packager/CISebcdic_mada.xml] -->
<header>0018C9F3F6F8F700000000000000000000000000000000000000000000000000000000000000000000000000000000000002</header>
<field id="0" value="0210"/>
<field id="2" value="165000100100700010"/>
<field id="3" value="000000"/>
<field id="4" value="002167959991"/>
<field id="7" value="0416083755"/>
<field id="11" value="199682"/>
<field id="15" value="0416"/>
<field id="32" value="06588850"/>
<field id="33" value="06004601"/>
<field id="37" value="123451234512"/>
<field id="38" value="183755"/>
<field id="39" value="00"/>
<field id="41" value="UTIS2I25"/>
<field id="48" value="060T6105000019203123420701032124328jHyn+7YFi1EUAREAAAAvNUe6Hv8="/>
<field id="49" value="356"/>
<field id="63" value="009MC2J2G6P8"/>
</isomsg>
my server
<server class="org.jpos.q2.iso.QServer" logger="Q2" name="gwmip-server-5281" realm="gwmip-server-5281">
<attr name="port" type="java.lang.Integer">5281</attr>
<channel class="org.jpos.iso.channel.GWMipChannel"
packager="org.jpos.iso.packager.GenericPackager"
type="server"
logger="Q2"
header="6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002"
>
<property name="packager-config" value="cfg/packager/CISebcdic_mada.xml" debug="True" />
<property name="timeout" value="180000"/>
</channel>
<request-listener class="org.jpos.iso.IncomingListener" logger="Q2" realm="incoming-request-listener">
<property name="queue" value="GWMIPTXNMGR" />
<property name="ctx.DESTINATION" value="gwmip-AUTORESPONDER" />
</request-listener>
</server>
my issuer channel is
<?xml version="1.0" ?>
<channel-adaptor name='gwmip-channel' class="org.jpos.q2.iso.ChannelAdaptor" logger="Q2">
<channel class="org.jpos.iso.channel.X9AChannel"
packager="org.jpos.iso.packager.GenericPackager"
logger="Q2"
header="6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002"
>
<property name="packager-config" value="cfg/packager/iso87ascii-backup.xml" debug="True" />
<property name="host" value="127.0.0.1" />
<property name="port" value="9001" />
</channel>
<in>gwmip-send</in>
<out>gwmip-receive</out>
<reconnect-delay>10000</reconnect-delay>
</channel-adaptor>
The issue here is in the response 0210 message jpos sends only the second half 25 bytes as header not the 50 bytes as it received from the issuer.the first 25 bytes of header is not send.

Related

jpos Gateway : Not able to send back the response message received from the remote host to the client requested

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

Jpos remote host query forwarding message to wrong destination

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

The states of a model for the Workflows in Odoo

I am trying to implement Odoo publishing workflows for my custom model 'product_images.product_image'.
My models look like this:
# product_images/models/models.py
# -*- coding: utf-8 -*-
from odoo import models, fields, api, tools
class PublishingStatus(models.Model):
_name = 'product_images.publishing_status'
_description = 'Publishing status'
name = fields.Char(string="Name")
slug = fields.Char(string="Slug")
class ProductImage(models.Model):
_name = 'product_images.product_image'
_description = 'Product image'
name = fields.Char(string="Alternative text")
product_id = fields.Many2one('product.product', string='Product', ondelete='set null', index=True)
original_image = fields.Binary(string='Original image')
#api.model
def _get_default_state(self):
return self.env['product_images.publishing_status'].search([['slug', '=', 'draft']])
#api.model
def _get_all_states(self, groups, domain, order):
state_ids = self.env['product_images.publishing_status'].search([])
return state_ids
state_id = fields.Many2one(
'product_images.publishing_status',
string='Publishing status',
default=_get_default_state,
group_expand='_get_all_states',
)
#api.multi
def action_set_to_draft(self):
self.state_id = self.env['product_images.publishing_status'].search([['slug', '=', 'draft']])
#api.multi
def action_request_for_approval(self):
self.state_id = self.env['product_images.publishing_status'].search([['slug', '=', 'pending']])
#api.multi
def action_approve(self):
self.state_id = self.env['product_images.publishing_status'].search([['slug', '=', 'approved']])
#api.multi
def action_reject(self):
self.state_id = self.env['product_images.publishing_status'].search([['slug', '=', 'rejected']])
Then I have some data records for the publishing statuses:
<!-- product_images/data/data.xml -->
<odoo>
<data>
<!-- explicit list view definition -->
<record model="product_images.publishing_status" id="product_images.publishing_status_draft">
<field name="name">Draft</field>
<field name="slug">draft</field>
</record>
<record model="product_images.publishing_status" id="product_images.publishing_status_pending">
<field name="name">Pending</field>
<field name="slug">pending</field>
</record>
<record model="product_images.publishing_status" id="product_images.publishing_status_approved">
<field name="name">Approved</field>
<field name="slug">approved</field>
</record>
<record model="product_images.publishing_status" id="product_images.publishing_status_rejected">
<field name="name">Rejected</field>
<field name="slug">rejected</field>
</record>
</data>
</odoo>
I also have some records to create a workflow which allows to switch between the publishing statuses:
<odoo>
<data>
<record model="workflow" id="product_images.wkf_image_publishing">
<field name="name">Product Image Publishing Workflow</field>
<field name="osv">product_images.product_image</field>
<field name="on_create">True</field>
</record>
<record model="workflow.activity" id="product_images.wkf_activity_draft">
<field name="name">Draft</field>
<field name="wkf_id" ref="product_images.wkf_image_publishing" />
<field name="flow_start" eval="True" />
<field name="kind">function</field>
<field name="action">action_set_to_draft()</field>
</record>
<record model="workflow.activity" id="product_images.wkf_activity_pending">
<field name="name">Pending</field>
<field name="wkf_id" ref="product_images.wkf_image_publishing" />
<field name="kind">function</field>
<field name="action">action_request_for_approval()</field>
</record>
<record model="workflow.activity" id="product_images.wkf_activity_approved">
<field name="name">Approved</field>
<field name="wkf_id" ref="product_images.wkf_image_publishing" />
<field name="flow_stop" eval="True" />
<field name="kind">function</field>
<field name="action">action_approve()</field>
</record>
<record model="workflow.activity" id="product_images.wkf_activity_rejected">
<field name="name">Rejected</field>
<field name="wkf_id" ref="product_images.wkf_image_publishing" />
<field name="flow_stop" eval="True" />
<field name="kind">function</field>
<field name="action">action_reject()</field>
</record>
<record model="workflow.transition" id="product_images.wkf_transition_draft_to_pending">
<field name="act_from" ref="product_images.wkf_activity_draft" />
<field name="act_to" ref="product_images.wkf_activity_pending" />
<field name="condition">name != "" and original_image != ""</field>
<field name="signal">pending</field>
</record>
<record model="workflow.transition" id="product_images.wkf_transition_pending_to_draft">
<field name="act_from" ref="product_images.wkf_activity_pending" />
<field name="act_to" ref="product_images.wkf_activity_draft" />
<field name="signal">draft</field>
</record>
<record model="workflow.transition" id="product_images.wkf_transition_pending_to_approved">
<field name="act_from" ref="product_images.wkf_activity_pending" />
<field name="act_to" ref="product_images.wkf_activity_approved" />
<field name="signal">approve</field>
</record>
<record model="workflow.transition" id="product_images.wkf_transition_pending_to_rejected">
<field name="act_from" ref="product_images.wkf_activity_pending" />
<field name="act_to" ref="product_images.wkf_activity_rejected" />
<field name="signal">reject</field>
</record>
</data>
</odoo>
And now the tickiest part! I need a form with the buttons to switch between workflow states and a status bar showing the currently active status. This is what I tried:
<record model="ir.ui.view" id="product_images.form">
<field name="name">Product Image</field>
<field name="model">product_images.product_image</field>
<field name="arch" type="xml">
<form>
<header>
<!--
<button name="draft"
type="workflow"
string="Set to draft"
attrs="{'invisible': [('state_id.slug','not in',['pending'])]}"
/>
<button name="pending"
type="workflow"
string="Request for approval"
attrs="{'invisible': [('state_id.slug','not in',['draft'])]}"
/>
<button name="approve"
type="workflow"
string="Approve"
attrs="{'invisible': [('state_id.slug','not in',['pending'])]}"
class="oe_highlight"
/>
<button name="reject"
type="workflow"
string="Reject"
attrs="{'invisible': [('state_id.slug','not in',['pending'])]}"
class="oe_highlight"
/>
-->
<field name="state_id" widget="statusbar" />
</header>
<sheet>
<group>
<field name="product_id" />
<field name="name" string="Alternative text" />
<field name="original_image" widget="image" class="oe_avatar" />
<field name="state_id" />
</group>
</sheet>
</form>
</field>
</record>
The problems I got:
The status bar is shown, but the current publishing status is not activated.
If I uncomment the buttons, they throw an error about invalid domain:
Uncaught Error: Unknown field state_id.slug in domain
[["state_id.slug","not in",["pending"]]]
What am I missing?
In domain attribute, we can not use parent field in left hand side. In your case, we need to add related field.
For example:
class ProductImage(models.Model):
_name = 'product_images.product_image'
slug = fields.Char(related='state_id.slug', string='Slug', store=True)
Put slug field after state_id in your view file
<field name="slug" invisible="1"/>
Now uncomment <button> codes.
Afterwards, restart Odoo server and upgrade your custom module.

I am getting AssertionError: Element openerp has extra content: data, line 2

I am trying to install a module, then I am getting below error.
AssertionError: Element openerp has extra content: data, line 2
What type of mistake I did for getting this error.
In which file I have to search for error rectify. I am using odoo9.
Files:
This is my xmlfile.xml
<data>
<record model="ir.ui.view" id="10">
<field name="name">model.name</field>
<field name="model">smp.model2</field>
<field name="arch" type="xml">
<form>
<sheet>
<group colspan="4">
<group colspan="2" cal="2">
<field name="name"/>
<field name="active"/>
</group>
<group colspan="2" cal="2">
<field name="age"/>
<field name="sal"/>
</group>
<group colspan="2" cal="2">
<field name="adharid"/>
<field name="cell"/>
</group>
<notebook colspan="4">
<page string="extrainfo"><field name="extrainfo"/></page>
<page string="temporaryaddress"><field name="temporaryaddress"/></page>
<page string="perminantaddress"><field name="perminantaddress"/></page>
</notebook>
</group>
</sheet>
</form>
</field>
</record>
<record model="ir.ui.view" id="20">
<field name="name">model.name</field>
<field name="model">smp.model2</field>
<field name="arch" type="xml">
<tree>
<field name="name"/>
<field name="active"/>
<field name="age"/>
<field name="sal"/>
<field name="adharid"/>
<field name="cell"/>
<field name="extrainfo"/>
<field name="temporaryaddress"/>
<field name="perminantaddress"/>
</tree>
</field>
</record>
<record model ="ir.actions.act_window" id="action_smp_model2">
<field name="name">sampmodel</field>
<field name="res_model">smp.model2</field>
<field name="view_type">form</field>
<field name="viwe_mode">tree,form</field>
</record>
<menuitem id="smp_main_menu1" name="smp model2"/>
<menuitem id="subsmp_main_menu1" name="Sub sample model"
parent="smp_main_menu1"/>
<menuitem id="actsmp_main_menu" name="action smp model"
parent="subsmp_main_menu1" action="action_smp_model2"/>
</data>
</openerp>
This is my data.xml file
<data>
<record id='1' name="smp.model2">
<filed name="name">name1</filed>
<filed name="age">23</filed>
<filed name="cell">123456434</filed>
</record>
<record id='2' name="smp.model2">
<filed name="name">name1</filed>
<filed name="age">23</filed>
<filed name="cell">123456434</filed>
</record>
<record id='3' name="smp.model2">
<filed name="name">name1</filed>
<filed name="age">23</filed>
<filed name="cell">123456434</filed>
</record>
</data>
</openerp>
This is python_file.py
from openerp import models,fields
class model2(models.Model):
_name="smp.model2"
name=fields.Char(string="model name", requred=True, help="name of the
model")
active=fields.Boolean(String="Active")
age=fields.Integer(string="person age",help="age of person")
sal=fields.Integer(string="sal")
adharid=fields.Integer(string="Adhar Id")
cell=fields.Integer(string="phone number",requred=True)
extrainfo=fields.Text(string="Extra information")
temporaryaddress=fields.Text(string="Temporary address")
perminantaddress=fields.Text(string="perminant address")
This is __openerp__.py file
{
'name':'module12',
'description':'module12',
'author':'naveen',
'version':'9.0',
'depends':['base'],
'data':['xmlfile.xml','data.xml']
}
you have errors in a xml, example:
requred=True is required=True
<filed is <field

Spring Batch Integration with BeanIO

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">

Resources