Tuesday, January 8, 2013

A JSON HelloWorld BPEL process

Introduction

In several previous posts I've discussed various issues encountered when trying to build a HelloWorld JSON BPEL process. Such as;

Differences between JSON and XML and an example of a simple conversion
- http://javaoraclesoa.blogspot.nl/2012/07/webinterface-restjson-vs-middleware.html

Receiving JSON requests in BPEL by using the SocketAdapter
- http://javaoraclesoa.blogspot.nl/2012/12/receiving-json-requests-in-oracle-bpel.html

A reusable solution for transforming from JSON to XML and back again in order to avoid a mapping layer.
- http://javaoraclesoa.blogspot.nl/2012/12/a-reusable-solution-for-conversion.html

In this post I'm expanding on the above posts and putting the things I've created together to provide a working example of how BPEL and Json can interoperate with each other in a reusable way. In this example I'll show how JSON can be received in BPEL, can be transformed to XML and be edited in BPEL (using XSLT). The result is then transformed back to JSON and returned to the requester.

Implementation

Receiving Json

A JSON message is received by using the SocketAdapter. As mentioned in a previous post, the request and response can be parsed by using XSLT functions. This however is difficult and not safe. For example, the inbound request contains HTTP headers. These headers tell things about the HTTP body. I would have to use XPath functions in order to create an HTTP interpreter. This did not seem the way to go (as concluded before) so I've used a different approach. I've a custom Java class which used Apache HttpComponents (http://hc.apache.org/) to provide the HTTP implementation and parsing of the incoming request. The code can be downloaded at the end of this post.

Editing JSON in BPEL

I've used my previously created Webservice to convert Json to XML and back to Json as described on; http://javaoraclesoa.blogspot.nl/2012/12/a-reusable-solution-for-conversion.html. This way I could do XSLT transformations on XML describing JSON messages and later go back to JSON again when sending the reply.

The result

First I've tested my service by using SOAP UI. The result can be seen below;


Next I looked up my BPEL process in the Fusion Middleware Console


This way you can exactly see what has happened to the JSON code. First it is received. Then it is translated to XML. Next XSLT is used to transform the resulting XML. This resulting XML is transformed back to JSON and the result is replied to the caller.

I've also tried opening the service in a webbrowser with the expected result (a normal GET HTTP request doesn't contain a body);


Performance

Sometimes stories are told about poor performance of BPEL and the large overhead incurred by using SOAP and XML. Since I was curious about this (claims should of course be tested!) I've done a small measure on my HelloWorldJSONBPEL service;


As can be seen in the screenshot above, 68ms is the average response time under high load. This was however not an optimized process on development audit logging running on a server in a virtual machine on my desktop. This performance does not surprise or worry me, I can however imagine that a plain Java servlet receiving/replying JSON is faster. I've not created such a servlet to test this. In plain Java however you won't be able to use some of the advanced monitoring tools of the SOA Suite.

Conclusion

Reusable interoperability between JSON and XML is possible. It requires however some work and figuring out. Also if you want to use different endpoints on the same port, some routing is required based on the status line in the HttpRequest. Security is also an issue. If you want to secure the SocketAdapter port you can implement HTTP classes which support authentication mechanisms or you can use for example a service bus to provide this functionality. It requires some tweaking though.

Something I'm not happy about is the sending of the HTTP response. I'm still manually providing HTTP header lines. This should not be needed when working with the Apache HttpComponents.

An expectation is that the 12c release of the SOA Suite which will be released somewhere half 2013 will contain better JSON support. Also see http://technology.amis.nl/wp-content/uploads/2012/11/AMIS-Whitepaper-OOW-2012.pdf. This would render custom implementations obsolete if the implementation provided in that release is sufficient.

You can download the complete sample project here; https://dl.dropbox.com/u/6693935/blog/JsonExample.zip

11 comments:

  1. Hi Marteen,

    Thanks for this blogpost, could you please explain how to test this process from SOAP UI. I dont see any option to test this service from em console.

    Thanks,
    Surya.

    ReplyDelete
    Replies
    1. At the following link there are screenshots on how to test the service in SOAP UI; http://dl.dropbox.com/u/6693935/blog/rest.zip. You can find the port by looking at the SocketAdapter configuration in the Weblogic console (under deployments). An example test message is shown as the first screenshot in this blogpost.

      Delete
  2. Hi Marteen,

    Thanks a lot for sharing the screenshots , I have a couple of questions,

    1. Should I give the hostname of the box where SOA server is running in SOAPUI or will it be localhost always for inbound testing?

    2. Should I set KeepAlive to true.

    Thanks,
    Surya.

    ReplyDelete
  3. Hi Marteen,

    I have followed the same steps as suggested by you in SOAP UI, however I am getting the following error from the soa server where the bpel process is deployed.

    Error while trying to retrieve the URL: http://:12110/test where host is the hostname of the server where BPEL process is deployed to and where I configured the Socket Adapter.

    Also, could you please explain as to why we have to append "/test" at the end of the URL?

    Thanks a lot.

    Regards,
    Surya.

    ReplyDelete
  4. Hi Marteen,

    Could you please clarify that after configuring the socket adapter in the admin console on the port 1211 and telnet the application server on 12110, its give me "cannot connect" error.

    Should telnet work in this case? I feel that as the reason for the error I am facing.

    Thanks.

    ReplyDelete
  5. I will get back to the above questions as soon as I have the time. In the URL, the /test part is not required but doesn't hurt either. It can be used for example for routing if you want to provide different services on the same port.

    ReplyDelete
  6. Hmmh. At the risk of sounding rude, I would suggest that whenever one converts JSON to XML for processing, something is wrong. Would it not rather make sure to use data-binding separately -- many frameworks already allow this (Jackson and Moxy)?
    I am not just worried about performance (which will be sub-standard with transformations), but also correctness, convenience.

    ReplyDelete
    Replies
    1. In my opinion, there are several use-cases for converting JSON to XML or the other way around.

      - When BPEL is used for orchestration of REST/JSON services and orchestration depends on message content. Instead of calling out to services to get specific parts of the message, it is more efficient to convert the entire message at once.
      - BPEL provides integration options in the form of adapters (https://java.net/projects/oraclesoasuite11g/pages/Adapters). These adapters are called with XML messages and can be configured in JDeveloper by using wizards (mostly zero coding). Converting JSON to XML or the other way around allows usage of these adapters
      - The Oracle SOA Suite infrastructure provides several additional options when comparing to a plain Java implementation (I might misunderstand the 'use data-binding separately' here. if so, please correct me) such as options for fault management, audit logging, message sensors and others.

      I've used Jackson in the webservice in the example for the data binding. Jackson allows conversion of JSON objects to XML but this does not work perfectly in my experience. Also it is unsure to which XSD the resulting object will conform, which might provide difficulties during further processing of the message. Admittedly, the code I've used for the conversion can be improved, but the transformation is reversible and predictable.

      Delete
    2. The following might be interesting. I've compared different methods of Java embedding. For JSON queries I usually use the XPath expression now; http://javaoraclesoa.blogspot.nl/2013/06/bpel-and-java-comparison-of-different.html

      Delete
  7. Hello..I have tried to compile and execute JSONExample project but I get an error
    package oracle.tip.pc.services.translation.util doesnt exist.Cannot find ICustomParser object in HTTPRequestReply.java.Please let me know where to get that package from.Thanks

    ReplyDelete
    Replies
    1. Hello,

      The ICustomParser interface files are in the bpm-infra.jar file. This jar file is available in the following directory: $SOA_ORACLE_HOME/soa/modules/oracle.soa.fabric_11.1.1

      See the following for more information on implementing this class: http://docs.oracle.com/cd/E21764_01/integration.1111/e10231/adptr_sock.htm

      With kind regards,
      Maarten

      Delete