E++: A pattern language for J2EE applications, Part 2

Weave the design patterns together

1 2 3 Page 2
Page 2 of 3

According the Layered Architecture, you need an unified entry point to the EJB tier.

The problem

Since you have an EJB controller as single entry point for the EJB tier, is it really necessary to have this layer?

The forces

If you support a user-intensive J2EE production system, you may have encountered unrepeatable exceptions from the EJB tier. The problem could stem from concurrent access to EJBs. EJB 1.1 spec handles EJB concurrent access by asking EJBs to throw an EJBException to their container when they are accessed concurrently. This might result in exceptions for legitimate access requests at user-intensive time.

The solution

As our solution, we turn to the EJB Facade pattern, shown in Figure 4. I've called it a facade because, as the unified interface to access the EJB tier, it performs an important synchronization task. Since each cross-tier EJB access-method is synchronized, it guarantees that the event-based control mechanism works well in any user-intensive and concurrent-access situation.

The EJB Facade also simplifies cluster deployment in a production environment, since it is the only linkage between the Web tier and the EJB tier. When you deploy the EJB tier on a machine other than the one on which the Web tier runs, you need to make minimal changes on the EJB Facade. Indeed, often you need to change only its JNDI lookup.

Pattern name: EJB Controller

Context

At the EJB tier, you need a unique stateful object to act on a specific user's behavior to coordinate the user's application models.

The problem

What type of EJB should we use as an EJB controller?

The forces

There has been some debate as to whether or not we should keep application state information on the EJB tier. I believe, given an n-tier architecture, that it's not sufficient to keep a user's state exclusively on the Web tier. Indeed, placing a user's state on the EJB tier enhances application performance and EJB accessibility because a stateful session EJB's instance variables serve as an ideal means for nonpersistent caching.

The solution

With the EJB Controller, the EJB accepts all event handling tasks and provides model information to the client side or other EJBs. As a stateful session EJB, it represents the user on the EJB tier and manages the model EJBs' lifecycles. Although stateful EJBs prove expensive in performance terms, EJB Controller represents the classic case for when to employ them. Each EJB Controller possesses a State Machine object to delegate all processing commands. Moreover, it keeps an EJB registration so that clients can quickly access EJB models. When the session ends, it should invalidate all the cached objects by marking them for garbage collection. Keep in mind that vendors implement EJB containers differently in setting EJBContex, a fact that may influence your EJB Controller. You'll find the EJB Controller's UML diagram in Figure 6.

Figure 6. The EJB Controller

Pattern name: State Machine

Context

You need a pattern to change any or all application models in a generic, reusable fashion.

The problem

How do you change or update application state in a reusable way?

The forces

Given that the state machine is a generic state-processing object, you need to keep the machine from directly referring to application-specific components. With that in mind, the State Machine pattern takes client requests, then changes or updates the application models. Further, it keeps a state map to track down a user's specific application state. It typically manipulates the cached application states via help objects.

The solution

To process individual events, E++ employs the Command pattern. The machine keeps a model HashMap to accommodate all possible model changes. The State Machine's UML diagram is shown in Figure 6. State Machine leverages the JNDI directory server to discover specific handlers, provided by application programmers. Moreover, it keeps a Handler HashMap to achieve better performance by caching used handlers.

The State Machine keeps the machine instance in the EJB Controller. When the EJB Controller is being moved, the controller should, by assigning it to null, make the State Machine eligible for garbage collection.

Pattern name: Scheduler

Context

Under the REAI architecture pattern, your components need to start or schedule B2B tasks.

The problem

How do you design the B2B scheduler such that it provides a generic mechanism to start your B2B tasks, and implements specific handlers without changing codes?

The forces

You can start B2B tasks in two ways: directly initiated from B2C method invocations, or from a B2B scheduler. If the B2B-related query requires a realtime response and the B2B connectivity is efficient, go with the former approach. With that approach, the entire interactive process holds off while it awaits responses from the backends.

In most B2B integration cases it is not necessary or possible to have a realtime response. Keep in mind that holding backend connectivity for a response increases network traffic, possibly sparking user frustration.

The solution

As an alternate, more flexible solution, you can employ the Scheduler pattern to start your B2B tasks. As shown in Figure 7, the Scheduler instantiates with knowledge of the Dispatcher and RuleEngine patterns. The Scheduler, a Java thread, executes the B2B tasks. When running, it loads the available B2B Events into the B2BEvent HashMap.

Each event possesses an associated B2BTaskHandler to take information from the event. The handlers implement the Runable interface to associate them with threads. They can also be executed independently from each other. To improve application performance, you should also prioritize each task.

If a task fails, the main thread and other tasks will execute continuously. One advantage over other solutions: with the Scheduler pattern, you can start B2B tasks systematically in a well-organized fashion, as well as decouple one task from another. I'm not suggesting that you bypass problems; rather, if a handler cannot fulfill its tasks, it should notify the B2B administrator by resetting the B2Bevent task status. You can discover B2BTaskHandler through JNDI lookup and cache it for further use.

As for application security, the client, which starts the scheduler, should first obtain authorization, implemented through either declarative or programmatic authorization. It is worthwhile to mention that you're starting a multithreaded process here; however, you're not creating a concurrent threads situation because of the thread scheduler's algorithm.

Figure 7. The Scheduler

Pattern name: Integration Rule Engine

Context

You want to automate your integration process and the integration business rule described in a text script, so that each B2BTaskHandler can consult with the Integration Rule Engine about how to conduct the actual tasks, and nonprogrammers can modify the rules.

The problem

When and how do you use a rule engine to help develop a more flexible integration solution?

The forces

Although rule engines can be difficult to use, many frequently changing and sometimes poorly structured B2B tasks can benefit from a rule engine.Consider a billing module for the TSP company from

Part 1

. Pricing for the call is based on combined rules derived from marketing concerns, local regulations, various subcarriers, and special arrangements with large customers -- all on top of the expected rules based on time-of-day, the call's physical distance, its duration, and whether it was a prepaid or postpaid.

The solution

You can pick from several options for embedding a rule engine in J2EE-based systems. JESS (Java Expert System Shell) allows rules to access any JavaBean's get or set methods as simple property values (see Resources).

In E++, I suggest you load a rule engine with RuleEngineController, which provides you with a RuleEngine instance, rule parser, and fact-assert functionality. The RuleEngine can be implemented as a stateless session EJB so that the container can handle any security issues. You define specific business rules in clp script. Each B2Bhandler uses one rule engine instance to fulfill its task. Therefore, you can define your working memory element (WME) to resolve conflict set (CS). The UML diagram is also shown in Figure 7.

Pattern name: Dispatcher

Context

You want to design a remote service dispatcher so that B2BTaskHandler can get services from it without being bound in any specific service implementation.

The problem

How do you design a dispatcher that dynamically loads or removes available remote services?

The forces

Even if the B2BTaskHandler or RuleEngine want specific remote services, they shouldn't need to know the services' locations. In case of any service failure or network problem, you could change the services dynamically.

The solution

The Dispatcher component acts as an intermediate layer between B2BTaskHandler and services. The Dispatcher implements a unique service name so the handlers can refer to services by a simple string name instead of their implementation details. The handlers rely on the Dispatcher to locate a particular service; the Dispatcher's registration maintains all the available services. As another benefit, Dispatcher provides methods so the administrator can add or remove services dynamically. One could think of having a daemon process running against the Dispatcher to update the list of available services.

The Dispatcher's UML diagram is shown in Figure 7.

Pattern name: XML DTD

Context

According to your business requirements, to communicate with backend services you need to use an XML schema to define your messaging.

The problem

Should you define your own XML schema?

The forces

XML's real strength will become apparent as more industries agree on standard schemas. However, due to competition concerns, numerous companies continue to define proprietary XML schemas. Moreover, XML does not define how information content should be structured. As a result, you'll face difficulties when dealing with business integration.

The solution

Because DTD schema design requires effort, in an ideal world you could adopt a well-accepted schema as your own. (I've provided links to preconstructed e-commerce schemas in Resources.)

If you cannot find a predefined schema to fit your needs, you'll have to develop one yourself. In that case, consider these points:

  • How do you represent information for integration? Take as an example an order.xml in the TSP case from Part 1. To me, designing a good XML DTD is similar to designing a Java object. An order.xml attribute acts just like a private attribute in an Order.java object, such as orderId. The Order.java object contains several objects, such as credit card, billing address, order date -- these should be elements.
  • In a serious integration application, XML transformation proves essential. As such, you shouldn't deal directly with any incoming XML responses from the backend systems. In that way, you carry your partner's specifications to your problem. You do want to transfer the schemas into your XML schema so your application handles only one DOM structure converted from the schema. As such, in case you need to integrate with new partners in the future, you won't have to change much. The Java API for XML Parsing (JAXP) 1.1 provides a standard way for an application to access any XML-conformant parser and XSLT-conformant processor.

Pattern name: Security

Context

You understand that to secure your communications with your business partners, you must address security.

The problem

TCP connections are subject to eavesdropping, spoofing, masquerading, false packet insertion, and packet modification. What level of security do you need to build trusted relationship with your business partners?

The forces

Your potential integration partners will be either within the same large organization or over the Internet, so you must address all possible scenarios to secure the remote method invocations or messaging communication.

The solution

Recent cryptography technologies can make your Internet communication acceptably secure. You can choose from several well-accepted security standards:

1 2 3 Page 2
Page 2 of 3