Monday, March 23, 2009

Creating a JMS queue for SOA consumption

This post will move permanently to here: http://blog.ipnweb.com/2009/03/creating-jms-queue-for-soa-consumption.html

This post describes how to create a JMS queue in the Oracle database to use within your BPEL processes and/or ESB services.
Create a JMS queue

Log on to the Oracle Database and create a queue table called JMS_ABC_QUEUETABLE. Afterwards, create a queue called JMS_ABC_QUEUE on this queue table. Finally, start the queue.

    begin sys.dbms_aqadm.create_queue_table( queue_table => 'JMS_ABC_QUEUETABLE', queue_payload_type => 'SYS.AQ$_JMS_MESSAGE', sort_list => 'PRIORITY, ENQ_TIME', compatible => '10.0.0', primary_instance => 0, secondary_instance => 0, storage_clause => 'tablespace pctfree 10 initrans 1 maxtrans 255
    storage ( initial 64K minextents 1 maxextents unlimited )');
    end;
    /
    begin sys.dbms_aqadm.create_queue( queue_name => 'JMS_ABC_QUEUE', queue_table => 'JMS_ABC_QUEUETABLE', queue_type => sys.dbms_aqadm.normal_queue);
    end;
    /


    EXECUTE dbms_aqadm.start_queue (queue_name => 'JMS_ABC_QUEUE');
Configure the Oracle SOA Suite server
Edit the
$ORACLE_HOME/j2ee/oc4j_soa/config/application.xml file and add the "myjms" resource provider.
    <resource-provider class="oracle.jms.OjmsContext" name="myjms"> <description>oc4j-jms loop back resource provider</description> <property name="url" value="jdbc:oracle:thin:<user>/<password>@<dbhost>:<dbport>:<dbsid>"/>
    </resource-provider>
    "/>
Edit the $ORACLE_HOME/j2ee/oc4j_soa/application-deployments/default/JmsAdapter/oc4j-ra.xml file and add the "myconnfac" connector factory.

    <connector-factory location="eis/Jms/myconnfac" connector-name="Jms Adapter"> <config-property name="connectionFactoryLocation"
    value="java:comp/resource/myjms/QueueConnectionFactories/myQCF"/>
    <config-property name="factoryProperties" value=""/> <config-property name="acknowledgeMode" value="AUTO_ACKNOWLEDGE"/> <config-property name="isTopic" value="false"/> <config-property name="isTransacted" value="false"/> <config-property name="username" value="<user>"/> <config-property name="password" value="<password>"/> <connection-pooling use="none"></connection-pooling> <security-config use="none"></security-config>
    </connector-factory>
Enqueing via PL/SQL

For testing purposes, you may decide to enqueue a payload via PL/SQL.

    declare l_message clob := ''; v_enqueue_options dbms_aq.enqueue_options_t; v_msg_props dbms_aq.message_properties_t; v_msg_id RAW(16); v_message SYS.AQ$_JMS_MESSAGE := SYS.AQ$_JMS_MESSAGE.construct(DBMS_AQ.JMS_TEXT_MESSAGE);

    begin
    l_message := '<ns4:elements xmlns:ns4="http://ns.thisisahmed.com/MyMessage/20080702"><ns4:element><ns4:firstname>Ahmed</ns4:firstname><ns4:lastname>Naga</ns4:lastname></ns4:element></ns4:elements>';
    v_message.set_text(xmltype(l_message).getstringval());
    dbms_aq.enqueue(queue_name => 'JMS_ABC_QUEUE', enqueue_options => v_enqueue_options, message_properties => v_msg_props, payload => v_message, msgid => v_msg_id);
    commit;
    end;
    /
When configuring the JMS Adapter within JDeveloper, here are the settings you will want to use:

Service Name: (whatever name you choose; e.g., JMSQueue)
OEMS: Database JNDI Name: (whatever your JNDI name is; e.g., eis/Jms/LocalDB) Operation Type: Consume Message Resource Provider: myjms Destination Name: JMS_ABC_QUEUE Schema Location: (whatever schema you want)

This is how my final BPEL process looked like.
Good luck.

13 comments:

Anonymous said...

Hi Ahmed,
Can I encrypt the password at config-property name="password" value="password"/
in $ORACLE_HOME/j2ee/oc4j_soa/application-deployments/default/JmsAdapter/oc4j-ra.xml

Thank You.
JP

Ahmed said...

JP,

This is done via the 'encrypt.bat' or 'encrypt.sh' script located in your SOA Suite install.

cd %ORACLE_HOME%\bpel\bin
encrypt.bat mypassword

Use the output of this command in your oc4j-ra.xml file.

Anonymous said...

Thank You Ahmed for your response!!

I have another question...
Can I use password indirection with jdbc data sources in oc4j 10.1.3.4 but using Oracle Internet Directory to provide it?
Do have an example?
Thank You in advance!!

JP

Ahmed said...

I don't think this is possible. Why would you want to do it?

kkchopra said...

Is there any other option to implement JMS Queue apart from this DB option ?

Why I want to avoid this DB option since in a clustering env if there are so many DBs maintained then we need to configure this JMS queue on each DB. I heard about some Application server based queue implementation.

Can u provide some details.

Ahmed said...

What you are referring to is OracleAS JMS (instead of OJMS which is what my example showed). Check out the link below, and scroll down to "Configuring for OC4J JMS":

http://download-west.oracle.com/docs/cd/B14099_19/integrate.1012/b25307/adptr_jms.htm

kkchopra said...

Thanks Ahmed, I will go through this link.

I need your suggestion on one scenario too:
I am implementing two systems integration using ESB and BPEL. Here details in the form files will come from the source and the details will be moved to the target system.

Now suppose if the middleware server is down then what will happen to those files which are like in between the source system and the middleware server where the integration logic is running.

Suppose files are coming through EDI onto the middleware server itself.


Bottom line is what should be the strategy to overcome recovery of the data if the SOA server goes down.

Ahmed said...

It's probably going to be easier if you email me at aaboulnaga@itconvergence.com, and we can discuss at greater lengths than here. :)

Rakesh said...

Hi Ahmed,

Thanks for this post, it helped us a lot.
I have a question for you.

we have 4 different payloads which are enqueued in the same JMS queue can we use a single dequeue/Consumer to Pull out all these 4 different payloads.

Please suggest.

Thanks
Rakesh

Ahmed said...

Rakesh,

One way to do this is to create a generic schema that incorporates your 4 different payload types.

For example, let's say that the root elements of your 4 different payloads are:
     <Customer1>
     <Customer2>
     <Customer3>
     <Customer4>

Create your top level root element to be <Customer> which includes the 4 elements above as optional child elements. Then in your BPEL process, use a switch activity.

harshu said...

Hi Ahmed,
The pl/sql code u have given for enqueueing the the jms queue is giving following error
PLS-00302: component 'CONSTRUCT' must be declared
I think something is wrong in the following statement :-
v_message SYS.AQ$_JMS_MESSAGE := SYS.AQ$_JMS_MESSAGE.construct(DBMS_AQ.JMS_TEXT_MESSAGE);
Can you please help?

With Regards,
Harshwardhan Ghugare

J (Encrypted Flash Drive Guy) said...

I am just creating my JMS queue, I have found entries for “testQ” in web sphere and also JMS provided screen in admin console but how do I lookup this queue?

Mishit said...

Thanks for Enqueing via PL/SQL section.