Friday, 8 June 2012

Subversion Id in your SOASuite service

Wouldn't it be nice to see what particular version you have deployed on your SOASuite test or production environment. How often does it occur that you thought you solved a problem but it still does not work on test or production. And after doing loads of tests and investigation you encounter that not the version you expected was deployed?

This week I tried to add the svn Id keyword in a piece of comments in the WSDL of the service. But it turns out that at deployment the SOASuite filters out the comments. So that won't work.
But since I'm writing this blog you might expect I found a trick...

First add the svn keywords  to the files you want to have the properties in. In this particular case it would be the service wsdl. This can be done with Tortoise SVN by right clicking the file, and choose TortoiseSVN->Properties. Then clicking the new button you can choose for Keywords:


 After that you can check the SVN properties you like to use. For most cases ID gives you all the info you need.
 Clicking OK will get you back to the properties screen, where you'll see:

Mark that in the list of checkboxes the Id-keyword is all in capitals, while in the comma-seperated list of keywords in the properties pane, the Id-property is in the correct spelling (one capital I).
The trick is to add the property as a namespace declaration as:
  xmlns:svnid="$Id$"
  xmlns:version="1.1"


After a SVN-commit this will expand to:
  xmlns:svnid="$Id: ImportEquipment.wsdl 765 2012-06-08 13:07:10Z makker $"
  xmlns:version="1.1"
Like such:

The reason I added a "version" namespace as well is that your wsdl will not change every time the service changes. Often you change a bit of BPEL or XSL or something like that, while your interface, the wsdl, stays unchanged. To force SVN increase the revisionid in your wsdl, you can change the xmlns:version namespace.

Thursday, 7 June 2012

Delete svn subfolders

Here and there migrate/upgrade projects for SoaSuite10g to SoaSuite11g are running. Most of the time the source is committed to Subversion. It turns out that JDeveloper makes a full copy of the project folder at upgrade.
This means that also the .svn folders are copied. And you probably don't want that. I would have the new project in a different branch in my subversion folder.

At a former customer there was a registry file that creates a menu item in the Windows explorer pop-up menu. This would hierarchically delete all .svn folders in the selected folder. But not allways you're able to install such a shell-command.

So I created a little ant script. Since we're working with JDeveloper11g, we have an Ant install. I also created a windows bat file to run the ant script with a folder that can be given as a command line parameter.

The build.xml:
<?xml version="1.0" encoding="windows-1252" ?>
<project default="run">
  <target name="run">
    <tstamp/>
    <property environment="env"/>
    <property name="scan.folder" value="${env.SCAN_FOLDER}" />
    <!--<property file="./build.properties"/>-->
    <echo message="Delete all .svn from ${scan.folder}"></echo>
    <delete includeemptydirs="true"  verbose="true">
      <fileset dir="${scan.folder}" includes="**/.svn/**,**/.svn" defaultexcludes="false"/>
    </delete>
  </target>
</project>
The fileset in the delete can be found as an example in the doc of the Ant Delete Task. However, I found that the example did not work as such, for .svn folders with content. So I expanded the includes property to "**/.svn/**,**/.svn" to delete the content of .svn folders, before deleting them.
I set the verbose attribute, to see which folders/files are actually deleted.

The delete deleteSVNFolders.bat file is:
@echo off
cls
set ORACLE_HOME=d:\oracle\Product\JDeveloper11116\Middleware
set ANT_HOME=%ORACLE_HOME%\jdeveloper\ant
set PATH=%ANT_HOME%\bin;%PATH%
set JAVA_HOME=%ORACLE_HOME%\jdk160_24
set SCAN_FOLDER=%1
ant

You'll have have to change the ORACLE_HOME setting to point to your JDeveloper middleware home.
Of course this works on linux as well, but than you'll have to transform the bat file to a bash script. But that's no rocket science...

Monday, 4 June 2012

Using MDS in SOASuite11g Projects

In a SOA application there will be many services that are dependent on each other. Naturally one would develop a service, deploy it to a server and in a next service refer to that deployed service. That means that in the new project a reference is created based on a concrete WSDL that resides on a remote server. Often the WSDL and related XSD’s are copied to the referencing project. This causes several copies of basically the same XSD and WSDL throughout the whole SOA application system. Maintaining these xsd’s is a tedious job. At compilation of a project the server delivering the deployed service should be up and running. And at the end the deployment of the whole application to a new server (System Test, Acceptance Test, Production) is constrained in the order of deploying the different components of the application.

The solution in SOASuite 11g is to use the Meta Data Store (MDS). There are a few blog-entries on how to relate to XSD’s/WSDL’s in the MDS on the server and how to synchronize the XSD’s and WSDL’s. For a good starting point the following two blog entries are helpful:
However, these blog entries don’t provide an overall description on how to setup your project/application for using the MDS. Also these entries don’t show how to relate the application to a shared local “MDS” folder elsewhere besides in the Jdeveloper install folder. In a regular project you would place the artifacts in a subversion (SVN) server. So the references to the XSD’s and WSDL’s would be to a folder structure in the SVN working copy and that won’t (should not) reside in the Jdeveloper install folder.
That leaves me to tie the pieces together. So I created a demo application to work-out the details and wrote a whitepaper about it. You can download the whitepaper from our site.

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.