Java EE and .NET Interoperability: Integration Strategies, Patterns, and Best Practices
Modern large-scale enterprise applications encompass a multitude of services that have to remain secure, highly available, and scalable to an increasing volume of Internet transactions. In a traditional common e-commerce application, a purchase order request has to be submitted across multiple systems. These can include a warehousing system that tracks goods, an order fulfillment service that manages individual orders, and a CRM system that maps orders to corresponding customer records. The list can vary depending on the business workflow and complexity of the Service Oriented Architecture (SOA). Individual transactions may take minutes, hours, or days to complete; therefore, in most cases the business workflow is executed as part of a long-running asynchronous process. In the context of Java EE and .NET, Figure 10-1 shows asynchronous interactions between components of the Business tier and the back-end resources such as CRM, HR, and other applications. Figure 10-1. Java EE-.NET asynchronous Resource tier integration
Asynchronous integration of the Business Tier with the Resource tier enables the rest of the application logic to execute at a consistent pace. Another benefit of asynchronous integration is that long-running back-end processes do not impact the overall application performance. An ASP.NET application may submit a purchase order to an EJB that processes this request. The EJB makes an asynchronous call, such as a long running query, to the Resource tier and returns an acknowledgement back to the ASP.NET without having to wait for the query to complete. Once the query returns updated, information is rendered on the page. A long-running database transaction does not cause an end user's browser to time out. Web tier performance is not the only advantage of asynchronous processing. A back-end system may go offline due to an internal failure or for maintenance, while incoming requests get queued for offline processing. With asynchronous communication, reliability, availability, and scalability of the Resource tier can be managed independently from the rest of the application components, which makes it easier to meet required SLAs. There are a number of techniques to manage distributed asynchronous processing. A couple of main techniques include callback or notifications and polling, both of which are discussed in Chapter 8, "Asynchronous Web Services Integration." Asynchronous application-to-application integration does not come without some overhead. The request initiating Business tier often has to encompass a sophisticated error-handling mechanism to ensure that the request either returns back, times out, is resubmitted, or an error is propagated up the invocation chain. Managing distributed transactions and executing compensating logic is also quite involved. Different asynchronous integration techniques are covered in Chapter 8, and there is a distributed transaction discussion in Chapter 12, "Managing Distributed Transactions." This chapter sheds some light on asynchronous integration strategies to develop a scalable SOA model. The discussion starts with asynchronous query execution under Java and .NET. Asynchronous Query
In both Java and .NET it is possible to create asynchronous queries by creating a thread pool and using individual threads to make calls to the back-end systems. Details of the Java and .NET threading models are explained in Chapter 8, thus this discussion continues on to the asynchronous queries supported by the ADO.NET. The ADO.NET 2.0 enables asynchronous database programming. The .NET database connection object, SqlConnection, takes a Boolean async parameter indicating the connection type. Setting this parameter to TRue indicates that the connection on which the command executes will be asynchronous, as shown here: String connectionStr= "server=localhost;async=true;uid=sa;psw=admin;database=Warehouse_A" The ADO.NET asynchronous programming model derives from the .NET asynchronous model that spans across the .NET Framework and was introduced earlier in this book. To execute an asynchronous query, the corresponding method is divided into two partsbegin and endjust like the rest of the asynchronous methods in the .NET Framework. The ADO.NET asynchronous method list is a replica of the ADO.NET methods that include ExecuteReader, ExecuteNonQuery, and ExecuteXMLReader. Asynchronous extensions of these methods are shown here: IAsyncResult asyncResult = command.BeginExecuteReader(); ... SQLDataReader reader = command.EndExecuteReader(asyncResult);
The IAsyncResult object encapsulates all necessary components to obtain the query result. The WaitHandle property can be used to wait a certain period of time before polling for a response. When executing multiple queries, one can issue WaitHandle.WaitAll or WaitHandle.WaitAny commands to wait until all or any queries complete. IasyncResult also has the IsCompleted property that is set to true once the operation finishes. Calling the end operation ahead of time turns the call into a synchronous one and blocks until the query is complete. After the query result is retrieved, it is necessary to invoke the end method to avoid leaking system resources. For notification services, the ADO.NET 2.0 SqlNotification API, System.Data.Sql.SqlNotificationRequest, can be used to notify an application of changes [QueryNotifications]. Following are a few strategies on how to leverage asynchronous back-end integration, starting with the Indirect Data Access strategy. |
Категории