Web Services
The EJB Advocate: SOA Applications Using Java EE
Implementing Loosely Coupled SOA Applications Using Java EE
Jan. 30, 2006 01:00 PM
Still too many options to choose from
Dear EJB Advocate,
Thanks.
I hadn't considered before now that services like JNDI and remote interfaces provide aspects of loose coupling. I can also see how we (as you put it) "tightly coupled" the idea of SOAP and MQ, and should try to separate them where possible. So it makes a lot of sense to treat the parsing and generating of SOAP messages like a service itself that is reused by the Web services servlet and the MDB.
But no thanks.
Before this discussion, SOA seemed pretty simple: every service exposed a SOAP/MQ interface. Now it seems that I have too many choices to think about, and since I am treating the SOAP message parsing and generation like services, why wouldn't I want to make a separate session bean to encapsulate them for reuse like you show in your figures?
I'm afraid that I am:
Still Disconnected
Not everything is a service: use the business model to decide
Dear Disconnected,
This discussion is a great example of what happens when you get down to the implementation details too soon. The EJB Advocate column, "Which type of EJB component should assemble the data returned by a service?" was important because it describes a top-down approach to defining services that tied them directly to the business process model. To summarize the essential details of that approach here:
1. Develop a model of the business process, showing the major milestones in the lifecycle of an important domain object
a. We used a state-transition diagrams for this model, where the states represent the milestones, and the transitions represent events that cause changes in that state. The transitions can be considered the services offered by the application (see Figure 5 for an example).
b. We extend the state-transition diagram with UML "Actor" notation to show the owner of the object when it is in that state. The owner of the state is responsible for initiating the transitions, so drives the security model of the application (also see Figure 5).
c. For each state in the business process, we also model the attributes of each domain object and the relationships between them needed to support the actions of the transitions. The notation we typically use is a UML class diagram (see Figure 6 for an example). Having separate diagrams for each state let us model the changing "shape" of the object over time. These diagrams drive the persistent data.
2. Develop a model of the user interface flow, showing how a given actor from the business process will interact with the system during a typical "session."
a. Like the business process model, we used a state-transition diagram, where the states indicate the screens and dialogs and the transitions represents the actual UI events, like menu items being selected and buttons being pressed. The actions associated with the transitions are specified in terms of business process transitions.
b. Also like the business process model, we build a class diagram to show the data that must be visible in each state to support the various choices. The implication is that this data must be derivable from user inputs and drives the read operations on the services in a top down fashion.
c. Unlike the business process model, we need not extend the state diagram with Actor notation, since the diagram itself can be thought of as a "day in the life" of a single user role.
This comprehensive approach insures that:
- The right operations are grouped together into a service (all the transitions and read methods associated with a state in the business process lifecycle).
- The purpose of each service is well understood (the actions are specified in terms of the related business objects).
- The pre-conditions needed to invoke a service and the post conditions that can result are communicated (the current state and optional guards, as well as the next state are specified by the transition).
- The user role responsible for invoking the service is identified (an actor is associated with each state).
None of this information is provided by a method signature regardless of where they are implemented, but this information is crucial to a good SOA. Otherwise, programmers will fall back on another tendency:
when in doubt, build it over again. Since development costs are higher for SOA (to provide all the different mediators and adaptors needed for the completely loose coupling shown in Figure 4), this tendency against reuse can minimize the benefits.
To answer the issue in your reply about simplicity, none of this information forces you to expose the interfaces in a certain way, and the EJB Advocate has learned that simplicity is in the eye of the beholder. If you want to eliminate choices for the service developer, you can simply provide all of the "blue" components shown Figure 5 for each service:
- A remote service interface to provide location independent synchronous Java EE client access to the service operations.
- A MDB associated with each operation that provides asynchronous non-Java client access over a JMS compliant MQ implementation. Optionally, this or a different MDB can be coded to expect Java messages for JMS clients (to avoid the HTTP Parsing overhead).
- A Web services servlet associated with each operation that provides synchronous SOAP over HTTP client access. For those worried about the number of unused components that this approach would generate, another approach to simplicity is to apply what the EJB Advocate likes to call client-oriented architecture (COA); give the client exactly what they need to use the service in a way most natural to them.
This COA approach requires looking at the details of the business process and UI models to pick the most likely candidates for each approach. For example:
- Transitions between states in the business process lifecycle are likely candidates for asynchronous services, since there will be a change of "owner" for the associated domain object. For example, the submit method can simply change the state of the order to "submitted" in the open order application (we called this OrderEntry in the example above), and send a JMS message to copy it into the submitted order application (we called this one OrderFulfillment).
- Transitions within states should normally be synchronous, since there is no change of owner. As an example of why these operations should not be asynchronous, imagine if you went to a book seller's Web application and had to poll or wait for a pub-sub event for the catalog to be displayed or an item to be added to the shopping cart! And for those that want to use a pseudo-synchronous style over an asynchronous channel, please, please, please, see Bobby Woolf's book on Designing Messaging Systems.
- Only provide SOAP over HTTP or MQ for integration scenarios where you have non-Java clients or services involved.
The COA approach results in the components being developed "just-in-time," which is why the EJB Advocate likes to recommend it.
And a final point to address your question (why not treat everything like a service, even the transformations associated with mediators and adapters): the simple answer goes beyond the fact that there can be too much of a good thing. When developing SOA or COA Java EE applications, it is best to consider services as operations on the business process model. Services have to do with the functional requirements of the application. Mediations and the associated transformations are associated with the non-functional requirements like reliability, usability, efficiency, maintainability, and portability. If you treat the mediations or the associated transformations as a first class service, you eventually obscure the real purpose of the application.
I know this is a lot to take in, so do not hesitate to contact me on the details as you apply these approaches.
OK then,
Your EJB Advocate
Conclusion
The dialog in these exchanges show how Java EE provides a complete implementation framework for applications employing service-oriented architecture, with each component or API playing an important role in some aspect of "loose coupling":
- Operating system independence is provided by Java itself because Java provides a write-once run anywhere language for components that decouples your code from the underlying operating system.
- Implementation independence is provided by the Java Naming and Directory Interface (JNDI), with the ability to bind a logical name to an implementation at runtime.
- Location independence is provided by remote interfaces using RMI over IIOP to stateless session beans or entity home methods that encapsulate the services. RMI/IIOP is a stateful connection that is relatively fast, but does not scale all that well.
- Web server independence is provided by HttpServlets that can respond to the synchronous HTTP protocol. Unlike RMI/IIOP, HTTP is (normally) a stateless protocol that scales well, but does not perform as well due to the size of the messages and the need to create and break down the connection between client and server each time.
- Application independence is provided by the asynchronous Java Messaging Service (or MQ for non-Java clients) and message-driven beans (for the queue handler).
- Language independence is provided by using a standard message format like SOAP, whether it flows on RMI/IIOP, HTTP, or MQ. Thus, SOAP may be used by every component, but it is important to only use it when necessary.
We are willing to bet you can find others. The challenge is managing the tradeoffs associated with each. That should keep you busy until next year.
Resources
- Java Platform, Enterprise Edition (JEE) specification (formerly J2EE); the '2' was dropped in order to separate the main concept of a Java platform for the enterprise from a specific version.
- Enterprise Java Programming with IBM WebSphere, Second Edition by Kyle Brown, Gary Craig, Greg Hester, Russell Stinehour, W. David Pitt, Mark Weitzel, JimAmsden, Peter M. Jakab, Daniel Berg. Foreword by Martin Fowler.
- Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions by Gregor Hohe and Bobby Wolfe. Has a number of really great patterns and anti-patterns associated with messaging applications.
About Geoff HambrickGeoff Hambrick is a lead consultant with the IBM Software Services for WebSphere Enablement Team and lives in Round Rock, Texas (near to Austin). The Enablement Team generally helps support the pre-sales process through deep technical briefings and short term Proof of Concept engagements. Geoff was appointed an IBM Distinguished Engineer in March of 2004 for his work in creating and disseminating best practices for developing J2EE applications hosted on IBM WebSphere Application Server.