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.

14 comments:

  1. AnonymousMay 19, 2009

    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

    ReplyDelete
  2. 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.

    ReplyDelete
  3. AnonymousJune 05, 2009

    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

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

    ReplyDelete
  5. 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.

    ReplyDelete
  6. 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

    ReplyDelete
  7. 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.

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

    ReplyDelete
  9. 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

    ReplyDelete
  10. 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.

    ReplyDelete
  11. 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

    ReplyDelete
  12. 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?

    ReplyDelete
  13. Thanks for Enqueing via PL/SQL section.

    ReplyDelete