« June 4, 2007 | Main | June 8, 2007 »

June 6, 2007 Archives

June 6, 2007

Diving for Perls with WSIF

Talking to Perl from BPEL

or WSIF HTTP Bindings

Earlier this week I was asked how to call Perl from BPEL.  My first inclination was to use a <bpelx:exec> to embed some Java and then in Java use Runtime.getRuntime().exec() to invoke a Perl script.  A little more thought came up with a better solution.  Perl is usually used as part of a cgi solution so why not us WSIF to create an HTTP binding.  Lets look at this solution.

The Perl Script

Not being a Perl guru I created a tremendously unsophisticated Perl script
#!/usr/bin/perl
use strict;
use CGI;
my $cgi = CGI::new();
print $cgi->header(-type => "text/xml; charset=utf-8");
print <<XML;
<?xml version= '1.0' encoding= 'UTF-8' ?>
<response xmlns="http://perl.antony.blog">
XML
print "  <name>Hello " . $cgi->param('name') . "</name>";
print <<XML
</response>
XML
This just takes the parameter "name" passed into the script and creates an XML document response that conforms to the following schema
<?xml version="1.0" encoding="windows-1252" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns="http://perl.antony.blog"
            targetNamespace="http://perl.antony.blog"
            elementFormDefault="qualified">
      <xsd:element name="name" nillable="true" type="xsd:string" />
      <xsd:element name="response">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element ref="name"/>
            </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
</xsd:schema>
To deploy the Perl script I dropped it into the $ORACLE_HOME/Apache/Apache/cgi-bin directory of Oracle App server which by default will run Perl scripts in this directory.
A sample query may be "http://localhost/perl/helloParamXML.pl?name=Jackson%20Franklin"  This produces the following XML document
<?xml version= '1.0' encoding= 'UTF-8' ?>
<response xmlns="http://perl.antony.blog">
  <name>Hello Jackson Franklin</name>
</response>
So now I had a sample Perl script.  The next step was to create a WSIF wrapper for the Perl service.

Wrapping Up an HTTP GET in WSIF

WSIF enables us to create a WSDL description with non-SOAP bindings.  In this case I wanted to create a HTTP GET binding.  There just happens to be an example of this in the BPEL Process manager samples at $ORACLE_HOME/bpel/samples/tutorials/702.Bindings/HTTPBinding/HTTPBindingSample/bpel/QuoteService.wsdl.
I used this a a template to create my own WSIF.  Here is the WSIF I created.
<?xml version="1.0" encoding="utf-8"?>
<definitions
xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://perl.antony.blog"
xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
xmlns:plnk="http://schemas.xmlsoap.org/ws/2003/05/partner-link/"
targetNamespace="http://perl.antony.blog"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:perl="http://perl.antony.blog">
I didn't check all the definitions to see if they were all needed.  The changes I made from the sample are highlighted.
    <types>
        <schema xmlns="http://www.w3.org/2001/XMLSchema">
    <xsd:import schemaLocation="PerlSchema.xsd"
                namespace="http://perl.antony.blog"/>
        </schema>
    </types>
Message types are imported from a seperate XSD, I find this makes it cleaner and easier to modify the schema because the same schema can be used in multiple places.
  <message name="CallPerlRequest">
    <part name="name" type="xsd:string" />
  </message>
This is the input message and will later be bound onto a HTTP GET request.   It consists of a single string.  Multiple parameters would be entered as multiple parts.  If a complex XML type or document is the input then it would be better to map onto a POST request and enter the XML document as the value of a an input parameter.
  <message name="CallPerlResponse">
    <part name="Body" element="perl:response" />
  </message>
This is the response message and is the XML document returned by the Perl service.
  <portType name="PerlHttpGet">
    <operation name="CallPerl">
      <input message="tns:CallPerlRequest" />
      <output message="tns:CallPerlResponse" />
    </operation>
  </portType>
Having set up the Port Type now need to bind the service onto an HTTP GET Request
  <binding name="PerlHttpGet" type="tns:PerlHttpGet">
    <http:binding verb="GET" />
    <operation name="CallPerl">
      <http:operation location="/perl/helloParamXML.pl" />
      <input>
        <http:urlEncoded />
      </input>
      <output>
        <mime:mimeXml part="Body" />
      </output>
    </operation>
  </binding>
The binding maps the operation onto a URL path and species that the input message is mapped onto HTTP URL encoded parameters and the response is an XML document.
  <service name="HelloPerl">
    <port name="PerlHttpGet" binding="tns:PerlHttpGet">
      <http:address location="http://localhost" />
    </port>
  </service>
  The service binding identifies the server providing this service.
  <plnk:partnerLinkType name="HelloPerlService">
    <plnk:role name="HelloPerlServiceProvider">
      <plnk:portType name="tns:PerlHttpGet"/>
    </plnk:role>
  </plnk:partnerLinkType> 
</definitions>
The WSIF descriptor is finished off by adding a partner link for use by BPEL.

Putting it to Work

We can now use our new Perl service directly from BPEL, just as we would any other web service.  As you can see from the above the process to create an HTTP WSIF is pretty straightforward.  It would be nice if the Designer could do that for you ut it doesn't, although it can create WSIF for Java services.  Obviously this approach is not limited to Perl but can be used with any service that takes HTTP requests and returns an XML document as the response.

About June 2007

This page contains all entries posted to Antony Reynolds' Blog in June 2007. They are listed from oldest to newest.

June 4, 2007 is the previous archive.

June 8, 2007 is the next archive.

Many more can be found on the main index page or by looking through the archives.

Powered by
Movable Type and Oracle