Real-World Remoting Application
Let's start the discussion of the sample application with a list of design goals:
Interface-based design: An interface-based design frees the clients from needing to know the implementation details of the remote service. The implementation can change without any modifications in the client code.
Test-driven development: All components in the application should be testable outside the container. The example will use JUnit to write simple unit tests to verify the design of each class as you write the code.
Layered architecture: A layered architecture provides loose coupling, isolation, and flexibility. A typical J2EE application has layers such as user interface (UI), application (or controller), domain (domain model or service), and infrastructure. The sample application has controller, service, and domain layers.
Separation of concerns: Since the remoting function has nothing to do with the business service, the separation of concerns plays an important role in implementing the service.
Lightweight services: The example uses the Spring HTTP Invoker API to implement the remote service. HTTP invoker is very lightweight compared with other component models.
Non-intrusive: Spring is an excellent framework for having a non-intrusive API in business applications. Using techniques such as Aspects and AOP, and design patterns such as Inversion of Control (IoC), Proxy, and Factory patterns, you can encapsulate the implementation details of a business task in the service class and expose only the interface to the clients.
Other than these goals, the example also follows an Agile software development approach in designing and coding the classes for the sample application (click here to download the source code).
Now that you know the design goals of the application, let's discuss the actual business requirements. The sample application is a loan-processing system (loanapp) that customers use to submit applications for home mortgage loans. The business use case for the remoting example is to process the flood certification check for a specified home property. A flood certification check is required for every home loan application to ensure the property is not located in a flood zone. If it is in a flood zone, the homeowner is required to obtain flood insurance by paying a "813 Fee" (813 is the code used to identify the flood certification fee).
Flood maps refer to areas of high, medium, or low risk as "flood hazard zones" and the zones of highest risk as "special flood hazard areas". The properties in high flood risk zones (AE, A, or AO zones) have a one percent chance of flooding in any year and a 26 percent chance of flooding over the life of a 30-year mortgage. Real estate properties in VE or V zones (also high risk) have a one percent chance of flooding in any year and also face hazards associated with coastal storm waves. And the homes in low or moderate flood risk zones (B or C zones) are outside the high-risk zones, where the flood risk is reduced but not removed.
The flood certification check is triggered once the borrower has completed the home loan application and selects an interest rate for the loan amount. A flood check is required before the loan processing and underwriting phases of the mortgage process can begin.
Here are the steps involved in the flood certification check use case:
- The customer completes the loan application, entering details such as borrower name, property name, property address, city, zip code, and loan amount.
- The user selects a loan product and interest rate and locks the loan for a specific period of time (e.g., 30 or 45 days).
- The loanapp program calls a flood certification check based on the property details, such as the address and zip code.
- Based on the client's property zip code, the flood service determines if the specified property is in a flood zone and if it requires flood certification (This call is synchronous, so the client will wait for the response from the service before continuing with the loan application process).
- Once the flood check request comes back, the loan is submitted to an automated underwriting system (AUS) to get the credit history of the borrower as well as the risk assessment of the loan application.
Following the agile development process, the next step is a technical design for the requirements defined. The example uses the following design (classes and methods) to accomplish the requirements in the use case:
- The client class (FloodCertClient) calls the requestFloodCheck() method in the flood controller class (FloodCertController).
- The controller then calls the processFloodCheck() method in the service (FloodCertService) by sending the loan details in the HTTP request.
- The flood service calls the FloodDAO class to access the back-end database and check if the specified property needs the flood certification.
- The DAO returns a result object with the flood certification results, which is passed to the client to display on the Web page.
Since remote services act as the entry points into the business domain model of an enterprise, the design of the service layer as a whole also is very important. Following are some of the general considerations you need to keep in mind when designing remote services:
- Remote call type (Should the remote call be stateless or stateful?)
- Remote call invocation type (Is the call synchronous or asynchronous?)
- Client type (Java, .NET, or some other type of client)
- Operating system (Windows, Unix, or another OS)
- Transactions (Do you need the remote service to be transactional so any database or JMS queue updates made in the service method are committed or rolled back as a single unit of work.)
To fulfill all the requirements for the use case, the sample loan processing application will use the following technologies and frameworks:
- Tomcat 5.5
- Spring 2.0
- Commons HttpClient