A common requirement with the Oracle ESB is to use it to invoke one or
more EJBs; one way to do this is to create a standard SOAP service from
an existing EJB using the wizards in JDeveloper.
Creating the WSIF WSDL File
Before
you can invoke an EJB via WSIF you need to create a WSDL file which
contains the appropriate binding information required by the WSIF
framework to invoke the EJB.There are two basic approaches you can take:
Define Abstract WSDL File
The
first step is to define a simple abstract WSDL file to describe your
services, for our purpose we have defined the following:At first glance there is nothing here to indicate that the WSDL is for a service to be implemented using an EJB. The only thing worth mentioning is that we have defined our XML schema elements for our input and outputs parameters in a separate file, which we have imported into our WSDL document. The reason for doing this it that at a later stage we will need to generate Java classes based on the XML Schema, and separating out the schema makes this process slightly simpler, especially if you need share the Schema between multiple EJBs. The schema for Person.xsd is as follow: Note: We have defined all our parameters as elements and NOT complexTypes since the Oracle ESB will complain if you try and use a WSDL which uses complexTypes in its message definitions.
Implement Session EJB
The next step is to implement a corresponding stateless session EJB to implement our Greeting service. The simplest way to do this in JDeveloper is right click your Greeting project and select New. This will bring up the ‘Gallery’ as shown below. Browse to the Business Tier-> EJB section and select Session Bean (as shown below) and click OK.Figure 1 - Creating a Session Bean This will launch the Create Session Bean Wizard. In Step 1, select ‘Enterprise Java Beans 3.0(J2EE 5.0)’ as the version of EJB you wish to use and click next. In step 2; specify the EJB Name, i.e. Greeting, Keep the default settings for the Session EJB 3.0 options (as shown below) and click ‘Next’.
Figure 2 – Specify EJB Name and Options
Next specify the bean class name. This will have already been defaulted based on the EJB Name you specified in the previous step (i.e. it will have appended bean to it). Leave the class name as is, but specify the package name as appropriate. In our case we set the package name to com.bpelpeople.ejb and then click next.
Figure 3 – Specify Class Name
Finally specify that you want the EJB to implement a remote, local and web service endpoint interface (as shown below). Then hit ‘Finish’ to generate your EJB.
Figure 4 – Specify EJB Interfaces
For each operation defined in our WSDL file we should create the equivalent method in our EJB. For each method we need to define its input and return parameters. For operations or method that return simple XML types (e.g. xsd:string, xsd:integer) we can use the equivalent type in Java. However for complex types, such as our Person element we need to implement the appropriate classes required for serialization/de-serialization between java and xml.
Using schemac to generate serialization/de-serialization classes
As
part of the SOA Suite, Oracle provides the schemac utility (bundled
with BPEL PM) which you can use to generate the
serialization/de-serialization classes. To use this utility open the
BPEL Developer Prompt and then run the following command:schemac –noCompile –sourceOut < dir=""> < file=""> This will generate the source Java for serialization/de-serialization classes for the specified schema file (e.g. Person.xsd in our case) and places these within the specified source directory. Within JDeveloper you will need to import these classes into you project containing your EJB. You will notice that for each element, schemac will generate three classes (e.g. Person, IPerson and PersonFactory); we will use the actual concrete class (i.e. Person) for the input parameter to our method. So for our Greeting EJB we have defined the following method:
Setting Project Classpath
Once
you have imported the generated Java classes into your project, in
order to compile them you will need to add the orabpel.jar file to your
project classpath, this is located at:$SOA_HOME/bpel/lib/orabpel.jar
Create Deployment Descriptor
Finally
we need to create a deployment descriptor for our EJB, within the
Application Navigator right click on our Greeting project and select
‘New’. From the gallery, browse to General -> Deployment Profiles and
select ‘EJB Jar File’. This will bring up the Create Deployment Profile
window.Figure 7 – Specify Deployment Profile Name Specify a profile name, i.e. ‘Greeting’ in our example and click ‘OK’. This will launch the ‘EJB JAR Deployment Profile Properties’ window, as shown below. Figure 8 – EJB JAR Deployment Profile Properties Specify a name for the application, in our case we have chosen ‘GreetingApp’ (note: you will need to make a note of this value as you will use it when defining the WSIF Binding for your service) and click ‘OK’. Note: you will need to define an Application Server connection to the OC4J instance to which you want to deploy your EJB first.
Deploying the EJB
You can now use JDeveloper to deploy your EJB, however before doing this you should define an Application Server connection with JDeveloper to the oc4j instance on which the SOA Suite is deployed (e.g. oc4j_soa). You are now ready to deploy your EJB. You can now use the deployment file you just created to deploy your EJB. Right click on this file and select deployTo-> oc4j_soa (where oc4j_soa is the name of your application server connction). As part of the deployment process, JDeveloper will bring up the Configure Application window. However if you click ‘OK’ and follow the standard deployment process, you will need to include the orabpel.jar within your .ear file. This can be a bit cumbersome, particularly if you have several EAR files to deploy. The other option is to deploy your application as a child of the orabpel application. By designating orabpel as the parent application, your EJB will inherit the set of shared libraries imported by the parent including orabpel.jar. To do this select ‘GreetinApp’ within the ‘Configure Application’ window and then select orabpel as the parentApp as show below in figure 9. Figure 9 – Setting the Parent Application Then click ‘ok’ and JDeveloper will complete the deployment of our EJB.
Adding WSIF Bindings
Now that we have written and deployed our EJB we are ready to add the WSIF bindings to our abstract WSDL file to enable it to be called from the ESB.
Modify Definitions Element
Within the <definitions> element of your WSDL file you need to add the following namespaces:
Add Bindings Element
This
is where we bind our service to an EJB rather than a standard SOAP
service. For our example, the WSDL <binding> element is defined as
follows:
Ejb Binding
<ejb:binding> should be the first element within our <bindings> tag and identifies that this is service is bound to an EJB rather than a SOAP service.
Type Definitions
Next,
you need to map the XML Schema elements used within the WSLD message
definitions to the Java types used in the method invocations for your
EJB.The <format:typemapping> element will contain one <format:typemap> for each xml schema element that we need to map, it has two attributes encoding and style both of which should be set to ‘Java’ to indicate that we are mapping to Java classes. The <format:typemap> element has two attributes, typeName which hold the name of the xml schema element that we are mapping and formatType which contains the class name of the Java class to which we are mapping it. In our example, we have specified two type mappings one between our Person element and the corresponding class that we generated using schemac, and the other between the Return element and the java.lang.String class.
Method Mapping
The final step is now to map the EJB method calls onto the WSDL operations. This is done using the <ejb:operation> tag to identify which EJB method should be used to support a given operationThis element has the following attributes:
Add Services Binding
Finally we have to add the
element to our WSDL to specify where to locate the service. This looks
pretty normal, except that instead of a <soap:address> element, we
need to specify an <ejb:address> element.This contains one attribute jndiName; which specifiec the JNDI Name of the deployed EJB. In our example the <service> element is defined as follows:
Calling your EJB from ESB
We
are now ready to invoke our EJB from within our ESB. To do this, create
a SOAP Service based on our WSDL file within your ESB project in the
normal way (note you will need to import the Schema into your ESB
project first).However before registering your ESB project you will need to define the following endpoint properties on your service:
This is so that the ESB is able to locate and invoke the EJB at run time.
java.naming.provider.url
Specifies the URL for the provider (or application) which contains our EJB, this takes the form:opmn:ormi://<hostname>:<opmn request port>:<oc4j container>/<application> Where
To do this first close down JDeveloper (otherwise you can get sync issues) and then open the appropriate .esbsvc file in your favourite text editor and specify the endpoint properties at the end of this file as follows: Once done, you can open up JDeveloper and deploy your ESB project.
Deploy EJB Classes to ESB Engine
Before we can call the EJB from the ESB, we must first deploy the remote interface class of our EJB (Greeting.class)
and our Java serialization/de-serialization classes to the ESB engine,
the simplest way to do this is to copy the java classes into the
directory:<soa_home>\bpel\system\classes Once done you will need to re-start the SOA Suite so that it picks up the classes.
Deploy Patch to ESB
Finally if you are using 10.l.3.3 of Oracle SOA Suite you will need to install patch 6314009 which is available at metalink.oracle.com. |
Wednesday, May 9, 2012
Invoking EJB's from Oracle ESB using WSIF
########
Subscribe to:
Post Comments (Atom)
0 comments:
Post a Comment