Abstract
Most of the functionality in the FUSE Services Framework runtime is implemented by interceptors. Every endpoint created by the FUSE Services Framework runtime has three potential interceptor chains for processing messages. The interceptors in the these chains are responsible for transforming messages between the raw data transported across the wire and the Java objects handled by the endpoint's implementation code. The interceptors are organized into phases to ensure that processing happens on the proper order.
A large part of what FUSE Services Framework does entails processing messages. When a consumer makes a invocation on a remote service the runtime needs to marshal the data into a message the service can consume and place it on the wire. The service provider must unmarshal the message, execute its business logic, and marshal the response into the appropriate message format. The consumer must then unmarshal the response message, correlate it to the proper request, and pass it back to the consumer's application code. In addition to the basic marshaling and unmarshaling, the FUSE Services Framework runtime may also do a number of other things with the message data. For example if WS-RM is activated the runtime must process the message chunks and acknowledgement messages before doing the marshaling and unmarshaling. If security is activated the runtime must do credential validation as part of the message processing sequence.
Figure 1.1, “FUSE Services Framework Interceptor Chains” shows the basic path that a request message takes when it is received by a service provider.
When a FUSE Services Framework developed consumer invokes a remote service the following message processing sequence is started:
The FUSE Services Framework runtime creates an outbound interceptor chain to process the request.
If the invocation starts a two-way message exchange, the runtime creates an inbound interceptor chain and a fault processing interceptor chain.
The request message is passed sequentially through the outbound interceptor chain.
Each interceptor in the chain performs some processing on the message. For example, the FUSE Services Framework supplied SOAP interceptors package the message in a SOAP envelope.
If any of the interceptors on the outbound chain create an error condition the chain is unwound and control is returned to the application level code.
An interceptor chain is unwound by calling the fault processing method on all of the previously invoked interceptors.
The request is dispatched to the appropriate service provider.
When the response is received, it is passed sequentially through the inbound interceptor chain.
If the response is an error message, it is passed into the fault processing interceptor chain.
If any of the interceptors on the inbound chain create an error condition the chain is unwound.
When the message reaches the end of the inbound interceptor chain it is passed back to the application code.
When a FUSE Services Framework developed service provider receives a request from a consumer a similar process takes place:
The FUSE Services Framework runtime creates an inbound interceptor chain to process the request message.
If the request is part of a two-way message exchange, the runtime also creates an outbound interceptor chain and a fault processing interceptor chain.
The request is passed sequentially through the inbound interceptor chain.
If any of the interceptors on the inbound chain create an error condition the chain is unwound and a fault is dispatched to the consumer.
An interceptor chain is unwound by calling the fault processing method on all of the previously invoked interceptors.
When the request reaches the end of the inbound interceptor chain it is passed to the service implementation.
When the response is ready it is passed sequentially through the outbound interceptor chain.
If the response is an exception, it is passed through the fault processing interceptor chain.
If any of the interceptors on the outbound chain create an error condition the chain is unwound and a fault message is dispatched.
Once the request reaches the end of the outbound chain, it is dispatched to the consumer.
All of the message processing in the FUSE Services Framework runtime is done by interceptors. Interceptors are POJOs that have access to the message data before it is passed to the application layer. They can do a number of things including transforming the message, stripping headers off of the message, or validating the message data. For example, an interceptor could read the security headers off of a message, validate the credentials against an external security service, and decide if message processing can continue.
The message data available to an interceptor is determined by a number of factors:
the interceptor's chain
the interceptor's phase
the other interceptors that occur earlier in the chain
Interceptors are organized into phases. A phase is a logical grouping of interceptors that perform a common portion of the message processing. For example, interceptors that process the marshaled Java objects that are passed to the application layer would all occur in the same phase.
Phases are built into interceptor chains based on the type of message they process. An interceptor chain is a list of interceptors that process either inbound or outbound messages. Each endpoint created using FUSE Services Framework has three interceptor chains:
a chain for inbound messages
a chain for outbound messages
a chain for error messages
The chains are constructed based on the configuration of the endpoint, the bus that manages the endpoint, and a few other internal components. The FUSE Services Framework adds interceptors to an endpoint's interceptor chains based on the protocol in use and the list of features that are configured. For example, WS-RM adds several interceptors to both the inbound and outbound interceptor chains.
Developing an interceptor, regardless of its functionality, always follows the same basic procedure:
Determine what abstract interceptor class to extend.
FUSE Services Framework provides a number of abstract interceptors to make it easier to develop custom interceptors.
Determine the phase in which the interceptor will run.
Interceptors require certain parts of a message to be available and in a certain form. The phase in which an interceptor is executed partially determines what parts of the message is still available and the form of the message data.
The order in which interceptors are executed inside of a phase determines what message data is available.
Implement the interceptor's fault processing logic.
If an error occurs in the active interceptor chain after the interceptor has executed, its fault processing logic is invoked.
Attach the interceptor to one of the endpoint's interceptor chains.