Chapter One Message Facade An enterprise Java bean client wants to invoke the methods of multiple EJBs within the context of one use case,and doesn't require an immediate response from the server. How can an EJB client invoke the methods of multiple session or entity beans within one transaction,without the need to block and wait for responses from each bean? Especially in large-scale systems,scalability dictates that the business logic of a use case execute separately from that of the client,without requiring the client to wait for the execution to complete.This type of behavior,called asyn- chronous behavior,allows clients to interact with the User Interface(UI)with maximum response times.because they don't need to sit and wait while the use case they initiated executes.This approach allows a large system to scale because use cases can be queued and operated on in a batch,transparent to the user,who instantly moves on to the next part of a UI.Portions of the system that actually execute the use cases can also be scaled up and go through system upgrades if backlogs of queued use cases begin to develop,all without chang- ing the quality or availability of service for the clients. Consider a simple Web-based airline registration system in which a servlet receives a request to reserve a seat for a user for a particular flight.In this scenario,a servlet must register a user with an airline,determine if seats are available on a flight,and if so,reserve a seat for a user,as shown in Figure 1.5. Servlet UserHome Elight findByPrimaryKey(UserPK) Key(airlinePK gisterwithAirline(aUser) areSe reserveSeatFor(aUser) Figure 1.5 Reserve Seat use case
Message Façade An enterprise Java bean client wants to invoke the methods of multiple EJBs within the context of one use case, and doesn’t require an immediate response from the server. How can an EJB client invoke the methods of multiple session or entity beans within one transaction, without the need to block and wait for responses from each bean? * * * Especially in large-scale systems, scalability dictates that the business logic of a use case execute separately from that of the client, without requiring the client to wait for the execution to complete. This type of behavior, called asynchronous behavior, allows clients to interact with the User Interface (UI) with maximum response times, because they don’t need to sit and wait while the use case they initiated executes. This approach allows a large system to scale, because use cases can be queued and operated on in a batch, transparent to the user, who instantly moves on to the next part of a UI. Portions of the system that actually execute the use cases can also be scaled up and go through system upgrades if backlogs of queued use cases begin to develop, all without changing the quality or availability of service for the clients. Consider a simple Web-based airline registration system in which a servlet receives a request to reserve a seat for a user for a particular flight. In this scenario, a servlet must register a user with an airline, determine if seats are available on a flight, and if so, reserve a seat for a user, as shown in Figure 1.5. Figure 1.5 Reserve Seat use case. areSeatsAvailable()areSeatsAvailable() registerWithAirline(aUser)registerWithAirline(aUser) findByPrimaryKey(pk)findByPrimaryKey(pk) areSeatsAvailable() registerWithAirline(aUser) getFlight(flightNum) AirlineHome findByPrimaryKey(pk) findByPrimaryKey(UserPK) Servlet UserHome Airline Flight reserveSeatFor(aUser) findByPrimaryKey(airlinePK) 12 Chapter One
EJB Layer Architectural Patterns 13 In this example,we have a client performing multiple synchronous calls to the server to execute a use case.Each step of the process requires a separate network call and blocking on the part of the client.On a system as massive as an airline reservation application,this bottleneck is obviously unacceptable Furthermore,executing the logic in this fashion reduces the maintainability and reusability of the system and does not provide transaction consistency or isolation for the use case The most common solution is to use the Session Facade pattern.With this pattern,an application creates a layer of session beans that contain business logic to fulfill business use cases.Each session bean performs bulk operations or entity beans or other server -side resources on behalf of the s,in one bulk call,as shown in Figure 1.3 in the Session Facade pattern.Unfortunately, even if the entire use case is wrapped in one Session Facade method,the approach still suffers from several drawbacks: Unacceptable Response Time.A user interacting with a Web site will not stick around for longer than a couple of seconds.The execution of this use case requires a lot of background processing that could span multiple databases on different airline systems.Because the call to the EJB layer is a"synchronous"call,the client would have to block until the entire process has been completed. Unreliable/not fault tolerant.This use case could potentially involve EJBs that are spread out on as many as three separate EJB Server instances and three separate databases(one for users,one for airlines, one for flights).If any one of those servers were down,the entire process would fail,and the user's reservation request would be lost. Even if the servlet layer w vere communicating with only one EJB server the process would fail if the server were down. Using Session Facade solves the problems of coupling,performance,main- tainability,reusability,and consistency,but does not completely solve the problems of response time and reliability.The client still has to block while a complex and time-consuming reservation use case runs.The use case will also fail if the EJB server or any of the systems it relies on is not running at the time the use case is executed. The takeaway point from our discussion is that we need a fault-tolerant server-side abstraction that serves as an intermediary,executing use cases in one call and one transaction (sheltering clients from the complexities of the server-side object model),which doesn't require a cli ent to bl lock and wait for the use case to complete.Message-driven beans are designed just for this. Therefore: Use message-driven beans to create a fault-tolerant,asynchronous facade.Clients should have access to message-driven beans only,not to entity beans
In this example, we have a client performing multiple synchronous calls to the server to execute a use case. Each step of the process requires a separate network call and blocking on the part of the client. On a system as massive as an airline reservation application, this bottleneck is obviously unacceptable. Furthermore, executing the logic in this fashion reduces the maintainability and reusability of the system and does not provide transaction consistency or isolation for the use case. The most common solution is to use the Session Façade pattern. With this pattern, an application creates a layer of session beans that contain business logic to fulfill business use cases. Each session bean performs bulk operations on entity beans or other server-side resources on behalf of the clients, in one bulk call, as shown in Figure 1.3 in the Session Façade pattern. Unfortunately, even if the entire use case is wrapped in one Session Façade method, the approach still suffers from several drawbacks: ■■ Unacceptable Response Time. A user interacting with a Web site will not stick around for longer than a couple of seconds. The execution of this use case requires a lot of background processing that could span multiple databases on different airline systems. Because the call to the EJB layer is a “synchronous” call, the client would have to block until the entire process has been completed. ■■ Unreliable/not fault tolerant. This use case could potentially involve EJBs that are spread out on as many as three separate EJB Server instances and three separate databases (one for users, one for airlines, one for flights). If any one of those servers were down, the entire process would fail, and the user’s reservation request would be lost. Even if the servlet layer were communicating with only one EJB server, the process would fail if the server were down. Using Session Façade solves the problems of coupling, performance, maintainability, reusability, and consistency, but does not completely solve the problems of response time and reliability. The client still has to block while a complex and time-consuming reservation use case runs. The use case will also fail if the EJB server or any of the systems it relies on is not running at the time the use case is executed. The takeaway point from our discussion is that we need a fault-tolerant server-side abstraction that serves as an intermediary, executing use cases in one call and one transaction (sheltering clients from the complexities of the server-side object model), which doesn’t require a client to block and wait for the use case to complete. Message-driven beans are designed just for this. Therefore: Use message-driven beans to create a fault-tolerant, asynchronous façade. Clients should have access to message-driven beans only, not to entity beans. EJB Layer Architectural Patterns 13
Chapter One Using message-driven beans(MDB)as a facade improves upon the Session Facade pattern by adding the capability to execute use cases in an asynchro- nous,fault-tolerant manner.When we use a message facade,the business logic in each of the use cases of an application maps to its own MDB. Consider the previous example.Our business logic for reserving a seat on a flight will now be placed in the onMessage()method on a ReserveSeat message- driven bean.The purpose of this MDB is to encapsulate all business/workflow logic related to reserving a seat on a flight,and to execute asynchronously,as shown in Figure 1.6. Here we have a servlet client creating a Java Message Service (JMS)message and passing in the necessary parameters.The servlet constructs a message containing all the parameters required (user's primary key,flight number,air- line primary key)and sends this message to a JMS destination created for the Reserve Seat use case.Upon receiving the message at the appropriate destina tion,the client will be free to continue (display the next Web page).At this point,the message-driven bean container will attempt to pass the message to the next available ReserveSeat message-driven bean.If all ReserveSeat MDBs in the pool are being used at the time of message reception,the JMS server should wait until the next one becomes available.Had this use case been exe- cuted through a session facade,a fully used session bean pool would have been a single point of failure,and the client would have to manually retry. Once a MDB becomes available,the container will execute the onMessage() method.At this point,the ReserveSeat message-driven bean will linearly go through the process of executing the use case:register the user with the airline, check if seats are available,and reserve a seat.While this time- onsuming process is occurring,the end user is free to surf around the site and go about his or her business. end IMS Me≤sagE Jser areSeatsAvailable reserveSeatFor(aUser) Figure 1.6 Reserve Seat use case through a Message Facade
Using message-driven beans (MDB) as a façade improves upon the Session Façade pattern by adding the capability to execute use cases in an asynchronous, fault-tolerant manner. When we use a message façade, the business logic in each of the use cases of an application maps to its own MDB. Consider the previous example. Our business logic for reserving a seat on a flight will now be placed in the onMessage() method on a ReserveSeat messagedriven bean. The purpose of this MDB is to encapsulate all business/workflow logic related to reserving a seat on a flight, and to execute asynchronously, as shown in Figure 1.6. Here we have a servlet client creating a Java Message Service (JMS) message and passing in the necessary parameters. The servlet constructs a message containing all the parameters required (user’s primary key, flight number, airline primary key) and sends this message to a JMS destination created for the Reserve Seat use case. Upon receiving the message at the appropriate destination, the client will be free to continue (display the next Web page). At this point, the message-driven bean container will attempt to pass the message to the next available ReserveSeat message-driven bean. If all ReserveSeat MDBs in the pool are being used at the time of message reception, the JMS server should wait until the next one becomes available. Had this use case been executed through a session façade, a fully used session bean pool would have been a single point of failure, and the client would have to manually retry. Once a MDB becomes available, the container will execute the onMessage() method. At this point, the ReserveSeat message-driven bean will linearly go through the process of executing the use case: register the user with the airline, check if seats are available, and reserve a seat. While this time-consuming process is occurring, the end user is free to surf around the site and go about his or her business. Figure 1.6 Reserve Seat use case through a Message Façade. findByPrimaryKey(UserPK) registerWithAirline(aUser)registerWithAirline(aUser)registerWithAirline(aUser)registerWithAirline(aUser) areSeatsAvailable() registerWithAirline(aUser) getFlight(flightNum) AirlineHome findByPrimaryKey(UserPK) ReserveSeatMDB JMS Destination send JMS Message Message contains userPK, airlinePK, flightNum on Message() UserHome Airline Flight reserveSeatFor(aUser) Servlet findByPrimaryKey(airlinePK) 14 Chapter One
EJB Layer Architectural Patterns 15 One important advantage that the Message Facade pattern has over the Session Facade pattern is that asychrononously executed use cases can be guaranteed.That is,if the transaction fails at any point(perhaps the airlines's systems go down or some other system failure occurs),the transaction will be rolled back and the JMS message will be put back in the queue.The transaction will then be retried later,without the knowledge of the client. This behind-the-scenes behavior also presents a problem.How is the client to be notified if the use case fails or succeeds?For example,if a seat cannot be reserved because the plane is fully booked,the client needs to be notified.In a synchronous model (using a session facade),the client would know immedi- ately.In the asynchronous model,the client is no longer waiting to see if the use case succeeded,and needs to be alerted in some application-specific form. The most common solution is email.If the use case succeeds/fails then the system will notify the user by email.Some companies might implement a system in such a way that a human being would make a phone call,and so on. If the e application requirements allow it,some applications could usea polling model.That is,an end user will be assigned a particular place they can go to check the status of their request,similar to a tracking number used by modern courier services The takeaway point here is that when using the Message Facade pattern, developers must devise novel ways to communicate the results of a use case to the client. one disadvantag ge of usin ng the Message Facade pattern is that now business logic is distributed across both message-driven beans(for the message facade) and session beans(for the session facade).This may not be a major concern for most,but it would be nice to keep business logic in one place in the applica tion.A clever way to solve this problem is to implement all the use cases on the session facade itself,and use the message facade to delegate to the session facade.This way,all the benefits of using an asynchronous,fault-tolerant construct such as a message-driven bean is maintained,while keeping logic localized to the session bean layer The advantages of the Message Facade pattern include all those outlined in the Session Facade pattern,as well as: Instant response time/asynchronous communication.When a client sends a JMS message,it is free to continue processing without waiting for the server to complete the use case and respond.A lengthy,complex use case can thus be initiated while control flow instantly returns to the user Eliminates single points of failure.Using messaging will ensure that your application continues functioning even if the EJB server or some other subsystem it relies upon is down.For example,if the database is
One important advantage that the Message Façade pattern has over the Session Façade pattern is that asychrononously executed use cases can be guaranteed. That is, if the transaction fails at any point (perhaps the airlines’s systems go down or some other system failure occurs), the transaction will be rolled back and the JMS message will be put back in the queue. The transaction will then be retried later, without the knowledge of the client. This behind-the-scenes behavior also presents a problem. How is the client to be notified if the use case fails or succeeds? For example, if a seat cannot be reserved because the plane is fully booked, the client needs to be notified. In a synchronous model (using a session façade), the client would know immediately. In the asynchronous model, the client is no longer waiting to see if the use case succeeded, and needs to be alerted in some application-specific form. The most common solution is email. If the use case succeeds/fails then the system will notify the user by email. Some companies might implement a system in such a way that a human being would make a phone call, and so on. If the application requirements allow it, some applications could use a polling model. That is, an end user will be assigned a particular place they can go to check the status of their request, similar to a tracking number used by modern courier services. The takeaway point here is that when using the Message Façade pattern, developers must devise novel ways to communicate the results of a use case to the client. One disadvantage of using the Message Façade pattern is that now business logic is distributed across both message-driven beans (for the message façade) and session beans (for the session façade). This may not be a major concern for most, but it would be nice to keep business logic in one place in the application. A clever way to solve this problem is to implement all the use cases on the session façade itself, and use the message façade to delegate to the session façade. This way, all the benefits of using an asynchronous, fault-tolerant construct such as a message-driven bean is maintained, while keeping logic localized to the session bean layer. The advantages of the Message Façade pattern include all those outlined in the Session Façade pattern, as well as: ■■ Instant response time/asynchronous communication. When a client sends a JMS message, it is free to continue processing without waiting for the server to complete the use case and respond. A lengthy, complex use case can thus be initiated while control flow instantly returns to the user. ■■ Eliminates single points of failure. Using messaging will ensure that your application continues functioning even if the EJB server or some other subsystem it relies upon is down. For example, if the database is EJB Layer Architectural Patterns 15
16 Chapter One down,the MDB's transaction will not complete,and the reserve seat message will remain on the queue and be retried later.If the EJB con tainer is down,the message will again be stored.Such fail-over capabil ities would not be possible if we used a synchronous model.Of course if your JMS server is not clustered and it goes down,this still represents a single point of failure,but at least the number of potential show stop- pers is reduced. However,as a by-product of using message-driven beans,the Message Facade pattern also has some drawbacks: Message-driven beans have weakly-typed input parameters.The role of a message-driven bean is to consume JMS messages,all of which appear identical at compile time.This is in contrast tosession/entity beans,which leverage Java's built-in strong typing of the methods and parameters of the remote and local interfaces to catch at compile time.Extra care must be taken by the developer to load a JMS message with the appropriate contents required by its destined MDB. One solution to this problem is to encapsulate all the data from the JMS message into a custom data transfer object,and serialize this object into the MS Message. Message-driven beans do not have any return values.Since MDB invocations are asynchronous,Message Facade cannot be used for use cases that require a return value after execution.Using Message Facade is thus superficially similar to using Session Facade,in which all session bean methods simply return void.However,it is possible to get a response from a message-driven bean back to the message creator by using JMS as the tran sport mechanism,please refer to the book Mastering Enterprise Java Beans,Second Edition for a discussion of this mechanism. Message-driven beans do not propagate exceptions back to clients. Unlike session/entity beans,message-driven beans cannot throw appli- cation exceptions or RemoteException from any of their methods.MDBs must therefore handle all the exceptions presented in some application- specific format(that is,emailing the user if something went wrong logging errors to an admin log,and so on). Message Facade is a very powerful pattern for building decoupled,highly scalable applications.A typical EJB system would likely use a combination of the Session Facade and Message Facade patterns.Session Facade is the clear choice for"read"type operations,where a client requires some data from the server,or when a client needs to explicitly wait for a use case to complete.Mes sage Facade is clear choice for update operations,where the client does not need to instantly see the results of the update
down, the MDB’s transaction will not complete, and the reserve seat message will remain on the queue and be retried later. If the EJB container is down, the message will again be stored. Such fail-over capabilities would not be possible if we used a synchronous model. Of course if your JMS server is not clustered and it goes down, this still represents a single point of failure, but at least the number of potential show stoppers is reduced. However, as a by-product of using message-driven beans, the Message Façade pattern also has some drawbacks: ■■ Message-driven beans have weakly-typed input parameters. The role of a message-driven bean is to consume JMS messages, all of which appear identical at compile time. This is in contrast to session/entity beans, which leverage Java’s built-in strong typing of the methods and parameters of the remote and local interfaces to catch common errors at compile time. Extra care must be taken by the developer to load a JMS message with the appropriate contents required by its destined MDB. One solution to this problem is to encapsulate all the data from the JMS message into a custom data transfer object, and serialize this object into the JMS Message. ■■ Message-driven beans do not have any return values. Since MDB invocations are asynchronous, Message Façade cannot be used for use cases that require a return value after execution. Using Message Façade is thus superficially similar to using Session Façade, in which all session bean methods simply return void. However, it is possible to get a response from a message-driven bean back to the message creator by using JMS as the transport mechanism, please refer to the book Mastering Enterprise Java Beans, Second Edition for a discussion of this mechanism. ■■ Message-driven beans do not propagate exceptions back to clients. Unlike session/entity beans, message-driven beans cannot throw application exceptions or RemoteException from any of their methods. MDBs must therefore handle all the exceptions presented in some applicationspecific format (that is, emailing the user if something went wrong, logging errors to an admin log, and so on). Message Façade is a very powerful pattern for building decoupled, highly scalable applications. A typical EJB system would likely use a combination of the Session Façade and Message Façade patterns. Session Façade is the clear choice for “read” type operations, where a client requires some data from the server, or when a client needs to explicitly wait for a use case to complete. Message Façade is clear choice for update operations, where the client does not need to instantly see the results of the update. 16 Chapter One