Securing an ESB Service using OWSM

Recently I was organizing a seminar regarding Oracle Soa Suite and the focus lied on Securing web services and integration.

In my demo I wanted to show the different features of BPEL, ESB and OWSM and of course the ease of integration of these different technologies.

The ame was to secure as well existing web services as the ESB services itself which are called inside my bpel processes.

In this way I can call stand-alone BPEL processes, ESB services and web services or integrate these technologies with eachother when required.

The difficulty of this exercise lies in calling secured soap services inside an ESB Service. Using a gateway we can secure the ESB Services and BPEL Processes used throughout the organization. The external webservices we need to integrate with are secured as well, and these security requirements need to be met by the calling service, which in our case is an existing BPEL Process or an ESB Service.

First lets have a look on how to call a secured external webservice, a partnerlink, in a bpel process. The webservice expects user-credentials to be able to call the webservice, these credentials can be added to the secured webservice using by editing the partnerlink.

Go to the partnerlink and click ‘edit’, go to the 3d tab which is the ‘Property’ tab and add the needed parameters to your webservice call. These parameters will define that credentials are added to the header of the web service call and the username and password which are required in this header. The properties you need to add are shown in the printscreen, for each property you need to define the proper values.
Such as for the wsseHeaders property, you need to define ‘credentials’ to state that the header will contain user credentials. This is standard web service security we’re using.

To be able to add these same credentials to the external web service, which is invoked from an ESB Service now, we need to come up with another solution. In the demo the same integration exercise is defined, once integration of external web service with BPEL and once through integration of ESB Routing Service with a SOAP Service. The only difficulty in the ESB Service is, that we can’t add these properties in a declarative way to the ESB Service. Instead we need to work with transformations to be able to add the credentials to the SOAP Service call.
How can we accomplish this, by adding parameters to the xsl-stylesheet which is used to transform the call that’s being made to the SOAP Service.

Have a look at the screenshot below to have a clear view on the needed parameters to add to the SOAP Service using an xsl-stylesheet in the transformation-property of our ESB Routing Service.

Errors when trying to invoke an ESB Service from BPEL or UI

When you try to invoke an ESB Service from a BPEL Process or from an ADF application you can run into the following error/exception:

Error happened when reading wsdl at “http://localhost:8888/esb/wsil/Fulfillment/OrderFulfillment?wsdl”, because “Failed to read wsdl file at: “http://localhost:8888/esb/wsil/Fulfillment/OrderFulfillment?wsdl”, caused by: : connect: Address is invalid on local machine, or port is not valid on remote machine”.

What does this error mean, and how can you solve it?
When the Bpel Process or UI tries to access the ESB Service but can’t find the webservice or wsdl these exceptions will be thrown. The first step to perform is to check the connection properties in your Esb Control such as shown in the screen below:

Make sure the VirtualHost and Port are defined correctly, afterwards you can check the Routing Service itself to make sure the endpoint is defined correctly.

Create a demo using EJB 3.0, Toplink and ADF as the UI layer and Bpel and ESB as the back-end layer (through web service invocation) – Episode 1

The case I worked out for my demo application is the following: Create a new person via the UI (using JSF and EJB3.0 as data-layer) and initiate a bpel process for the creation of the person. The bpel process will check if all business requirements were met for the person that needs to be created using Business Rules.
A human task was added to make sure the Personal Manager has approved the new person and finally an ESB was added to actually create the person.
The ESB will transform the person-object, an xml-file, to the specific format I need to be able to insert the person in my db.

During the creation of my demo-project I faced some design problems which I will explain in the following chapters:

The first part of the case was simple, create a UI using EJB 3.0 and ADF Faces using JDeveloper as my IDE.
The UI consists of a ListPersons.jspx – page that lists all existing persons of my persons-db and a link to the CreatePerson.jspx-page. In the CreatePerson.jspx page I will create a new Person and initiate the bpel process from here.

But it wasn’t as simple as I thought … to be able to initiate my bpel process using the EJB-objects I needed to prefetch the sequence-value needed for uniquely identifying the person-object, e.g. the Person.personid. This is needed because the bpel process needs all xml-tags to be filled in. If for example the personid, or firstname isn’t filled in you will get the following exception ‘unexpected null value for literal data’.

To be able to prefetch the id in my EJB i thought I could ‘eagerly fetch’ this id using an annotation in EJB 3.0, but there’s no such annotation available :(

What to do next … fetch the sequence value myself and populate the Person.personID with my sequence-value.

I’ve added a new method in my SessionBean that gets the sequence value from my db-sequence, this method is invoked from my custom-method ‘createPersonObject() which constitutes a valid person-object.

The custom-method to fetch the sequence-value uses the ‘createNativeQuery’-method on the EntityManager:

em.createNativeQuery(“select person_seq.nextval from dual”);

The UI now works correctly, using the createPersonObject()-method as binding-layer to go to the CreatePerson.jspx file.

Now I need to link my existing Bpel Process to this UI … coming up soon …

Deploying a User Interface Application to the Oracle Bpel Server:

When you want to access a deployed business proces via a User interface, e.g. a JSP-page, you will use the Oracle Bpel Java API. This Api gives you the possibility to instantiate deployed processes of your Oracle Bpel Server and to get process audit information, etc.
There are several examples available of how to build such a User Interface (Tutorial 102.InvokingProcesses, technet, …) but information about deployment isn’t available.
If you take a look at technet you will find a lot of questions about best practices, errors when instantiating this UI, … so I thought it would be very nice to have a best practice about the deployment-issues of a User Interface application on the Oracle Bpel Server.

Best practice on deployment of a UI-application on the Oracle Bpel Server:

  • Create a new deployment profile, WAR-file
  • In the general-topic (the default shown) choose the second radio-button ‘Specify J2EE Web Context Root’ for the Web Application Context Root. Enter ‘AsyncLoanFlowUI’ for the contextroot.
  • Add following parameter to the platform ‘Standalone OC4J’-node -parent orabpel (otherwise you will need to restart the server to add this parameter manually everytime you redeploy the application to the Oracle Bpel Server, there’s a post about this on Clemens-blog)

  • Right-click the deployment profile and choose to create a new connection, the Application Server Connection Wizard will be shown
    o Connection name: LocalBpelServer
    o Connection Type: Standalone OC4J

You don’t need to have a build.xml-file or application.xml-file, you only need to have a deployment-descriptor in which you’ve added the parent-parameter to be able to access the UI in your Oracle Bpel Server.