Swordfish Documentation: Architecture: Parameter Propagation
In a SOA environment service consumers and service providers need the ability to communicate technical parameters additional to the message payload. Swordfish supports this requirement by providing an SwordfishCallContext class which allows service participants (consumer/provider) to set and read technical properties via static access to a Map storing the parameters. From the consumer side a (Spring)-configuration based solution is preferred to a programmatic solution.
These properties can be context or message specific and some of them are propagated together with the message payload.
CXF, which is currently used by Swordfish to support the implementation of service participants via JAX-WS provides such capabilities only for specific technical properties, for security related properties see
Swordfish aims at generalizing the propagation of technical parameters. Other application areas are for instance policy-, correlation- and participant-ids and parameters for policy driven message interceptors. Requirements for the Swordfish participant-parameter-API are:
- Dependencies to specific JAX-WS implementations (like CXF) should be hidden from the Swordish user.
- Extendability: Later addition of other parameters should be easy.
- Parameters related to security, policy handling, correlation, participant identification and configuration of interceptors should be supported out of the box.
- Standards (like WS-Security) should be supported to enable the communication with non-Swordfish participants. This means that standard parameters should be transferred as part of the SOAP message header as specified by the standard.
The following picture illustrates the message flow between a Swordfish service consumer and a Swordfish service provider.
If the communication partner is not realized using Swordfish, its internal structure is irrelevant for the following discussion.
A Swordfish service participant (consumer/provider) uses JAX-WS to call / provide web services. Swordfish currently uses CXF to implement JAX-WS and provides hooks for message handling via interceptors which run inside the Servicemix 4 NMR. Implementing additional Swordfish NMR-interceptors is the standard way how functionality is realized in Swordfish. This principle will also guide the design of the parameter transport mechanism.
The SwordfishCallContext class will be used by the Swordfish service consumer/provider to set and retrieve parameters to be transferred together with the message content. Beside generic parameters the API supports standard parameters (security credentials, policy id, participant id, correlation id) and uses standardized parameter names if possible (WS-Security). The SwordfishCallContext stores its parameters into a (private) ThreadLocal<Map<String,?>> object which means that access to the correct parameter Map is possible only from the same thread.
Technical Parameter Propagation CXF Interceptors
Parameter Propagation CXF Interceptors (separate for providers - TechnicalParameterProviderCXFInterceptor - and consumers - TechnicalParameterConsumerCXFInterceptor) realize the parameter transfer between the SwordfishCallContext and the soap message header. They run in the same thread as the businesscode (consumer/provider) therefore the correct parameter Map is accessed from the SwordfishCallContext.
The TechnicalParameterProviderCXFInterceptor transfers parameters from the soap message header into the SwordfishCallContext.
The TechnicalParameterConsumerCXFInterceptor transfers parameters from the SwordfishCallContext into the soap message header. Additionally it is possible to define via Spring configuration a consumer specific instance of TechnicalParameterConsumerCXFInterceptor. The Spring configuration of this TechnicalParameterConsumerCXFInterceptor instance contains technical parameter settings, so a programmatic use of the SwordfishCallContext could be avoided in this case.
Technical Parameter Propagation NMR-Interceptors
On both sides of the communication (consumer+provider) a Swordfish Servicemix 4 NMR-Interceptor is responsible for transferring the parameters to be transferred between properties of the normalized message and a Swordfish specific parameter map object in the message exchange.
The TechnicalParameterProviderInterceptor reads technical parameters as properties of the normalized message - which before were transferred from the soap header into the normalized message by the binding component. These parameters are transfered into a parameter map object in the message exchange. Other Swordfish NMR interceptors then can read/modify this parameter map. The TechnicalParameterProviderInterceptor should therefore be the first inteceptor in the chain. At the end of the interceptor chain another interceptor is responsible to transfer the new parameters to be propagated from the parameter map into the normalized message. A separate pair of interceptors will be deployed in both directions (incoming/outgoing).
The TechnicalParameterConsumerInterceptor reads technical parameters as properties of the normalized message - which were generated before from the TechnicalParameterConsumerCXFInterceptor. These parameters are transfered into a parameter map object in the message exchange. Other Swordfish NMR interceptors then can read/modify this parameter map. Parameters not to be propagated will be deleted from the normalized message. The TechnicalParameterConsumerInterceptor should be the first inteceptor in the chain. At the end of the interceptor chain another interceptor is responsible to transfer the new parameters to be propagated from the parameter map into the normalized message. The other parameters are then transferred from the normalized message into the soap header by the binding component. A separate pair of interceptors will be deployed in both directions (incoming/outgoing).
Main component classes
The parameter propagation process from the service consumer side is described by the following scenario:
The parameter propagation process from the service provider side is described by the following scenario: