Сообщение о переадресации запроса удаленного хоста Jpos в неправильный пункт назначения

Я использую адаптер канала вместе с Mux для маршрутизации сообщений от клиента к серверу назначения. Однако, когда он обращается к удаленному хосту (используя мультиплексор и адаптер канала), он направляется обратно к клиенту, а не к целевому серверу, как указано в файлах конфигурации.

Пожалуйста, найдите используемый класс:

@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();
        }
    }
}

Вот необходимые файлы конфигурации:

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> 

Из системного вывода видно, что сначала он достигает MyRequestListner, а затем RemoteHostQuery (Process) и мгновенно пересылает/отвечает на клиентский IP-адрес и порт, тогда как он должен пересылать его на удаленный хост, как определено в адаптере канала. Поскольку он не может получить ответ (очевидно), вызывается метод ABORT:

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

person Diwas Sapkota    schedule 12.09.2019    source источник
comment
Ну, так как вы не поделились, куда вы отправляете ответ клиенту, у меня нет полной картины, и я могу только догадываться. Предполагая, что вы в каком-то другом месте отправляете контекстное содержимое ключа PROCESSRESPONSE клиенту, и что код, которым вы поделились, является единственным местом, где вы помещаете что-то в этот ключ, тогда единственный возможный ответ заключается в том, что mux.request возвращает точно что вы отправили. И затем вы отправляете это клиенту, это не означает, что jpos пересылает ваш запрос клиенту.   -  person Andrés Alcarraz    schedule 12.09.2019
comment
Другой вариант заключается в том, что мультиплексор возвращает null, а в каком-то другом месте вы помещаете сообщение REQUEST в ответ в качестве запасного варианта.   -  person Andrés Alcarraz    schedule 12.09.2019
comment
@AndrésAlcarraz На самом деле коммутатор ожидает ответа в queryRemote = mux.request(queryRemote,30000); logger.info(=== + queryRemote); до этого времени я вижу ответ (такой же, как запрос) на стороне клиента. Поскольку клиент не будет отвечать, он получает тайм-аут и возвращает нулевое значение для queryRemote, а метод прерывания правильно отвечает клиенту, и сеанс завершается.   -  person Diwas Sapkota    schedule 12.09.2019
comment
каким-то образом ваше приложение отправляет это сообщение клиенту, но не является мультиплексором, если только ваш сервер (тот, который получает запросы от вашего клиента, для которого вы не предоставили общий доступ к файлу развертывания) не имеет в очереди с именем VISA_IN, может' t сказать без полного журнала и полного кода txngms и полного участника   -  person Andrés Alcarraz    schedule 12.09.2019
comment
@AndrésAlcarraz Я обновил содержание проблемы, надеюсь, это даст вам подсказку для анализа проблемы. Пожалуйста, дайте мне знать, если что-то еще потребуется.   -  person Diwas Sapkota    schedule 12.09.2019
comment
Привет, я дал ответ на основе новой информации, и я надеюсь, что это поможет   -  person Andrés Alcarraz    schedule 12.09.2019


Ответы (1)


Ваша проблема здесь:

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

Как упоминалось в комментариях:

если только ваш сервер (тот, который получает запросы от вашего клиента, для которого вы не предоставили общий доступ к файлу развертывания) не имеет очереди с именем «VISA_IN»

У вас есть очереди in и out, определенные на сервере, с одинаковыми именами канала, поэтому сервер конкурирует с каналом за сообщения, помещенные в эти очереди, сообщения, которые поступают в очередь in сервера, отправляются в его очередь. клиент, вам нужно их удалить, так как вы не используете очереди для связи с клиентом, подключенным к серверу, а вызываете send() от участника транзакции

person Andrés Alcarraz    schedule 12.09.2019