Saturday, June 11, 2016

Apache Camel: Integrating Weblogic Queue with Jboss Fuse ESB

This is article is about to integrate the Weblogic Message broker with Jboss Fuse using Apche Camel integration framework. For this I assume that you already have a weblogic server in place with JMS queue. I'm not going in detail to explain more about Weblogic message broker, Apache Camel, Jboss fuse, OSGi.

The requirement for this integrations,
  1. Jboss Fuse ESB 6.1
  2. Apache Camel
  3. Eclipse
  4. Weblogic Server with Queue Configuration
  5. wlthint3client.jar [Download from official page of Weblogic server]
Now we required below details of your WL server,
  1. Weblogic broker URL with port
  2. Credentials for this URL to connect (username, password)
  3. Weblogic JNDI Name exposed for communication with queue
  4. Weblogic queue name
Here, for this integration I have used as per below,

WL broker URL -->  t3://localhost:8090
Credentials -->  Username : wl_admin, password : wl_pass
WL JNDI Name -->  jms/TestJndiName
WL Queue Name -->  testqueue

We are done with the configuration related requirement. So, let's do camel riding for this integration.

To send and received data with WL queue we need to create one camel component which will do our job. This component will be responsible for exchange data with WL queue. To create this component we required object of jndiTemplate, jndiObjectFactoryBean, jndiDestinationResolver and jmsConfiguration. Each of this object we can refer respective java docs. Will explain each of the required object in the next section. 

jndiTemplate

This is the helper class which specify JNDI operations. It provides methods to lookup and bind objects, and allows implementations of the JndiCallback interface to perform any operation they like with a JNDI naming context provided. Here we have specified all the required properties which is required to lookup exposed JNDI object.

 Ref: Spring Docs


jndiObjectFactoryBean

This exposes the singleton object found in JNDI for bean references in a application context. The default behavior of this object is to lookup the object on startup and cache it. We can change its behavior to lazy initialization by setting lookupOnStartup=false and setting proxyInterface=javax.jms.ConnectionFactory. You can have more detail on this by referring spring docs. The simple code snippet is like this,


jndiDestinationResolver

This allows for customizing the JNDI environment if necessary, for example specifying appropriate JNDI environment properties. Dynamic queues and topics get cached by destination name. As a consequence, you need to use unique destination names across both queues and topics. You can have more detail on this by referring spring docs. The simple code snippet is like this,


jmsConfiguration
This object holds all the configuration and required object which are needed to create the camel weblogic component which exchanges the data between fuse and WL. The simple code snippet is like this,
wlqueue

This is the camel component with which we will access the queue/topic to send or receive the messages to/from WL.

Full context file is as per below,

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:camel="http://camel.apache.org/schema/spring"
  
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans.xsd
  http://camel.apache.org/schema/spring 
  http://camel.apache.org/schema/spring/camel-spring.xsd">

<!-- JNDITemplate object which holds basic property for JNDI lookup -->
<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
   <property name="environment">
       <props>
           <prop key="java.naming.factory.initial">weblogic.jndi.WLInitialContextFactory</prop>
           <prop key="java.naming.provider.url">t3://localhost:8090</prop>
           <prop key="java.naming.security.principal">wl_admin</prop>
           <prop key="java.naming.security.credentials">wl_pass</prop>
       </props>
   </property>
</bean>
<!-- jndiObjectFactoryBean object -->
<bean id="jndiObjectFactoryBean" class="org.springframework.jndi.JndiObjectFactoryBean">
   <property name="jndiName" value="jms/TestJndiName"/>
   <property name="jndiTemplate" ref="jndiTemplate"/>
   <property name="lookupOnStartup" value="false"/> <!--  -->
   <property name="proxyInterface" value="javax.jms.ConnectionFactory"/>
</bean>
<!-- jndiDestinationResolver object -->
<bean id="jndiDestinationResolver" class="org.springframework.jms.support.destination.JndiDestinationResolver">
   <property name="jndiTemplate" ref="jndiTemplate"/>
</bean>
<!-- jmsConfiguration object -->
<bean id="jmsConfiguration" class="org.apache.camel.component.jms.JmsConfiguration">
<property name="connectionFactory" ref="jndiObjectFactoryBean"/>
<property name="destinationResolver" ref="jndiDestinationResolver"/>
</bean>
<!-- wlqueue object -->
<bean id="wlqueue" class="org.apache.camel.component.jms.JmsComponent">
<property name="configuration" ref="jmsConfiguration" />
</bean>
<camel:routeContext id="main-weblogic-consumer-producer-route-context">
<!-- This route will process by consuming weblogic queue  -->
<camel:route id="simple-weblogic-consumer-route">
<camel:from uri="wlqueue:queue:testqueue" />
<log loggingLevel="DEBUG" logName="simple-weblogic-consumer-route" 
message="Consumed message from weblogic queue:testqueue :: ${body}" />
<camel:to uri="direct:consumer-message-process-route" />
</camel:route>

<camel:route id="consumer-message-process-route">
<camel:from uri="direct:consumer-message-process-route" />
<log loggingLevel="DEBUG" logName="consumer-message-process-route" 
message="Processing initiated for consumed message :: ${body}" />
</camel:route>
<camel:route id="message-creater-for-wl-producer-route">
<camel:from uri="file://some-dir/file/input" />
<log loggingLevel="DEBUG" logName="message-creater-for-wl-producer-route" 
message="Message for web logic queue :: ${body}" />
<camel:to uri="direct:simple-weblogic-producer-route" />
</camel:route>
<!-- This route will push message in weblogic queue  -->
<camel:route id="simple-weblogic-producer-route">
<camel:from uri="direct:simple-weblogic-producer-route" />
<log loggingLevel="DEBUG" logName="simple-weblogic-consumer-route" 
message="Message to be push in weblogic queue:testqueue :: ${body}" />
<camel:to uri="wlqueue:queue:testqueue" />
</camel:route>
</camel:routeContext>
</beans>

Here, I have created route which consume message from WL queue and to push the message in the WL queue.

Now, our module is ready to exchange messages between web logic and jboss fuse esb. Generate OSGi using maven. Before deploying your bundle you have to install wlthint3client.jar in fuse server. To install this jar file you to convert it into OSGi bundle. Don't worry for this conversion. Below command will convert your jar into OSGi and will deploy into fuse esb.

Start your jboss fuse server and login to karaf console. fire below command to install wlthint3client.jar in fuse server. 

$osgi:install -s wrap:file:///<absolute-path>/wlthint3client.jar

Once you deployed this now you need to deploy you osgi module in jboss fuse. 


We are done now. That's it. Try to push message in WL queue and observe fuse server log.

Don't forget to share your feedback to make this article more helpful.

Cheers,
Ashish Mishra

Saturday, May 14, 2016

Java Integration with Oracle Tuxedo using JCA Adapter

Today's article is about integrating Tuxedo based system with J2EE using Application Server. I think this article will helpful if you are looking to integrate tuxedo system with J2EE application. So, let us begin this integration.

For this article I have used Jboss EAP/AS as a application server, Orcale Tuxedo Adapter and Java based web application. I assume that you guys have basic knowledge of JBoss AS configuration, java web based application and JCA and have some basic idea about Tuxedo System.

Now, you have to setup the environment so we can start the development.
Download Jboss Application Server(6.xxx) or Jboss EAP(6.xxx) from official Redhat
Download Tuxedo JCA connector from Oracle official site. You can have introductory knowledge by referring Data sheet pdf file.

Ref. Oracle


Note, we will have imaginary Tuxedo system because configuring Tuxedo system is tedious job and again its one big topic. You can have basic understanding from  Data Sheet of Oracle Tuxedo document. I think this will help you guys to get basic knowledge of Tuxedo.

Ref. Oracle
I think this is sufficient to have basic knowledge of Tuxedo and Tuxedo Adapter based on JCA provided by Oracle.

Now, after environment  is ready please check Jboss server should be up and functioning without any failure. You can check Jboss server admin console by typing in your browser http://127.0.0.1:9990. It will ask for username and password. You provide whatever you have given at the time of user creation with Jboss.

Jboss Configuration :
Once server is up and running, we need to do some configuration changes in Jboss AS as per below which is required to deploy the Tuxedo JCA Adapter in server,

  1. Need to disable archive-validation in $JbossAS\standalone\configuration\standalone.xml
      2. Need to add resource-adapters entry in $JbossAS\standalone\configuration\standalone.xml
      
....        <subsystem xmlns="urn:jboss:domain:pojo:1.0"/>
        <subsystem xmlns="urn:jboss:domain:remoting:1.1">
            <connector name="remoting-connector" socket-binding="remoting" security-realm="ApplicationRealm"/>
        </subsystem>
        <subsystem xmlns="urn:jboss:domain:resource-adapters:1.0">
            <resource-adapters>
                <resource-adapter>
                    <archive>com.oracle.tuxedo.TuxedoAdapter.rar</archive>
                    <transaction-support>LocalTransaction</transaction-support>
                    <config-property name="traceLevel">80000</config-property>
                    <config-property name="xaAffinity">true</config-property>
                    <config-property name="dmconfig">
                       $JbossAS/standalone/configuration/dmconfig.xml
                    </config-property>
                    <connection-definitions>
                        <connection-definition class-name="javax.resource.cci.ConnectionFactory" jndi-name="java:tuxedo/Connection" enabled="true" use-java-context="true" pool-name="Connection" use-ccm="true">
                            <pool>
                                <min-pool-size>0</min-pool-size>
                                <max-pool-size>10</max-pool-size>
                                <prefill>false</prefill>
                                <use-strict-min>false</use-strict-min>
                                <flush-strategy>FailingConnectionOnly</flush-strategy>
                            </pool>
                            <security>
                                <application/>
                            </security>
                        </connection-definition>
                    </connection-definitions>
                </resource-adapter>
            </resource-adapters>
        </subsystem>
        <subsystem xmlns="urn:jboss:domain:sar:1.0"/>
        <subsystem xmlns="urn:jboss:domain:security:1.1">
     .....
In this we have to note that we have exposed JNDI context with name java:tuxedo/Connection for Tuxedo Adapter in Jboss container. The same will be used to  create a connection object to do transaction with Tuxedo system.

Tuxedo JCA Adapter Configuration:
We are done with Jboss AS configuration. Now we will do Tuxedo Adapter internal configuration to connect real Tuxedo based system. Tuxedo JCA adapter is bundled as a rar file like com.oracle.tuxedo.TuxedoAdapter.rar. Follow below configuration with Tuxedo Adapter

1) Remove dmconfig.xml fle from adapter .rar file and placed it into $JbossAS\standalone\configuration. Later we will modify it for connection and transaction. Below files and jar files are the part of the adapter.
 

Also, we need to remove all the files from META-INF dir except ra.xml and MANIFEST.MF. Later we will update the ra.xml file as per our requirement.




2) Copy all the jar files which is available inside adapter into your web app from where we will get the connection from JNDI and do the programming to send data to Tuxedo system.

3) Modification in dmconfig.xml as per below. It varies as per your requirement. This file contains Tuxedo system related configuration. Configuration like, local access point, remote access point, session profile, session, exposed services by Tuxedo System. I'm not going to explain more about this file, you can learn it from official oracle web site. But for reference you can refer this site. This is the key file which is used by tuxedo adapter to establish connection and trigger the request based on exposed services by Tuxedo System.
dmconfig.xml :

<?xml version="1.0" encoding="UTF-8"?>
<TuxedoConnector>
<!-- Local Access point from where Tuxedo System is being called,
Your server IP and your server IP needs to be configured at Tuxedo System
as remote access point
-->
<LocalAccessPoint name="local_acc_point">
<AccessPointId>local_acc_point_id</AccessPointId>
<NetworkAddress>//localhost:8080</NetworkAddress>
</LocalAccessPoint>
<!-- 
Remote Tuxedo System IP along with port
-->
<RemoteAccessPoint name="remote_acc_point">
<AccessPointId>remote_acc_point_id</AccessPointId>
<NetworkAddress>//remote.tuxedo.system.host.endpoint:port</NetworkAddress>
</RemoteAccessPoint>
<!-- 
Basic configuration to establish session with Tuxedo System.
-->
<SessionProfile name="profile_1">
<Security>NONE</Security>
<BlockTime>30000</BlockTime>
<Interoperate>false</Interoperate>
<ConnectionPolicy>ON_DEMAND</ConnectionPolicy>
<ACLPolicy>local</ACLPolicy>
<CredentialPolicy>local</CredentialPolicy>
<RetryInterval>60</RetryInterval>
<MaxRetries>1000</MaxRetries>
<CompressionLimit>1000000</CompressionLimit>
<KeepAlive>100000</KeepAlive>
<KeepAliveWait>200000</KeepAliveWait>
</SessionProfile>
<!-- 
This session will be used by Tuxedo Adapter for transaction by
using session profile and remote/loca access point.
-->
<Session name="session_1">
<LocalAccessPointName>local_acc_point</LocalAccessPointName>
<RemoteAccessPointName>remote_acc_point</RemoteAccessPointName>
<ProfileName>profile_1</ProfileName>
</Session>
<Import name="TOUPPER">
    <RemoteName>TOUPPER</RemoteName>
    <SessionName>session_1</SessionName>
    <LoadBalancing>RoundRobin</LoadBalancing>
  </Import>
  <Import name="ECHO">
    <RemoteName>ECHO</RemoteName>
    <SessionName>session_1</SessionName>
    <LoadBalancing>RoundRobin</LoadBalancing>
  </Import>
   <!-- More than one  Import will be configured here as per the Tuxedo services exposed -->
  <Import name="Service_Name_1">
    <RemoteName>Service_Name_1</RemoteName>
    <SessionName>session_1</SessionName>
    <LoadBalancing>RoundRobin</LoadBalancing>
  </Import>
  <Import name="Service_Name_2">
    <RemoteName>Service_Name_2</RemoteName>
    <SessionName>session_1</SessionName>
    <LoadBalancing>RoundRobin</LoadBalancing>
  </Import>
</TuxedoConnector>


4)
Need to modify the Adapter's ra.xml as I did. Here, we have to make sure the dmconfig.xml file should be correctly placed and correctly configured in this file.This configuration is used internally by Tuxedo Adapter. You can read more about this file from here.
ra.xml :
<?xml version="1.0" encoding="UTF-8"?>
<connector 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"
    version="1.5">
<display-name>Tuxedo JCA Adapter</display-name>
<vendor-name>Oracle</vendor-name>
<eis-type>Tuxedo</eis-type>
<resourceadapter-version>11gR1(11.1.1.2.1)</resourceadapter-version>
<license>
<description>Tuxedo SALT license</description>
<license-required>false</license-required>
</license>
<resourceadapter>
<resourceadapter-class>com.oracle.tuxedo.adapter.TuxedoResourceAdapter</resourceadapter-class>
<config-property>
<config-property-name>debugConfig</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>traceLevel</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>100000</config-property-value>
</config-property>
<config-property>
<config-property-name>xaAffinity</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>true</config-property-value>
</config-property>
<config-property>
<config-property-name>dmconfig</config-property-name>
<config-property-type>java.lang.String</config-property-type>
<config-property-value>$JbossAS/standalone/configuration/dmconfig.xml</config-property-value>
</config-property>
<outbound-resourceadapter>
<connection-definition>
<managedconnectionfactory-class>com.oracle.tuxedo.adapter.spi.TuxedoManagedConnectionFactory</managedconnectionfactory-class>
<connectionfactory-interface>javax.resource.cci.ConnectionFactory</connectionfactory-interface>
<connectionfactory-impl-class>com.oracle.tuxedo.adapter.cci.TuxedoConnectionFactory</connectionfactory-impl-class>
<connection-interface>javax.resource.cci.Connection</connection-interface>
<connection-impl-class>com.oracle.tuxedo.adapter.cci.TuxedoJCAConnection</connection-impl-class>
</connection-definition>
<transaction-support>LocalTransaction</transaction-support>
<authentication-mechanism>
<authentication-mechanism-type>BasicPassword</authentication-mechanism-type>
<credential-interface>javax.resource.spi.security.PasswordCredential</credential-interface>
</authentication-mechanism>
<reauthentication-support>false</reauthentication-support>
</outbound-resourceadapter>
</resourceadapter>
</connector>


We almost completed configuration related things for this integration. So, let's do some programming now.

Application Programming:
Create one web application say it test-tuxedo-connector. Create one jsp and one servlet. From servlet create one service class from where we will prepare tuxedo request and will establish a connection with Tuxedo system and post our request to Tuxedo system. Let's move step by step.

1) Create a jsp-servlet based web app. Include a jars file in web-inf/lib directory from adapter.rar file which I explained earlier.Add this jars in the classpath of your web app.

2) I assume that you have already read about Tuxedo based system and aware with .FML file(Field Mapping List). Basically in this file all the fields and services are defined. This file is similar like wdl and xsd file for SOAP based web services. This is the mapping file in which fields are defined which are used in Tuxedo system along with data type. I have used below test.fml file in this example.


3) Need to create java class in which all the fields are mapped with respect to test.fml. Going to say this class as TuxedoFmlTable.java. In this class we have to create unique integer value for each of the field defined in test.fml. We are going to create one utility class which creates unique numeric value by using test.fml.

public class TuxedoFmlFieldsCreater extends weblogic.wtc.jatmi.DynamicFldTbl{
static final String USER_FML_TABLE_FILE = "<file_location_of_fml_file>\\test.fml";
public TuxedoFmlFieldsCreater() {
super(USER_FML_TABLE_FILE, true);
}
public static void main(String[] args) {
TuxedoFieldTable bf = new TuxedoFieldTable();
String[] list = bf.getFldNames();
for (int i = 0; i < list.length; i++ )
System.out.println("FieldName = [" + list[i] + "], FieldId = [" + bf.name_to_Fldid(list[i]) + "]");

System.out.println("Total entries = " + list.length);
}
}

Output of above class file.

TuxedoFmlTable.java

import java.util.Hashtable;
import weblogic.wtc.jatmi.FldTbl;

public class TuxedoFmlTable implements FldTbl{
Hashtable<String, Integer> nameToFieldTable;
Hashtable<Integer, String> fieldToNameTable;

public final static int TST_DATE = 167772161;
public final static int TST_TIME = 167772162;
public final static int TST_MSGNAME = 167772163;
public final static int TST_CONTEXTID = 33554436;
public final static int TST_USERID = 167772165;
public final static int TST_ERRORNUM = 33554438;
public final static int TST_STATUSTEXT = 167772167;
public final static int TST_STATUSFLAG = 167772168;

public TuxedoFmlTable(){
if(nameToFieldTable == null || nameToFieldTable.isEmpty()){
nameToFieldTable = new Hashtable<String, Integer>(9, 0.75f);

nameToFieldTable.put("TST_DATE", TST_DATE);
nameToFieldTable.put("TST_TIME", TST_TIME);
nameToFieldTable.put("TST_MSGNAME", TST_MSGNAME);
nameToFieldTable.put("TST_CONTEXTID", TST_CONTEXTID);
nameToFieldTable.put("TST_USERID", TST_USERID);
nameToFieldTable.put("TST_ERRORNUM", TST_ERRORNUM);
nameToFieldTable.put("TST_STATUSTEXT", TST_STATUSTEXT);
nameToFieldTable.put("TST_STATUSFLAG", TST_STATUSFLAG);
}

if(fieldToNameTable == null || fieldToNameTable.isEmpty()){
fieldToNameTable = new Hashtable<Integer, String>(9, 0.75f);

fieldToNameTable.put(TST_DATE, "TST_DATE");
fieldToNameTable.put(TST_TIME, "TST_TIME");
fieldToNameTable.put(TST_MSGNAME, "TST_MSGNAME");
fieldToNameTable.put(TST_CONTEXTID, "TST_CONTEXTID");
fieldToNameTable.put(TST_USERID, "TST_USERID");
fieldToNameTable.put(TST_ERRORNUM, "TST_ERRORNUM");
fieldToNameTable.put(TST_STATUSTEXT, "TST_STATUSTEXT");
fieldToNameTable.put(TST_STATUSFLAG, "TST_STATUSFLAG");
}
}

@Override
public String Fldid_to_name(int fldId) {
return ((String) fieldToNameTable.get(new Integer(fldId)));
}

@Override
public String[] getFldNames() {
String[] fieldNames = {
"TST_DATE","TST_TIME","TST_MSGNAME","TST_CONTEXTID",
"TST_USERID","TST_ERRORNUM","TST_STATUSTEXT","TST_STATUSFLAG"
};
return fieldNames;
}

@Override
public int name_to_Fldid(String fieldName) {
Integer fldId = nameToFieldTable.get(new String(fieldName));
if (fldId == null) {
return (-1);
} else {
return (fldId.intValue());
}
}
}


4) We have created all the basic class which is required to created FML32 object which is going to send by our web app to tuxedo system via adapter. I assume that you have created web apps in which you have created one servelt and jsp page from where you will trigger the request and which will be served by servlet. Here in below class I will explain to create an tuxedo connection object through JNDI lookup from in Jboss server. We have already deploy the adapter in $JbossAS\standalone\deployments and hope its successfully deployed. We have already exposed java:tuxedo/Connection.

Full implementation of the main class where we are creating connection and posting data to tuxedo system via adapter.

TuxedoExecutor.java

import java.util.Map;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.resource.cci.Connection;
import javax.resource.cci.ConnectionFactory;
import javax.resource.cci.Interaction;
import javax.resource.cci.InteractionSpec;
import weblogic.wtc.jatmi.TypedFML32;
import com.oracle.tuxedo.adapter.cci.TuxedoFML32Record;
import com.oracle.tuxedo.adapter.cci.TuxedoInteractionSpec;

public class TuxedoExecutor {
private static Context contextObj = null;
private static ConnectionFactory conFactoryObj = null;
private static TuxedoFmlTable fmlTable = null;

private void createTuxedoConnectionFactory() throws NamingException, Exception {
try {
if(contextObj == null)
contextObj = new InitialContext();
if(conFactoryObj == null)
conFactoryObj = (ConnectionFactory) contextObj.lookup("java:tuxedo/Connection");
} catch (NamingException ne) {
throw ne;
} catch (Exception e) {
throw e;
}
}

public Connection getTuxedoConnection() throws Exception{
Connection connection = null;
try {
if(conFactoryObj == null)
createTuxedoConnectionFactory();
connection = conFactoryObj.getConnection();
} catch (Exception e) {
throw e;
}
return connection;
}

public void postDataToTuxedoSystem(Map<String, String> paramMap) throws Exception{
Connection tuxConObj = null;
Interaction tuxInteraction = null;
TuxedoInteractionSpec tuxInterSpec = null;
try {
if(fmlTable == null)
fmlTable = new TuxedoFmlTable();
tuxConObj = getTuxedoConnection(); 
tuxInteraction = tuxConObj.createInteraction();
tuxInterSpec = new TuxedoInteractionSpec();
tuxInterSpec.setFunctionName("");
tuxInterSpec.setInteractionVerb(InteractionSpec.SYNC_SEND_RECEIVE);
TypedFML32 inFml32 = new TypedFML32(fmlTable);
//Setting key-value in inFml32 object
inFml32.Fchg(fmlTable.name_to_Fldid("TST_DATE"), new Short((short)0), paramMap.get("TST_DATE").trim());
inFml32.Fchg(fmlTable.name_to_Fldid("TST_TIME"), new Short((short)0), paramMap.get("TST_TIME").trim());
inFml32.Fchg(fmlTable.name_to_Fldid("TST_MSGNAME"), new Short((short)0), paramMap.get("TST_MSGNAME").trim());
inFml32.Fchg(fmlTable.name_to_Fldid("TST_CONTEXTID"), new Short((short)0), paramMap.get("TST_CONTEXTID").trim());
inFml32.Fchg(fmlTable.name_to_Fldid("TST_USERID"), new Short((short)0), paramMap.get("TST_USERID").trim());
inFml32.Fchg(fmlTable.name_to_Fldid("TST_ERRORNUM"), new Short((short)0), paramMap.get("TST_ERRORNUM").trim());
//inFml32.Fchg(fmlTable.name_to_Fldid("TST_STATUSTEXT"), new Short((short)0), paramMap.get("TST_STATUSTEXT").trim());
//inFml32.Fchg(fmlTable.name_to_Fldid("TST_STATUSFLAG"), new Short((short)0), paramMap.get("TST_STATUSFLAG").trim());

TuxedoFML32Record inRecord = new TuxedoFML32Record(inFml32);
TypedFML32 outFml32 = new TypedFML32(fmlTable);
TuxedoFML32Record outRecord = new TuxedoFML32Record(outFml32);
//This will execute our requet to Tuxedo system via adapter
tuxInteraction.execute(tuxInterSpec, inRecord, outRecord);
if(outRecord.getTperrno() == 0){
System.out.println("Transaction Successful.");
//Fetching details from the outRecord
TypedFML32 fml32 = outRecord.getFML32();
String statusText = (String) fml32.Fget(fmlTable.name_to_Fldid("TST_STATUSTEXT"), new Short((short)0));
String statusFlag = (String) fml32.Fget(fmlTable.name_to_Fldid("TST_STATUSFLAG"), new Short((short)0));
} else {
System.out.println("Some problem occurred during the transaction.");
System.out.println("Tperrno : " + outRecord.getTperrno());
System.out.println("Tpurcode : " + outRecord.getTpurcode());
System.out.println("Tperrordetail : " + outRecord.getTperrordetail());
}
} catch (Exception e) {
throw e;
}
finally {
if(tuxInteraction != null)
tuxInteraction.close();
if(tuxConObj != null)
tuxConObj.close();
}
}
}


We are done now. Once you are ready with all this than please deploy your web application in the same directory where we have deployed the adapter. Our application should be deployed successfully. Now you trigger the request and observe the log in your system as well as in Tuxedo system which you wish to connect.

Please don't forget to give your input to make this article more helpful.

Cheers,
Ashish Mishra

Saturday, March 12, 2016

Create Common Module in JBoss AS7x/EAP6x

Hello Guys.

Hope you are doing great in your environment and enjoying the beautiful life.

After very long time I'm writing blogs. Today's I will explain the problem which I've faced during Tuxedo system integration with Jboss EAP server. `

During the integration I faced many strange exception and errors. I applied different approach but seemed no luck. Than among all try I thought that some common jars which were being used by my apps might be causing the issue. Sorry I didn't brief about project's architecture. So, let me explain first. I've to do integration with Tuxedo System via JBoss EAP server. I've used TuxedoAdapter.rar which is provided by Oracle as a JCA. This adapter will communicate with Tuxedo system and my web apps needed to communicate with this adapter.

I've started thinking to create a common module in which the commonly used jars files were available and by surprise this approach worked for me. Let me shared the basic steps which I took to do this.

Step 1: I've created one module.xml in which I've added the jar which are going to used commonly.

<module xmlns="urn:jboss:module:1.1" name="common-jars">
<!--<properties>
    <property name="jboss.api" value="private"/>
</properties>-->

<resources>
    <resource-root path="com.bea.core.i18n_1.4.0.0.jar"/>
    <resource-root path="com.bea.core.jatmi_1.3.1.0.jar"/>
    <resource-root path="com.oracle.tuxedo.adapter_1.1.0.0.jar"/>
    <!-- Insert resources here -->
</resources>

<dependencies>
    <module name="javaee.api"/>
    <module name="javax.api"/>
</dependencies>
</module>
Step 2: Created a directory as following common\jars\main in $EAP-HOME\modules\system\layers\base

Step 3: 
Added module.xml and the jar files in $EAP-HOME\modules\system\layers\base\common\jars\main

Step 4: Modified $EAP-HOME\standalone\configuration\standalone.xml as per below,


<subsystem xmlns="urn:jboss:domain:ee:1.2">
     <global-modules>
          <module name="common.jars"/>
     </global-modules>
     <spec-descriptor-property-replacement>false</spec-descriptor-property-replacement>
     <jboss-descriptor-property-replacement>true</jboss-descriptor-property-replacement>
     <annotation-property-replacement>false</annotation-property-replacement>
</subsystem>
Note: <module> element has an optional attribute with name @slot where you can specify the directory to look into your common jar files. If you don't specify than default value is main

Step 5:Removed the common jars from TuxedoAdapter.rar and my web app war file.

Step 6: Restarted the JBoss AS or EAP server
That's it. It's worked for me. This article is more about how to create the shared/common module which being used by various deployed apps in EAP or server. Sometime you have case like more than one apps are using some common third party libraries. This time it is better to use common/shared module rather than using duplicate libraries in the apps which adds extra overhead on Application Server.

Hope this will help. Share your valuable inputs to make this article more informative among all of tech-guys.

Kindly add your comment if you have some suggestions. I will see those feedback and if required I will add in this article.

Cheers,
Ashish Mishra