JMS Step 5 - How to Create an 11g BPEL Process Which Reads a Message Based on an XML Schema from a JMS Queue
By John-Brown.Evans-Oracle on Dec 05, 2012
Welcome to another post in the series of blogs which demonstrates how to use JMS queues in a SOA context. The previous posts were:
- JMS Step 1 - How to Create a Simple JMS Queue in Weblogic Server 11g
- JMS Step 2 - Using the QueueSend.java Sample Program to Send a Message to a JMS Queue
- JMS Step 3 - Using the QueueReceive.java Sample Program to Read a Message from a JMS Queue
- JMS Step 4 - How to Create an 11g BPEL Process Which Writes a Message Based on an XML Schema to a JMS Queue
Today we will create a BPEL process which will read (dequeue) the message from the JMS queue, which we enqueued in the last example. The JMS adapter will dequeue the full XML payload from the queue.
1. Recap and Prerequisites
In the previous examples, we created a JMS Queue, a Connection Factory and a Connection Pool in the WebLogic Server Console. Then we designed and deployed a BPEL composite, which took a simple XML payload and enqueued it to the JMS queue. In this example, we will read that same message from the queue, using a JMS adapter and a BPEL process. As many of the configuration steps required to read from that queue were done in the previous samples, this one will concentrate on the new steps. A summary of the required objects is listed below. To find out how to create them please see the previous samples. They also include instructions on how to verify the objects are set up correctly.
WebLogic Server Objects
Schema XSD File
The following XSD file is used for the message format. It was
created in the previous example and will be copied to the new
<?xml version="1.0" encoding="windows-1252" ?>
<xsd:element name="exampleElement" type="xsd:string">
After executing the previous samples, the following XML message should be in the JMS queue located at jms/TestJMSQueue:
<?xml version="1.0" encoding="UTF-8" ?><exampleElement xmlns="http://www.example.org">Test Message</exampleElement>
You will need a valid Application Server Connection in JDeveloper pointing to the SOA server which the process will be deployed to.
2. Create a BPEL Composite with a JMS Adapter Partner Link
In the previous example, we created a composite in JDeveloper called JmsAdapterWriteSchema. In this one, we will create a new composite called JmsAdapterReadSchema.
There are probably many ways of incorporating a JMS adapter into a
SOA composite for incoming messages. One way is design the process
in such a way that the adapter polls for new messages and when it
dequeues one, initiates a SOA or BPEL instance. This is possibly the
most common use case. Other use cases include mid-flow adapters,
which are activated from within the BPEL process. In this example we
will use a polling adapter, because it is the most simple to set up
and demonstrate. But it has one disadvantage as a demonstrative
model. When a polling adapter is active, it will dequeue all
messages as soon as they reach the queue. This makes it difficult to
monitor messages we are writing to the queue, because they will
disappear from the queue as soon as they have been enqueued. To work
around this, we will shut down the composite after deploying it and
restart it as required. (Another solution for this would be to pause
the consumption for the queue and resume consumption again if
needed. This can be done in the WLS console JMS-Modules -> queue
-> Control -> Consumption -> Pause/Resume.)
We will model the composite as a one-way incoming process. Usually, a BPEL process will do something useful with the message after receiving it, such as passing it to a database or file adapter, a human workflow or external web service. But we only want to demonstrate how to dequeue a JMS message using BPEL and a JMS adapter, so we won’t complicate the design with further activities. However, we do want to be able to verify that we have read the message correctly, so the BPEL process will include a small piece of embedded java code, which will print the message to standard output, so we can view it in the SOA server’s log file. Alternatively, you can view the instance in the Enterprise Manager and verify the message.
The following steps are all executed in JDeveloper. Create the project in the same JDeveloper application used for the previous examples or create a new one.
Create a SOA Project
Create a new project and choose SOA Tier > SOA Project as its type. Name it JmsAdapterReadSchema. When prompted for the composite type, choose Empty Composite.
Create a JMS Adapter Partner Link
In the composite editor, drag a JMS adapter over from the Component Palette to the left-hand swim lane, under Exposed Services.
This will start the JMS Adapter Configuration Wizard. Use the following entries:
Service Name: JmsAdapterRead
Oracle Enterprise Messaging Service (OEMS): Oracle WebLogic JMS
AppServer Connection: Use an application server connection pointing to the WebLogic server on which the JMS queue and connection factory mentioned under Prerequisites above are located.
Adapter Interface > Interface: Define from operation and schema (specified later)
Operation Type: Consume Message
Operation Name: Consume_message
Consume Operation Parameters
Destination Name: Press the Browse button, select Destination Type: Queues, then press Search. Wait for the list to populate, then select the entry for TestJMSQueue , which is the queue created in a previous example.
JNDI Name: The JNDI name to use for the JMS connection. As in the previous example, this is probably the most common source of error. This is the JNDI name of the JMS adapter’s connection pool created in the WebLogic Server and which points to the connection factory. JDeveloper does not verify the value entered here. If you enter a wrong value, the JMS adapter won’t find the queue and you will get an error message at runtime, which is very difficult to trace. In our example, this is the value eis/wls/TestQueue . (See the earlier step on how to create a JMS Adapter Connection Pool in WebLogic Server for details.)
URL: We will use the XSD file created during the previous example, in the JmsAdapterWriteSchema project to define the format for the incoming message payload and, at the same time, demonstrate how to import an existing XSD file into a JDeveloper project.
Press the magnifying glass icon to search for schema files. In the Type Chooser, press the Import Schema File button.
Select the magnifying glass next to URL to search for schema files. Navigate to the location of the JmsAdapterWriteSchema project > xsd and select the stringPayload.xsd file.
Check the “Copy to Project” checkbox, press OK and
confirm the following Localize Files popup.
Now that the XSD file has been copied to the local project, it can be selected from the project’s schema files. Expand Project Schema Files > stringPayload.xsd and select exampleElement: string .
Press Next and Finish, which will complete the JMS Adapter
Save the project.
Create a BPEL Component
Drag a BPEL Process from the Component Palette (Service Components) to the Components section of the composite designer. Name it JmsAdapterReadSchema and select Template: Define Service Later and press OK.
Wire the JMS Adapter to the BPEL Component
Now wire the JMS adapter to the BPEL process, by dragging the arrow from the adapter to the BPEL process. A Transaction Properties popup will be displayed. Set the delivery mode to async.persist.
This completes the steps at the composite level.
3 . Complete the BPEL Process Design
Invoke the BPEL Flow via the JMS Adapter
Open the BPEL component by double-clicking it in the design view of the composite.xml, or open it from the project navigator by selecting the JmsAdapterReadSchema.bpel file. This will display the BPEL process in the design view. You should see the JmsAdapterRead partner link in the left-hand swim lane.
Drag a Receive activity onto the BPEL flow diagram, then drag a wire (left-hand yellow arrow) from it to the JMS adapter. This will open the Receive activity editor. Auto-generate the variable by pressing the green “+” button and check the “Create Instance” checkbox. This will result in a BPEL instance being created when a new JMS message is received.
At this point it would actually be OK to compile and deploy the composite and it would pick up any messages from the JMS queue. In fact, you can do that to test it, if you like. But it is very rudimentary and would not be doing anything useful with the message. Also, you could only verify the actual message payload by looking at the instance’s flow in the Enterprise Manager.
There are various other possibilities; we could pass the message to another web service, write it to a file using a file adapter or to a database via a database adapter etc. But these will all introduce unnecessary complications to our sample. So, to keep it simple, we will add a small piece of Java code to the BPEL process which will write the payload to standard output. This will be written to the server’s log file, which will be easy to monitor.
Add a Java Embedding Activity
First get the full name of the process’s input variable, as this will be needed for the Java code. Go to the Structure pane and expand Variables > Process > Variables. Then expand the input variable, for example, "Receive1_Consume_Message_InputVariable > body > ns2:exampleElement”, and note variable’s name and path, if they are different from this one.
Drag a Java Embedding activity from the Component Palette (Oracle Extensions) to the BPEL flow, after the Receive activity, then open it to edit.
Delete the example code and replace it with the following, replacing the variable parts with those in your sample, if necessary.:
System.out.println("JmsAdapterReadSchema process picked up a message");
oracle.xml.parser.v2.XMLElement inputPayload =
String inputString = inputPayload.getFirstChild().getNodeValue();
System.out.println("Input String is " + inputPayload.getFirstChild().getNodeValue());
Tip. If you are not sure of the exact syntax of the input variable, create an Assign activity in the BPEL process and copy the variable to another, temporary one. Then check the syntax created by the BPEL designer.
This completes the BPEL process design in JDeveloper. Save, compile and deploy the process to the SOA server.
3. Test the Composite
Shut Down the JmsAdapterReadSchema Composite
After deploying the JmsAdapterReadSchema composite to the SOA server it is automatically activated. If there are already any messages in the queue, the adapter will begin polling them. To ease the testing process, we will deactivate the process first
Log in to the Enterprise Manager (Fusion Middleware Control) and navigate to SOA > soa-infra (soa_server1) > default (or wherever you deployed your composite to) and click on JmsAdapterReadSchema [1.0] . Press the Shut Down button to disable the composite and confirm the following popup.
Monitor Messages in the JMS Queue
In a separate browser window, log in to the WebLogic Server Console and navigate to Services > Messaging > JMS Modules > TestJMSModule > TestJMSQueue > Monitoring. This is the location of the JMS queue we created in an earlier sample (see the prerequisites section of this sample). Check whether there are any messages already in the queue. If so, you can dequeue them using the QueueReceive Java program created in an earlier sample. This will ensure that the queue is empty and doesn’t contain any messages in the wrong format, which would cause the JmsAdapterReadSchema to fail.
Send a Test Message
In the Enterprise Manager, navigate to the JmsAdapterWriteSchema created earlier, press Test and send a test message, for example “Message from JmsAdapterWriteSchema”.
Confirm that the message was written correctly to the queue by verifying it via the queue monitor in the WLS Console.
Monitor the SOA Server’s Output
A program deployed on the SOA server will write its standard output to the terminal window in which the server was started, unless this has been redirected to somewhere else, for example to a file. If it has not been redirected, go to the terminal session in which the server was started, otherwise open and monitor the file to which it was redirected.
Re-Enable the JmsAdapterReadSchema Composite
In the Enterprise Manager, navigate to the JmsAdapterReadSchema composite again and press Start Up to re-enable it. This should cause the JMS adapter to dequeue the test message and the following output should be written to the server’s standard output:
JmsAdapterReadSchema process picked up a message.
Input String is Message from JmsAdapterWriteSchema
Note that you can also monitor the payload received by the process, by navigating to the the JmsAdapterReadSchema’s Instances tab in the Enterprise Manager. Then select the latest instance and view the flow of the BPEL component. The Receive activity will contain and display the dequeued message too.
4 . Troubleshooting
This sample demonstrates how to dequeue an XML JMS message using a
BPEL process and no additional functionality. For example, it
doesn’t contain any error handling. Therefore, any errors in
the payload will result in exceptions being written to the log file
or standard output. If you get any errors related to the payload,
Message handle error ... ORABPEL-09500 ... XPath expression failed to execute. An error occurs while processing the XPath expression; the expression is /ns2:exampleElement. ... etc.
check that the variable used in the Java embedding part of the process was entered correctly. Possibly follow the tip mentioned in previous section. If this doesn’t help, you can delete the Java embedding part and simply verify the message via the flow diagram in the Enterprise Manager. Or use a different method, such as writing it to a file via a file adapter.
This concludes this example. In the next post, we will begin with an AQ JMS example, which uses JMS to write to an Advanced Queue stored in the database.
Oracle Technology Proactive Support Delivery