Learn JPOS Part 3 Transaction Manager and Selector

Hi There, in this is the part 3 I will give you the example about JPOS Transaction Manager and Selector.

I will start with simple scenario in this example we will have JPOS service to response message that coming from client simulator but the service can have the process to handle request based MTI and route to specific participant (based on MTI), for example we will handle message request with MTI 0200 as Transaction and message request with MTI 0800 as Network check.

you can clone the code in Github and choose the SimpleListener Project for this tutorial

https://github.com/Gemuruh-Geo/Learn-JPOS.git

2.png

first we create the JPOS setting

000_mogger.xml

000_mogger.xml is responsible as log the application

<logger name="Q2" class="org.jpos.q2.qbean.LoggerAdaptor">
    <log-listener class="org.jpos.util.SimpleLogListener" />
    <log-listener class="org.jpos.util.BufferedLogListener">
        <property name="max-size" value="100" />
        <property name="name" value="logger.Q2.buffered" />
    </log-listener>

    <log-listener class="org.jpos.util.DailyLogListener">
        <property name="window" value="86400" /> <!-- optional, default one day -->
        <!--needed-->
        <property name="prefix" value="log/q2" />
        <property name="suffix" value=".log"/> <!-- optional -->
        <!--optional the default is "-yyyy-MM-dd" -->
        <property name="date-format" value="-yyyy-MM-dd-HH"/>
        <!--optional the default is gzip-->
        <property name="compression-format" value="gzip"/>
    </log-listener>

</logger>

501_Transaction_Listener.xml

<server class="org.jpos.q2.iso.QServer" logger="Q2" name="HostQServer502">
    <attr name="port" type="java.lang.Integer">2300</attr>
    <attr name="maxSessions" type="java.lang.Integer">20</attr>
    <attr name="minSessions" type="java.lang.Integer">10</attr>

    <channel class="org.jpos.iso.channel.ASCIIChannel" name="ASCIIChannel" logger="Q2"
             packager="org.jpos.iso.packager.ISO87APackager">
    </channel>

    <request-listener class="com.gl.listener.ServerApplicationListener" logger="Q2" name="isoListener">
        <property name="space" value="transient:default" />
        <property name="queue" value="TXNQueue" />
        <property name="spaceTimeout" value="60000" />
    </request-listener>
</server>

As you can see in transaction listener configuration we directed the logging process to our moger.xml using previous logger name logger=“Q2”.

In transaction listener configuration we have configuration to set channel as ASCIIChannel and set packager as ISO87APackager also we register our listener class com.gl.listener.ServerApplicationListener and some parameter like space,queue, and spaceTimeout those property we will use letter to send our interest variable to space.

Little Touch In Space

Basically the space in JPOS is like big room where you can throw object to those room, but to make sure you can pick up your object later you need give signature to those object so you not incidentally pick the wrong object. Space using key value process like map to give signature to the object.

503_Transaction_Manager.xml

<txnmgr name="SimpleTransactionManager" logger="Q2" class="org.jpos.transaction.TransactionManager">
    <property name="space" value="transient:default" />
    <property name="queue" value="TXNQueue" />
    <property name="sessions" value="5" />
    <property name="debug" value="true" />

    <participant class="com.gl.selector.Selector" name="Selector" logger="Q2">
        <property name="0200" value="Transaction" />
        <property name="0800" value="Network" />
    </participant>
    <participant class="com.gl.participant.SenderResponseParticipant" logger="Q2"/>
    <group name="Transaction">
        <participant class="com.gl.participant.TransactionResponseParticipant" logger="Q2" />
    </group>

    <group name="Network">
        <participant class="com.gl.participant.NetworkParticipant" logger="Q2" />
    </group>

</txnmgr>

On the transaction manager configuration we register selector class that responsible to switch the participant base on MTI 0200 or 0800. Pay attention to SenderResponseParticipant those participant is reside outside the group and those participant will be execute after participant that choose by selector.

After we create xml setting for logger, listener, and transaction manager we ready to add the listener class to listen the request, selector class to switch the participant and participants class to handle the request logic.

Listener Class

package com.gl.listener;

import com.constant.Constants;
import org.jpos.core.Configurable;
import org.jpos.core.Configuration;
import org.jpos.core.ConfigurationException;
import org.jpos.iso.ISOException;
import org.jpos.iso.ISOMsg;
import org.jpos.iso.ISORequestListener;
import org.jpos.iso.ISOSource;
import org.jpos.space.Space;
import org.jpos.space.SpaceFactory;
import org.jpos.transaction.Context;

/**
 * Created by ggpratama on 10/7/2015.
 */
public class ServerApplicationListener implements ISORequestListener,Configurable{

    private Configuration configuration;
    @Override
    public void setConfiguration(Configuration configuration) throws ConfigurationException {
        this.configuration = configuration;
    }

    @Override
    public boolean process(ISOSource isoSource, ISOMsg isoMsg) {
        String spaceN = configuration.get("space");
        Long timeout = configuration.getLong("spaceTimeout");
        String queueN = configuration.get("queue");
        Context context = new Context();
        Space<String,Context> space = SpaceFactory.getSpace(spaceN);

        try {
            ISOMsg respMsg = (ISOMsg)isoMsg.clone();
            respMsg.setResponseMTI();
            respMsg.set(39,"00");

            context.put(Constants.REQUEST_KEY,isoMsg);
            context.put(Constants.RESPONSE_KEY,respMsg);
            context.put(Constants.RESOURCE_KEY,isoSource);

        } catch (ISOException e) {
            e.printStackTrace();
        }

        space.out(queueN,context,timeout);
        return false;
    }
}

Pay attention to process method in the process method we register request message, response message, and isoSource to the Context class and we throw the Context class to Space.

Selector class

package com.gl.selector;

import com.constant.Constants;
import org.jpos.core.Configurable;
import org.jpos.core.Configuration;
import org.jpos.core.ConfigurationException;
import org.jpos.iso.ISOException;
import org.jpos.iso.ISOMsg;
import org.jpos.transaction.Context;
import org.jpos.transaction.GroupSelector;

import java.io.Serializable;

/**
 * Created by ggpratama on 10/7/2015.
 */
public class Selector implements GroupSelector,Configurable{
    private Configuration configuration;
    @Override
    public void setConfiguration(Configuration configuration) throws ConfigurationException {
        this.configuration = configuration;
    }

    @Override
    public String select(long l, Serializable serializable) {
        Context ctx = (Context)serializable;
        ISOMsg resIsoMsg = (ISOMsg)ctx.get(Constants.REQUEST_KEY);
        String selector = "";
        try {
            selector = configuration.get(resIsoMsg.getMTI());
        } catch (ISOException e) {
            e.printStackTrace();
        }
        return selector;
    }

    @Override
    public int prepare(long l, Serializable serializable) {
        return PREPARED|ABORTED|NO_JOIN;
    }

    @Override
    public void commit(long l, Serializable serializable) {

    }

    @Override
    public void abort(long l, Serializable serializable) {

    }
}

The select method responsible to change the participant base on message MTI, on the select method we get the request message from context and check the MTI and using those MTI to change the participant.

NetworkParticipant

package com.gl.participant;

import com.constant.Constants;
import org.jpos.iso.ISOException;
import org.jpos.iso.ISOMsg;
import org.jpos.transaction.Context;
import org.jpos.transaction.TransactionParticipant;

import java.io.Serializable;

/**
 * Created by ggpratama on 10/7/2015.
 */
public class NetworkParticipant implements TransactionParticipant{

    @Override
    public int prepare(long l, Serializable serializable) {
        Context ctx = (Context)serializable;
        //Set Response for Network Check
        ISOMsg respMsg = (ISOMsg)ctx.get(Constants.RESPONSE_KEY);
        try {
            respMsg.set(39,"00");
            ctx.put(Constants.RESPONSE_KEY,respMsg);
        } catch (ISOException e) {
            e.printStackTrace();
        }
        return PREPARED;
    }

    @Override
    public void commit(long l, Serializable serializable) {

    }

    @Override
    public void abort(long l, Serializable serializable) {
    }
}

On network participant we just change the message response bit 39 to 00 as transaction success.

Transaction Response Participant

package com.gl.participant;

import com.constant.Constants;
import org.jpos.iso.ISOException;
import org.jpos.iso.ISOMsg;
import org.jpos.transaction.Context;
import org.jpos.transaction.TransactionParticipant;

import java.io.Serializable;

/**
 * Created by ggpratama on 10/7/2015.
 */
public class TransactionResponseParticipant implements TransactionParticipant{
    @Override
    public int prepare(long l, Serializable serializable) {
        Context ctx = (Context)serializable;
        ISOMsg respMsg = (ISOMsg)ctx.get(Constants.RESPONSE_KEY);
        try {
            respMsg.set(39,"00");
            ctx.put(Constants.RESPONSE_KEY,respMsg);
        } catch (ISOException e) {
            e.printStackTrace();
        }
        return PREPARED;
    }

    @Override
    public void commit(long l, Serializable serializable) {

    }

    @Override
    public void abort(long l, Serializable serializable) {

    }
}

Transaction response participant do the same job as Network participant, the different just the response MTI will be different because the Transaction is choose base on request MTI 200.

Sender Response Participant

package com.gl.participant;

import com.constant.Constants;
import org.jpos.iso.ISOException;
import org.jpos.iso.ISOMsg;
import org.jpos.iso.ISOSource;
import org.jpos.transaction.Context;
import org.jpos.transaction.TransactionParticipant;

import java.io.IOException;
import java.io.Serializable;

/**
 * Created by ggpratama on 10/7/2015.
 */
public class SenderResponseParticipant implements TransactionParticipant{
    @Override
    public int prepare(long l, Serializable serializable) {
        Context ctx = (Context)serializable;
        ISOMsg respMsg = (ISOMsg)ctx.get(Constants.RESPONSE_KEY);
        String bit39 = respMsg.getString(39);
        if(bit39==null){
            try {
                respMsg.set(39,"06");

            } catch (ISOException e) {
                e.printStackTrace();
            }
        }
        ctx.put(Constants.RESPONSE_KEY,respMsg);
        return PREPARED;
    }

    @Override
    public void commit(long l, Serializable serializable) {
        sendMessage((Context)serializable);
    }

    @Override
    public void abort(long l, Serializable serializable) {
        sendMessage((Context)serializable);
    }
    private void sendMessage(Context context){
        ISOSource source = (ISOSource)context.get(Constants.RESOURCE_KEY);
        ISOMsg msgResp = (ISOMsg)context.get(Constants.RESPONSE_KEY);
        try {
            source.send(msgResp);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ISOException e) {
            e.printStackTrace();
        }
    }
}

The Sander Response Participant responsible to send the response message and to change the bit39 to 06 to represent unknown error.

Run The Application
I am using intellij to run the application for eclipse user maybe you can googling to find the solution.

  1. First you need to go to run configuration and point out the main method to JPOS Q2 class.

  2. Pointed the working directory to resource.

Setting 1.png

  1. Create new configuration to run the client simulator.

Setting 2.png

  1. You need to run the listener first after that you run the client simulator to send the ISO Message

That’s it guys I suggest you to read the JPOS guide to get more understanding in transaction manager, space and context.

 
100
Kudos
 
100
Kudos

Now read this

Learn JPOS Part 4 throw rest service to Host

This part actually my experiment to throw rest message to host we will using spring boot as RestFul service and using those service to throw ISOMsg as JSON data upon the request on web. If you read the previous tutorial (Part 3) the code... Continue →