Examples

This chapter describes how to externally execute OpenFrame CTG, which is a program in an OSC application server.

1. EJB 2.0 Example with JCA

The following is an example that a servlet calls EJB to insert a value to a database table and call a specific program in an OSC server by using a single transaction.

<ejb/server/CtgXa.java>

package ejb.server;

import javax.ejb.Remote;

@Remote
public interface CtgXa{
    String doXATest(String data);
}

The following example implements EJB. It creates UserTransaction through Bean Management Transaction (BMT), inserts a value to a database table, and calls a program registered in an OSC Region server by using a single transaction.

<ejb/server/CtgXaBean.java>

package ejb.server;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import javax.annotation.Resource;
import javax.ejb.SessionContext;
import javax.ejb.Stateless;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.resource.ResourceException;
import javax.resource.cci.ConnectionFactory;
import javax.resource.cci.Interaction;
import javax.resource.cci.InteractionSpec;
import javax.sql.DataSource;
import javax.transaction.SystemException;
import javax.transaction.UserTransaction;

import com.tmax.ofctg.connector.cics.CICSResourceException;
import com.tmax.ofctg.connector.cics.ECIConnectionSpec;
import com.tmax.ofctg.connector.cics.ECIInteractionSpec;
import com.tmax.ofctg.connector.cics.ECIResourceAdapterRc;

@Stateless(mappedName="ejb.server.DBTest")
@TransactionManagement(TransactionManagementType.BEAN)
public class CtgXaBean implements CtgXa
{
    @Resource
    SessionContext ejbContext;

    public String doXATest(String data) {
        UserTransaction tx = null;
        String dbResult = null;
        String ctgResult = null;

        try {
            tx = this.ejbContext.getUserTransaction();
            tx.begin();

            dbResult = insertToDatabase("INSERT INTO CTG_TEST2 VALUES('TST7')");
            ctgResult = insertToCTG(data);

            tx.commit();
            System.out.println("Transaction Committed.");

        } catch (Exception e) {
            try {
                tx.rollback();
                System.out.println("Rollback Succeeded.");
            } catch (IllegalStateException e1) {
                e1.printStackTrace();
                System.out.println("Rollback failed.");
            } catch (SecurityException e1) {
                e1.printStackTrace();
                System.out.println("Rollback failed.");
            } catch (SystemException e1) {
                e1.printStackTrace();
                System.out.println("Rollback failed.");
            }
        }
        return "DB Result = " + dbResult + " <br> Result2 = " + ctgResult;
    }

    public String insertToDatabase(String query) {
        Connection conn = null;
        Statement stmt = null;
        String result = null;

        try {
            Context ctx = new InitialContext();
            DataSource ds = (DataSource) ctx.lookup("tibero_xa_datasource");
            conn = ds.getConnection();

            stmt = conn.createStatement();
            int count = stmt.executeUpdate(query);
            if (count > 0)
                result = String.valueOf(count);

        } catch (SQLException sqle) {
        } catch (Exception e) {
        } finally {
            try {
                if (stmt != null)
                    stmt.close();
                if (conn != null)
                    conn.close();
            } catch (SQLException e) {
            }
        }
        return result;
    }

    public String insertToCTG(String commarea) {
        javax.resource.cci.Connection conn = null;
        String returnStr = null;
        String functionName = "PIVPECIT";

        try {
            InitialContext ctx = new InitialContext();
            ConnectionFactory connFactory = (ConnectionFactory) ctx.lookup("CTGConnector");

            ECIConnectionSpec cs = new ECIConnectionSpec();
            conn = connFactory.getConnection(cs);
            Interaction action = conn.createInteraction();

            ECIInteractionSpec eciiSpec = new ECIInteractionSpec();
            eciiSpec.setUserID("");
            eciiSpec.setPassword("");
            eciiSpec.setFunctionName(functionName);
            eciiSpec.setCommareaLength(5000);
            eciiSpec.setInteractionVerb(InteractionSpec.SYNC_SEND_RECEIVE);

            GenericRecord sndRecord = new GenericRecord(commarea.getBytes("UTF-8"));
            GenericRecord rcvRecord = new GenericRecord();

            if (action.execute(eciiSpec, sndRecord, rcvRecord)) {
                byte[] result = rcvRecord.getCommarea();
                returnStr = new String(result, "UTF-8");
            }
            System.out.println("execute CTG Successed.");

        } catch (CICSResourceException e) {
            String abendCode = e.getAbendCode();
            int respCode = e.getCicsRespCode();

            if (respCode != ECIResourceAdapterRc.ECI_NO_ERROR)
                returnStr = "Func: " + functionName + ", Abend: " + abendCode +
                ", Resp: " + ECIResourceAdapterRc.getErrorMessage(respCode);
            else
                returnStr = "Func: " + functionName + ", Abend: " + abendCode;

            System.out.println("execute CTG failed, " + returnStr);

        } catch (ResourceException e) {
            e.printStackTrace();
            return e.getMessage();

        } catch (Exception e) {
            e.printStackTrace();
            return e.getMessage();

        } finally {
            try {
                if (conn != null)
                    conn.close();
            } catch (ResourceException e) {
                e.printStackTrace();
            }
        }

        return returnStr;
    }
}

2. COMMAREA Buffer Class

The following is the COMMAREA buffer class used to communicate with an OSC server. The javax.resource.cci.Streamable interface must be implemented.

<ejb/server/GenericRecord.java>

package ejb.server;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.resource.cci.Record;
import javax.resource.cci.Streamable;

public class GenericRecord implements Streamable, Record {
    private static final long serialVersionUID = -7600580218655773637L;
    private byte[] commarea = null;
    private String recordName;

    public GenericRecord() {
    }

    public GenericRecord(byte[] comm) {
        setCommarea(comm);
    }

    public void setCommarea(byte[] comm) {
        commarea = (byte[]) comm.clone();
    }

    public byte[] getCommarea() {
        return commarea;
    }

    public void read(InputStream in) throws IOException {
        commarea = null;

        int total = in.available();
        if (total > 0) {
            commarea = new byte[total];
            in.read(commarea);
        }
    }

    public void write(OutputStream out) throws IOException {
        if (commarea != null) {
            out.write(commarea);
            out.flush();
        }
    }

    @Override
    public GenericRecord clone() throws CloneNotSupportedException {
        return new GenericRecord(getCommarea());
    }

    @Override
    public String getRecordName() {
        return recordName;
    }

    @Override
    public void setRecordName(String recordName) {
        this.recordName = recordName;
    }

    @Override
    public void setRecordShortDescription(String arg0) {
    }

    @Override
    public String getRecordShortDescription() {
        return null;
    }
}

3. Servlet Program

The following is a servlet that calls EJB. It calls doXATest() of CtgXa and displays the result in a web browser screen.

<ejb/client/HelloClient.java>

package ejb.client;

import java.io.IOException;
import java.io.PrintWriter;
import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import ejb.server.CtgXa;

public class HelloClient extends HttpServlet {
    private static final long serialVersionUID = 5385358571284268459L;
    @EJB(mappedName="ejb.server.CtgXa")
    private CtgXa ctgXaTest;

    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        PrintWriter out = response.getWriter();
        try {
            String result = ctgXaTest.doXATest("TestData");

            response.setContentType("text/html");
            out.println("<html>");
            out.println("<head>");
            out.println("<title>HelloClient</title>");
            out.println("</head>");
            out.println("<body>");
            out.println("<h1>" + result + "</h1>");
            out.println("</body>");
            out.println("</html>");
            out.close();

        } catch(Exception ex){
            response.setContentType("text/plain");
            ex.printStackTrace(out);
        }
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    }
}

4. Resource Adapter Configuration File

The following is the resource adapter configuration file. For information about each config-property-name item, refer to resource adapter properties in Resource Adapter Configuration.

host, host_port, regionName, and txHelperClassName must be specified according to the testing environment.

<ra.xml>

<?xml version="1.0" encoding="UTF-8"?>
<connector id="Connector_ID" version="1.5"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/connector_1_5.xsd">
  <description>OFCTG Resource Adapter</description>
  <display-name>OFCTG_RA</display-name>
  <vendor-name>TmaxSoft</vendor-name>
  <eis-type>TP Monitor</eis-type>
  <resourceadapter-version>1.0.0.0</resourceadapter-version>
  <resourceadapter>
    <resourceadapter-class>
      com.tmax.connector.spi.TmaxResourceAdapterImpl
    </resourceadapter-class>
    <config-property>
      <config-property-name>port</config-property-name>
      <config-property-type>java.lang.Integer</config-property-type>
      <config-property-value>6557</config-property-value>
    </config-property>
    <config-property>
      <config-property-name>fdlfile</config-property-name>
      <config-property-type>java.lang.String</config-property-type>
      <config-property-value>/home/openframe/samples/tmax.fdl</config-property-value>
    </config-property>
    <outbound-resourceadapter>
      <connection-definition>
        <managedconnectionfactory-class>
          com.tmax.ofctg.connector.cics.ECIManagedConnectionFactory
        </managedconnectionfactory-class>
        <connectionfactory-interface>
          javax.resource.cci.ConnectionFactory
        </connectionfactory-interface>
        <connectionfactory-impl-class>
          com.tmax.ofctg.connector.cics.ECIConnectionFactory
        </connectionfactory-impl-class>
        <connection-interface>
          javax.resource.cci.Connection
        </connection-interface>
        <connection-impl-class>
          com.tmax.ofctg.connector.cics.ECIConnection
        </connection-impl-class>
        <config-property>
          <config-property-name>host</config-property-name>
          <config-property-type>java.lang.String</config-property-type>
          <config-property-value>192.168.100.200</config-property-value>
        </config-property>
        <config-property>
          <config-property-name>host_port</config-property-name>
          <config-property-type>java.lang.Integer</config-property-type>
          <config-property-value>9000</config-property-value>
        </config-property>
        <config-property>
          <config-property-name>backup</config-property-name>
          <config-property-type>java.lang.String</config-property-type>
          <config-property-value>192.168.100.201</config-property-value>
        </config-property>
        <config-property>
          <config-property-name>backup_port</config-property-name>
          <config-property-type>java.lang.Integer</config-property-type>
          <config-property-value>9000</config-property-value>
        </config-property>
        <config-property>
          <config-property-name>support_xa</config-property-name>
          <config-property-type>java.lang.Boolean</config-property-type>
          <config-property-value>true</config-property-value>
        </config-property>
        <config-property>
          <config-property-name>txHelperClassName</config-property-name>
          <config-property-type>java.lang.String</config-property-type>
          <config-property-value>jeus.transaction.TxHelper</config-property-value>
        </config-property>
        <config-property>
          <config-property-name>regionName</config-property-name>
          <config-property-type>java.lang.String</config-property-type>
          <config-property-value>OSCOIVP1</config-property-value>
        </config-property>
        <config-property>
          <config-property-name>headerType</config-property-name>
          <config-property-type>java.lang.String</config-property-type>
          <config-property-value>extendedV4</config-property-value>
        </config-property>
        <config-property>
          <config-property-name>connectTimeout</config-property-name>
          <config-property-type>java.lang.Integer</config-property-type>
          <config-property-value>30000</config-property-value>
        </config-property>
        <config-property>
          <config-property-name>fdlFile</config-property-name>
          <config-property-type>java.lang.String</config-property-type>
          <config-property-value>/home/openframe/samples/tmax.fdl</config-property-value>
        </config-property>
        <config-property>
          <config-property-name>xidMapperPath</config-property-name>
          <config-property-type>java.lang.String</config-property-type>
          <config-property-value>/home/openframe/xalog/</config-property-value>
        </config-property>
        <config-property>
          <config-property-name>xidMapperFile</config-property-name>
          <config-property-type>java.lang.String</config-property-type>
          <config-property-value>webtxidmapper</config-property-value>
        </config-property>
        <config-property>
          <config-property-name>logLevel</config-property-name>
          <config-property-type>java.lang.String</config-property-type>
          <config-property-value>DEV</config-property-value>
        </config-property>
        <config-property>
          <config-property-name>logDir</config-property-name>
          <config-property-type>java.lang.String</config-property-type>
          <config-property-value>/home/openframe/log/</config-property-value>
        </config-property>
        <config-property>
          <config-property-name>logFile</config-property-name>
          <config-property-type>java.lang.String</config-property-type>
          <config-property-value>webt.log</config-property-value>
        </config-property>
        <config-property>
          <config-property-name>logValidDays</config-property-name>
          <config-property-type>java.lang.Integer</config-property-type>
          <config-property-value>1</config-property-value>
        </config-property>
        <config-property>
          <config-property-name>connectionName</config-property-name>
          <config-property-type>java.lang.String</config-property-type>
          <config-property-value>tmax1</config-property-value>
        </config-property>
      </connection-definition>
      <transaction-support>XATransaction</transaction-support>
      <reauthentication-support>false</reauthentication-support>
    </outbound-resourceadapter>
    <inbound-resourceadapter>
      <messageadapter>
        <messagelistener>
          <messagelistener-type>
            javax.resource.cci.MessageListener
          </messagelistener-type>
          <activationspec>
            <activationspec-class>
              com.tmax.connector.spi.TmaxActivationSpec
            </activationspec-class>
            <required-config-property>
              <config-property-name>serviceName</config-property-name>
            </required-config-property>
          </activationspec>
        </messagelistener>
      </messageadapter>
    </inbound-resourceadapter>
  </resourceadapter>
</connector>