JMS Step 5 - How to Create an 11g BPEL Process Which Reads a Message
Based on an XML Schema from a JMS Queue
.jblist{list-style-type:disc;margin:0;padding:0;padding-left:0pt;margin-left:36pt}
ol{margin:0;padding:0}
.c12_5{vertical-align:top;width:468pt;border-style:solid;background-color:#f3f3f3;border-color:#000000;border-width:1pt;padding:5pt 5pt 5pt 5pt}
.c8_5{vertical-align:top;border-style:solid;border-color:#000000;border-width:1pt;padding:5pt 5pt 0pt 5pt}
.c10_5{vertical-align:top;width:207pt;border-style:solid;border-color:#000000;border-width:1pt;padding:5pt 5pt 5pt 5pt}
.c14_5{vertical-align:top;border-style:solid;border-color:#000000;border-width:1pt;padding:0pt 5pt 0pt 5pt}
.c21_5{background-color:#ffffff}
.c18_5{color:#1155cc;text-decoration:underline}
.c16_5{color:#666666;font-size:12pt}
.c5_5{background-color:#f3f3f3;font-weight:bold}
.c19_5{color:inherit;text-decoration:inherit}
.c3_5{height:11pt;text-align:center}
.c11_5{font-weight:bold}
.c20_5{background-color:#00ff00}
.c6_5{font-style:italic}
.c4_5{height:11pt}
.c17_5{background-color:#ffff00}
.c0_5{direction:ltr}
.c7_5{font-family:"Courier New"}
.c2_5{border-collapse:collapse}
.c1_5{line-height:1.0}
.c13_5{background-color:#f3f3f3}
.c15_5{height:0pt}
.c9_5{text-align:center}
.title{padding-top:24pt;line-height:1.15;text-align:left;color:#000000;font-size:36pt;font-family:"Arial";font-weight:bold;padding-bottom:6pt}
.subtitle{padding-top:18pt;line-height:1.15;text-align:left;color:#666666;font-style:italic;font-size:24pt;font-family:"Georgia";padding-bottom:4pt}
li{color:#000000;font-size:10pt;font-family:"Arial"}
p{color:#000000;font-size:10pt;margin:0;font-family:"Arial"}
h1{padding-top:0pt;line-height:1.15;text-align:left;color:#888;font-size:24pt;font-family:"Arial";font-weight:normal}
h2{padding-top:0pt;line-height:1.15;text-align:left;color:#888;font-size:18pt;font-family:"Arial";font-weight:normal}
h3{padding-top:0pt;line-height:1.15;text-align:left;color:#888;font-size:14pt;font-family:"Arial";font-weight:normal}
h4{padding-top:0pt;line-height:1.15;text-align:left;color:#888;font-size:12pt;font-family:"Arial";font-weight:normal}
h5{padding-top:0pt;line-height:1.15;text-align:left;color:#888;font-size:11pt;font-family:"Arial";font-weight:normal}
h6{padding-top:0pt;line-height:1.15;text-align:left;color:#888;font-size:10pt;font-family:"Arial";font-weight:normal}
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
Object Name
Type
JNDI Name
TestConnectionFactory
Connection Factory
jms/TestConnectionFactory
TestJMSQueue
JMS Queue
jms/TestJMSQueue
eis/wls/TestQueue
Connection Pool
eis/wls/TestQueue
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
process.
stringPayload.xsd
<?xml version="1.0"
encoding="windows-1252" ?>
<xsd:schema
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.example.org"
targetNamespace="http://www.example.org"
elementFormDefault="qualified">
<xsd:element name="exampleElement"
type="xsd:string">
</xsd:element>
</xsd:schema>
JMS Message
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>
JDeveloper Connection
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.)
Messages/Message SchemaURL:
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
configuration.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 =
(oracle.xml.parser.v2.XMLElement)getVariableData(
"Receive1_Consume_Message_InputVariable",
"body",
"/ns2:exampleElement");
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,
such as
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.
Best regards
John-Brown Evans
Oracle Technology Proactive Support Delivery