Setting up a logon manager

1,628 views
Skip to first unread message

Pieter Botha

unread,
Aug 10, 2012, 4:33:06 AM8/10/12
to jpos-...@googlegroups.com
Good day everyone,

I'm busy with the network management messages (001/030/161/162 - logon/echo/keys). On the one side I would be pushing a key to a client that is connected to a IsoServer whilst on the other side I will be receiving a key on a channel-adapter published by a server to which I connected using a channel-adapter/mux. 

Targeting the server side for which I need to create a key first:
- I should be able to create & receive echo's (every 5min) 
- I will receive logon requests (on reconnect)
- I will receive key-exchange requests / 161
- I must send a new key at 24hour intervals.

Targetting the client side for which I will receive a key: 
- I need to submit a logon on a specific channel once that channel reconnects
- I need to request a key every 24hours
- I will receive a new key at random intervals
- Echos need to be responded to.

For the server side where I have a client connecting to me, what will be the best approach?

I have read that a logon manager seems to be the way to go when connecting to a 3rd party (example below). What I do not understand is how the components are glued together, The logon manager xml contains elements corresponding to the Mux, however it does not show when/how these elements are used. When will the LogonManager xml be called? When a channel is reconnected at the Mux, how will the Mux know it needs to call doEcho() or doSignon() or pass the trigger to the LogonManager xml ?

Is there somewhere an example showing how these components are integrated?

The example below is a paste from Andy's blog.
Channel XML:
<channel-adaptor name='amex' class="org.jpos.q2.iso.ChannelAdaptor" logger="Q2">
<channel class="org.jpos.amex.AMEXChannel" logger="Q2" realm="amex-channel" packager="org.jpos.iso.packager.GenericPackager">
<property name="packager-logger" value="Q2" />
<property name="packager-realm" value="amex-debug" />
<property name="packager-config" value="cfg/amex.xml" />
<property name="host" value="@amex0.host@" />
<property name="port" value="@amex0.port@" />
</channel> 
<in>amex-send</in>
<out>amex-receive</out>
<reconnect-delay>10000</reconnect-delay>
</channel-adaptor>

Mux Xml:
<mux class="org.jpos.q2.iso.QMUX" logger="Q2" name="amex-mux">
<in>amex-receive</in>
<out>amex-send</out>
<ready>amex.ready amex1.ready</ready>
<unhandled>amex-unhandled</unhandled>
</mux>

LogonManager XML:
<amex-logon-mgr class="org.jpos.amex.LogonManager" logger="Q2">
<property name="persistent-space" value="@amex.logon.space@" />
<property name="mux" value="amex-mux" />
<property name="channel-ready" value="amex.ready" />
<property name="timeout" value="900000" />
<property name="echo-interval" value="600000" />
<property name="logon-interval" value="43200000" />
</amex-logon-mgr>

LogonManager Java extract:
private void doEcho () throws ISOException {
ISOMsg resp = mux.request (createMsg (), timeout);
if (resp != null) {
sp.out (ECHO, new Object(), echoInterval);
}
}
private ISOMsg createMsg () throws ISOException {
long traceNumber = SpaceUtil.nextLong (psp, TRACE) % 1000000;
ISOMsg m = new ISOMsg ("1804");
m.set (3, "000000");
m.set (11, ISOUtil.zeropad (Long.toString (traceNumber), 6));
m.set (12, ISODate.getDateTime (new Date()));
m.set (24, "831"); // “Are You There?” (per AMEX specs)
m.set (25, "8700"); // Client-specific magic number
return m;
}

Thanks,
  Pieter

Alejandro Revilla

unread,
Aug 13, 2012, 8:17:51 PM8/13/12
to jpos-...@googlegroups.com
I wish I could have more time to answer your full email, will just pick a few easy parts, hope some other users can jump in and help too, see comments inline below:


I'm busy with the network management messages (001/030/161/162 - logon/echo/keys). On the one side I would be pushing a key to a client that is connected to a IsoServer whilst on the other side I will be receiving a key on a channel-adapter published by a server to which I connected using a channel-adapter/mux. 

Targeting the server side for which I need to create a key first:
- I should be able to create & receive echo's (every 5min) 
- I will receive logon requests (on reconnect)
- I will receive key-exchange requests / 161
- I must send a new key at 24hour intervals.

When your client connects to your server, and sends the initial logon request, you can store a reference to that ISOChannel somewhere in your application (you can use the Space, or just a Map). Actually, I suggest you don't store a reference to the ISOSource (to avoid leaks), ISOServer maintains weak references to the ISOChannel names, so you can cast your ISOSource to an ISOChannel, and store its name (using ISOChannel.getName() method). Then you can use ISOServer.getISOChannel(String) to get a hold of the channel. If it is null, it means the channel got disconnected.
 
Targetting the client side for which I will receive a key: 
- I need to submit a logon on a specific channel once that channel reconnects
- I need to request a key every 24hours
- I will receive a new key at random intervals
- Echos need to be responded to.

You can do this with a small LogonManager code that would monitor the 'ready' indicator of a given channel. 
 
For the server side where I have a client connecting to me, what will be the best approach?

Mentioned above.
 
I have read that a logon manager seems to be the way to go when connecting to a 3rd party (example below). What I do not understand is how the components are glued together, The logon manager xml contains elements corresponding to the Mux, however it does not show when/how these elements are used. When will the LogonManager xml be called? When a channel is reconnected at the Mux, how will the Mux know it needs to call doEcho() or doSignon() or pass the trigger to the LogonManager xml ?

Actually the LogonManager XML is a runnable Q2 service, Q2 reads the XML and  launches it, so it will run in its own thread, monitoring the status of the channel, checking the keys validity in the space, and taking action. This is far from an optimal thing, sonner rather than later we'll have to add some hooks at the server and channel level to deal with the popular problem you are implementing now.

--Alejandro

Sumeet Phadnis

unread,
Aug 14, 2012, 1:11:26 AM8/14/12
to jpos-...@googlegroups.com
Hi Pieter,

ISOServer has a very useful feature - it is Observable. If you observe it, you will get updates whenever a channel connects (arg instanceof ISOServer) or disconnects (arg instanceof ISOChannel). You can make use of this in the LogonManager to "grab" the channel.

Regards,
Sumeet

chhil

unread,
Aug 14, 2012, 4:03:33 AM8/14/12
to jpos-...@googlegroups.com
Just some thoughts:
I feel the ready for the channel probably needs to be intercepted and put in space only after the logon is completed to prevent messages being sent and possibly declined because you are not logged on.

Echo messages should not be an issue when you are the initiator or responder.

Synchronizing keys may be tricky with a service that runs on its own, considering transactions that are being processed or in flight.

-chhil

--
--
jPOS is licensed under AGPL - free for community usage for your open-source project. Licenses are also available for commercial usage.
Please support jPOS, contact: sa...@jpos.org
 
You received this message because you are subscribed to the "jPOS Users" group.
Please see http://jpos.org/wiki/JPOS_Mailing_List_Readme_first
To post to this group, send email to jpos-...@googlegroups.com
To unsubscribe, send email to jpos-users+...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/jpos-users
 
 
 

Alejandro Revilla

unread,
Aug 14, 2012, 8:33:22 AM8/14/12
to jpos-...@googlegroups.com
Problem is the 'ready' indicator is checked by the MUX to send the message, and the MUX is in turn used by the TransactionManager, so perhaps we need another way to indicate the channel is logged on, checked by the higher level application. This is the problem the 'Stations' in jPTS intend to solve (in addition to logon status, we also have to take care of exchanged keys, etc.).

@apr

Pieter Botha

unread,
Aug 14, 2012, 10:46:49 AM8/14/12
to jpos-...@googlegroups.com
Thanks for the excellent ideas. I've been going over the Spaces, SpaceListener etc. It looks like the basic idea of a LogonManager is to be instantiated after the Mux and would need to check the Mux periodically for the status of certain channels. 

The LogonManager would also need to submit echo requests periodically at say 3min intervals (which is different from the 5min hardcode of TSpace garbage collection). The LogonManager  would thus need to "put" an object into the specified space (I guess a space per mux would be best? - to isolate echo's flying around) with a timeout value. The LogonManager would then use myspace.rdp(key) to check whether an entry exists, if not it means it has expired and a new entry need to be created / echo request sent. 

The problem here is now how does one detect that all the channels dropped and reconnected whilst you were sleeping and you need to do a logon? The isConnected() call to the mux would return true as everything is now connected (again).

Would the following pseudo code be acceptable?

constructor() {
  mux = (QMUX) NameRegistrar.get("mux.my_visa_mux")
  myspace = SpaceFactory.getSpace("mux.my_visa_mux")  //specially create this space to isolate echo's from other service echo's for other servers
  while (true) {
    if (mux.isConnected() { //one must be connected in order to send messages
      logonReply = mux.request(logonIsoRequest,10000) 
      myspace.out("ECHO",new Object(), 60000*3) //put an item in the space that expires when we must do an echo again
      doProcessing()
      break;
    }
    sleep(5000);
  }
}

doProcessing() {
  while (true) {
    if (myspace.rdp("ECHO") == null) //if the item does not exists in the space anymore, it has expired so redo echo
    {
      echoReply = mux.request(echoIsoRequest,10000)
      myspace.out("ECHO",new Object(), 60000*3)
    }
    if (myspace.rdp("KEY") == null) //same behaviour applies to other 0800 messages
    {
      //do similar 0800 action such as key exchange
    }
    sleep(20);
  }
}

Pieter

Alejandro Revilla

unread,
Aug 14, 2012, 7:41:47 PM8/14/12
to jpos-...@googlegroups.com

The problem here is now how does one detect that all the channels dropped and reconnected whilst you were sleeping and you need to do a logon? The isConnected() call to the mux would return true as everything is now connected (again).

The ChannelAdaptor uses a different object (currently a Date object, but you can't rely on that because it's not part of its contract) on every connection, so you can save an 'Object sessionId' and check if it is the same.

A LogonManager run method looks like this:

   public static final String TRACE = "JPTS_TRACE";
   public static final String LOGON = "JPTS_LOGON.";
   public static final String ECHO  = "JPTS_ECHO.";

   public void run () {
        while (running()) {
            Object sessionId = sp.rd (readyKey, 60000);
            if (sessionId == null) {
                getLog().info ("Channel " + readyKey + " not ready");
                continue;
            }
            try {
                if (!sessionId.equals (sp.rdp (LOGON+readyKey))) {
                    doLogon (sessionId);
                } else if (sp.rdp (ECHO+readyKey) == null) {
                    doEcho ();
                }
            } catch (Throwable t) {
                getLog().warn (t);
            }
            ISOUtil.sleep (1000);
        }
    }


Pieter Botha

unread,
Aug 16, 2012, 12:20:38 PM8/16/12
to jpos-...@googlegroups.com
Hi Alejandro,

Thank you very much for the example. It turned out perfect (and I learned that Mastercard is now more ASCII friendly (I'm used to Mastercard being all EBCDIC)). 

Just a side question, Mastercard has the option where you request a key(162 I think - 0800 request to Mastercard) and eventually they then provide you with a key (161 - a new 0800 request from Mastercard). I tested out a scenario and it looks like should I add a request-listener to the mux, it will be triggered when a fresh request from Mastercard arrives and not when a reply comes back or when a request to mastercard is submitted. Am I correct in saying this? If so, it would mean that I merely need to add more"fat" to the logon-manager code to cater for requests from Mastercard relating to network management.

Thanks for the assistance & patience, I appreciate it.

Pieter

Alejandro Revilla

unread,
Aug 16, 2012, 2:47:51 PM8/16/12
to jpos-...@googlegroups.com

Thank you very much for the example. It turned out perfect (and I learned that Mastercard is now more ASCII friendly (I'm used to Mastercard being all EBCDIC)). 

Yes. I believe you can ask to be configured as an ASCII endpoint.
 
Just a side question, Mastercard has the option where you request a key(162 I think - 0800 request to Mastercard) and eventually they then provide you with a key (161 - a new 0800 request from Mastercard). I tested out a scenario and it looks like should I add a request-listener to the mux, it will be triggered when a fresh request from Mastercard arrives and not when a reply comes back or when a request to mastercard is submitted. Am I correct in saying this?

Absolutely, messages arriving to the MUX that doesn't match a pending request, will get forwarded to the ISORequestListener. You need to be prepare to catch there some late responses.
 
If so, it would mean that I merely need to add more"fat" to the logon-manager code to cater for requests from Mastercard relating to network management.

If you use the Space to place your keys, and your programs pick the working keys from the Space (which is good, because you can use some of the space block operations to wait a little bit for an initial key at startup), you don't need to add too much "fat" to the logon manager, you can do part of the work in your ISORequestListener (or TransationManager if you choose to forward those messages to the TM).

Thanks for the assistance & patience, I appreciate it.

You're welcome!


Keshaw Sinha

unread,
Nov 14, 2018, 2:35:52 AM11/14/18
to jPOS Users
Thanks all for suggesting different methods for handling network messages. It would be great if someone can clarify the following for me:
1. Alejandro had suggested the following:
public static final String TRACE = "JPTS_TRACE";
   public static final String LOGON = "JPTS_LOGON.";
   public static final String ECHO  = "JPTS_ECHO.";

   public void run () {
        while (running()) {
            Object sessionId = sp.rd (readyKey, 60000);
            if (sessionId == null) {
                getLog().info ("Channel " + readyKey + " not ready");
                continue;
            }
            try {
                if (!sessionId.equals (sp.rdp (LOGON+readyKey))) {
                    doLogon (sessionId);
                } else if (sp.rdp (ECHO+readyKey) == null) {
                    doEcho ();
                }
            } catch (Throwable t) {
                getLog().warn (t);
            }
            ISOUtil.sleep (1000);
        }
    }
Wont the expression sessionId.equals (sp.rdp (LOGON+readyKey)) be always false considering sessionId = sp.rd (readyKey, 60000) ? Or I am missing something here?

2. There is another way suggested by Sumeet. We can observe the channel (since BaseChannel is observable) in our LogonManager so that we get a notification just after channel has connected and just before channel has disconnected on below lines of pseudo-code?


public class LogonManager extends QBeanSupport implements Observer {

      BaseChannel channel1;

     

      @Override

      protected void startService() {

            try {

                  channel1 = (BaseChannel)NameRegistrar.get("channel.channel1");

                  channel1.addObserver(this);

                  //Add this observer to other channels as well (including server channel)

            } catch (NotFoundException e) {

                  // TODO Auto-generated catch block

                  e.printStackTrace();

            }

      }

      @Override

      public void update(Observable o, Object arg) {

            // TODO Auto-generated method stub

            doSomething(); //Based on Observable and arg

      }

 

}


3. Which of the aforementioned approaches one should take - one requiring infinitely probing the ready key and the other notified only during connection and disconnection? Has there been any update on the way one should handle these network messages? 

Thanks for your valuable inputs.

-Keshaw

chhil

unread,
Nov 14, 2018, 9:09:32 AM11/14/18
to jpos-...@googlegroups.com

1.Wont the expression sessionId.equals (sp.rdp (LOGON+readyKey)) be always false considering sessionId = sp.rd (readyKey, 60000) ? Or I am missing something here?


In the doLogon for a successful request response you would do something like the following so that you don't logon more than once.
sp.out(LOGON + readyKey, sessionId);
If you need to logon at regular interval then you expire the entry
sp.out(LOGON + readyKey, sessionId, expirelogonTime);

2.

Sumeet talks about ISOServer you are talking clients here. For servers there is listener you can add to get connect/disconnect events. For client connections, there is only a the readyKey that I am aware of.

-chhil

--
--
jPOS is licensed under AGPL - free for community usage for your open-source project. Licenses are also available for commercial usage. Please support jPOS, contact: sa...@jpos.org
---
You received this message because you are subscribed to the Google Groups "jPOS Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jpos-users+...@googlegroups.com.
To post to this group, send email to jpos-...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jpos-users/848f2593-82f4-477d-924a-f5001e788dd2%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Keshaw Sinha

unread,
Nov 15, 2018, 1:55:14 AM11/15/18
to jPOS Users
Thanks Chhil for clarification regarding Alejandro's method. I'll also explore the other method if that is possible.
Reply all
Reply to author
Forward
0 new messages