Friday, December 19, 2008

Error Handling in Oracle's ESB

This is a re-post of an earlier article I wrote. Any links to the old version will now be busted... Sorry.

In our project, we follow a strict governance process for governing our services. We identify the services and their operations from our Business Process Model, then proceed to producing a WSDL and associated XSDs to represent that service. Only once this is done will we proceed to implementation. This is called top down design and is generally a good thing. By doing this, we end up with a clean design that represents the ideal, pure business requirements, rather than being technology driven as is often the case with bottom up designs. Nothing new here. Sooner or later, the rubber hits the road, and we end up implementing the service using some sort of technology. In a recent case, Oracle’s ESB product was selected as the implementation technology for some entity services that we are developing. It allowed us to provide a SOAP interface to our entities, whilst still preserving transactions and speedy performance by tying into WSIF and Oracle’s optimised message delivery capabilities. So far, everything was looking rosy. Then we got to implementing the fault handling. Now, I think most people would agree that having a variety of different faults for an operation is a good idea. That way, the caller can distinguish between the different types of fault that can happen. In particular, this service had these faults:
  1. PersistenceFault, if there was a general technical fault with the service (e.g. the database was down)
  2. IllegalUpdateFault, if the caller has attempted to modify a field that they shouldn't be.
Now we find a limitation of the ESB product. It turns out that the current version (10.1.3.3) doesn't support operations which can return multiple faults. All products have their limitations, so all we need here is a workaround, right? What are the possible solutions. Here's what we came up with:
  1. Create some sort of XSL mapping the ESB to try and fudge multiple faults: This is impossible, as normally faults would have different messages, and the ESB will only route to one destination message.
  2. Use a common fault type, and distinguish between the different faults using a fault code, either numeric or enumeration based. This will work, but there is no way of including structured data in the fault, as it will need to be generic
  3. Use a common fault type which is a <choice> of the different faults, and get the caller to work out which one it was.
  4. Use a common fault type, and then extend it via XSD methods, and use polymorphism to tell the difference.
Options 3 and 4 are discussed further below:

Option 3.

<xsd:complexType name="SimpleFaultType">

<xsd:sequence>

<xsd:element name="faultstring" type="xsd:string"/>

<xsd:element name="detail" type="xsd:string"/>

</xsd:sequence>

</xsd:complexType>

<xsd:element name="CombinedFault">

<xsd:complexType>

<xsd:choice>

<xsd:element name="PersistenceFailureFault" type="SimpleFaultType"/>

<xsd:element name="IllegalUpdateFault" type="PersistenceFailureFaultType"/>

</xsd:choice>

</xsd:complexType>

</xsd:element>

Option 4.

<xsd:complexType name="BaseFaultType">

<xsd:sequence>

<xsd:element name="faultstring" type="xsd:string"/>

<xsd:element name="detail" type="xsd:string"/>

</xsd:sequence>

</xsd:complexType>

<xsd:complexType name="PersistenceFailureFaultType">

<xsd:complexContent>

<xsd:extension base="BaseFaultType">

<!-- Place additional fields in here -->

</xsd:extension>

</xsd:complexContent>

</xsd:complexType>

<xsd:complexType name="IllegalUpdateFault">

<xsd:complexContent>

<xsd:extension base="BaseFaultType">

<!-- Place additional fields in here -->

</xsd:extension>

</xsd:complexContent>

</xsd:complexType>



Using this approach, the fault message/element in the WSDL will be of type BaseFaultType. The caller can then interrogate the xsi:type attribute to work out exactly which fault has been thrown.

Our entity pattern calls for using the ESB to wrap EJB functionality, and will need to route exceptions back from the EJB into the Core Data Model version of the fault. This will need to preserve any polymorphic faults, which represents additional work both for the java developer and the ESB designer who must write a non-standard XSLT file to map the exceptions. This approach seems quite neat, but it does sacrifice type safety. Unlike Option 3, a consumer looking at a WSDL will not know exactly which faults a web service can throw, as it in theory could throw any of the extensions of the base fault type. Instead, he will need to look at additional documentation (we call this the CSP or Consumer Service Profile) to work out which faults can be thrown by the service. Developer tools such as JDeveloper will also not be able to use wizards to interrogate parts of the fault message, for exactly the same reason. Instead, the developer will need to examine the xsi:type attribute, then copy the XML element into a variable that represents the right fault (this is as close as BPEL gets to casting). If we were to take the xsd:choice approach, then the WSDL would represent all of the fault information in the XSD, and JDeveloper would be able to pick up the types and work with them. In addition to all of this, a special BaseFaultType will need to be added to the Canonical Data Model (CDM). This would not be necessary using Option 3, as the CombinedFault fault used would be specific to each service and be placed in its local namespace.

The Wash Up

Either option 3 or option 4 will work. They are effectively the same solution, but use different mechanisms to shoe horn multiple exceptions into the one message. Due to the enhanced type safety, my position is that Option 3 is the way to go. Either solution is a pain in the butt, for a few reasons. The consumer is going to have to perform logic when a fault occurs to work out which error occurred. This will unnecessarily clutter up our BPEL or Java processes, especially if the different faults have different scopes. For example, we might want to deal with an IllegalUpdateFault within a tight context, but bubble PersistenceFault out to a wider context. The fault handling code in the consumer will need to deal with that. We also sacrifice readability of the interface itself, as it becomes difficult to see which Faults are being thrown where. But the real annoying thing is that now our technology is dictating terms of the interface. We can not participate fully in top down design because our tool doesn't support all of the ways that we may want to shape our WSDL. For something as fundamental as multiple fault handling to be left out is unforgivable in my opinion.

UDDI registries and Mocking

This is a re-post of an earlier article I wrote. Any links will now be busted... Sorry.

UDDI registries provide a number of features. Primarily they are billed as governance mechanisms for enterprises running SOA environments. They also provide endpoint indirection capabilities, which are useful from a governance perspective, but can also be used for testing. This is an extension of the dependency injection pattern, which is commonly used in object oriented programming, into the distributed world. When a developer unit tests he wants to test only his component, and not necessarily the dependencies of his component. This leads to more directed testing, and means that a high level component can be developed in parallel to lower level components, or even before.

By using dependency injection, we can abstract away the dependencies of a component and replace the code that we are calling with an interface which gets updated at run time to point to the implementation that we want: either the real implementation (for production) or a testing stub implementation that suits the test that we are running. This approach is generally called Mocking and is in widespread use throughout the industry.

In the SOA world, our interfaces are WSDLs, so we don’t really need to change our development practices to support dependency injection; all we need is a mechanism. Oracle’s BPEL product provides a test tool that allows the developer to run his orchestration process in a special mode where any invoke/receive step can be replaced by a Mocked response. This is great, but it is not a general solution, and the testing tool has several.... well bugs.... that make it more difficult to use. UDDI registries also provide the capability to indirect endpoints, so they could equally well be used in this regard. It has the advantage of being ubiquitous. Wherever you invoke web services, you can use UDDI. Those endpoints can be changed to point to your mock services, possibly written in SoapUI. What this requires is runtime access to the UDDI server The general process for running a unit test would now be:
  1. Set up your UDDI registry to contain your consumed interface (the target service)
  2. Code and deploy your consumer service to use this UDDI service
  3. Run your unit test
    1. Start up your Mock Service
    2. Update the UDDI endpoint to point to the mock
    3. Run the test code
    4. Restore the UDDI key to its original value (optional)
  4. Report your Results


For this to work correctly your tests must have control over the UDDI server. For the duration of the tests, the endpoints must be set correctly on your UDDI server for the tests to work. If you have multiple developers all working on the same system, this means that they each need their own environment. If a common environment was used, one developer could update the key for a service that another developer was using, thus making the results inconsistent.

Now product licensing rears its ugly head. Commercial products need to be licensed to be used, and most SOA toolsets do not support free licenses for these tools. The thought is that these are enterprise tools and should be charged appropriately. This is unfortunate, as it makes dependency injection and unit testing using services very difficult. JUDDI is an open source implementation of the UDDI v2 specification. In my project we are currently evaluating whether this would be appropriate for use as a dependency injection tool. If it is, then this will be great, but I still don't think its ideal. All products are not created equal, and we will need to perform additional testing to make sure that our system supports our commercial, expensive UDDI registry as well as the free JUDDI. It also means that we are restricted to the most common denominator of functionality between the two products.

Life would be much easier if the SOA tools were freely licensed for development purposes. I'm probably hoping against hope, but to me it makes good business sense. If you let developers use your products for development, they will get used more in production.


Thursday, December 18, 2008

Weight Loss

I'm trying to loose weight, and I'm tracking it using google docs

Here's a graph of my current weight. Due to some google docs charts wierdness, I can't show the actual weight, so you'll have to read 0 as 80, 1 as 81, etc... Hopefully, this graph should change as I update the data. Thats what I'm checking out.



How am I achieving this? Work kindly provides a gym, and has hired personal trainers to come in each day during the lunch break. By going to these I'm managing to drop some weight, plus I'm finding it has some motivational benefits as well. I feel happier in the afternoons and more willing to work with a smile on my face :)

Nobody cares, except for me of course, but insn't blogging the height of narcacism anyway?

I give in

I have run my own blog, on and off, for some time now. I was paying for hosting, and setting up my own wordpress install.

The first one got deleted due to user error (PEBKAC).
The second one got defaced by remarkably funny russians.
The third one had its database corrupted.

I don't care if google has my information any more. You win, its easier to do it this way... oh well.