Wednesday 16 May 2012

Import Oracle Workflow in BPM Suite 11g

Cool! Since BPM 11g PS4FP you can import Oracle Workflow models in BPM 11g. From PS5 (11.1.1.6) it should be possible as well. See this whitepaper.
I'm going to try. 

Monday 14 May 2012

Using JDeveloper HTTP Analyser to intercept/forward requests


In my previous entry I showed how to create a SoapUI test case to do a WS-Adressing driven request-response interaction with an asynchronous BPEL Process. But how does this WS-Adressing request look like?
To get this above the water a tool like the HTTP Analyser of JDeveloper 11g may come in handy.

It is found in the tools option of JDeveloper:


This opens the HTTP Analyser normally at the bottom of the screen:

To use it for our purpose we have to create a HTTP-listener with a forwarding rule. This means that it just listens to request and forwards the request to a URL we provide.
To do this I added a new listener with a new port 8100:
Then click on the "Configure Rules" button, add a forward rule (click on the dropdown triangle of the Add button and choose Forward Rule):
In the reference URL part in the screen above you can put a URL that is used to test the URL Filter.
But after playing around I just left this URL Filter field.

In the Target URL I put the complete URL of the original endpoint of the WSDL from SoapUI, found in the Test Request step in SoapUI. But this one I've replaced by adding a new endpoint:


The added endpoint will have the original URL but with the hostname:port replaced to localhost:8100 (where the HTTP Analyser is listening):

Thus:
http://localhost:8100/soa-infra/services/default/M10HelloWorld/helloworld_client_ep
Then you can run the HTTP Analyser:



I've copied and pasted the message from the screendump into a new XML Document in JDeveloper and reformated it:
 <?xml version="1.0" encoding="windows-1252" ?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                  xmlns:hel="http://xmlns.oracle.com/M10_Demo/M10HelloWorld/HelloWorld">
   <soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
      <wsa:Action soapenv:mustUnderstand="1">process</wsa:Action>
      <wsa:ReplyTo soapenv:mustUnderstand="1">
         <wsa:Address>http://hostname.darwin-it.nl:8989/HelloWorldCallbackBinding/processResponse</wsa:Address>
      </wsa:ReplyTo>
      <wsa:MessageID soapenv:mustUnderstand="1">uuid:36f10438-0270-4318-a5a5-fd2ad44d6136</wsa:MessageID>
   </soapenv:Header>
   <soapenv:Body>
      <hel:process>
         <hel:input>Astrid</hel:input>
      </hel:process>
   </soapenv:Body>
</soapenv:Envelope>

Here you can see the properties set in SoapUI (see previous blog in the WSA-header:
  • Action - mustUnderstand="1"
  • Action (defaulted): process
  • ReplyTo - Address: http://hostname.darwin-it.nl:8989/HelloWorldCallbackBinding/processResponse
  • MessageID (generated): uuid:36f10438-0270-4318-a5a5-fd2ad44d6136
 Now with this configuration each request to localhost:8100 is forwarded to this process. If you need to support multiple processes different rules should be added or in stead of a forward rule a substitute rule should be applied.

A substitute rule will look like:
 With this each request to localhost:8100 is forwarded to hostname.darwin-it.nl:8001.

Testing of Asynchronous BPEL Processes with SoapUI made simple

Recently I wrote some blog-entries about scripting in SoapUI. Now I had to help my current customer to test Asynchrounous BPEL processes using SoapUI. Now calling a BPEL Process (in Oracle SOASuite 11g) from SoapUI is very easy. And if it is a synchronous process then you'll get the response right away. But if the BPEL process is Asynchronous then the response is seperated from the request. In fact technically an asynchrounous webservice call that is implemented by a BPEL process are two complementary one-way requests. The client calls the bpel process but let then listens to the response of the bpel service. The BPEL service calls then the client with the response.

The glue between the two is WS-Addressing. This standard enables the client to put in a little piece of xml in the request-message with information on:
  • the address of the endpoint to call to deliver the response message
  • the message id to correlate the response message to the request message
Luckily both SOASuite11g (and 10g by the way) and SoapUI support WS-Adressing and it turns out pretty easy to work it out.

To read more you can find a tutorial on OTN. However, unfortunately the pictures don't correspond to the text, so I found it a bit hard to read. Therefor I made a HelloWorld setup myself. I might extend it in next blogs, if my further experiences are worthy to share (and time let me).

Create a Asynchronous BPEL Process

First, let us create a HelloWorld project. For those that are new to SOASuite 11g: in JDeveloper create a SOAApplication with a SOAProject based on a BPEL process:
Then name the BPEL process HelloWorld and make sure you base it on the asynchronous BPEL process template.

Then add an assign, drag the Expression Builder Icon (most left "fx" icon in the row of icons top right) on the result node of the output variable. Then add the line
concat("Hello ", bpws:getVariableData('inputVariable','payload','/client:process/client:input'))

to the expression:
then the Assign will look like:
resulting in the following bpel process.
This process can be deployed and run on enterprise manager resulting in the following audit-trail with request message.
Now start SoapUI and create a new project based on the wsdl of the deployed bpel process:
This creates a request message that can be used. to call the BPEL process:

Create a SoapUI Project


As I explained above, the client (our SoapUI setup) will call the BPEL process, and as a result the BPEL process will call back our SoapUI client. This means that we need to create a Test Suite with a Test case with two steps:
  1. Test Request
  2. Mock Service

Create a Test Request

So, in SoapUI create a 'Test Suite' with a 'Test Case' in it. Then the request created/generated above can be dragged and dropped into the Test Case. That will create a initiating Test Request:

Create a Mock response

Now, at this point, you'll need the host name or ip-address of your SoapUI running computer. If your SoaSuite is running on the same machine as SoapUI then you could use localhost. But if it is on another server (being the host of your development or test environment) than localhost won't do of course. Since most development machines use DHCP to get an ip-address automatically this might change. So get the host name of your machine at the System Properties:
(I obfuscated/blurred my hostname since it is a machine at my customer in this example).
With this name you can add a Mock Response step to the testcase:


This will ask you to set the operation to mock. Make sure to set the interface to the HelloWorldCallBackBinding, and the operation to processResponse.
In the port set a free listen port, for example 8989, and the path to "/HelloWorldCallbackBinding/processResponse":

(first set the interface, then the operation above will automatically set to the only one in that interface/binding).
For the path I choose to concatenate the binding-name with the operation-name from the WSDL. These two entries are important since they will make-up the end-point that is mentioned to the BPEL process in the WS-Addressing node as the address it should call to send the response back.

 Edit the WS-Addressing properties of the Test Request

Now it's time to edit the WS-Addressing properties of the Test Request. So open the test request step editor. Then click on the WS-Adressing tab at the bottom of the request message:
You might need to resize the window and drag the splitter between the request and response message panel to the right to see the tab at the bottom of the request pane.

Now you'll see the following tab/panel:


In this tab (see above) edit the following properties:
  • Check the "Enable/Disable WS-A addressing" check box
  • Set the poplist "Must Understand" to true
  • Check  the "Add default WS-A:action" check box
  • In the Reply to field put in the addres:
http://<name of your SoapUI client host>:8989/HelloWorldCallbackBinding/processResponse

Test the Test Case

Now this is in fact al there is to do to get it working. You run the test case and the response message will appear in the response pane of the Mock Response test step:



Conclusion 

As simple as that. Now you can expand your test with assertions and adhoc interactions with your BPEL process or call another with the output of this one. Also it might be handy to use the scripts in my former blogs to write the response to a file in a folder on the file system.

But how would the message adapted with the WS-Addressing node look like? Well that can be investigated  using the HTTP Analyser in JDeveloper. Let me demo that in a next blog.

Wednesday 9 May 2012

SOA Infra starting problems

I'm helping my new customer in migrating an Oracle Forms application to a new 11g databased environment. Since the application is using Oracle Workflow the transition includes replacing Workflow with BPEL11g. So a SoaSuite installation is needed. The installation of the development server is done on a virtual (VMware ESX) Windows 2008 server. Installing Weblogic and SoaSuite and configuring the domain is pretty straighforward. However at starting the server the SOAInfra won't come up. After a while we encountered the following exception in the soa_server.out log:
<26-apr-2012 15:50:34 uur CEST> <Error> <org.springframework.web.context.ContextLoader> <BEA-000000> <Context initialization failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'SensorManager' defined in ServletContext resource [/WEB-INF/fabric-config-core.xml]: Cannot resolve reference to bean 'FabricMesh' while setting bean property 'fabricMesh'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'FabricMesh': FactoryBean threw exception on object creation; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'FabricMeshTarget' defined in ServletContext resource [/WEB-INF/fabric-config.xml]: Cannot resolve reference to bean 'SpringServiceEngine' while setting bean property 'serviceEngines' with key [6]; nested exception is org.springframework.beans.factory.CannotLoadBeanClassException: Error loading class [oracle.integration.platform.blocks.java.SpringServiceEngine] for bean with name 'SpringServiceEngine' defined in ServletContext resource [/WEB-INF/fabric-config.xml]: problem with class file or dependent class; nested exception is java.lang.NoClassDefFoundError: weblogic/sca/api/ScaReferenceProcessor

         at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:275)

         at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:104)

         at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1245)

         at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1010)

         at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:472)

         at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)

         at java.security.AccessController.doPrivileged(Native Method)
   ...
Apparently this is caused by a class not found: "java.lang.NoClassDefFoundError: weblogic/sca/api/ScaReferenceProcessor". We (the administrator Gerrit and me) searched around the forums and eventually found that this was caused by a missing com.oracle.weblogic.sca.engine.jar in the weblogic classpath. From there the solution is quite simple. The jar file is found in the modules folder in the COMMON_COMPONENTS_HOME, eg. in our case "D:\oracle\product\11.1.1\fmw\oracle_common\modules". But apparently in the domain configuration this is missed to be added to the class path in the setDomainEnv.cmd file. So edit this file (setDomainEnv.cmd), which is found in DOMAIN_HOME/bin, in our case: "E:\oracle\admin\domains\soa_domain\bin\setDomainEnv.cmd". At the top of that file you'll find the setting:
set COMMON_COMPONENTS_HOME=D:\oracle\product\11.1.1\fmw\oracle_common
This variable can be used to add the jar file to the classpath. So search in the file to the lines that build up the POST_CLASSPATH variable and add the following line:
set POST_CLASSPATH=%COMMON_COMPONENTS_HOME%\modules\com.oracle.weblogic.sca.engine.jar;%POST_CLASSPATH%
Then (in our case) the SOA_Infra should be able to start. In file E:\oracle\admin\domains\soa_domain\bin\setDomainEnv.cmd By the way, our SOASuite environment was a 11.1.1.6 setup on windows.