CDI - Service Contracts
kcbabo Nov 24, 2010 11:27 AMTom Fennelly wrote:
How do we plan on dealing with non-object payloads (e.g. XML, JSON, etc.)? Obviously this can be handled through handlers or other services, but my point is how would this be expressed easily by the developer that is adding the @Service annotation to provide or consume a service from a bean?
Yeah... been wondering about this too. To me, this is a more general transformation issue and so is probably part of a wider discussion.
I don't think it makes sense to define transformation details on the @ESBService itself because that has implications all the way back. I don't really like the idea of defining them on the Consumer class either because I think that's hardwiring details into the consumer + requires the consumer to have detailsed knowledge of the provider (tight coupling etc).
Ideally, I think transformation details should be defined as part of each possible Exchange, so that different transformations can be defined, depending on the source/target details of the exchange.
Some random use cases...
- CDI <-> CDI: No transformation required, or a Java to Java transform (e.g. where the API changed in a new version). Or perhaps you want Java <-> JSON <-> Java on the exchange, where JSON is what's sent between sender and receiver etc etc
- File Component <-> CDI: Obviosuly depends on the file payload e.g. XML to Java.
- CDI <-> XML Consumer Service: Java to XML
- etc
How will this work in an environment where Weld and SwitchYard are deployed as indpedent services? Lifecycle and classloading are two sticky points that need to be resolved.
I think this part of a more general discussion around how service contracts are handled between CDI and SwitchYard. As you stated, transformation between formats is a processing detail that is outside the scope of the definition of the service itself. That said, in order to perform transformation, we need to know which formats are used/expected by the service consumer and provider.
Let's start with a bare bones service contract that consists of a service name, a set of operations, and the definition of inputs and output messages. Applying that to providing a service from CDI:
Service Name :
- Defaults to bean name
- Can be overriden with @Service annotation property
Operations:
- Do we need a JSR-181 style set of rules for which methods are exposed as service operations? Or do we simplify and say any public method?
- Do we include any methods on the bean class and its super class(es)? Or should we require an interface that is annotated with @Service which is then implemented by the bean? This would solve the issue of which methods to include.
- I wonder if we need a default contact, similar to the way process() works today.
- As an aside, I think this is mainly a concern for contract publishing from SwitchYard. The dispatch logic in our CDI extension uses this information, but only to connect an inbound exchange with the correct Java method to invoke.
Inputs/Outputs:
- The most straightforward option is for input and output to be a Java object. This is easily handled by CDI, natch, but I think it represents a minority of the cases for SwitchYard.
- The majority of cases will involve a non-object payload in the request message. This can be handled in two ways:
- 1) The bean method can declare a type that directly maps to the request message type (e.g. StreamMessage, XMLMessage, etc.)
- 2) We can transform the request message
- For #2, we can support an annotation on the service that provides a pointer to the transformation logic (e.g. JAXBContext, smooks transform). Or we can make this part of the configuration surrounding the service that maps to an exchange handler. Or we could support both.