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>