0

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>
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • Well, since you haven't shared where you send the response to the client I don't have the full picture and I can only guess. Assuming you are in some other place sending the context content of "PROCESSRESPONSE" key to the client, and that the code you shared is the only place where you put something in that key, then the only possible anser is that the mux.request is returning exactly what you sent. And then you are sending that to the client, that doesn't mean jpos is forwarding your request to the client – Andrés Alcarraz Sep 12 '19 at 02:27
  • Other option is that mux is returning null and in some other place you are putting the "REQUEST" message in the response as a fallback. – Andrés Alcarraz Sep 12 '19 at 02:30
  • @AndrésAlcarraz Actually switch waits for the response in **queryRemote = mux.request(queryRemote,30000); logger.info("===" + queryRemote);** till that time i can see the response (same as request) in client end. Since client will not be responding back and it gets timeout and returns null value for queryRemote and abort method responds properly back to client and the session is completed. – Diwas Sapkota Sep 12 '19 at 03:43
  • well somehow your application is sending that message to the client, but is not the mux, 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", can't tell without full log and full txngms and full participants code – Andrés Alcarraz Sep 12 '19 at 04:11
  • @AndrésAlcarraz I have updated the content of the issue, hope it will give you some hint to analyze the issue. Please do let me know if anything else is required. – Diwas Sapkota Sep 12 '19 at 06:39
  • Hi I've provided an answer based on the new information and I hope this helps – Andrés Alcarraz Sep 12 '19 at 18:00

1 Answers1

2

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

Andrés Alcarraz
  • 1,570
  • 1
  • 12
  • 21