If you can't wait next summer to know what's going to happen with SOA Suite 11g,
here's a sample to manage your frustration :)
Presenting the context
The example I've chosen is a quite simple one. Indeed, it's no real case,
just a convenient way to illustrate how the complete chain works.
=> A user wants to go to the movies. He will send the movie title to a webservice
which will route him to the theater where there are the most available seats.
To do that example, I've installed :
- => OSB 10gR3 / Workshop 10gR3
- => SOA Suite 10g 10.1.3.1.0
In the end, I'll have three JVMs running :
- => One for OSB
- => One for WLS (hosting the webservices)
- => One for BPEL Process Manager (OC4J)
Designing some webservices (JAX-WS)
We'll design three webservices, in order to have enough data to process.
Three webservices (one per theater) :
- => UGB
- => Gomon (GMN)
- => MK3
They all have the same business contract : only the returned result differs from one to another.
You can have a detailed example on how to design a JAX-WS webservice on another blogpost :
http://m-button.blogspot.com/2008/07/building-jax-rpc-or-jax-ws-webservices.html
Example : the Gomon Webservice
package fr.mbutton.blog;
import javax.jws.*;
@WebService(targetNamespace="http://fr.mbutton.blog/gomon")
public class CheckAvailability_GMN {
@WebMethod
public boolean isMovieStillPlaying(String movieTitle) {
return true;
}
@WebMethod
public int getAvailableSeatsForMovie (String movieTitle) {
return 124;
}
}
And here's a sample build.xml for this webservice :
<project name="GMN" basedir="." default="build-webservice">
<taskdef name="jwsc" classname="weblogic.wsee.tools.anttasks.JwscTask" />
<property name="dest.dir" value="D:\BEA_ROOT\user_projects\workspaces\osb_bpel\Theaters\EarContent" />
<target name="build-webservice">
<jwsc srcdir="src" destdir="${dest.dir}">
<jws file="fr/mbutton/blog/CheckAvailability_GMN.java" type="JAXWS" />
</jwsc>
</target>
</project>
The execution of the ANT build.xml will create one WAR per webservice.
Then, just deploy the three WARs to your WLS domain and make sure they're all reachable.
To do so, click on each of them :
And then, once you've clicked on the webservice you want to test, you should see a "Testing" tab.
You can choose either to show the WSDL or launch a test client. Either way, you'll be sure it's up & running.
Setting up an OSB configuration
Here's a very simple definition. No extra processing : the proxy service will directly route to the
business service, with no additional computing.
Note : If you're working with two separate domains at the same time, I'll advise you to read that article :
http://m-button.blogspot.com/2009/02/working-with-two-weblogic-domains-on.html
A little remark : if you take a closer look to the generated webservice, and especially to their WSDLs, you'll see
that the XML schema is imported :
<types>
<xsd:schema>
<xsd:import namespace=http://fr.mbutton.blog/gomon
schemaLocation="http://192.168.100.1:8001/CheckAvailability_GMN/CheckAvailability_GMNService?xsd=1" />
</xsd:schema>
</types>
In OSB, you'll have to import those schemas separately and then link them to the corresponding webservice.
Then create as explained above, one business service per webservice exposed, and one proxy service per business service, like :
Once everything is correctly set up, test your configuration by trying to reach the proxy services.
To do so, click on a proxy service, it will lead you to this screen :
To test it, take your server URL (for example : http://myserver:7001), add the endpoint URI + "?WSDL" and check it you've got something :)
No need to tell that if you don't, it's not normal, right ?
Orchestrating webservice calls thanks to BPEL PM
Here we go ! Now, we've got three webservices up and running and we applied the mediator pattern thanks to an ESB.
What we need now is to call the webservices, store the results and return a computed result.
Exactly what BPEL was designed for.
Note : former BEA clients used WLI (WebLogic Integration) for the same kind of matter.
First thing, open JDeveloper and create a new Application (similar to an Eclipse workspace).
Once created, add a synchronous BPEL Process Project.
Next step :
In the application pane, an empty BPEL project is created :
In the graphical view, you'll only see two steps (receiveInput & replyOutput) and a partnerLink (client).
First of all, let's modify the name of the BPEL process variables.
To do so, open the associated XSD in Integration Content > Schemas and change element names (in blue) :
<schema attributeFormDefault="unqualified"
elementFormDefault="qualified"
targetNamespace="http://fr.mbutton.blog"
xmlns="http://www.w3.org/2001/XMLSchema">
<element name="BlogSampleProcessRequest">
<complexType>
<sequence>
<element name="movieTitle" type="string"/>
</sequence>
</complexType>
</element>
<element name="BlogSampleProcessResponse">
<complexType>
<sequence>
<element name="theaterName" type="string"/>
</sequence>
</complexType>
</element>
</schema>
As we will call three webservices at the same time, we'll need a "Flow" activity.
(Note : BPEL PM does spawn a thread for each branch. Whereas WLI has a flow-like activity, it's not parallel but sequential)
Drag and drop it to the node between the receive and the reply.
Open the branches. We'll need three branches and in each, a call to a webservice will be performed.
Add an "Invoke" activity in the first branch.
We'll have to link that Invoke activity to one of the webservice.
What you have to know is that any external part to the BPEL process
is called a "Partner Link" or "Adapter".
- PartnerLink (client, webservice)
- Adapter (file, JMS message and so on)
So to create a reference to the webservice, let's create a partnerLink.
Drag and drop a partnerLink service to the right side of the BPEL process. (it's a good practice to keep BPEL process callers
on the left and BPEL process called partners on the right).
Once the item is dropped, a popup will show up.
Enter the URL of your webservice and click refresh (circle made of the two blue arrows).
Accept the proposal.
Draw a line between the invoke action and the partnerLink (you can bind these items differently)
Choose the operation to invoke and create local variables.
For now, the wiring has been made, but we need to assign the bpel input variable to the webservice input variable.
Just add a Assign activity
and copy the value such as :
In order to see if our bpel process is working, we'll add another Assign activity which will assign the returned value
to the client.
Of course, this copy isn't right : the returned result represents a number of seats and the client expects a theater name ...
But it's just for some testing matters.
To build and deploy your BPEL process, edit the build.properties and make sure all the information match your configuration.
(port/user/password ...)
Right-click the application, chose "Make". Then right-click on the build.xml file and choose "Run Ant Target" > "Deploy".
Log in to your BPEL console (for me, it's http://localhost:8888/BPELConsole).
Select your BPEL Process and run the test console. Enter a movie title and notice the result.
It should be something like :
Our BPEL process works perfectly.
I won't go deeper in the process and explain how to compare and assign values; you can figure out what to do next
by yourself and if not, you will find some good references on the Net.
If you want to learn more, contact Oracle University :)
Exposing the BPEL process through OSB
Last but not least, our BPEL process has to be exposed as a webservice. But as we started to use the mediator pattern,
no way a client can call the BPEL process directly. It has to be called through the ESB.
To do so, create a business service based on the BPEL process WSDL.
To get the WSDL, click on the corresponding tab :
And in the bus, create a Business Service based on this WSDL.
Note : You'll have to create a schema first.
Import your schema from the URL (for me it's : http://mbutton01:8888/orabpel/default/BlogSample/1.0/BlogSample.xsd)
Once your WSDL is successfully created, map a business service on it and choose "BPEL 10g" as the transport :
For the endpoint URI, use the URL given on the WSDL page, but replace protocol "http" by "opmn".
On the next screen, chose "Synchronous Client".
Review and accept the configuration.
Create a proxy service based on the newly created business service :
Test your proxy service and you should have your BPEL process correctly exposed.