Tuesday, January 22, 2013

Generic configuration plan for SOA Suite 11g composite deployments

In order to adapt deployments of SOA Suite 11g composites to specific environments, configuration plans can be used to rewrite the composite.xml file. These configuration plans can be used during deployment by the Oracle supplied ANT scripts. See for example; http://biemond.blogspot.nl/2009/09/deploy-soa-suite-11g-composite.html on how these ANT scripts can be used to deploy composites.

A configuration plan can be generated from the composite.xml file. See figure 41-1 on http://docs.oracle.com/cd/E14571_01/integration.1111/e10224/sca_lifecycle.htm.

When however using the JDeveloper default generated configuration plan per process, adding new references, WSDL files, XSD files, JCA files, imports, properties, etc requires updating the configuration plan. Maintaining the configuration plans can become quite cumbersome when there are a lot of composites, endpoints and regular changes in environments.

As stated in http://www.oracle.com/technetwork/articles/soa/start-small-luttikhuizen-1502916.html; 'Another best practice is to avoid creating a separate configuration plan per composite per environment.'

This led me to want to create such a common configuration plan file which would be composite independent and thus reusable.

Implementation

Usually development is done against a development environment. The processes which are under version control have endpoints and properties specific to the development environment. To make a process specific for other environments, the development references are replaced by for example test references.

I generated a standard configuration plan for a process and made it generally usable. I reduced the standard generated configuration plan to the following (of course the http://dev and http://tst should be replaced with your specific environment);

<?xml version="1.0" encoding="UTF-8"?>
<SOAConfigPlan xmlns:jca="http://platform.integration.oracle/blocks/adapter/fw/metadata"
               xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
               xmlns:orawsp="http://schemas.oracle.com/ws/2006/01/policy"
               xmlns:edl="http://schemas.oracle.com/events/edl"
               xmlns="http://schemas.oracle.com/soa/configplan">
    <composite name="*">
        <import>
            <searchReplace>
                <search>http://dev</search>
                <replace>http://tst</replace>
            </searchReplace>
        </import>
        <reference name="*">
            <binding type="ws">
                <property name="endpointURI">
                    <searchReplace>
                        <search>http://dev</search>
                        <replace>http://tst</replace>
                    </searchReplace>
                </property>
            </binding>
        </reference>
        <reference name="*">
            <binding type="ws">
                <attribute name="location">
                    <searchReplace>
                        <search>http://dev</search>
                        <replace>http://tst</replace>
                    </searchReplace>
                </attribute>
            </binding>
        </reference>
    </composite>
    <wsdlAndSchema name="*">
        <searchReplace>
            <search>http://dev</search>
            <replace>http://tst</replace>
        </searchReplace>
    </wsdlAndSchema>
</SOAConfigPlan>

This configuration plan works composite independent and replaces all imports, references to endpoints and location references and environment references in all WSDL, XSD and JCA files.

Conclusion

Configuration plans are the recommended option to use for making composites environment specific (http://www.oracle.com/technetwork/articles/soa/start-small-luttikhuizen-1502916.html). Efficient use of configuration plans can greatly reduce the work required per process.

The configuration plan as displayed above does not replace BPEL properties which might also be environment specific. To achieve replacing of BPEL properties, the properties should be consistent in name and value among processes. In order to add such replacement code to the configuration plan, you can add properties to your BPEL process, generate a configuration plan, adapt the generated code and add the relevant portion to the generic configuration plan.

You should check if using this configuration plan does what is required by validating it in JDeveloper and checking if all required references are replaced. The danger of not having all references replaced is that messages meant for for example the test environment end up on development or even worse; production messages end up in development. Also message definitions can change among environments. If an XSD from a wrong environment is imported, conflicts can arise.

An alternative for using configuration plans is deploying against localhost. Localhost is a reference to the current machine. When developing for example on a standalone machine, localhost refers to that machine. When the process is deployed on a different server, localhost refers to that different machine. This method has several drawbacks however and is thus not recommended. Questions arise when using such a method;
- How to deal with external services? (especially if they differ amongst environments). Using an abstraction to the actual service endpoints (such as a service registry) can help, but you will undoubtedly encounter other similar issues in this category.
- How to deal with load balancing in a clustered environment? Localhost is the current machine so a process initiated on one machine does not initiate processes on the other machines in the cluster and thus load balancing is limited.

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