rev 2.0 - 10/2009
Contents
REST-Based Interaction with ActiveVOS
About HTTP Headers, Authentication and Security
The "Yahoo News Search Service" Process Proxy
Summary
ActiveVOS REST XML Schema - aeREST.xsd

Exposing and Consuming REST Services

REST-Based Interaction with ActiveVOS

ActiveVOS enables developers to expose processes as Representational State Transfer (REST)-based services as well as to create processes that consume REST services. Using REST, a WSDL interface is not required, but like SOAP-based orchestrations, one-way and synchronous/synchronous request-reply message exchange patterns are supported. And, of course a mix of REST, SOAP, JMS or POJO can be implemented within a single process.

REST is an architectural style that describes how resources are defined and addressed. REST consumers and services communicate over HTTP to exchange representations of resources addressable by a URL. A representation is an XML document with optional attachments of a different content type.

ActiveVOS provides built-in REST capabilities which handle all communication on behalf of the developer. Using ActiveVOS, you can instantiate a process with a request such as: 
http://<server>:<port>/active-bpel/services/REST/simpleNewsSearch?appid=YahooDemo&query=activevos&results=2&language=en

In turn the process can invoke a REST service using a similarly formed URL such as that exposed by the Yahoo News Search Service (see http://developer.yahoo.com/search/news/V1/newsSearch.html ) at:
http://search.yahooapis.com/NewsSearchService/V1/newsSearch?appid=YahooDemo&query=activevos&results=2&language=en.

ActiveVOS generates and receives REST requests on behalf of processes. When a REST request destined for a process is received, ActiveVOS converts the request to a normalized representation that allows a developer to manipulate its content. This mechanism is also used when invoking a REST service. The aeREST.xsd schema (see Appendix) specifies the content of the request, response, and fault messages.

ActiveVOS allows you to specify communication details of a REST request message, including for example, the HTTP method to use, the payload and attachments, and authentication information. The following XML instance document lists the parameters that can be specified.

<ns2:RESTRequest
    xmlns:ns2="http://schemas.activebpel.org/REST/2007/12/01/aeREST.xsd">
    <ns2:subdomain />
    <ns2:method />
    <ns2:pathInfo />
    <ns2:params>
        <ns2:param name="" value="" />
    </ns2:params>
    <ns2:headers>
        <ns2:header name="" value="" />
    </ns2:headers>
    <ns2:payload contentType=""></ns2:payload>
    <ns2:queryString />
    <ns2:authType />
    <ns2:ssl />
    <ns2:contextPath />
    <ns2:requestURI />
</ns2:RESTRequest>

To learn more about these parameters see the "Creating a REST-based Receive or Invoke" section of the ActiveVOS Designer Online Help at Infocenter. To locate the topic, select "Custom Service Interaction" and then "Use a REST-based Service".
Invoking a REST service is similar. In this case, you can specify:

A response returned is presented to the process for manipulation using the RESTResponse structure also specified by aeREST.xsd. For example, invoking the Yahoo News Search Service with query parameters of appid, query, results and language such as those specified by http://search.yahooapis.com/NewsSearchService/V1/newsSearch?appid=YahooDemo&query=activevos&results=2&language=en will return an XML instance document similar to the following:

<RESTResponse xmlns="http://schemas.activebpel.org/REST/2007/12/01/aeREST.xsd"
    statusCode="200">
   <headers>
      <header name="Connection" value="close" />
      <header name="Date" value="Thu,12 Mar 2009 15:33:06 GMT" />
      <header name="Content-Type" value="text/xml;charset=utf-8" />
      <header name="P3P"
          value="policyref=http://p3p.yahoo.com/w3c/p3p.xml,CP=CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA POL HEA PRE GOV" />
      <header name="Transfer-Encoding" value="chunked" />
      <header name="Cache-Control" value="private" />
   </headers>
   <payload contentType="text/xml">
      <ResultSet xmlns="urn:yahoo:yn 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          firstResultPosition="1" totalResultsAvailable="4"
          totalResultsReturned="2"
          xsi:schemaLocation="urn:yahoo:yn" http://api.search.yahoo.com/NewsSearchService/V1/NewsSearchResponse.xsd">
    <Result>
            <Title>Active Endpoints Announces ActiveVOS 6.1</Title>
            <Summary>Active Endpoints announced the general availability
              of ActiveVOS 6.1,  ...</Summary>
            <Url>http://linux.sys-con.com/node/873364</Url>
            <ClickUrl>http://linux.sys-con.com/node/873364</ClickUrl>
            <NewsSource>Linux World</NewsSource>
            <NewsSourceUrl>http://linux.sys-con.com/</NewsSourceUrl>
            <Language>en</Language>
            <PublishDate>1236787926</PublishDate>
            <ModificationDate>1236787926</ModificationDate>
         </Result>

         <Result>
            <Title>Active Endpoints Announces ActiveVOS 6.1</Title>
            <Summary>Active Endpoints, Inc. (www.activevos.com) today
              announced the general availability of ActiveVOS 6.1...</Summary>
            <Url>http://www.ebizq.net/news/11072.html?rss</Url>
            <ClickUrl>http://www.ebizq.net/news/11072.html?rss</ClickUrl>
            <NewsSource>ebizQ.net</NewsSource>
            <NewsSourceUrl>http://www.ebizq.net/</NewsSourceUrl>
            <Language>en</Language>
            <PublishDate>1236695630</PublishDate>
            <ModificationDate>1236695631</ModificationDate>
         </Result>
      </ResultSet>
   </payload>
</RESTResponse>

The content of this response can then be accessed by a developer and processed as needed. 

About HTTP Headers, Authentication and Security

If a REST target requires that specific HTTP headers be sent with the request, the developer can specify these using the wsa:ReferenceParameters element.  This is analogous to the approach ActiveVOS uses for SOAP messages, where an endpoint’s reference parameters are delivered as SOAP headers. 

Developers can specify the name/value pairs sent as HTTP headers using the <param> element defined in the aeREST.xsd. The following example endpoint specifies HTTP headers for "Content-Type" and "User-Agent", sets authentication credentials and sets HTTP transport properties (line wrapping used for readability):


<wsa:EndpointReference xmlns:wsa="http://schemas.xmlsoap.org/ws/2003/03/addressing">
  <wsa:Address>http://search.yahooapis.com:80/NewsSearchService/V1/newsSearch
  </wsa:Address>
  <wsa:ReferenceParameters>
      <param name="Content-Type" value="text/xml" />
      <param name="User-Agent" value="Active Endpoints HTTP Transport" />
   </wsa:ReferenceParameters>
   <wsp:Policy xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
       xmlns:abp="http://schemas.active-endpoints.com/ws/2005/12/policy"
       xmlns:wsu="http://test.activebpel.org/wsdl/policy#BasicAuthCredentials"
       wsu:Id="BasicAuthCredentials">
       <abp:Authentication>
           <abp:User>accountname</abp:User>
           <abp:CleartextPassword>password</abp:CleartextPassword>
           <abp:HTTPPreemptive />
       </abp:Authentication>
       <abp:HTTPTransportOptions
            httpSocketTimeout="15000"
            httpTcpNoDelay="true"
            httpClientConnectionTimeout="10000"
            httpConnectionManagerTimeout="500" />                     
   </wsp:Policy>
</wsa:EndpointReference>



The "Yahoo News Search Service" Process Proxy


Let’s work with a simple process that exposes a REST interface that takes the input query parameters it receives and uses these to subsequently invoke a REST service. The response returned by the REST service is then returned to the caller of the process.

In this example we use the Yahoo News Search Services specified at http://developer.yahoo.com/search/news/V1/newsSearch.html.

Creating a REST Process

Creating a process that exposes the process as a REST service or that consumes REST-based services can be achieved using the same mechanism to create BPEL processes. Select File > New > BPEL process. Provide a file name and then select Next. You will be offered the choice of building the process from a template. Select either the REST Process or REST Process (One-Way) template.

This will have the effect of providing you with a starting point and importing the ActiveVOS System REST aeREST.wsdl service and the aeREST.xsd schema.

If you want to add REST based integration to an existing process, use the RESTPortType’s oneway or requestResponse operation for the REST service you want to consume. Doing so will allow you to interact with the REST service using the same design techniques you use with Web services.

Our Sample *

Let’s get started with the rest-online-tester.bpel sample. 

* Note: a second process is included with this sample that aggregates the results of a keyword search from multiple search engines.

First save one of the sample's archive packages (REST.zip or REST.tar.gz) to your file sytem and unpack it.  Next open the ActiveVOS Designer and import the project in to the workspace by selecting File > Import > General > Existing Projects into Workspace:

Press next, then navigate to the sample's support folder and select it by pressing OK:

Finally, verify that the RESTSamples project is selected (checked) and press Finish: 

Note: if you already have a RESTSamples project in your workspace you need to delete it first.

After the project is added to your workspace navigate to the bpel folder and open the rest-online-tester.bpel process.  Four activities are used as depicted here:

The receiveRESTRequest simply assigns the RESTRequest message construct generated by the ActiveVOS REST service and assigns it to the restRequest variable. Once assigned, this variable contains among other information the parameters submitted in the URL, namely appid=YahooDemo, query=activevos, results=2, and language=en. The following illustration shows the runtime variable instance data.

The second activity in the process, set Dynamic Endpoint, does nothing more than provide the address of the REST service that will be invoked next. Though the address could have been provided in the process deployment descriptor (PDD), specifying it in the process definition makes it explicit, as shown in the example below. Alternatively to make the address configurable at runtime, you could configure a URN mapping from the ActiveVOS console.


<wsa:EndpointReference xmlns:wsa="http://schemas.xmlsoap.org/ws/2003/03/addressing">
   <wsa:Address>http://search.yahooapis.com:80/NewsSearchService/V1/newsSearch
   </wsa:Address>
   <wsa:ReferenceParameters>
    <param name="Content-Type" value="text/xml"/>
   </wsa:ReferenceParameters>
</wsa:EndpointReference>

The Invoke REST Request activity takes as input the restRequest variable and outputs the restResponse variable that is then used directly by the send REST Response activity.

Deploying the Process

Deploying the process is simple. Using the PDD editor you first need to select the partner link of the partner service provider being invoked and declare it as a "REST Services" as depicted in the first screen shot.

The second screen shot depicts how the process is declaratively defined as a REST service using the RESTenabled policy assertion. Other policy assertions such authentication requirements can also be specified.

The following XML shows the policy assertion depicted in the illustration above:

<wsp:Policy xmlns:abp="http://schemas.active-endpoints.com/ws/2005/12/policy" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
  <aep:RESTenabled xmlns:aep="htp://schemas.active-endpoints.com/ws/2005/12/policy" description="A simple Yahoo News rest service">
      <aep:usage>e.g.: http://{host[:port]}/active-bpel/services/REST/simpleNewsSearch
  </aep:usage>
   </aep:RESTenabled>
</wsp:Policy>

Listing the deployed REST-enabled processes

To obtain a listing of REST-enabled processes deployed to your ActiveVOS server, connect to the following URL: http://<host>:<port>/active-bpel/services/REST?>

Invoking the simpleNewsSearch Process

Once deployed to the server, the SimpleNewsSearch process can be invoked from a browser using a URL similar to http://<server>:<port>/active-bpel/services/REST/simpleNewsSearch?appid=YahooDemo&query=nasdaq&results=2&language=en.  The following image shows the  Web browser embedded with ActiveVOS Designer with the results of searching for news about the nasdaq stock exchange.

At runtime, the response returned by the InvokeRESTRequest activity can be observed in the ActiveVOS console as depicted here in the content of the restResponse variable.

To access the content of the response, the developer can simply address the payload element of the RESTResponse structure. In the case of the Yahoo News Search Service, the result of the query returned the response shown in the first section of this document. 

Summary

ActiveVOS enables developers to expose processes as and consume REST services and interact with them using one-way and asynchronous / synchronous request-reply message exchange patterns. 
ActiveVOS makes this possible by using built-in REST capabilities which handles all communications aspects on behalf of the developer.
This sample described a simple process that exposes a REST interface that passes the input query parameters it received onto the Yahoo News Search Services.

ActiveVOS REST XML Schema - aeREST.xsd

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:tns="http://schemas.activebpel.org/REST/2007/12/01/aeREST.xsd"
           elementFormDefault="qualified"
           targetNamespace="http://schemas.activebpel.org/REST/2007/12/01/aeREST.xsd">

    <!-- HTTP Method enumeration used for REST -->
    <xs:simpleType name="httpMethodType">
        <xs:restriction base="xs:string">
            <xs:enumeration value="GET"/>
            <xs:enumeration value="POST"/>
            <xs:enumeration value="PUT"/>
            <xs:enumeration value="DELETE"/>
            <xs:enumeration value="TRACE"/>
            <xs:enumeration value="OPTIONS"/>
        </xs:restriction>
    </xs:simpleType>

    <!-- Error type enumeration used for REST -->
    <xs:simpleType name="errorType">
        <xs:restriction base="xs:string">
            <xs:enumeration value="transport"/>
            <xs:enumeration value="system"/>
        </xs:restriction>
    </xs:simpleType>


    <xs:complexType name="pairType">
        <xs:attribute name="name" type="xs:string"/>
        <xs:attribute name="value" type="xs:string"/>
    </xs:complexType>
   
    <xs:complexType name="paramsType">
        <xs:sequence>
            <xs:element maxOccurs="unbounded" minOccurs="0" name="param" type="tns:pairType"/>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="headersType">
        <xs:sequence>
            <xs:element maxOccurs="unbounded" minOccurs="0" name="header" type="tns:pairType"/>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType mixed="true" name="payloadType">
        <xs:sequence>
            <xs:any minOccurs="0" namespace="##other" processContents="skip"/>
        </xs:sequence>
        <xs:attribute name="contentType" type="xs:string"/>
    </xs:complexType>

    <xs:element name="RESTRequest">
        <xs:complexType>
            <xs:sequence>
                <xs:element minOccurs="0" name="subdomain" type="xs:string"/>
                <xs:element name="method" type="tns:httpMethodType"/>
                <xs:element minOccurs="0" name="pathInfo" type="xs:string"/>
                <xs:element minOccurs="0" name="params" type="tns:paramsType"/>
                <xs:element minOccurs="0" name="headers" type="tns:headersType"/>
                <xs:element minOccurs="0" name="payload" type="tns:payloadType"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:element name="RESTResponse">
        <xs:complexType mixed="true">
            <xs:sequence>
                <xs:element minOccurs="0" name="headers" type="tns:headersType"/>
                <xs:element minOccurs="0" name="payload" type="tns:payloadType"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:element name="RESTFault">
        <xs:complexType>
            <xs:sequence>
                <xs:element maxOccurs="1" minOccurs="1" name="errorCode" type="xs:int"/>
                <xs:element maxOccurs="1" minOccurs="1" name="message" type="xs:string"/>
                <xs:element maxOccurs="1" minOccurs="1" name="messageDetails"
            type="xs:string"/>
            </xs:sequence>
            <xs:attribute name="errorType" type="tns:errorType" use="required"/>
        </xs:complexType>
    </xs:element>
</xs:schema>