Showing posts with label jms. Show all posts
Showing posts with label jms. Show all posts

Tuesday, March 31, 2015

Accessing Oracle Advanced Queue (OAQ) directly using JNDI and plain JMS from a standalone java program


I spent a while trying to insert a message into AQ from a standalone Java program. All examples in the internet were using a foreign JMS in weblogic and then accessing the Queues. I didn't want to go that route and add an extra layer between my stand alone program and Oracle AQ. I hope this helps you. You can also use a similar technique to configure OAQ as JMS connection in any middleware software.

Basically there are 3 jars that are required to be in the class path
1. aqapi.jar
2. jmscommon.jar
3. ojdbc6.jar


The Initial Context

The context Factory should be oracle.jms.AQjmsInitialContextFactory
Context.INITIAL_CONTEXT_FACTORY oracle.jms.AQjmsInitialContextFactory
Context.SECURITY_PRINCIPAL dbusername
Context.SECURITY_CREDENTIALS dbpassword
"db_url" jdbc:oracle:thin:dbusername/dbpassword@hostname:1521:SID

Looking up Connection Factory

If you are looking up QueueConnectionFactory use the string QueueConnectionFactory. Below are some valid Values
ConnectionFactory
QueueConnectionFactory
TopicConnectionFactory
XAConnectionFactory
XAQueueConnectionFactory
XATopicConnectionFactory

Looking Up Queues or Factories

For Queues use Queues/QUEUENAME
For Topics use Topics/TOPICNAME


Working snippet

try {
    QueueConnectionFactory qcf = null;
    Hashtable env = new Hashtable();
    env.put(Context.INITIAL_CONTEXT_FACTORY, "oracle.jms.AQjmsInitialContextFactory");
    env.put(Context.SECURITY_PRINCIPAL, "dbusername");
    env.put(Context.SECURITY_CREDENTIALS, "dbpassword");
    env.put("db_url", "jdbc:oracle:thin:dbusername/dbpassword@hostname:1521:SID");
    InitialContext ctx = new InitialContext(env);
    qcf = (QueueConnectionFactory)ctx.lookup("QueueConnectionFactory");
    QueueConnection qc = qcf.createQueueConnection( "dbusername","dbpassword");
    QueueSession qsession = qc.createQueueSession(true, Session.AUTO_ACKNOWLEDGE);
    System.out.println("Successfully created AQ session");
    Queue q = (Queue)ctx.lookup("Queues/OTMQUEUE");
    QueueSender qs = qsession.createSender(q);
    TextMessage msg = qsession.createTextMessage();
    msg.setText("Message hello world");
    qs.send(msg);
    qs.close();
    qsession.commit();
    qsession.close();
    qc.close();
} catch (Exception ex) {
    ex.printStackTrace();
}

Wednesday, March 12, 2014

Weblogic Bridge for IBM MQ Series(Running on AS400 / iseries / Mainframe) Part 1


Bridges help in improving reliability of messages that need to be created on a remote Messaging Servers. If we have a program in weblogic writing to queues in MQ series, we write the messages into a JMS queue created in weblogic. Then, we create a bridge that takes care of sending the message from the local weblogic queue to MQ series. By doing this, We are immune to remote MQ going down. The bridge takes care of reconnecting and sending messages to the remote MQ.

In this part we will look at the pre requisites to setup a Weblogic Bridge for IBM MQ. We need a .bindings file which described JNDI lookups for weblogic to connect to the MQSeries (Websphere MQ)

1. Install MQ Series MQ Explorer on Windows.

2. Set up connection to Remote Queue Manager

a. Open MQ explorer and right click on queue managers and select “Add Remote Queue Manager”

image

b. give a queue manager name, select “Connect Directly” and click next



image

c. Give HostName, port number and Server Connection Channel. (The MQ administrator can give you these details) and click next

d. click next

e. give the user name and password if MQ is secure

f. click finish (Sometimes you might have to put in other information. Contact your MQ Administrator)
you should be able to see the Queue manager and expand queues and see the queues on the remote server.


3. Create an Initial Context

a. right click on JMS administered Objects and select “Add Initial Context”


image

b. Select File System, and give a valid Bindings Directory. Click Next.

image

c.Click Finish

image


4. Create Connection Factory

a. Expand the Initial context you just created,
right click on Connection Factory –> New –> Connection Factory.

image

b. Give a connection factory name( We use this name to configure connection factory in weblogic)

image

c. Select Queue Connection Factory and check supports XA transactions

image

d. Select MQ Client in transport and click Next. click next

image

e. select the appropriate version of the server

image

f. Select connection on left.
Select the queue manager
Give the appropriate url and port in connection list
click Finish.
image


5. Create a Destination


a. Right click on Destinations
Select new –> Destinations

image

b. Give a Destination Name(You will use the same name in Weblogic Destination Name)
Select Type and click Next.

image

c. Click Next.

d. Select the Queue Manager and the queue and click Finish.


image 


(Will continue tomorrow)

Friday, May 3, 2013

MDB throttling using Work Managers in Weblogic


A JMS Message Burst can result in a lot of threads created to process these messages. Because of this other applications/processes might not have threads to run or exhaust on data source connections etc..

One way to solve this is to use work Managers.
Work managers can be created globally or in the application scope.
1. Global Scoped Work Managers: These are accessible by every application running in the targeted server. These are created in the weblogic console
2. Application Scoped: These are defined in the application and are only available to the application.  They can be defined in weblogic-application.xml(the ear) or weblogic-ejb-jar.xml(module) or weblogic.xml(particular web application).

if you are defining in this in  weblogic-ejb-jar.xml
<weblogic-ejb-jar xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                  xsi:schemaLocation="http://www.bea.com/ns/weblogic/weblogic-ejb-jar/1.0/weblogic-ejb-jar.xsd"
                  xmlns="http://www.bea.com/ns/weblogic/weblogic-ejb-jar">
<weblogic-enterprise-bean>
<ejb-name>MyEJBBean</ejb-name>
  <message-driven-descriptor>
    <destination-jndi-name>jms/dq</destination-jndi-name>
    <connection-factory-jndi-name>jms/tqcf</connection-factory-jndi-name>
  </message-driven-descriptor>
  <dispatch-policy>WM1</dispatch-policy>
</weblogic-enterprise-bean>
<work-manager>
  <name>WM1</name>
  <min-threads-constraint>
    <name>wm2_mintc1</name>
    <count>0</count>
  </min-threads-constraint>
  <max-threads-constraint>
    <name>wm2_maxtc1</name>
    <count>3</count>
  </max-threads-constraint>
</work-manager>
</weblogic-ejb-jar>

You can also have the workmanager defined in the weblogic.xml or in weblogic-application.xml by having xml like this. and the MDB will refer the work manager in <dispatch-policy> tag.
work-manager>
  <name>WM1</name>
  <min-threads-constraint>
    <name>wm2_mintc1</name>
    <count>0</count>
  </min-threads-constraint>
  <max-threads-constraint>
    <name>wm2_maxtc1</name>
    <count>3</count>
  </max-threads-constraint>
</work-manager>

If you want to to define a global scoped work manager. You can do it in the weblogic console as below


image

If you want to throttle MDB threads by Database connection Pool Size. You can change the max constraint to have  pool-name tag instead of count tag. You fill the data source name here and not the jndi
work-manager>
  <name>WM1</name>
  <min-threads-constraint>
    <name>wm2_mintc1</name>
    <count>0</count>
  </min-threads-constraint>
  <max-threads-constraint>
    <name>wm2_maxtc1</name>
   <pool-name>OracleDS</pool-name>  </max-threads-constraint>
</work-manager>