2 Replies Latest reply on Nov 29, 2010 8:00 AM by Tom Fennelly

    CDI - Service Contracts

    Keith Babo Master

      Tom 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...

       

      1. 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
      2. File Component <-> CDI:  Obviosuly depends on the file payload e.g. XML to Java.
      3. CDI <-> XML Consumer Service: Java to XML
      4. 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.
        • 1. Re: CDI - Service Contracts
          Tom Fennelly Master

          Second attempt at replying to this... this SBS software is such a bag of crap!!

           

          Anyway....

           

          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.

           

          This is how we're doing it presently and the reasons I'm currently driving it off an interface were:

          1. Clear definition of the contract methods, as you also stated.
          2. Easy proxy generation via java.reflect.Proxy mechansim Vs having to generate a proxy using javassist (or some other bcm framework).  I'm sure we could reuse some bcm utility code from weld for generating proxies from concrete impls, but still wanted to avoid bcm if possible (for now anyway).

           

          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. 

           

          I think we'll need both, but I do think we can create a simple enough "default" and easy to use mechanism along the lines of the Camel Converter system.  One option here would be for the incoming exchange to have type info set on it and then allow definition of "transformer" beans that apply a from -> to transformation based on this type info.  Obviously we could use the CDI extension to wire in an ExchangeHandler to apply the appropriate mapping.  The transformer class could look something like….

           

          public class OrdersTransformer {
              
              @From(mime = "text/xml", namespace = "http://com.acme/v1/Orders")
              public Orders transformV1XML(Reader inputStream) {
                  // transform logic
              }
              
              @From(mime = "text/xml", namespace = "http://com.acme/v2/Orders")
              public Orders transformV1XML(Reader inputStream) {
                  // transform logic
              }
              
              @From(mime = "text/json", namespace = "http://com.acme/v1/Orders")
              public Orders transformV1JSON(Reader inputStream) {
                  // transform logic
              }    
          }

           

          Of course you could do that in a number of diff ways... have the @From annotation on the method arg... also support a @To annotation etc

          • 2. Re: CDI - Service Contracts
            Tom Fennelly Master

            I split out a specific topic on payload transformation here... http://community.jboss.org/thread/159400?tstart=0