Using REST with Oracle Service Bus

Overview

Oracle Service Bus (OSB), the rebranded name for BEA's AquaLogic Service Bus, is one of the products I help customers with frequently.  Recently questions from both customers and internally at Oracle have been increasing about OSB support for REST. In this entry I cover the current and future state of REST support in OSB.

Background

REST can be a loaded term.  There are a couple of InfoQ articles introducing REST and REST Anti-Patterns that should be required reading for those considering a REST architecture.  What does REST support really mean in the context of an Enterprise Service Bus?

A Service Bus applies mediation to both clients and providers of services.  This results in a loosely coupled architecture, as well as other benefits.  Being loosely coupled means that Providers and Consumers can now vary different aspects of a message exchange:

  • Location of Provider/Consumer
  • Transport (Http, Https, JMS, EJB, FTP, Email, etc)
  • Message Format (SOAP, POX - Plain Old Xml, JSON, txt, etc)
  • Invocation Style (Asynchronous, Synchronous)
  • Security (Basic Auth, SSL, Web Service Security, etc)

Two aspects where Service Bus support for REST would apply in an example would be Transport and Message Format.

A Contrived But Realistic Example

orderService

OrderDiagram 

Consider a contrived example where REST support in the Service Bus could easily come up.  Assume an organization already has an Order SOAP based service that is mediated by the Service Bus.  Currently this service is used by several applications from different business units.  SOAP web services with well-known XSD contracts work great for an interchange format for existing systems.  However, there is a new initiative to give management a mobile application to get order status.  The sponsoring executive has heard that AJAX is important and tasked an intern to quickly build the front-end because of frustration with IT delays.  The front-end is quickly mocked up using an AJAX framework and the executive tells the IT staff to deploy it immediately.  The problem is that the client-side AJAX framework doesn't work with SOAP and XML, it was mocked up with JSON.

Instead of developing a second Order Service to support this new invocation style and format, OSB can be configured to mediate both the invocation style and the message format and reuse the perfectly working, tested, provisioned, etc Order Service.  A new proxy could be configured to accept HTTP requests and map them to SOAP over HTTP.  The response, which is normally XML described by XSD, can be converted to JSON.

OSB Capabilities

A common REST approach in practice is the use of HTTP verbs POST, GET, PUT, and DELETE to correspond to the CRUD methods of CREATE, READ, UPDATE, DELETE.  So we can map those verbs to the Order Service, mapping DELETE to cancelOrder since it is against company policy to delete orders from the system.

The HTTP transport for inbound requests (a Proxy) in the Service Bus provides a mechanism to intercept invocations to a user customized URI base path.  So if my server binds to the context "user_configured_path" and localhost and port 7001, then the HTTP Proxy intercepts all HTTP GET and POST calls to http://localhost:7001/user_configured_path .  This includes suffixes to that path such as http://localhost:7001/user_configured_path/foo/bar/etc .

AquaLogic Service Bus 3.0 (as well as 2.x releases of ALSB) supports GET and POST use cases, but does not have developer friendly support for HTTP verbs PUT and DELETE out of the box.  For GET requests, pertinent information is available in the $inbound/ctx:transport/ctx:request/http:relative-URI variable.  To parse query string information, use $inbound/ctx:transport/ctx:request/http:query-string.   A common pattern for HTTP GET is to use XQuery parsing functions on that variable to extract extra path detail, but the $body variable will be empty.  For POST requests, the same applies, but the $body variable may have a message payload submitted as xml, text, or some other format.

I have heard from product management that first class support for HTTP verbs such as PUT and DELETE is planned in the next release of OSB, which is scheduled sometime in the Fall of 2008.  For customers that require PUT and DELETE verb support immediately, OSB does have a transport SDK, which could be used to add inbound and outbound REST support.  That approach would require some development.  There are other inbound options besides the transport SDK, such as a basic approach of deploying an HTTP servlet with doDelete() and doPut() implemented.  This servlet could be deployed on OSB instances and forward to specific proxies to provide PUT and DELETE support.  An outbound option would be to use a java call-out to invoke a REST style provider.

Returning to the example for a moment, the executive dashboard only requires order status in the first release, so only HTTP GET support is necessary.  In the existing SOAP-based Order Service, the interaction looks like this:

orderRR

An equivalent REST-ful URL might look like http://localhost:7001/Order/123 where 123 is the OrderID.  Clients using this interface might expect a JSON response like this:

{
"Status":"Submitted",
"OrderID":"123",
"OrderDetailID":"345",
"CustomerID":"234"
}

Types like int are supported JSON values, although the above value types are strings as you can see by the double quotes.  Let's just assume that strings are ok for now to make this easier.  Here is a proxy configuration bound to the Order URI context:

OrderRESTProxy

Notice that the response type is "text" because we will convert the XML to JSON.  I tried using the JSON java library from json.org to convert xml nodes in the response to a JSON format.  One gotcha is namespace conversion.  For simplicity I tested with xml nodes with no namespaces, and that worked.  That code looks like this: 


org.json.JSONObject j = org.json.XML.toJSONObject( xmlStringBuffer.toString() );
System.out.println( j.toString() );

There are other techniques to convert between XML and JSON that use convention to map namespaces to JSON structures, but that is for another time.  Because my example used real-world xml with namespaces, I used a java callout to loop over child nodes of an XmlObject to build the JSON structure in java code.  Let me know what you think and if you have considered alternative approaches.  I've attached my code artifacts that are completely for illustrative purposes only and worked on my machine with ALSB 3.0 and Workshop 10.2.

For another example that works with currently released versions of Service Bus, check out "The Definitive Guide to SOA - BEA AquaLogic Service Bus" by Jeff Davies.  In the book he has a Command example where a Proxy is used for a service that handles multiple types of commands.  An updated version of the book should be available shortly.

Comments:

Have you taken this concept and tried to use it against a GET REST service? For instance, we are trying to use this information http://forums.bea.com/thread.jspa?threadID=300002837 to register a REST service like Yahoo or Google Maps. Then we want to send a GET Request to a proxy service that passes those params onto the Business Service (which is the Yahoo or Google Maps Endpoint). This hasn't worked at all from the different paths we have used. Any thoughts on how to make your example apply to this? Thanks - jay

Posted by Jay Blanton on August 14, 2008 at 03:04 AM PDT #

Jay, For whatever reason I can't see the old BEA forums right now, it simply times out. Would you mind detailing the scenario or reposting it in the Oracle-hosted forum for OSB and sending me a link? http://forums.oracle.com/forums/forum.jspa?forumID=320 My initial thoughts are that I believe outbound actions from OSB (Publish, Service Callout or Route) are issued with Http POST. I will try and get confirmation from the PM team if the option to use other HTTP verbs will be supported in the OSB 3.1 release, scheduled for the fall. *James Edit* I was able to confirm that the ability to choose the outbound http verb is planned in the upcoming fall release. In the meantime, the only things that come to mind are fairly basic/crude such as using a Java callout to invoke the URL. However, that won't give you the same level of feature support that typical business services have such as load-balancing, etc. Thanks, James

Posted by James Bayer on August 14, 2008 at 03:29 AM PDT #

James, What Modelling tool did you use to design the order gif? I have been looking for some tools for a while now and have not got anywhere as they all seem a bit weak for SOA diagrams. thanks, Damien

Posted by Damien on October 23, 2008 at 05:57 PM PDT #

I'm really somewhat embarrassed to admit that the Service Bus diagram with the proxies is a PowerPoint screenshot. The OrderService Design showing the 4 operations is a screenshot from WebLogic Workshop's web service design view. On another note, the 10gR3 release of ServiceBus with REST support is now officially out, check the OTN page for details and a download. Thanks, James

Posted by James Bayer on October 23, 2008 at 07:05 PM PDT #

James, we have a similar case to Jay's. We'd like to pass param and query string to proxy service vir http GET request and have OSB to router the request to back-end restful services based on URI param and query string. I could not figure out how to do it in OSB? just wonder its doable? Thanks -Fran

Posted by Fran on February 13, 2009 at 03:05 AM PST #

Fran, Additional REST capabilities were added in the 10gR3 release of OSB, that was GA’d after my original blog entry which was done on a previous release (ALSB 3.0). Please See: http://download.oracle.com/docs/cd/E13159_01/osb/docs10gr3/relnotes/relnotes.html#wp1234356 http://download.oracle.com/docs/cd/E13159_01/osb/docs10gr3/httppollertransport/transports.html#wp1083292 I imagine that most scenarios will be supported now. Thanks, James

Posted by James Bayer on February 19, 2009 at 05:24 AM PST #

Hi, I am trying java call out from OSB,i have jar file,When try to call method it shows all static methods only

Posted by linesh on February 23, 2009 at 05:33 PM PST #

Linesh, OSB is stateless, so only static methods are supported by design per the documentation: http://download.oracle.com/docs/cd/E13159_01/osb/docs10gr3/userguide/pojo.html Thanks, James

Posted by James Bayer on February 23, 2009 at 08:43 PM PST #

I'm considering using the OSB for our RESTful service as well. We want to take a GET operation in the form of something like http://OSB_context_url/?param1=5¶m2=farm and then forward this request to multiple REST services using the OSB so that they would go to http://server1_url/?param1=5¶m2=farm and http://server2_url/?param1=5¶m2=farm Would it be possible to do that? We would then take the response xml's from each service and aggregate them into one response xml in the OSB. Also, in terms of caching on the server side, does the OSB have the capability to cache requests and responses? So that if another request of : http://OSB_context_url/?param1=5¶m2=farm came in, then it would just send back a cached response? And if so, is the cache life configurable?

Posted by Jason Kim on March 02, 2009 at 06:45 AM PST #

Hi James! I started from this great post to develop a kind of restfull soa datagrid. Pls, take a look at: http://blogs.oracle.com/woa/2009/04/restify_your_world_and_put_it.html and let me know what you think.

Posted by Emiliano Pecis on April 22, 2009 at 03:55 AM PDT #

Great work Emiliano! I love that it's such a complete example. I've been meaning to write an entry about the improved REST support in 10gR3 of OSB. This really takes it to the next level. I'm looking forward to seeing more. Cheers, James

Posted by James Bayer on April 22, 2009 at 04:02 AM PDT #

Hi James! I had a question about putting the proxy in the middle. Say you take the example in the OSB tutorial of a loan service that sells off loans to another company at x amount. I'm looking in the documentation, and I can't figure out how to set it up to use an external web service. Say I have my SOAP service created in JDeveloper running on WLS, and I want to create a proxy to sit in between that service and that of the bank's service to translate SOAP to REST in between. OSB seems to only accept local WSDLs, how would I use a remote one? Tom

Posted by Tom Kies on June 30, 2009 at 12:40 PM PDT #

I'm going on vacation, so I suggest you send your query to SOA Suite forum for help with the SOA products. It would go something like this: Import WSDL into OSB or Workshop I'm pretty confident you have to import a copy of the remote WSDL into OSB. You can do this in a fairly straightforward manner in either the Browser console or IDE. Something like: System Administration->Import->Resources from URL->URI of the WSDL If the WSDL relies on external XSD's etc, those should be pulled in too. Create a Business Service based off that WSDL Create a Proxy Service based off that business service Now instead of exposing a WSDL file from the proxy, which would be the default for exposing the proxy to SOAP clients, you would want to expose either XML or TEXT depending on the style of REST you are using. Jeff Davies has a really good example with REST with the later release of OSB: http://blogs.oracle.com/jeffdavies/2009/06/restful_services_with_oracle_s_1.html

Posted by James Bayer on June 30, 2009 at 07:53 PM PDT #

We have formed query string and relative uri from xml request in proxy example QS: sessionid=123456&opid=ajoy&port=sim&serviceid=delete&msisdn=20161 example relative uri : gui. relative uri can be either gui or selfcare. Now the web application we are invoking with this query string and relative uri require basic authetication. If relative uri is gui we have to set one set of user name and password and if selfcare we have to use another set of userid and password. Please suggest how to do it.

Posted by Ajoy on November 08, 2009 at 12:14 PM PST #

Ajoy, I would look at the HTTP Transport guide documentation. http://download.oracle.com/docs/cd/E13159_01/osb/docs10gr3/httppollertransport/transports.html#wp1082764 There is a setting on a business service for indicating that the security should be BASIC authentication. You should be able to override those inputs at runtime. If you have questions, post in the SOA Suite forum. http://forums.oracle.com/forums/forum.jspa?forumID=320 Thanks, James

Posted by james.bayer on November 08, 2009 at 08:51 PM PST #

I am trying to create a SOAP proxy for a REST service. I have to send a binary attachment as part of my SOAP request. I tried to use Service Callout to call my REST business service. Even though I receive the attachment as part of the request (I could log $attachments and see it), it is not being sent to the Business Service. I would appreciate your advice. Thanks.

Posted by Ardi on November 25, 2009 at 12:28 AM PST #

Ardi, I have not worked at all with attachments in OSB. A couple of places for you to try and get some help: SOA Suite OTN forum - http://forums.oracle.com/forums/forum.jspa?forumID=320 Jeff Davie's book might have some examples on attachments http://www.amazon.com/Definitive-Guide-SOA-Oracle-Service/dp/1430210575 Oracle Support - Ask support for some advice. Best of luck to you. Thanks, James

Posted by james.bayer on November 28, 2009 at 12:35 AM PST #

Post a Comment:
Comments are closed for this entry.
About

James Bayer Image
I was formerly a Product Manager on the WebLogic Server team based out of Oracle HQ. You can find my new blog at http://iamjambay.com.
Follow Me on Twitter
Oracle WebLogic

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today