Practical Enterprise Service Bus Use Cases for SOA
Pages: 1, 2, 3

Use Case 3: Handling complex and dynamic Web service data validation requirements

In a non-ESB Web service environment, validation of incoming SOAP requests must be included in the service implementation layer either as part of a handler chain or embedded within the service itself. Here are some things to consider with these approaches:

  • Since service consumers directly bind to the service layer, all requests, whether valid or invalid, will invoke the actual service implementation.
  • Implementing data validation as part of the incoming request handler chain provides a separation of the validation logic from the business logic but tightly couples the application to a particular SOAP stack because of the lack of portability of Web service handlers.
  • Including data validation within the service implementation is not desirable because it unnecessarily increases the complexity of the application by embedding the validation logic with the business logic. Since the validation rules are dynamic and expected to change, it would be necessary in this scenario to redeploy a new version of the application to affect the changes to validation rules.
  • If data validation is deployed at the service implementation layer, it is difficult to reuse the data validation components without duplicating source code and/or a deployment. Since the ubiquitous nature of XML Schema lends itself toward reuse, it is logical for data validation to be developed as a decoupled and reusable application component.

With an ESB Web service environment, it is possible to perform data validation at the ESB layer; by doing so, validation logic is separated from business logic and the service implementation is insulated from dynamically changing validation requirements. From a deployment perspective the use of an ESB has the added benefit of being able to reject invalid requests without invoking the actual service implementation. Therefore, the service implementation layer will not be forced to handle the load of invalid requests.

For the sake of this example, let's assume the validation requirements include a number of validation rules that cannot be expressed simply with XML Schema and it is expected that the validation rules will need to be updated at a higher frequency than the application. Let's consider a Web service request and response messages that are defined by the XML schema elements below:

<xs:element name="purchaseLoanRequest">

  <xs:complexType>

    <xs:sequence>

      <xs:element name="loanAmount" 

      type="xs:decimal" />

      <xs:element name="interestRate" 

      type="xs:decimal" />

    </xs:sequence>

  </xs:complexType>

</xs:element>

<xs:element name="purchaseLoanResponse" 

type="xs:anyType" />

<xs:element name="validationResponse">

  <xs:complexType>

    <xs:sequence>

      <xs:element name="passedValidation" 

      type="xs:boolean" />

      <xs:element name="validationErrors" 

      type="tns:validationErrorType" />

    </xs:sequence>

  </xs:complexType>

</xs:element>

<xs:complexType name="validationErrorType">

  <xs:sequence>

    <xs:element name="message" type="xs:string" />

    <xs:element name="targetElement" 

    type="xs:string" />

  </xs:sequence>

</xs:complexType>

In the above XML schema snippet, you'll notice there are request and response messages defined for the purchaseLoan operation. Notice the response is defined as an xs:anyType and there is a definition for a validationResponse. This response type will be returned if incoming data fails validation.

For the purposes of this example, let's consider a validation rule that states if the loanAmount is less than $250,000, then the interestRate of the loan must be greater than 5%.

This business rule can be implemented by configuring the Message Flow of a Proxy Service. The high-level steps to implement this solution are described below. If you wish to view the completed configuration in full detail, import use-case-3.jar into your ALSB domain and view the configuration through the service bus console.

  1. Upload the Loan Service WSDL document.
  2. Create a Proxy Service based on the Loan Service WSDL definition.
  3. Configure the Message Flow of the Loan Service as follows:
    1. Add a Pipeline Pair and add a Stage to the Request Pipeline
    2. In the new Request Stage, create an If-Then action with the following XQuery condition:
      $body/loan:purchaseLoanRequest/loan:loanAmount < 250000 
      
      and 
      
      $body/loan:purchaseLoanRequest/loan:interestRate <= 5
      
    3. In the Then execution block, add an Assign action that assigns
      <passedValidation>false</passedValidation>
      
      to variable passedValidation.
    4. In the Then execution block, add an Assign action that assigns
      <loan:validationResponse>
      
          <loan:passedValidation>false</loan:passedValidation>
      
          <loan:validationErrors>
      
          <loan:message>
      
             Interest Rate must be higher than 
      
             5% for loans less than 250,000
      
          </loan:message>
      
          <loan:targetElement>
      
             {fn:node-name($body/loan:validationRequest/loan:interestRate)}
      
          </loan:targetElement>
      
          </loan:validationErrors>
      
      </loan:validationResponse>
      
      to variable validationError.
    5. Create a Branch Node that follows the Pipeline Pair.
    6. Add a path named Failed Validation to the Branch Node by associating it with the condition.
      passedValidation = "false"
      
  4. Edit the newly created Failed Validation path.
    1. Add a Pipeline Pair.
    2. On the Response Pipeline, add a Stage called Generate Validation Error Response.
    3. Within the new Stage, add a Replace Action defined as: Replace node contents of . in variable body with $validationError.

Figure 6
Figure 6. The Loan Service Message Flow

Figure 7
Figure 7. The Failed Validation Branch Node Message Flow

Figure 6 and Figure 7 show the implementation of a simple business rule in the ESB layer. This is a viable strategy for handling simple Boolean comparisons through XQuery expressions. If a more complex business rules implementation is necessary, the ESB layer can be configured to perform a Web service callout to an external business rules implementation and handle the routing of the rules evaluation results in a similar fashion.

Summary

After gaining some experience with ALSB through the use cases and the solutions discussed in this article, the ALSB interpretation of an ESB becomes apparent. Each of the use cases described in the article involves the ALSB providing, though configuration, an "aspect" of a web service in a similar way that aspects are defined in Aspect-Oriented Programming:

  • Use Case 1 - Transport Security
  • Use Case 2 - Messaging Pattern
  • Use Case 3 - Data Validation

In addition to the aspects discussed in this article, an ESB could certainly handle other aspects such as monitoring, message-level security, data mediation, and transactions.

By utilizing an ESB to provide and implement these aspects, the Web service implementation layer can be enriched with a great deal of functionality with a minimal amount of development effort. The abstraction of these Web service aspects at the ESB layer allows for a Web service implementation to focus solely on implementing business logic, greatly simplifying the complexity of the implementation. As additional Web service standards become finalized, ESB products will be able to provide support for a larger set of Web service aspects, thereby increasing the overall value of an ESB in an enterprise.

Kenny Shin is an independent consultant based in the Washington, DC metro area.